From d9f0514584c909247cfd097dee3e538c1cbd5e0b Mon Sep 17 00:00:00 2001 From: Vlad Scherbich Date: Wed, 18 Feb 2026 17:06:37 -0500 Subject: [PATCH 1/4] unflake a System Test: 'test_remote_sampling_rules_retention' --- tests/parametric/test_dynamic_configuration.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/parametric/test_dynamic_configuration.py b/tests/parametric/test_dynamic_configuration.py index 62cb25a2e0c..8c49d5fcc7e 100644 --- a/tests/parametric/test_dynamic_configuration.py +++ b/tests/parametric/test_dynamic_configuration.py @@ -1,6 +1,7 @@ """Test the dynamic configuration via Remote Config (RC) feature of the APM libraries.""" import json +import time from pathlib import Path from typing import Any @@ -1045,7 +1046,17 @@ def test_remote_sampling_rules_retention(self, test_agent: TestAgentAPI, test_li }, ) - trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") + # After updating the RC config, the library may briefly still be applying the + # previous sampling rules. set_and_wait_rc waits for telemetry and RC acknowledgment, + # but these signals can be satisfied by stale events from the prior config, causing a + # window where the new rules aren't yet active. Retry to allow for full propagation. + trace = None + for _ in range(30): + trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") + span = find_first_span_in_trace_payload(trace) + if span["metrics"].get("_dd.rule_psr", 1.0) == pytest.approx(0.1): + break + time.sleep(0.1) assert_sampling_rate(trace, 0.1) trace = send_and_wait_trace(test_library, test_agent, name="test2", service="svc") From d22ddf44119ef170a33693b25e342ca5e1f2fb80 Mon Sep 17 00:00:00 2001 From: Vlad Scherbich Date: Thu, 19 Feb 2026 08:31:03 -0500 Subject: [PATCH 2/4] Revert "unflake a System Test: 'test_remote_sampling_rules_retention'" This reverts commit 57a30e39b8c04a952fb6e328181ca079b8c63ed2. --- tests/parametric/test_dynamic_configuration.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/parametric/test_dynamic_configuration.py b/tests/parametric/test_dynamic_configuration.py index 8c49d5fcc7e..62cb25a2e0c 100644 --- a/tests/parametric/test_dynamic_configuration.py +++ b/tests/parametric/test_dynamic_configuration.py @@ -1,7 +1,6 @@ """Test the dynamic configuration via Remote Config (RC) feature of the APM libraries.""" import json -import time from pathlib import Path from typing import Any @@ -1046,17 +1045,7 @@ def test_remote_sampling_rules_retention(self, test_agent: TestAgentAPI, test_li }, ) - # After updating the RC config, the library may briefly still be applying the - # previous sampling rules. set_and_wait_rc waits for telemetry and RC acknowledgment, - # but these signals can be satisfied by stale events from the prior config, causing a - # window where the new rules aren't yet active. Retry to allow for full propagation. - trace = None - for _ in range(30): - trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") - span = find_first_span_in_trace_payload(trace) - if span["metrics"].get("_dd.rule_psr", 1.0) == pytest.approx(0.1): - break - time.sleep(0.1) + trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") assert_sampling_rate(trace, 0.1) trace = send_and_wait_trace(test_library, test_agent, name="test2", service="svc") From 42219622ec7027b962723b4ff5c47150f7a2c601 Mon Sep 17 00:00:00 2001 From: Vlad Scherbich Date: Thu, 19 Feb 2026 08:33:21 -0500 Subject: [PATCH 3/4] unrevert the fix --- tests/parametric/test_dynamic_configuration.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/parametric/test_dynamic_configuration.py b/tests/parametric/test_dynamic_configuration.py index 62cb25a2e0c..8c49d5fcc7e 100644 --- a/tests/parametric/test_dynamic_configuration.py +++ b/tests/parametric/test_dynamic_configuration.py @@ -1,6 +1,7 @@ """Test the dynamic configuration via Remote Config (RC) feature of the APM libraries.""" import json +import time from pathlib import Path from typing import Any @@ -1045,7 +1046,17 @@ def test_remote_sampling_rules_retention(self, test_agent: TestAgentAPI, test_li }, ) - trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") + # After updating the RC config, the library may briefly still be applying the + # previous sampling rules. set_and_wait_rc waits for telemetry and RC acknowledgment, + # but these signals can be satisfied by stale events from the prior config, causing a + # window where the new rules aren't yet active. Retry to allow for full propagation. + trace = None + for _ in range(30): + trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") + span = find_first_span_in_trace_payload(trace) + if span["metrics"].get("_dd.rule_psr", 1.0) == pytest.approx(0.1): + break + time.sleep(0.1) assert_sampling_rate(trace, 0.1) trace = send_and_wait_trace(test_library, test_agent, name="test2", service="svc") From 9f8ebf460cdea80a286be362cfc4622c7d2261bb Mon Sep 17 00:00:00 2001 From: Vlad Scherbich Date: Thu, 19 Feb 2026 08:44:54 -0500 Subject: [PATCH 4/4] name magic numbers, add type annotations --- .../parametric/test_dynamic_configuration.py | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/parametric/test_dynamic_configuration.py b/tests/parametric/test_dynamic_configuration.py index 8c49d5fcc7e..57a7553eb1c 100644 --- a/tests/parametric/test_dynamic_configuration.py +++ b/tests/parametric/test_dynamic_configuration.py @@ -1014,22 +1014,25 @@ def test_trace_sampling_rules_with_tags(self, test_agent: TestAgentAPI, test_lib @parametrize("library_env", [{**DEFAULT_ENVVARS}]) def test_remote_sampling_rules_retention(self, test_agent: TestAgentAPI, test_library: APMLibrary) -> None: """Only the last set of sampling rules should be applied""" - rc_state = set_and_wait_rc( + old_rate: float = 0.5 + new_rate: float = 0.1 + max_propagation_retries: int = 30 + + rc_state: dict = set_and_wait_rc( test_agent, config_overrides={ "tracing_sampling_rules": [ { "service": "svc*", "resource": "*", - "sample_rate": 0.5, + "sample_rate": old_rate, "provenance": "customer", } ], }, ) - # Keep a reference on the RC config ID - config_id = rc_state["id"] + config_id: str = rc_state["id"] set_and_wait_rc( test_agent, @@ -1039,7 +1042,7 @@ def test_remote_sampling_rules_retention(self, test_agent: TestAgentAPI, test_li { "service": "foo*", "resource": "*", - "sample_rate": 0.1, + "sample_rate": new_rate, "provenance": "customer", } ], @@ -1050,14 +1053,15 @@ def test_remote_sampling_rules_retention(self, test_agent: TestAgentAPI, test_li # previous sampling rules. set_and_wait_rc waits for telemetry and RC acknowledgment, # but these signals can be satisfied by stale events from the prior config, causing a # window where the new rules aren't yet active. Retry to allow for full propagation. - trace = None - for _ in range(30): + trace: list[Span] | None = None + for _ in range(max_propagation_retries): trace = send_and_wait_trace(test_library, test_agent, name="test", service="foo") - span = find_first_span_in_trace_payload(trace) - if span["metrics"].get("_dd.rule_psr", 1.0) == pytest.approx(0.1): + span: Span = find_first_span_in_trace_payload(trace) + if span["metrics"].get("_dd.rule_psr", 1.0) == pytest.approx(new_rate): break time.sleep(0.1) - assert_sampling_rate(trace, 0.1) + assert trace is not None + assert_sampling_rate(trace, new_rate) trace = send_and_wait_trace(test_library, test_agent, name="test2", service="svc") - assert_sampling_rate(trace, 1) + assert_sampling_rate(trace, DEFAULT_SAMPLE_RATE)