1818telemetry_name_mapping : dict [str , dict [str , str | list [str ]]] = {
1919 "instrumentation_source" : {
2020 "java" : "DD_INSTRUMENTATION_SOURCE" ,
21+ "nodejs" : ["instrumentationSource" , "instrumentation_source" ],
2122 },
2223 "ssi_injection_enabled" : {
2324 "python" : "DD_INJECTION_ENABLED" ,
2425 "java" : "DD_INJECTION_ENABLED" ,
2526 "ruby" : "DD_INJECTION_ENABLED" ,
27+ "nodejs" : ["DD_INJECTION_ENABLED" , "injectionEnabled" , "ssi_injection_enabled" ],
2628 "golang" : ["DD_INJECTION_ENABLED" , "injection_enabled" ],
2729 },
2830 "ssi_forced_injection_enabled" : {
2931 "python" : "DD_INJECT_FORCE" ,
3032 "ruby" : "DD_INJECT_FORCE" ,
3133 "java" : "DD_INJECT_FORCE" ,
34+ "nodejs" : ["DD_INJECT_FORCE" , "injectForce" , "ssi_forced_injection_enabled" ],
3235 "golang" : ["DD_INJECT_FORCE" , "inject_force" ],
3336 },
3437 "trace_sample_rate" : {
4144 },
4245 "logs_injection_enabled" : {
4346 "dotnet" : "DD_LOGS_INJECTION" ,
44- "nodejs" : "DD_LOG_INJECTION " , # TODO: rename to DD_LOGS_INJECTION in subsequent PR
47+ "nodejs" : [ "DD_LOGS_INJECTION " , "DD_LOG_INJECTION" ],
4548 "python" : "DD_LOGS_INJECTION" ,
4649 "php" : "trace.logs_enabled" ,
4750 "ruby" : "DD_LOGS_INJECTION" ,
6770 "trace_enabled" : {
6871 "dotnet" : "DD_TRACE_ENABLED" ,
6972 "java" : "DD_TRACE_ENABLED" ,
70- "nodejs" : " tracing" ,
73+ "nodejs" : [ "DD_TRACE_ENABLED" , " tracing"] ,
7174 "python" : "DD_TRACE_ENABLED" ,
7275 "ruby" : "DD_TRACE_ENABLED" ,
7376 "golang" : ["DD_TRACE_ENABLED" , "trace_enabled" ],
7477 },
7578 "profiling_enabled" : {
7679 "dotnet" : "DD_PROFILING_ENABLED" ,
77- "nodejs" : " profiling.enabled" ,
80+ "nodejs" : [ "DD_PROFILING_ENABLED" , " profiling.enabled"] ,
7881 "python" : "DD_PROFILING_ENABLED" ,
7982 "ruby" : "DD_PROFILING_ENABLED" ,
8083 "golang" : ["DD_PROFILING_ENABLED" , "profiling_enabled" ],
8184 "java" : "DD_PROFILING_ENABLED" ,
8285 },
8386 "appsec_enabled" : {
8487 "dotnet" : "DD_APPSEC_ENABLED" ,
85- "nodejs" : " appsec.enabled" ,
88+ "nodejs" : [ "DD_APPSEC_ENABLED" , " appsec.enabled"] ,
8689 "python" : "DD_APPSEC_ENABLED" ,
8790 "ruby" : "DD_APPSEC_ENABLED" ,
8891 "golang" : ["DD_APPSEC_ENABLED" , "appsec_enabled" ],
8992 "java" : "DD_APPSEC_ENABLED" ,
9093 },
9194 "data_streams_enabled" : {
9295 "dotnet" : "DD_DATA_STREAMS_ENABLED" ,
93- "nodejs" : " dsmEnabled" ,
96+ "nodejs" : [ "DD_DATA_STREAMS_ENABLED" , " dsmEnabled"] ,
9497 "python" : "DD_DATA_STREAMS_ENABLED" ,
9598 "java" : "DD_DATA_STREAMS_ENABLED" ,
9699 "golang" : ["DD_DATA_STREAMS_ENABLED" , "data_streams_enabled" ],
99102 "runtime_metrics_enabled" : {
100103 "java" : "DD_RUNTIME_METRICS_ENABLED" ,
101104 "dotnet" : "DD_RUNTIME_METRICS_ENABLED" ,
102- "nodejs" : " runtime.metrics.enabled" ,
105+ "nodejs" : [ "DD_RUNTIME_METRICS_ENABLED" , " runtime.metrics.enabled"] ,
103106 "python" : "DD_RUNTIME_METRICS_ENABLED" ,
104107 "ruby" : "DD_RUNTIME_METRICS_ENABLED" ,
105108 "golang" : ["DD_RUNTIME_METRICS_ENABLED" , "runtime_metrics_enabled" ],
106109 },
107110 "dynamic_instrumentation_enabled" : {
108111 "java" : "DD_DYNAMIC_INSTRUMENTATION_ENABLED" ,
109112 "dotnet" : "DD_DYNAMIC_INSTRUMENTATION_ENABLED" ,
110- "nodejs" : " dynamicInstrumentation.enabled" ,
113+ "nodejs" : [ "DD_DYNAMIC_INSTRUMENTATION_ENABLED" , " dynamicInstrumentation.enabled"] ,
111114 "python" : "DD_DYNAMIC_INSTRUMENTATION_ENABLED" ,
112115 "php" : "dynamic_instrumentation.enabled" ,
113116 "ruby" : "DD_DYNAMIC_INSTRUMENTATION_ENABLED" ,
@@ -162,16 +165,22 @@ def _check_propagation_style_with_inject_and_extract(
162165 """
163166 # Define the inject and extract key names for each language
164167 if library_name in ("python" , "ruby" ):
165- inject_key = "DD_TRACE_PROPAGATION_STYLE_INJECT"
166- extract_key = "DD_TRACE_PROPAGATION_STYLE_EXTRACT"
168+ inject_keys = [ "DD_TRACE_PROPAGATION_STYLE_INJECT" ]
169+ extract_keys = [ "DD_TRACE_PROPAGATION_STYLE_EXTRACT" ]
167170 elif library_name == "nodejs" :
168- inject_key = " tracePropagationStyle.inject"
169- extract_key = " tracePropagationStyle.extract"
171+ inject_keys = [ "DD_TRACE_PROPAGATION_STYLE_INJECT" , " tracePropagationStyle.inject"]
172+ extract_keys = [ "DD_TRACE_PROPAGATION_STYLE_EXTRACT" , " tracePropagationStyle.extract"]
170173 else :
171174 raise ValueError (f"Unsupported library for inject/extract propagation style: { library_name } " )
172175
173176 # Check inject key
174- inject_item = test_agent .get_telemetry_config_by_origin (configuration_by_name , inject_key , expected_origin )
177+ inject_item = None
178+ inject_key = inject_keys [0 ]
179+ for candidate in inject_keys :
180+ inject_item = test_agent .get_telemetry_config_by_origin (configuration_by_name , candidate , expected_origin )
181+ if inject_item is not None :
182+ inject_key = candidate
183+ break
175184 assert inject_item is not None , (
176185 f"No configuration found for '{ inject_key } ' with origin '{ expected_origin } '. Full configuration_by_name: { configuration_by_name } "
177186 )
@@ -182,7 +191,13 @@ def _check_propagation_style_with_inject_and_extract(
182191 assert inject_item ["value" ], f"Expected non-empty value for '{ inject_key } '"
183192
184193 # Check extract key
185- extract_item = test_agent .get_telemetry_config_by_origin (configuration_by_name , extract_key , expected_origin )
194+ extract_item = None
195+ extract_key = extract_keys [0 ]
196+ for candidate in extract_keys :
197+ extract_item = test_agent .get_telemetry_config_by_origin (configuration_by_name , candidate , expected_origin )
198+ if extract_item is not None :
199+ extract_key = candidate
200+ break
186201 assert extract_item is not None , (
187202 f"No configuration found for '{ extract_key } ' with origin '{ expected_origin } '. Full configuration_by_name: { configuration_by_name } "
188203 )
@@ -320,12 +335,9 @@ def test_library_settings(self, test_agent: TestAgentAPI, test_library: APMLibra
320335 )
321336 == "5.2.0"
322337 )
323- assert (
324- test_agent .get_telemetry_config_by_origin (
325- configuration_by_name , "DD_TRACE_RATE_LIMIT" , "env_var" , return_value_only = True
326- )
327- == "10"
328- )
338+ assert test_agent .get_telemetry_config_by_origin (
339+ configuration_by_name , "DD_TRACE_RATE_LIMIT" , "env_var" , return_value_only = True
340+ ) in ("10" , 10 )
329341 assert (
330342 test_agent .get_telemetry_config_by_origin (
331343 configuration_by_name , "DD_TRACE_HEADER_TAGS" , "env_var" , return_value_only = True
@@ -1084,17 +1096,27 @@ def test_injection_enabled(
10841096 ssi_enabled_telemetry_names = _mapped_telemetry_name ("ssi_injection_enabled" )
10851097 inject_enabled = None
10861098 for ssi_name in ssi_enabled_telemetry_names :
1087- inject_enabled = test_agent .get_telemetry_config_by_origin (
1088- configuration_by_name , ssi_name , "env_var" , fallback_to_first = (expected_value is None )
1089- )
1099+ inject_enabled = test_agent .get_telemetry_config_by_origin (configuration_by_name , ssi_name , "env_var" )
10901100 if inject_enabled is not None :
10911101 break
1102+ if inject_enabled is None and context .library == "nodejs" :
1103+ for ssi_name in ssi_enabled_telemetry_names :
1104+ inject_enabled = test_agent .get_telemetry_config_by_origin (
1105+ configuration_by_name , ssi_name , "calculated" , fallback_to_first = True
1106+ )
1107+ if inject_enabled is not None :
1108+ break
10921109 assert inject_enabled is not None , (
10931110 f"No configuration found for any of { ' or ' .join (ssi_enabled_telemetry_names )} "
10941111 )
10951112 assert isinstance (inject_enabled , dict )
1096- assert inject_enabled .get ("value" ) == expected_value
1097- if expected_value is not None :
1113+ expected_values : tuple [object , ...] = (expected_value ,)
1114+ if context .library == "nodejs" :
1115+ expected_values += ([item .strip () for item in expected_value .split ("," )],)
1116+ assert inject_enabled .get ("value" ) in expected_values
1117+ # Node.js now derives the SSI source config from canonical config entries. Once PR #7734
1118+ # is fully rolled out, restore the strict env_var origin assertion here.
1119+ if expected_value is not None and context .library != "nodejs" :
10981120 assert inject_enabled .get ("origin" ) == "env_var"
10991121
11001122 @pytest .mark .parametrize (
@@ -1132,16 +1154,26 @@ def test_inject_force(self, expected_value: str, test_agent: TestAgentAPI, test_
11321154 inject_force = None
11331155 for inject_force_name in inject_force_telemetry_names :
11341156 inject_force = test_agent .get_telemetry_config_by_origin (
1135- configuration_by_name , inject_force_name , "env_var" , fallback_to_first = ( expected_value == "none" )
1157+ configuration_by_name , inject_force_name , "env_var"
11361158 )
11371159 if inject_force is not None :
11381160 break
1161+ if inject_force is None and context .library == "nodejs" :
1162+ for inject_force_name in inject_force_telemetry_names :
1163+ inject_force = test_agent .get_telemetry_config_by_origin (
1164+ configuration_by_name , inject_force_name , "calculated" , fallback_to_first = True
1165+ )
1166+ if inject_force is not None :
1167+ break
11391168 assert inject_force is not None , (
11401169 f"No configuration found for any of { ' or ' .join (inject_force_telemetry_names )} "
11411170 )
11421171 assert isinstance (inject_force , dict )
11431172 assert str (inject_force .get ("value" )).lower () == expected_value
1144- assert inject_force .get ("origin" ) == "env_var"
1173+ # Node.js now derives the SSI source config from canonical config entries. Once PR #7734
1174+ # is fully rolled out, restore the strict env_var origin assertion here.
1175+ if context .library != "nodejs" :
1176+ assert inject_force .get ("origin" ) == "env_var"
11451177
11461178 @pytest .mark .parametrize ("library_env" , [{** DEFAULT_ENVVARS , "DD_SERVICE" : "service_test" }])
11471179 def test_instrumentation_source_non_ssi (self , test_agent : TestAgentAPI , test_library : APMLibrary ):
@@ -1161,6 +1193,15 @@ def test_instrumentation_source_non_ssi(self, test_agent: TestAgentAPI, test_lib
11611193 )
11621194 if instrumentation_source is not None :
11631195 break
1196+ # Node.js reports instrumentationSource as a calculated value with the new config pipeline.
1197+ # Remove this fallback after PR #7734 lands and older values no longer need coverage.
1198+ if instrumentation_source is None and context .library == "nodejs" :
1199+ for instrumentation_source_name in instrumentation_source_telemetry_names :
1200+ instrumentation_source = test_agent .get_telemetry_config_by_origin (
1201+ configuration_by_name , instrumentation_source_name , "calculated" , fallback_to_first = True
1202+ )
1203+ if instrumentation_source is not None :
1204+ break
11641205 assert instrumentation_source is not None , (
11651206 f"No configuration found for any of { ' or ' .join (instrumentation_source_telemetry_names )} "
11661207 )
@@ -1217,15 +1258,23 @@ def _assert_telemetry_sca_enabled_propagated(
12171258 ):
12181259 assert test_library .is_alive (), "Library container is not running"
12191260 configuration_by_name = test_agent .wait_for_telemetry_configurations ()
1220- dd_appsec_sca_enabled = TelemetryUtils .get_dd_appsec_sca_enabled_str (context .library )
1261+ dd_appsec_sca_enabled_names = TelemetryUtils .get_dd_appsec_sca_enabled_names (context .library )
1262+ dd_appsec_sca_enabled = " or " .join (dd_appsec_sca_enabled_names )
12211263
12221264 logger .info (f"""Check that:
12231265 * the env var DD_APPSEC_SCA_ENABLED={ library_env ["DD_APPSEC_SCA_ENABLED" ]}
12241266 * is reported in telemetry configuration { dd_appsec_sca_enabled } as value={ outcome_value } """ )
12251267
12261268 assert configuration_by_name is not None , "Missing telemetry configuration"
12271269
1228- cfg_appsec_enabled = configuration_by_name .get (dd_appsec_sca_enabled )
1270+ cfg_appsec_enabled = next (
1271+ (
1272+ configuration_by_name .get (config_name )
1273+ for config_name in dd_appsec_sca_enabled_names
1274+ if config_name in configuration_by_name
1275+ ),
1276+ None ,
1277+ )
12291278 logger .info (f"Oberved { dd_appsec_sca_enabled } : { cfg_appsec_enabled } " )
12301279 assert cfg_appsec_enabled is not None , f"Missing telemetry config item for '{ dd_appsec_sca_enabled } '"
12311280
@@ -1239,11 +1288,19 @@ def test_telemetry_sca_enabled_not_propagated(self, test_agent: TestAgentAPI, te
12391288
12401289 assert configuration_by_name is not None , "Missing telemetry configuration"
12411290
1242- dd_appsec_sca_enabled = TelemetryUtils .get_dd_appsec_sca_enabled_str (context .library )
1291+ dd_appsec_sca_enabled_names = TelemetryUtils .get_dd_appsec_sca_enabled_names (context .library )
1292+ dd_appsec_sca_enabled = " or " .join (dd_appsec_sca_enabled_names )
12431293
12441294 if context .library in ("java" , "nodejs" , "python" , "ruby" ):
1245- cfg_appsec_enabled = configuration_by_name .get (dd_appsec_sca_enabled )
1295+ cfg_appsec_enabled = next (
1296+ (
1297+ configuration_by_name .get (config_name )
1298+ for config_name in dd_appsec_sca_enabled_names
1299+ if config_name in configuration_by_name
1300+ ),
1301+ None ,
1302+ )
12461303 assert cfg_appsec_enabled is not None , f"Missing telemetry config item for '{ dd_appsec_sca_enabled } '"
12471304 assert cfg_appsec_enabled [0 ].get ("value" ) is None
12481305 else :
1249- assert dd_appsec_sca_enabled not in configuration_by_name
1306+ assert all ( config_name not in configuration_by_name for config_name in dd_appsec_sca_enabled_names )
0 commit comments