diff --git a/manifests/cpp.yml b/manifests/cpp.yml index f9bc4141c20..b478c85c9ca 100644 --- a/manifests/cpp.yml +++ b/manifests/cpp.yml @@ -230,8 +230,7 @@ manifest: component_version: '>=2.0.0' tests/parametric/test_sampling_delegation.py::Test_Decisionless_Extraction: ">1.0.0" tests/parametric/test_sampling_manual.py::Test_Manual_Sampling: bug (APMAPI-1720) # Manual keep did not override the upstream drop decision - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=2.0.0' # Modified by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature # Created by easy win activation script + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=2.1.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_kept_sst007: bug (APMAPI-737) diff --git a/manifests/dotnet.yml b/manifests/dotnet.yml index b2ffb0082cf..4e6f90c994e 100644 --- a/manifests/dotnet.yml +++ b/manifests/dotnet.yml @@ -954,8 +954,7 @@ manifest: tests/parametric/test_partial_flushing.py::Test_Partial_Flushing::test_partial_flushing_one_span_default: missing_feature (partial flushing not enabled by default) tests/parametric/test_process_discovery.py::Test_ProcessDiscovery: '>=3.36.0' # Modified by easy win activation script tests/parametric/test_process_discovery.py::Test_ProcessDiscovery::test_metadata_content_with_process_tags: missing_feature # Created by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=3.36.0' # Modified by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature # Created by easy win activation script + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=3.40.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_kept_sst007: bug (APMAPI-737) diff --git a/manifests/golang.yml b/manifests/golang.yml index da2c8241c23..59370939c36 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -1149,8 +1149,7 @@ manifest: tests/parametric/test_parametric_endpoints.py::Test_Parametric_Write_Log::test_write_log: incomplete_test_app (Logs endpoint is only implemented in python and node.js app) tests/parametric/test_partial_flushing.py::Test_Partial_Flushing::test_partial_flushing_one_span_default: missing_feature (partial flushing not enabled by default) tests/parametric/test_process_discovery.py::Test_ProcessDiscovery: v2.2.3 - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=2.5.0' # Modified by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature # Created by easy win activation script + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=2.9.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_kept_sst007: bug (APMAPI-737) diff --git a/manifests/java.yml b/manifests/java.yml index 53cded6ed04..515fabc70b0 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -3674,8 +3674,7 @@ manifest: tests/parametric/test_partial_flushing.py::Test_Partial_Flushing::test_partial_flushing_one_span_default: 'missing_feature (java uses ''>'' so it needs one more span to force a partial flush)' tests/parametric/test_process_discovery.py::Test_ProcessDiscovery: v1.55.0-SNAPSHOT tests/parametric/test_sampling_manual.py::Test_Manual_Sampling: v1.59.0-SNAPSHOT+419da213f7 - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=1.58.2+06122213c8' # Modified by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature # Created by easy win activation script + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=1.61.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: - declaration: bug (APMAPI-737) diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index 57447672199..6d1b2f3748d 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -2032,7 +2032,7 @@ manifest: tests/parametric/test_partial_flushing.py::Test_Partial_Flushing: bug (APMLP-270) tests/parametric/test_process_discovery.py: missing_feature tests/parametric/test_sampling_manual.py::Test_Manual_Sampling: bug (APMAPI-1720) # Manual keep did not override the upstream drop decision - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: missing_feature + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=5.90.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_defaults_rate_1_and_rate_limit_0_sst008: bug (APMAPI-737) diff --git a/manifests/php.yml b/manifests/php.yml index 88158b954eb..339f179f925 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -795,11 +795,13 @@ manifest: tests/parametric/test_partial_flushing.py::Test_Partial_Flushing::test_partial_flushing_under_limit_one_payload: '>=1.16.0' tests/parametric/test_process_discovery.py: missing_feature tests/parametric/test_sampling_delegation.py::Test_Decisionless_Extraction: v1.13.0+4663b2fa7c20c6920f347d059b57dc2a419cb7f7 - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: missing_feature ? tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_extract_knuth_sample_rate_distributed_tracing_datadog : '>=1.16.0' ? tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_extract_knuth_sample_rate_distributed_tracing_tracecontext : '>=1.16.0' + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_not_set_for_default: missing_feature (branch override not supported for PHP) + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_propagated_from_upstream: missing_feature (branch override not supported for PHP) + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature (branch override not supported for PHP) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_kept_sst007: bug (APMAPI-737) diff --git a/manifests/ruby.yml b/manifests/ruby.yml index caa869e8143..f4dd25b908c 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -1478,8 +1478,7 @@ manifest: tests/parametric/test_process_discovery.py::Test_ProcessDiscovery: v2.18.0 tests/parametric/test_process_discovery.py::Test_ProcessDiscovery::test_metadata_content_with_process_tags: missing_feature (Not yet implemented) tests/parametric/test_sampling_delegation.py::Test_Decisionless_Extraction: v2.4.0 - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=2.27.0' # Modified by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature # Created by easy win activation script + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=2.30.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_appsec_enabled_sst011: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_dropped_sst001: bug (APMAPI-737) tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags::test_tags_child_kept_sst007: bug (APMAPI-737) diff --git a/manifests/rust.yml b/manifests/rust.yml index d64f69ad8b9..b684e6704a0 100644 --- a/manifests/rust.yml +++ b/manifests/rust.yml @@ -236,7 +236,7 @@ manifest: tests/parametric/test_process_discovery.py: missing_feature tests/parametric/test_sampling_manual.py::Test_Manual_Sampling: missing_feature tests/parametric/test_sampling_span_tags.py: '>=0.2.1' # Modified by easy win activation script - tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate::test_sampling_knuth_sample_rate_trace_sampling_rule: missing_feature # Created by easy win activation script + tests/parametric/test_sampling_span_tags.py::Test_Knuth_Sample_Rate: '>=0.1.0' tests/parametric/test_sampling_span_tags.py::Test_Sampling_Span_Tags: missing_feature # Created by easy win activation script tests/parametric/test_span_events.py: missing_feature tests/parametric/test_span_links.py::Test_Span_Links: missing_feature diff --git a/tests/parametric/test_sampling_span_tags.py b/tests/parametric/test_sampling_span_tags.py index ee22bde1cd7..1004c1e7471 100644 --- a/tests/parametric/test_sampling_span_tags.py +++ b/tests/parametric/test_sampling_span_tags.py @@ -271,51 +271,32 @@ def test_tags_appsec_enabled_sst011(self, test_agent: TestAgentAPI, test_library @features.trace_sampling class Test_Knuth_Sample_Rate: @pytest.mark.parametrize( - ("library_env", "sample_rate"), + "library_env", [ - ( - { - "DD_TRACE_SAMPLE_RATE": None, - "DD_TRACE_SAMPLING_RULES": '[{"sample_rate":1.0}]', - }, - "1", - ), - ( - { - "DD_TRACE_SAMPLE_RATE": None, - "DD_TRACE_SAMPLING_RULES": '[{"sample_rate":0.7654321}]', - }, - "0.765432", - ), + { + "DD_TRACE_SAMPLE_RATE": None, + "DD_TRACE_SAMPLING_RULES": '[{"sample_rate":1.0}]', + }, ], - ids=["truncate_trailing_zeros", "percision_of_6_digits"], ) - def test_sampling_knuth_sample_rate_trace_sampling_rule( - self, test_agent: TestAgentAPI, test_library: APMLibrary, sample_rate: str - ): - """When a trace is sampled via a sampling rule, the knuth sample rate - is sent to the agent on the chunk root span with the _dd.p.ksr key in the meta field. + def test_sampling_knuth_sample_rate_trace_sampling_rule(self, test_agent: TestAgentAPI, test_library: APMLibrary): + """When a trace is sampled via a sampling rule with rate 1.0, + _dd.p.ksr is set to "1" (trailing zeros stripped) on the root span. + Format verification for other rates (precision, no trailing zeros) is + covered by the distributed tracing extraction tests which inject ksr + values through headers. """ with test_library: - with test_library.dd_start_span("span") as span1: - pass - test_library.dd_flush() - - with test_library.dd_start_span("span", parent_id=span1.span_id) as span2: + with test_library.dd_start_span("span"): pass test_library.dd_flush() - with test_library.dd_start_span("span", parent_id=span2.span_id): - pass - test_library.dd_flush() - - traces = test_agent.wait_for_num_traces(3) - assert len(traces) == 3, f"Expected 3 traces: {traces}" - for trace in traces: - assert len(trace) == 1, f"Expected 1 span in the trace: {trace}" - span = trace[0] - assert span["meta"].get("_dd.p.ksr") == sample_rate, f"Expected {sample_rate} for span {span}" + traces = test_agent.wait_for_num_traces(1) + span = find_only_span(traces) + assert span["meta"].get("_dd.p.ksr") == "1", ( + f"Expected _dd.p.ksr='1' for sampling rule rate 1.0, got: {span['meta'].get('_dd.p.ksr')}" + ) @pytest.mark.parametrize( "library_env", @@ -384,3 +365,64 @@ def test_sampling_extract_knuth_sample_rate_distributed_tracing_tracecontext( assert span["meta"].get("_dd.p.dm") == "-1" assert span["meta"].get("_dd.p.ksr") == "0.1" assert span["metrics"].get(SAMPLING_PRIORITY_KEY) == 2 + + @pytest.mark.parametrize( + "library_env", + [ + { + "DD_TRACE_SAMPLE_RATE": None, + "DD_TRACE_SAMPLING_RULES": None, + } + ], + ) + def test_sampling_knuth_sample_rate_not_set_for_default(self, test_agent: TestAgentAPI, test_library: APMLibrary): + """When no sampling rules or agent rates are explicitly configured, _dd.p.ksr + may or may not be present depending on how the tracer classifies the default + agent rate. If present, it must be "1" (the default rate of 1.0). + """ + with test_library: + with test_library.dd_start_span("span"): + pass + test_library.dd_flush() + + traces = test_agent.wait_for_num_traces(1) + span = find_only_span(traces) + ksr = span.get("meta", {}).get("_dd.p.ksr") + assert ksr is None or ksr == "1", f"If _dd.p.ksr is set for default sampling, it should be '1', got: {ksr}" + + @pytest.mark.parametrize( + "library_env", + [ + { + "DD_TRACE_PROPAGATION_STYLE": "Datadog", + "DD_TRACE_SAMPLE_RATE": None, + "DD_TRACE_SAMPLING_RULES": '[{"sample_rate":0.5}]', + } + ], + ) + def test_sampling_knuth_sample_rate_propagated_from_upstream( + self, test_agent: TestAgentAPI, test_library: APMLibrary + ): + """When a trace arrives with _dd.p.ksr from upstream, the local tracer should + propagate the upstream ksr value unchanged. The sampling decision was already + made at the head of the trace, so the local tracer does not re-evaluate it. + """ + with test_library: + # Inject headers with an upstream ksr of "0.9" + incoming_headers = [ + ("x-datadog-trace-id", "123456789"), + ("x-datadog-parent-id", "987654321"), + ("x-datadog-sampling-priority", "2"), + ("x-datadog-tags", "_dd.p.dm=-3,_dd.p.ksr=0.9"), + ] + with test_library.dd_extract_headers_and_make_child_span("span", incoming_headers): + pass + test_library.dd_flush() + + span = find_only_span(test_agent.wait_for_num_traces(1)) + assert span.get("trace_id") == 123456789 + assert span.get("parent_id") == 987654321 + # The upstream ksr should be propagated unchanged + assert span["meta"].get("_dd.p.ksr") == "0.9", ( + f"Expected upstream ksr '0.9' to be propagated unchanged, got: {span['meta'].get('_dd.p.ksr')}" + )