From e695187976d2a38a5021b9937aa02fab70846768 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 11 Sep 2026 13:55:17 -0600 Subject: [PATCH 1/3] test: isolate sidecar sampling updates --- .../agent_sampling_sidecar.phpt | 55 ++++++------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/tests/ext/background-sender/agent_sampling_sidecar.phpt b/tests/ext/background-sender/agent_sampling_sidecar.phpt index 79b487830ed..2c51ae3ee8b 100644 --- a/tests/ext/background-sender/agent_sampling_sidecar.phpt +++ b/tests/ext/background-sender/agent_sampling_sidecar.phpt @@ -18,10 +18,9 @@ datadog.trace.agent_test_session_token=background-sender/agent_sampling_sidecar replayRequest(); // cleanup possible leftover -$expected = [1,0,1]; -$error = false; -$get_sampling = function() use ($rr, &$expected, &$error) { +$get_sampling = function($label, $expected) use ($rr) { $root = json_decode($rr->waitForDataAndReplay()["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $priority = $spans[0]["metrics"]["_sampling_priority_v1"]; - if ($priority != array_shift($expected)) { - $error = true; + if ($priority != $expected) { + throw new RuntimeException("{$label} sampling priority: expected {$expected}, got {$priority}"); } return $priority; }; -$rr->setResponse(["rate_by_service" => ["service:,env:" => 0, "service:agent_sampling_sidecar_test,env:first" => 1]]); +$nonce = getmypid() . "-" . bin2hex(random_bytes(8)); +$firstMarker = "service:agent-sampling-sidecar-sync-{$nonce},env:first"; +$secondMarker = "service:agent-sampling-sidecar-sync-{$nonce},env:second"; + +$rr->setResponse(["rate_by_service" => ["service:,env:" => 0, $firstMarker => 1]]); \DDTrace\start_span(); \DDTrace\close_span(); -echo "Initial sampling: {$get_sampling()}\n"; +echo "Initial sampling: {$get_sampling('Initial', 1)}\n"; -checkUpdated("service:agent_sampling_sidecar_test,env:first"); +checkUpdated($firstMarker); -$rr->setResponse(["rate_by_service" => ["service:,env:" => 0, "service:foo,env:none" => 1, "service:agent_sampling_sidecar_test,env:second" => 0]]); +$rr->setResponse(["rate_by_service" => ["service:,env:" => 0, "service:foo,env:none" => 1, $secondMarker => 0]]); -recordContents(); \DDTrace\start_span(); \DDTrace\close_span(); -recordContents(); -checkUpdated("service:agent_sampling_sidecar_test,env:second"); +checkUpdated($secondMarker); -echo "Generic sampling: {$get_sampling()}\n"; +echo "Generic sampling: {$get_sampling('Generic', 0)}\n"; // reset it for other tests $rr->setResponse(["rate_by_service" => []]); -recordContents(); $s = \DDTrace\start_span(); $s->service = "foo"; $s->env = "none"; \DDTrace\close_span(); -recordContents(); -echo "Specific sampling: {$get_sampling()}\n"; - -if ($error && PHP_OS === "Linux") { - var_dump($contents); -} +echo "Specific sampling: {$get_sampling('Specific', 1)}\n"; ?> --EXPECTF-- From a1b6c621e4b2c58320772aadfe74f026f144c0b9 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 11 Sep 2026 13:56:54 -0600 Subject: [PATCH 2/3] test: avoid retrying expected empty traces --- tests/Common/TracerTestTrait.php | 4 ++-- tests/Composer/ComposerInteroperabilityTest.php | 5 ++++- .../GH1070OriginHeaderSegfaultTest.php | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/Common/TracerTestTrait.php b/tests/Common/TracerTestTrait.php index 2ecfe382e8c..9515d79ebb7 100644 --- a/tests/Common/TracerTestTrait.php +++ b/tests/Common/TracerTestTrait.php @@ -178,9 +178,9 @@ public function isolateLimitedTracer($fn, $tracer = null) * This method executes a request into an ad-hoc web server configured with the provided envs and inis that is * created and destroyed with the scope of this test. */ - public function inWebServer($fn, $rootPath, $envs = [], $inis = [], &$curlInfo = null) + public function inWebServer($fn, $rootPath, $envs = [], $inis = [], $retryOnEmptyTraces = true, &$curlInfo = null) { - $retries = 1; + $retries = $retryOnEmptyTraces ? 1 : 0; do { self::putEnv('DD_TRACE_SHUTDOWN_TIMEOUT=666666'); // Arbitrarily high value to avoid flakiness self::putEnv('DD_TRACE_AGENT_RETRIES=3'); diff --git a/tests/Composer/ComposerInteroperabilityTest.php b/tests/Composer/ComposerInteroperabilityTest.php index 95ff9031855..a5ddf820202 100644 --- a/tests/Composer/ComposerInteroperabilityTest.php +++ b/tests/Composer/ComposerInteroperabilityTest.php @@ -30,6 +30,8 @@ protected function ddSetUp() public function testComposerInteroperabilityWhenNoInitHook() { + // Empty traces are the expected result, so they must not trigger the retry + // used by tests which expect the agent to receive a trace. $traces = $this->inWebServer( function ($execute) { $output = $execute(GetSpec::create('default', '/')); @@ -43,7 +45,8 @@ function ($execute) { ], [ 'datadog.trace.sources_path' => 'do_not_exists', - ] + ], + false ); // Will fallback to installed sources, which does not include DDTrace, only api/, thus doing a Noop diff --git a/tests/DistributedTracing/GH1070OriginHeaderSegfault/GH1070OriginHeaderSegfaultTest.php b/tests/DistributedTracing/GH1070OriginHeaderSegfault/GH1070OriginHeaderSegfaultTest.php index f1507567f51..d413e60b8f7 100644 --- a/tests/DistributedTracing/GH1070OriginHeaderSegfault/GH1070OriginHeaderSegfaultTest.php +++ b/tests/DistributedTracing/GH1070OriginHeaderSegfault/GH1070OriginHeaderSegfaultTest.php @@ -31,6 +31,7 @@ function ($execute) use (&$response) { 'DD_TRACE_DEBUG' => 1, ], [], + true, $curlInfo ); From b92e6bced879afcaf1802a6e499b24b64003d2f9 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 11 Sep 2026 16:17:49 -0600 Subject: [PATCH 3/3] test: restore sidecar sampling diagnostics --- .../agent_sampling_sidecar.phpt | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/tests/ext/background-sender/agent_sampling_sidecar.phpt b/tests/ext/background-sender/agent_sampling_sidecar.phpt index 2c51ae3ee8b..32d5471e788 100644 --- a/tests/ext/background-sender/agent_sampling_sidecar.phpt +++ b/tests/ext/background-sender/agent_sampling_sidecar.phpt @@ -18,6 +18,9 @@ datadog.trace.agent_test_session_token=background-sender/agent_sampling_sidecar replayRequest(); // cleanup possible leftover -$get_sampling = function($label, $expected) use ($rr) { +$errors = []; +$get_sampling = function($label, $expected) use ($rr, &$errors) { $root = json_decode($rr->waitForDataAndReplay()["body"], true); $spans = $root["chunks"][0]["spans"] ?? $root[0]; $priority = $spans[0]["metrics"]["_sampling_priority_v1"]; if ($priority != $expected) { - throw new RuntimeException("{$label} sampling priority: expected {$expected}, got {$priority}"); + $errors[] = "{$label} sampling priority: expected {$expected}, got {$priority}"; } return $priority; }; @@ -68,8 +85,10 @@ checkUpdated($firstMarker); $rr->setResponse(["rate_by_service" => ["service:,env:" => 0, "service:foo,env:none" => 1, $secondMarker => 0]]); +recordContents(); \DDTrace\start_span(); \DDTrace\close_span(); +recordContents(); checkUpdated($secondMarker); @@ -78,13 +97,24 @@ echo "Generic sampling: {$get_sampling('Generic', 0)}\n"; // reset it for other tests $rr->setResponse(["rate_by_service" => []]); +recordContents(); $s = \DDTrace\start_span(); $s->service = "foo"; $s->env = "none"; \DDTrace\close_span(); +recordContents(); echo "Specific sampling: {$get_sampling('Specific', 1)}\n"; +if ($errors) { + foreach ($errors as $error) { + echo "{$error}\n"; + } + if (PHP_OS === "Linux") { + var_dump($contents); + } +} + ?> --EXPECTF-- [ddtrace] [info] [%d] Flushing trace of size 1 to send-queue for http://request-replayer:80