From 0cb11db88dcbf89aaabbd17e7203bceffd57bf71 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Fri, 26 Sep 2025 13:20:39 -0400 Subject: [PATCH 01/23] Introduce extended_configs test with dd_tags --- tests/parametric/test_config_consistency.py | 44 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index db17227d21f..c9d35d2a11a 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -404,6 +404,10 @@ def test_dogstatsd_custom_port(self, library_env, test_agent, test_library): }.get(context.library.name, "false"), # Enabled by default in ruby } +SDK_EXTENDED_STABLE_CONFIG = { + "dd_tags": "[tag1:value1,tag2:value2]", +} + class QuotedStr(str): __slots__ = () @@ -502,7 +506,43 @@ def test_default_config( config = test_library.config() assert expected.items() <= config.items() - # @pytest.mark.parametrize("library_env", [{}]) + @pytest.mark.parametrize("library_env", [{}]) + @pytest.mark.parametrize( + ("name", "apm_configuration_default", "expected"), + [ + ( + "tags", + {"DD_TAGS": ["tag1:value1", "tag2:value2"]}, + {**SDK_EXTENDED_STABLE_CONFIG}, + ), + ], + ) + @pytest.mark.parametrize( + "path", + [ + "/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml", + "/etc/datadog-agent/application_monitoring.yaml", + ], + ) + def test_extended_configs( + self, test_agent, test_library, path, library_env, name, apm_configuration_default, expected + ): + with test_library: + self.write_stable_config( + { + "apm_configuration_default": apm_configuration_default, + }, + path, + test_library, + ) + test_library.container_restart() + config = test_library.config() + assert expected.items() <= config.items() + + @missing_feature( + context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], + reason="extended configs are not supported", + ) @pytest.mark.parametrize( "test", [ @@ -629,7 +669,7 @@ def test_config_precedence(self, name, test_agent, test_library, local_cfg, libr context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], reason="UST stable config is phase 2", ) - def test_config_stable(self, library_env, test_agent, test_library): + def test_targeting_rules(self, library_env, test_agent, test_library): path = "/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml" with test_library: self.write_stable_config( From 35996f756d0c74377236bf61cc4778c82188cd98 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Fri, 26 Sep 2025 13:44:04 -0400 Subject: [PATCH 02/23] Correct placement of annotation --- tests/parametric/test_config_consistency.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index c9d35d2a11a..9025688bcd9 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -524,6 +524,10 @@ def test_default_config( "/etc/datadog-agent/application_monitoring.yaml", ], ) + @missing_feature( + context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], + reason="extended configs are not supported", + ) def test_extended_configs( self, test_agent, test_library, path, library_env, name, apm_configuration_default, expected ): @@ -539,10 +543,6 @@ def test_extended_configs( config = test_library.config() assert expected.items() <= config.items() - @missing_feature( - context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], - reason="extended configs are not supported", - ) @pytest.mark.parametrize( "test", [ From 6de816616b56ef1fcbe8a26fe36b1f6d05f6e71c Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Mon, 29 Sep 2025 13:22:08 -0400 Subject: [PATCH 03/23] Enable test for dotnet, python; include test log msg for debugging --- tests/parametric/test_config_consistency.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index 9025688bcd9..3517909e1d8 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -525,7 +525,7 @@ def test_default_config( ], ) @missing_feature( - context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], + context.library in ["ruby", "cpp", "golang", "nodejs", "php"], reason="extended configs are not supported", ) def test_extended_configs( @@ -541,6 +541,7 @@ def test_extended_configs( ) test_library.container_restart() config = test_library.config() + print("TESTING: CONFIG IS", config) assert expected.items() <= config.items() @pytest.mark.parametrize( From 84e78563ceec2af3e947fa090d229beee507ea44 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Mon, 29 Sep 2025 13:45:31 -0400 Subject: [PATCH 04/23] remove print; expose config inside the test assertion --- tests/parametric/test_config_consistency.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index 3517909e1d8..542c480d99c 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -541,8 +541,7 @@ def test_extended_configs( ) test_library.container_restart() config = test_library.config() - print("TESTING: CONFIG IS", config) - assert expected.items() <= config.items() + assert expected.items() <= config.items(), f"Expected config items not found. Actual config is: {config}" @pytest.mark.parametrize( "test", From 27874b74c3c40628932f425bf994dda856b655f3 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Tue, 30 Sep 2025 11:43:44 -0400 Subject: [PATCH 05/23] Use propagation_style for another input --- tests/parametric/test_config_consistency.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index 542c480d99c..619ec7f2214 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -404,10 +404,6 @@ def test_dogstatsd_custom_port(self, library_env, test_agent, test_library): }.get(context.library.name, "false"), # Enabled by default in ruby } -SDK_EXTENDED_STABLE_CONFIG = { - "dd_tags": "[tag1:value1,tag2:value2]", -} - class QuotedStr(str): __slots__ = () @@ -513,9 +509,15 @@ def test_default_config( ( "tags", {"DD_TAGS": ["tag1:value1", "tag2:value2"]}, - {**SDK_EXTENDED_STABLE_CONFIG}, + {"dd_tags": "[tag1:value1,tag2:value2]"}, + ), + ( + "128bit_traceids", + {"DD_TRACE_PROPAGATION_STYLE": "tracecontext"}, + {"dd_trace_propagation_style": "tracecontext"}, ), ], + ids=lambda name: name, ) @pytest.mark.parametrize( "path", @@ -525,7 +527,7 @@ def test_default_config( ], ) @missing_feature( - context.library in ["ruby", "cpp", "golang", "nodejs", "php"], + context.library in ["cpp", "golang", "nodejs"], reason="extended configs are not supported", ) def test_extended_configs( From f4b090818db234b232376abea96592501b379a7f Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Wed, 1 Oct 2025 16:03:24 -0400 Subject: [PATCH 06/23] Introduce telemetry test for extended_configs --- tests/parametric/test_config_consistency.py | 7 +++ tests/parametric/test_telemetry.py | 62 +++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index 619ec7f2214..e223dde6d7e 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -533,6 +533,13 @@ def test_default_config( def test_extended_configs( self, test_agent, test_library, path, library_env, name, apm_configuration_default, expected ): + """Test that SDKs support extended configuration options beyond just product enablement. + + This test uses representative configurations (tags, propagation style) to verify that + stable config supports more than just the basic product enablement configs tested + in test_default_config. It ensures SDKs can handle complex configuration values + like tag arrays and propagation style settings through the stable config mechanism. + """ with test_library: self.write_stable_config( { diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 1a282316bf5..e2c99cb9b2d 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -84,6 +84,9 @@ "ruby": "DD_TRACE_DEBUG", "python": "DD_TRACE_DEBUG", }, + "tags": { + "java": "trace_tags", + }, } @@ -691,6 +694,65 @@ def test_stable_configuration_config_id( assert telemetry_item["origin"] == "local_stable_config" assert "config_id" not in telemetry_item or telemetry_item["config_id"] is None + @pytest.mark.parametrize( + ("local_cfg", "library_env", "fleet_cfg", "expected_origins"), + [ + ( + { + "DD_TAGS": ["tag1:value1", "tag2:value2"], + "DD_TRACE_PROPAGATION_STYLE": "tracecontext", + }, + { + "DD_TELEMETRY_HEARTBEAT_INTERVAL": "0.1", # Decrease the heartbeat/poll intervals to speed up the tests + }, + {"DD_TAGS": ["fleet:tag1", "fleet:tag2"]}, + { + "tags": "fleet_stable_config", + "trace_propagation_style": "local_stable_config", + }, + ) + ], + ) + def test_stable_configuration_origin_extended_configs( + self, local_cfg, library_env, fleet_cfg, test_agent, test_library, expected_origins + ): + """Test that extended configuration options (tags, propagation style) report their origin correctly. + + This test verifies that complex configuration values like tag arrays and propagation + styles are properly tracked with their configuration origin (local vs fleet stable config). + """ + with test_library: + self.write_stable_config( + { + "apm_configuration_default": local_cfg, + }, + "/etc/datadog-agent/application_monitoring.yaml", + test_library, + ) + self.write_stable_config( + { + "apm_configuration_default": fleet_cfg, + }, + "/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml", + test_library, + ) + # Sleep between telemetry events to ensure they are recorded with different timestamps, to later reorder them. + # seq_id can't be used to sort because payloads are sent from different tracer sessions. + time.sleep(1) + test_library.container_restart() + test_library.dd_start_span("test") + configuration_by_name = test_agent.wait_for_telemetry_configurations() + for cfg_name, expected_origin in expected_origins.items(): + apm_telemetry_name = _mapped_telemetry_name(context, cfg_name) + telemetry_item = test_agent.get_telemetry_config_by_origin( + configuration_by_name, apm_telemetry_name, expected_origin + ) + assert ( + telemetry_item is not None + ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'" + assert telemetry_item["origin"] == expected_origin, f"wrong origin for {telemetry_item}" + assert telemetry_item["value"] + DEFAULT_ENVVARS = { # Decrease the heartbeat/poll intervals to speed up the tests From 21a11bf6c1e6d64c52834aecb55ef1b35e0099a2 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Wed, 1 Oct 2025 16:46:34 -0400 Subject: [PATCH 07/23] change dd_tags input to exclude brackets --- tests/parametric/test_config_consistency.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index e223dde6d7e..b4d6ce3059f 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -508,8 +508,8 @@ def test_default_config( [ ( "tags", - {"DD_TAGS": ["tag1:value1", "tag2:value2"]}, - {"dd_tags": "[tag1:value1,tag2:value2]"}, + {"DD_TAGS": "tag1:value1,tag2:value2"}, + {"dd_tags": "tag1:value1,tag2:value2"}, ), ( "128bit_traceids", From 4fcb3dc86fcb8f07bae8ae23188d352b3e2e0c96 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Wed, 1 Oct 2025 16:52:12 -0400 Subject: [PATCH 08/23] Change tags to not use brackets in telemetry test --- tests/parametric/test_telemetry.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index e2c99cb9b2d..817ea6bc223 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -699,15 +699,15 @@ def test_stable_configuration_config_id( [ ( { - "DD_TAGS": ["tag1:value1", "tag2:value2"], + "DD_TAGS": "local1:value1,local2:value2", "DD_TRACE_PROPAGATION_STYLE": "tracecontext", }, { "DD_TELEMETRY_HEARTBEAT_INTERVAL": "0.1", # Decrease the heartbeat/poll intervals to speed up the tests }, - {"DD_TAGS": ["fleet:tag1", "fleet:tag2"]}, + {"DD_TAGS": "fleet1:tag1,fleet2:tag2"}, { - "tags": "fleet_stable_config", + "tags": "fleet_stable_config", # Note: Java reports it with origin:calculated... "trace_propagation_style": "local_stable_config", }, ) From beaa171a2153cf599e71a18b1866cb303cec80c8 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Thu, 2 Oct 2025 09:53:10 -0400 Subject: [PATCH 09/23] run linter --- tests/parametric/test_telemetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 817ea6bc223..6b1b2c13df1 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -707,7 +707,7 @@ def test_stable_configuration_config_id( }, {"DD_TAGS": "fleet1:tag1,fleet2:tag2"}, { - "tags": "fleet_stable_config", # Note: Java reports it with origin:calculated... + "tags": "fleet_stable_config", # Note: Java reports it with origin:calculated... "trace_propagation_style": "local_stable_config", }, ) From 286a6408ac3f11f6fc65c0a8fec9b0f211f6ea87 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Thu, 2 Oct 2025 12:36:56 -0400 Subject: [PATCH 10/23] Modify expected tags value for dotnet --- tests/parametric/test_config_consistency.py | 6 +++++- tests/parametric/test_telemetry.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index b4d6ce3059f..77c0b39b594 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -509,7 +509,11 @@ def test_default_config( ( "tags", {"DD_TAGS": "tag1:value1,tag2:value2"}, - {"dd_tags": "tag1:value1,tag2:value2"}, + { + "dd_tags": ["tag1:value1", "tag2:value2"] + if context.library in ["dotnet"] + else "tag1:value1,tag2:value2" + }, ), ( "128bit_traceids", diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 6b1b2c13df1..478d534b249 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -713,6 +713,10 @@ def test_stable_configuration_config_id( ) ], ) + @missing_feature( + context.library in ["cpp", "golang", "nodejs"], + reason="extended configs are not supported", + ) def test_stable_configuration_origin_extended_configs( self, local_cfg, library_env, fleet_cfg, test_agent, test_library, expected_origins ): From 51021f758503d431139820cdd340145260055dbb Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Thu, 2 Oct 2025 12:42:31 -0400 Subject: [PATCH 11/23] change tags value for php --- tests/parametric/test_config_consistency.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index 77c0b39b594..6963e5c2314 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -511,7 +511,7 @@ def test_default_config( {"DD_TAGS": "tag1:value1,tag2:value2"}, { "dd_tags": ["tag1:value1", "tag2:value2"] - if context.library in ["dotnet"] + if context.library in ["dotnet", "php"] else "tag1:value1,tag2:value2" }, ), From 4c6ee6f07ca139e3996f5ac1d52fb8990bd59818 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Thu, 2 Oct 2025 12:46:47 -0400 Subject: [PATCH 12/23] Make extended_config telemetry test more verbose on failure --- tests/parametric/test_telemetry.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 478d534b249..34dd2116b5f 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -753,8 +753,12 @@ def test_stable_configuration_origin_extended_configs( ) assert ( telemetry_item is not None - ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'" - assert telemetry_item["origin"] == expected_origin, f"wrong origin for {telemetry_item}" + ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" + + actual_origin = telemetry_item.get("origin", "") + assert ( + telemetry_item["origin"] == expected_origin + ), f"Origin mismatch for {telemetry_item}. Expected origin: '{expected_origin}', Actual origin: '{actual_origin}'" assert telemetry_item["value"] From a8751a204cbbcb4ac45604aea3d17cf09673a4c2 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Fri, 3 Oct 2025 15:22:42 -0400 Subject: [PATCH 13/23] Change telemetry order to use propagation_style for fleet override --- tests/parametric/test_telemetry.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index b15a2732c95..64d4ea98267 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -700,16 +700,18 @@ def test_stable_configuration_config_id( [ ( { - "DD_TAGS": "local1:value1,local2:value2", "DD_TRACE_PROPAGATION_STYLE": "tracecontext", + "DD_TAGS": "tag1:value1,tag2:value2", }, { "DD_TELEMETRY_HEARTBEAT_INTERVAL": "0.1", # Decrease the heartbeat/poll intervals to speed up the tests }, - {"DD_TAGS": "fleet1:tag1,fleet2:tag2"}, { - "tags": "fleet_stable_config", # Note: Java reports it with origin:calculated... - "trace_propagation_style": "local_stable_config", + "DD_TRACE_PROPAGATION_STYLE": "datadog", + }, + { + "tags": "local_stable_config", + "trace_propagation_style": "fleet_stable_config", }, ) ], From f3c9b99c837cf189cb379f100ce85291e2e0da08 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Fri, 3 Oct 2025 15:55:55 -0400 Subject: [PATCH 14/23] map tags to DD_TAGS for dotnet telemetry --- tests/parametric/test_telemetry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 64d4ea98267..72519ce879a 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -86,6 +86,7 @@ }, "tags": { "java": "trace_tags", + "dotnet": "DD_TAGS", }, } From e281615fa0664d102e51dbea811301d17ac3c8f2 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Fri, 3 Oct 2025 15:56:48 -0400 Subject: [PATCH 15/23] map tags to DD_TAGS for python telemetry --- tests/parametric/test_telemetry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 72519ce879a..819c80171da 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -87,6 +87,7 @@ "tags": { "java": "trace_tags", "dotnet": "DD_TAGS", + "python": "DD_TAGS", }, } From 6401306e28b61641a2101aa2717dc815fb2221b7 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Fri, 3 Oct 2025 16:10:28 -0400 Subject: [PATCH 16/23] map propagation_style for python and dotnet --- tests/parametric/test_telemetry.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 819c80171da..749ef9597cc 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -89,6 +89,10 @@ "dotnet": "DD_TAGS", "python": "DD_TAGS", }, + "trace_propagation_style": { + "dotnet": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? + "python": "DD_TRACE_PROPAGATION_STYLE", + }, } From 3dabf609443b0d8ffcf7133c432530bc88c61dcf Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Mon, 6 Oct 2025 10:46:00 -0400 Subject: [PATCH 17/23] swap python and dotnet for telemetry mapping - propagation style --- tests/parametric/test_telemetry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 749ef9597cc..8edd4cbb89c 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -90,8 +90,8 @@ "python": "DD_TAGS", }, "trace_propagation_style": { - "dotnet": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? - "python": "DD_TRACE_PROPAGATION_STYLE", + "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? + "dotnet": "DD_TRACE_PROPAGATION_STYLE", }, } From fc653840ad859c12da637391d1967d6d927830a8 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Mon, 6 Oct 2025 10:46:37 -0400 Subject: [PATCH 18/23] Add entry for php telemetry mapping --- tests/parametric/test_telemetry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 8edd4cbb89c..e7b4a97c841 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -92,6 +92,7 @@ "trace_propagation_style": { "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? "dotnet": "DD_TRACE_PROPAGATION_STYLE", + "php": "trace.propagation_style", }, } From 916e25d7aec07d78b0db59f0638095881617af67 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Mon, 6 Oct 2025 10:48:06 -0400 Subject: [PATCH 19/23] Add entry for ruby telemetry mapping --- tests/parametric/test_telemetry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index e7b4a97c841..9ba30845202 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -93,6 +93,7 @@ "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? "dotnet": "DD_TRACE_PROPAGATION_STYLE", "php": "trace.propagation_style", + "ruby": "tracing.propagation_style_inject" # Ruby doesn't emit just tracing.propagation_style?? }, } From 5ffdeb7fc81feaddfdabafe598881143419f33c6 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Mon, 6 Oct 2025 10:53:33 -0400 Subject: [PATCH 20/23] run liner --- tests/parametric/test_telemetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 9ba30845202..7070359a7c5 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -93,7 +93,7 @@ "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? "dotnet": "DD_TRACE_PROPAGATION_STYLE", "php": "trace.propagation_style", - "ruby": "tracing.propagation_style_inject" # Ruby doesn't emit just tracing.propagation_style?? + "ruby": "tracing.propagation_style_inject", # Ruby doesn't emit just tracing.propagation_style?? }, } From 2648b8f3fd4a59eedab3094a0e53d469da821d0c Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Tue, 7 Oct 2025 11:22:42 -0400 Subject: [PATCH 21/23] Use inject and extract propagation style keys for python and ruby --- tests/parametric/test_telemetry.py | 77 ++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 7070359a7c5..2ee5700704e 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -90,10 +90,10 @@ "python": "DD_TAGS", }, "trace_propagation_style": { - "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python doesn't emit just DD_TRACE_PROPAGATION_STYLE?? + "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python reports both _INJECT and _EXTRACT keys "dotnet": "DD_TRACE_PROPAGATION_STYLE", "php": "trace.propagation_style", - "ruby": "tracing.propagation_style_inject", # Ruby doesn't emit just tracing.propagation_style?? + "ruby": "tracing.propagation_style_inject", # Ruby reports both _inject and _extract keys }, } @@ -118,6 +118,48 @@ def _find_configuration_by_origin(config_list: list[dict], origin: str) -> dict return None +def _check_propagation_style_with_inject_and_extract( + test_agent, configuration_by_name: dict, expected_origin: str, library_name: str +) -> None: + """Check both inject and extract propagation style keys for languages that report them separately. + + Some libraries report propagation style using separate inject and extract keys + instead of a single combined key. This function validates that both keys exist with the + expected origin and have non-empty values. + + Raises an AssertionError if either key is missing, has wrong origin, or has empty value + """ + # Define the inject and extract key names for each language + if library_name == "python": + inject_key = "DD_TRACE_PROPAGATION_STYLE_INJECT" + extract_key = "DD_TRACE_PROPAGATION_STYLE_EXTRACT" + elif library_name == "ruby": + inject_key = "tracing.propagation_style_inject" + extract_key = "tracing.propagation_style_extract" + else: + raise ValueError(f"Unsupported library for inject/extract propagation style: {library_name}") + + # Check inject key + inject_item = test_agent.get_telemetry_config_by_origin(configuration_by_name, inject_key, expected_origin) + assert ( + inject_item is not None + ), f"No configuration found for '{inject_key}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" + assert ( + inject_item["origin"] == expected_origin + ), f"Origin mismatch for {inject_item}. Expected origin: '{expected_origin}', Actual origin: '{inject_item.get('origin', '')}'" + assert inject_item["value"], f"Expected non-empty value for '{inject_key}'" + + # Check extract key + extract_item = test_agent.get_telemetry_config_by_origin(configuration_by_name, extract_key, expected_origin) + assert ( + extract_item is not None + ), f"No configuration found for '{extract_key}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" + assert ( + extract_item["origin"] == expected_origin + ), f"Origin mismatch for {extract_item}. Expected origin: '{expected_origin}', Actual origin: '{extract_item.get('origin', '')}'" + assert extract_item["value"], f"Expected non-empty value for '{extract_key}'" + + @scenarios.parametric @rfc("https://docs.google.com/document/d/1In4TfVBbKEztLzYg4g0si5H56uzAbYB3OfqzRGP2xhg/edit") @features.telemetry_app_started_event @@ -758,19 +800,26 @@ def test_stable_configuration_origin_extended_configs( test_library.dd_start_span("test") configuration_by_name = test_agent.wait_for_telemetry_configurations() for cfg_name, expected_origin in expected_origins.items(): - apm_telemetry_name = _mapped_telemetry_name(context, cfg_name) - telemetry_item = test_agent.get_telemetry_config_by_origin( - configuration_by_name, apm_telemetry_name, expected_origin - ) - assert ( - telemetry_item is not None - ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" + # Python and Ruby only report inject and extract keys for trace_propagation_style + if cfg_name == "trace_propagation_style" and context.library.name in ["python", "ruby"]: + _check_propagation_style_with_inject_and_extract( + test_agent, configuration_by_name, expected_origin, context.library.name + ) + else: + # For all other configurations, use the standard mapping + apm_telemetry_name = _mapped_telemetry_name(context, cfg_name) + telemetry_item = test_agent.get_telemetry_config_by_origin( + configuration_by_name, apm_telemetry_name, expected_origin + ) + assert ( + telemetry_item is not None + ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" - actual_origin = telemetry_item.get("origin", "") - assert ( - telemetry_item["origin"] == expected_origin - ), f"Origin mismatch for {telemetry_item}. Expected origin: '{expected_origin}', Actual origin: '{actual_origin}'" - assert telemetry_item["value"] + actual_origin = telemetry_item.get("origin", "") + assert ( + telemetry_item["origin"] == expected_origin + ), f"Origin mismatch for {telemetry_item}. Expected origin: '{expected_origin}', Actual origin: '{actual_origin}'" + assert telemetry_item["value"] DEFAULT_ENVVARS = { From c37fcab87021106edd3494c886ff85fd9de7c34b Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Wed, 8 Oct 2025 13:24:33 -0400 Subject: [PATCH 22/23] Split config test into 'default' and 'rules' --- manifests/cpp.yml | 1 + manifests/dotnet.yml | 1 + manifests/golang.yml | 1 + manifests/java.yml | 1 + manifests/nodejs.yml | 1 + manifests/php.yml | 1 + manifests/python.yml | 1 + manifests/ruby.yml | 1 + tests/parametric/test_config_consistency.py | 17 ++-- tests/parametric/test_telemetry.py | 95 ++++++++++++++++----- 10 files changed, 92 insertions(+), 28 deletions(-) diff --git a/manifests/cpp.yml b/manifests/cpp.yml index 2603788cb19..e66a7bce353 100644 --- a/manifests/cpp.yml +++ b/manifests/cpp.yml @@ -19,6 +19,7 @@ tests/: Test_Config_TraceLogDirectory: missing_feature Test_Config_UnifiedServiceTagging: ">1.0.0" Test_Stable_Config_Default: missing_feature + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: missing_feature test_dynamic_configuration.py: TestDynamicConfigV1_EmptyServiceTargets: ">1.0.0" diff --git a/manifests/dotnet.yml b/manifests/dotnet.yml index 1e0b956007f..e2c42a63e6e 100644 --- a/manifests/dotnet.yml +++ b/manifests/dotnet.yml @@ -550,6 +550,7 @@ tests/: Test_Config_TraceLogDirectory: v3.3.0 Test_Config_UnifiedServiceTagging: v3.3.0 Test_Stable_Config_Default: v3.28.0 + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: Test_Crashtracking: v3.2.0 test_dynamic_configuration.py: diff --git a/manifests/golang.yml b/manifests/golang.yml index dc67e4b1693..4f639b81f42 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -749,6 +749,7 @@ tests/: Test_Config_TraceLogDirectory: v1.70.0 Test_Config_UnifiedServiceTagging: v1.72.0 Test_Stable_Config_Default: v2.1.0-dev.2 + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: missing_feature test_dynamic_configuration.py: TestDynamicConfigSamplingRules: v1.64.0 diff --git a/manifests/java.yml b/manifests/java.yml index 32b24b88c00..ff99a1c6dd2 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -2058,6 +2058,7 @@ tests/: Test_Config_TraceLogDirectory: missing_feature Test_Config_UnifiedServiceTagging: v1.41.1 Test_Stable_Config_Default: v1.49.0-SNAPSHOT + Test_Stable_Config_Rules: v1.49.0-SNAPSHOT test_crashtracking.py: Test_Crashtracking: v1.38.0 test_dynamic_configuration.py: diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index 186b04e3c65..706d113e670 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -1287,6 +1287,7 @@ tests/: Test_Config_TraceLogDirectory: missing_feature Test_Config_UnifiedServiceTagging: *ref_5_25_0 Test_Stable_Config_Default: *ref_5_62_0 + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: Test_Crashtracking: *ref_5_27_0 test_dynamic_configuration.py: diff --git a/manifests/php.yml b/manifests/php.yml index 42b20cab92f..e6395d0c601 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -552,6 +552,7 @@ tests/: Test_Config_TraceLogDirectory: missing_feature Test_Config_UnifiedServiceTagging: v1.5.0 Test_Stable_Config_Default: v1.8.0 + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: Test_Crashtracking: v1.3.0 test_dynamic_configuration.py: diff --git a/manifests/python.yml b/manifests/python.yml index 656a7eb6494..5066447fb18 100644 --- a/manifests/python.yml +++ b/manifests/python.yml @@ -1057,6 +1057,7 @@ tests/: Test_Config_TraceLogDirectory: missing_feature Test_Config_UnifiedServiceTagging: v2.12.2 Test_Stable_Config_Default: v3.12.0.dev # default value of log injection changed in v3.12.0 + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: Test_Crashtracking: v2.11.2 test_dynamic_configuration.py: diff --git a/manifests/ruby.yml b/manifests/ruby.yml index 6c56f447d6d..524e1073345 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -720,6 +720,7 @@ tests/: Test_Config_TraceLogDirectory: missing_feature Test_Config_UnifiedServiceTagging: v2.5.0 Test_Stable_Config_Default: v2.18.0 + Test_Stable_Config_Rules: missing_feature test_crashtracking.py: Test_Crashtracking: v2.3.0 test_dynamic_configuration.py: diff --git a/tests/parametric/test_config_consistency.py b/tests/parametric/test_config_consistency.py index 7d28a8088d9..7a75ca60008 100644 --- a/tests/parametric/test_config_consistency.py +++ b/tests/parametric/test_config_consistency.py @@ -428,7 +428,7 @@ class CustomDumper(yaml.Dumper): @features.stable_configuration_support @rfc("https://docs.google.com/document/d/1MNI5d3g6R8uU3FEWf2e08aAsFcJDVhweCPMjQatEb0o") class Test_Stable_Config_Default(StableConfigWriter): - """Verify that stable config works as intended""" + """Verify that stable config works as intended (apm_configuration_default)""" @pytest.mark.parametrize("library_env", [{}]) @pytest.mark.parametrize( @@ -680,11 +680,14 @@ def test_config_precedence(self, name, test_agent, test_library, local_cfg, libr "unexpected values for the following configurations: {}" ).format([k for k in config.keys() & expected.keys() if config[k] != expected[k]]) + +@scenarios.parametric +@features.stable_configuration_support +@rfc("https://docs.google.com/document/d/1MNI5d3g6R8uU3FEWf2e08aAsFcJDVhweCPMjQatEb0o") +class Test_Stable_Config_Rules(StableConfigWriter): + """Verify that stable config targeting rules work as intended (apm_configuration_rules)""" + @pytest.mark.parametrize("library_env", [{"STABLE_CONFIG_SELECTOR": "true", "DD_SERVICE": "not-my-service"}]) - @missing_feature( - context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], - reason="UST stable config is phase 2", - ) def test_targeting_rules(self, library_env, test_agent, test_library): path = "/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml" with test_library: @@ -713,10 +716,6 @@ def test_targeting_rules(self, library_env, test_agent, test_library): config["dd_service"] == "my-service" ), f"Service name is '{config["dd_service"]}' instead of 'my-service'" - @missing_feature( - context.library in ["ruby", "cpp", "dotnet", "golang", "nodejs", "php", "python"], - reason="UST stable config is phase 2", - ) @pytest.mark.parametrize( "library_extra_command_arguments", [ diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index 2ee5700704e..f244caf5713 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -11,7 +11,7 @@ from .conftest import StableConfigWriter from utils.telemetry_utils import TelemetryUtils -from utils import context, scenarios, rfc, features, missing_feature +from utils import context, scenarios, rfc, features, missing_feature, bug, irrelevant telemetry_name_mapping = { @@ -90,10 +90,8 @@ "python": "DD_TAGS", }, "trace_propagation_style": { - "python": "DD_TRACE_PROPAGATION_STYLE_INJECT", # Python reports both _INJECT and _EXTRACT keys "dotnet": "DD_TRACE_PROPAGATION_STYLE", "php": "trace.propagation_style", - "ruby": "tracing.propagation_style_inject", # Ruby reports both _inject and _extract keys }, } @@ -770,7 +768,79 @@ def test_stable_configuration_config_id( context.library in ["cpp", "golang", "nodejs"], reason="extended configs are not supported", ) - def test_stable_configuration_origin_extended_configs( + @bug(context.library == "python", reason="APMAPI-1630") + @bug(context.library == "ruby", reason="APMAPI-1631") + def test_stable_configuration_origin_extended_configs_good_use_case( + self, local_cfg, library_env, fleet_cfg, test_agent, test_library, expected_origins + ): + """Test that extended configuration options (tags, propagation style) report their origin correctly. + + This test verifies that complex configuration values like tag arrays and propagation + styles are properly tracked with their configuration origin (local vs fleet stable config). + """ + with test_library: + self.write_stable_config( + { + "apm_configuration_default": local_cfg, + }, + "/etc/datadog-agent/application_monitoring.yaml", + test_library, + ) + self.write_stable_config( + { + "apm_configuration_default": fleet_cfg, + }, + "/etc/datadog-agent/managed/datadog-agent/stable/application_monitoring.yaml", + test_library, + ) + # Sleep between telemetry events to ensure they are recorded with different timestamps, to later reorder them. + # seq_id can't be used to sort because payloads are sent from different tracer sessions. + time.sleep(1) + test_library.container_restart() + test_library.dd_start_span("test") + configuration_by_name = test_agent.wait_for_telemetry_configurations() + for cfg_name, expected_origin in expected_origins.items(): + apm_telemetry_name = _mapped_telemetry_name(context, cfg_name) + telemetry_item = test_agent.get_telemetry_config_by_origin( + configuration_by_name, apm_telemetry_name, expected_origin + ) + assert ( + telemetry_item is not None + ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" + + actual_origin = telemetry_item.get("origin", "") + assert ( + telemetry_item["origin"] == expected_origin + ), f"Origin mismatch for {telemetry_item}. Expected origin: '{expected_origin}', Actual origin: '{actual_origin}'" + assert telemetry_item["value"] + + @pytest.mark.parametrize( + ("local_cfg", "library_env", "fleet_cfg", "expected_origins"), + [ + ( + { + "DD_TRACE_PROPAGATION_STYLE": "tracecontext", + "DD_TAGS": "tag1:value1,tag2:value2", + }, + { + "DD_TELEMETRY_HEARTBEAT_INTERVAL": "0.1", # Decrease the heartbeat/poll intervals to speed up the tests + }, + { + "DD_TRACE_PROPAGATION_STYLE": "datadog", + }, + { + "tags": "local_stable_config", + "trace_propagation_style": "fleet_stable_config", + }, + ) + ], + ) + @missing_feature( + context.library in ["cpp", "golang", "nodejs"], + reason="extended configs are not supported", + ) + @irrelevant(context.library in ["java", "php", "dotnet"], reason="temporary use case for python and ruby") + def test_stable_configuration_origin_extended_configs_temporary_use_case( self, local_cfg, library_env, fleet_cfg, test_agent, test_library, expected_origins ): """Test that extended configuration options (tags, propagation style) report their origin correctly. @@ -805,21 +875,8 @@ def test_stable_configuration_origin_extended_configs( _check_propagation_style_with_inject_and_extract( test_agent, configuration_by_name, expected_origin, context.library.name ) - else: - # For all other configurations, use the standard mapping - apm_telemetry_name = _mapped_telemetry_name(context, cfg_name) - telemetry_item = test_agent.get_telemetry_config_by_origin( - configuration_by_name, apm_telemetry_name, expected_origin - ) - assert ( - telemetry_item is not None - ), f"No configuration found for '{apm_telemetry_name}' with origin '{expected_origin}'. Full configuration_by_name: {configuration_by_name}" - - actual_origin = telemetry_item.get("origin", "") - assert ( - telemetry_item["origin"] == expected_origin - ), f"Origin mismatch for {telemetry_item}. Expected origin: '{expected_origin}', Actual origin: '{actual_origin}'" - assert telemetry_item["value"] + if cfg_name == "tags" and context.library.name in ["ruby"]: + continue DEFAULT_ENVVARS = { From f1759a67a928696c3dbf9a5252c39a6b0776a959 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Thu, 9 Oct 2025 14:21:17 -0400 Subject: [PATCH 23/23] mark telemetry test with bug for ruby --- tests/parametric/test_telemetry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parametric/test_telemetry.py b/tests/parametric/test_telemetry.py index f244caf5713..f57306b42c2 100644 --- a/tests/parametric/test_telemetry.py +++ b/tests/parametric/test_telemetry.py @@ -839,6 +839,7 @@ def test_stable_configuration_origin_extended_configs_good_use_case( context.library in ["cpp", "golang", "nodejs"], reason="extended configs are not supported", ) + @bug(context.library == "ruby", reason="APMAPI-1650") @irrelevant(context.library in ["java", "php", "dotnet"], reason="temporary use case for python and ruby") def test_stable_configuration_origin_extended_configs_temporary_use_case( self, local_cfg, library_env, fleet_cfg, test_agent, test_library, expected_origins