|
17 | 17 |
|
18 | 18 | import pytest
|
19 | 19 | import webtest
|
20 |
| -from testing_support.fixtures import override_application_settings, validate_attributes |
| 20 | +from testing_support.fixtures import override_application_settings, validate_attributes, validate_attributes_complete |
21 | 21 | from testing_support.validators.validate_error_event_attributes import validate_error_event_attributes
|
22 | 22 | from testing_support.validators.validate_transaction_event_attributes import validate_transaction_event_attributes
|
23 | 23 | from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics
|
24 | 24 |
|
| 25 | +from newrelic.common.object_wrapper import wrap_function_wrapper |
25 | 26 | from newrelic.api.application import application_instance
|
26 | 27 | from newrelic.api.background_task import BackgroundTask, background_task
|
27 | 28 | from newrelic.api.external_trace import ExternalTrace
|
|
36 | 37 | )
|
37 | 38 | from newrelic.api.web_transaction import WSGIWebTransaction
|
38 | 39 | from newrelic.api.wsgi_application import wsgi_application
|
| 40 | +from newrelic.core.attribute import Attribute |
39 | 41 |
|
40 | 42 | distributed_trace_intrinsics = ["guid", "traceId", "priority", "sampled"]
|
41 | 43 | inbound_payload_intrinsics = [
|
@@ -409,3 +411,65 @@ def _test_inbound_dt_payload_acceptance():
|
409 | 411 | assert not result
|
410 | 412 |
|
411 | 413 | _test_inbound_dt_payload_acceptance()
|
| 414 | + |
| 415 | + |
| 416 | +@pytest.mark.parametrize( |
| 417 | + "sampled,remote_parent_sampled,remote_parent_not_sampled,expected_sampled,expected_priority,expected_adaptive_sampling_algo_called", |
| 418 | + ( |
| 419 | + (True, 'default', 'default', None, None, True), # Uses sampling algo. |
| 420 | + (True, 'always_on', 'default', True, 2, False), # Always sampled. |
| 421 | + (True, 'always_off', 'default', False, 0, False), # Never sampled. |
| 422 | + (False, 'default', 'default', None, None, True), # Uses sampling algo. |
| 423 | + (False, 'always_on', 'default', None, None, True), # Uses sampling alog. |
| 424 | + (False, 'always_off', 'default', None, None, True), # Uses sampling algo. |
| 425 | + (True, 'default', 'always_on', None, None, True), # Uses sampling algo. |
| 426 | + (True, 'default', 'always_off', None, None, True), # Uses sampling algo. |
| 427 | + (False, 'default', 'always_on', True, 2, False), # Always sampled. |
| 428 | + (False, 'default', 'always_off', False, 0, False), # Never sampled. |
| 429 | + ) |
| 430 | +) |
| 431 | +def test_distributed_trace_w3cparent_sampling_decision(sampled, remote_parent_sampled, remote_parent_not_sampled, expected_sampled, expected_priority, expected_adaptive_sampling_algo_called, wrap_sampling_algo_compute_sampled_and_priority): |
| 432 | + required_intrinsics = [] |
| 433 | + if expected_sampled is not None: |
| 434 | + required_intrinsics.append(Attribute(name="sampled", value=expected_sampled, destinations=0b110)) |
| 435 | + if expected_priority is not None: |
| 436 | + required_intrinsics.append(Attribute(name="priority", value=expected_priority, destinations=0b110)) |
| 437 | + |
| 438 | + wrap_function_wrapper("newrelic.api.transaction", "Transaction.sampling_algo_compute_sampled_and_priority", wrap_sampling_algo_compute_sampled_and_priority) |
| 439 | + |
| 440 | + test_settings = _override_settings.copy() |
| 441 | + test_settings.update({ |
| 442 | + "distributed_tracing.sampler.remote_parent_sampled": remote_parent_sampled, |
| 443 | + "distributed_tracing.sampler.remote_parent_not_sampled": remote_parent_not_sampled, |
| 444 | + "span_events.enabled": True, |
| 445 | + }) |
| 446 | + |
| 447 | + @override_application_settings(test_settings) |
| 448 | + @validate_attributes_complete("intrinsic", required_intrinsics) |
| 449 | + @background_task(name="test_distributed_trace_attributes") |
| 450 | + def _test(): |
| 451 | + txn = current_transaction() |
| 452 | + |
| 453 | + headers = { |
| 454 | + "traceparent": f"00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-{int(sampled):02x}", |
| 455 | + "tracestate": f"rojo=f06a0ba902b7,congo=t61rcWkgMzE", |
| 456 | + } |
| 457 | + accept_distributed_trace_headers(headers) |
| 458 | + |
| 459 | + _test() |
| 460 | + |
| 461 | + assert was_called == expected_adaptive_sampling_algo_called |
| 462 | + |
| 463 | + |
| 464 | +@pytest.fixture |
| 465 | +def wrap_sampling_algo_compute_sampled_and_priority(): |
| 466 | + global was_called |
| 467 | + was_called = False |
| 468 | + |
| 469 | + def _wrap_sampling_algo_compute_sampled_and_priority(wrapped, instance, args, kwargs): |
| 470 | + global was_called |
| 471 | + was_called = True |
| 472 | + return wrapped(*args, **kwargs) |
| 473 | + |
| 474 | + return _wrap_sampling_algo_compute_sampled_and_priority |
| 475 | + |
0 commit comments