From c8ceec2241ee27ae97f881cec489b38c61f2df1f Mon Sep 17 00:00:00 2001 From: rochdev Date: Fri, 24 Apr 2026 13:19:32 -0400 Subject: [PATCH 01/15] [nodejs] fix slowest tests --- utils/_context/_scenarios/__init__.py | 6 +++++- utils/_remote_config.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index d7276419b02..8216d230275 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -317,7 +317,11 @@ class _Scenarios: rc_api_enabled=True, appsec_enabled=False, iast_enabled=False, - weblog_env={"DD_APPSEC_WAF_TIMEOUT": "10000000", "DD_APPSEC_TRACE_RATE_LIMIT": "10000"}, # 10 seconds + weblog_env={ + "DD_APPSEC_WAF_TIMEOUT": "10000000", # 10 seconds + "DD_APPSEC_TRACE_RATE_LIMIT": "10000", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", + }, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_rasp], ) diff --git a/utils/_remote_config.py b/utils/_remote_config.py index c8dd28f7976..902b5460956 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -141,7 +141,7 @@ def remote_config_applied(data: dict) -> bool: library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses - time.sleep(2) + time.sleep(0.5) return current_states From 77646f0fd132cd21e45c48426196ce83ef77a3c8 Mon Sep 17 00:00:00 2001 From: rochdev Date: Fri, 24 Apr 2026 13:24:01 -0400 Subject: [PATCH 02/15] also fix APPSEC_API_SECURITY_RC --- utils/_context/_scenarios/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index 8216d230275..7bca7f66f98 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -354,6 +354,7 @@ class _Scenarios: "DD_API_SECURITY_SAMPLE_DELAY": "0.0", "DD_APPSEC_WAF_TIMEOUT": "10000000", "DD_APPSEC_TRACE_RATE_LIMIT": "10000", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, rc_api_enabled=True, doc=""" From fea76374608ad1ea071bcc62faf3a84b5eb96073 Mon Sep 17 00:00:00 2001 From: rochdev Date: Fri, 24 Apr 2026 13:29:05 -0400 Subject: [PATCH 03/15] apply the same fix everywhere --- utils/_context/_scenarios/__init__.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index 7bca7f66f98..8b873c5e01c 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -300,7 +300,7 @@ class _Scenarios: appsec_blocking_full_denylist = EndToEndScenario( "APPSEC_BLOCKING_FULL_DENYLIST", rc_api_enabled=True, - weblog_env={"DD_APPSEC_RULES": None}, + weblog_env={"DD_APPSEC_RULES": None, "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, doc=""" The spec says that if DD_APPSEC_RULES is defined, then rules won't be loaded from remote config. In this scenario, we use remote config. By the spec, when remote config is available, rules file @@ -453,6 +453,7 @@ class _Scenarios: "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": "2.0", "DD_API_SECURITY_REQUEST_SAMPLE_RATE": "1.0", "DD_API_SECURITY_SAMPLE_DELAY": "0.0", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, agent_env={ "DD_INFRASTRUCTURE_MODE": "none", @@ -470,6 +471,7 @@ class _Scenarios: "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": "2.0", "DD_API_SECURITY_REQUEST_SAMPLE_RATE": "1.0", "DD_API_SECURITY_SAMPLE_DELAY": "0.0", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, agent_env={ "DD_INFRASTRUCTURE_MODE": "none", @@ -549,7 +551,7 @@ class _Scenarios: "REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES", rc_api_enabled=True, appsec_enabled=False, - weblog_env={"DD_REMOTE_CONFIGURATION_ENABLED": "true"}, + weblog_env={"DD_REMOTE_CONFIGURATION_ENABLED": "true", "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config, scenario_groups.essentials], ) @@ -562,6 +564,7 @@ class _Scenarios: "DD_DEBUGGER_ENABLED": "1", "DD_REMOTE_CONFIG_ENABLED": "true", "DD_INTERNAL_RCM_POLL_INTERVAL": "1000", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, doc="", scenario_groups=[scenario_groups.remote_config, scenario_groups.essentials], @@ -570,7 +573,7 @@ class _Scenarios: remote_config_mocked_backend_asm_dd = EndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD", rc_api_enabled=True, - weblog_env={"DD_APPSEC_RULES": None}, + weblog_env={"DD_APPSEC_RULES": None, "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, doc=""" The spec says that if DD_APPSEC_RULES is defined, then rules won't be loaded from remote config. In this scenario, we use remote config. By the spec, when remote config is available, rules file @@ -605,7 +608,11 @@ class _Scenarios: remote_config_mocked_backend_asm_features_nocache = EndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE", rc_api_enabled=True, - weblog_env={"DD_APPSEC_ENABLED": "false", "DD_REMOTE_CONFIGURATION_ENABLED": "true"}, + weblog_env={ + "DD_APPSEC_ENABLED": "false", + "DD_REMOTE_CONFIGURATION_ENABLED": "true", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", + }, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config], ) @@ -663,6 +670,7 @@ class _Scenarios: "LIBRARY_CONF_CUSTOM_HEADER_TAGS", additional_trace_header_tags=(VALID_CONFIGS), rc_api_enabled=True, + weblog_env={"DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, doc="Scenario with custom headers to be used with DD_TRACE_HEADER_TAGS", ) library_conf_custom_header_tags_invalid = EndToEndScenario( @@ -696,6 +704,7 @@ class _Scenarios: "DD_TRACE_PROPAGATION_STYLE_EXTRACT": "datadog,tracecontext,b3multi,baggage", "DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT": "restart", "DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED": "true", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, appsec_enabled=False, # disable ASM to test non asm client ip tagging iast_enabled=False, @@ -752,6 +761,7 @@ class _Scenarios: "DD_LOGS_INJECTION": "true", "DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED": "false", "DD_TRACE_OTEL_ENABLED": "true", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, doc="", rc_api_enabled=True, @@ -851,6 +861,7 @@ class _Scenarios: "DD_DYNAMIC_INSTRUMENTATION_ENABLED": "1", "DD_EXCEPTION_REPLAY_ENABLED": "1", "DD_SYMBOL_DATABASE_UPLOAD_ENABLED": "1", + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, library_interface_timeout=5, doc="Test scenario for checking debugger telemetry.", From 02ccdf96090f93720c44b8a544eefc55dd9a88eb Mon Sep 17 00:00:00 2001 From: rochdev Date: Fri, 24 Apr 2026 15:37:57 -0400 Subject: [PATCH 04/15] fix bug in wait_for --- utils/_remote_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/_remote_config.py b/utils/_remote_config.py index 902b5460956..abda7131ff5 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -133,7 +133,7 @@ def remote_config_applied(data: dict) -> bool: if wait_for_acknowledged_status: for state in current_states.configs.values(): - if state["apply_state"] == ApplyState.UNKNOWN: + if state["apply_state"] != ApplyState.ACKNOWLEDGED: return False current_states.state = ApplyState.ACKNOWLEDGED From 9417c54c8805ca945a222919274c8a55731a65c6 Mon Sep 17 00:00:00 2001 From: rochdev Date: Fri, 24 Apr 2026 16:21:19 -0400 Subject: [PATCH 05/15] fix sleep too short --- utils/_remote_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/_remote_config.py b/utils/_remote_config.py index abda7131ff5..3e216babe00 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -133,7 +133,7 @@ def remote_config_applied(data: dict) -> bool: if wait_for_acknowledged_status: for state in current_states.configs.values(): - if state["apply_state"] != ApplyState.ACKNOWLEDGED: + if state["apply_state"] == ApplyState.UNKNOWN: return False current_states.state = ApplyState.ACKNOWLEDGED @@ -141,7 +141,7 @@ def remote_config_applied(data: dict) -> bool: library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses - time.sleep(0.5) + time.sleep(1) return current_states From a2db25cc022589f8573102e76b7e1d8d081ddd83 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Fri, 24 Apr 2026 18:26:39 -0400 Subject: [PATCH 06/15] fix dotnet --- utils/_context/_scenarios/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index 8b873c5e01c..802079f4692 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -321,6 +321,7 @@ class _Scenarios: "DD_APPSEC_WAF_TIMEOUT": "10000000", # 10 seconds "DD_APPSEC_TRACE_RATE_LIMIT": "10000", "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", + "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": "2.0", }, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_rasp], From 173493b04f352146cd44e2aa35df9c8639452c3c Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Fri, 24 Apr 2026 19:43:29 -0400 Subject: [PATCH 07/15] isolate the changes to nodejs --- utils/_context/_scenarios/__init__.py | 17 +++-------------- utils/_context/_scenarios/endtoend.py | 5 +++++ utils/_remote_config.py | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index 802079f4692..f7ab27222da 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -300,7 +300,7 @@ class _Scenarios: appsec_blocking_full_denylist = EndToEndScenario( "APPSEC_BLOCKING_FULL_DENYLIST", rc_api_enabled=True, - weblog_env={"DD_APPSEC_RULES": None, "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, + weblog_env={"DD_APPSEC_RULES": None}, doc=""" The spec says that if DD_APPSEC_RULES is defined, then rules won't be loaded from remote config. In this scenario, we use remote config. By the spec, when remote config is available, rules file @@ -320,8 +320,6 @@ class _Scenarios: weblog_env={ "DD_APPSEC_WAF_TIMEOUT": "10000000", # 10 seconds "DD_APPSEC_TRACE_RATE_LIMIT": "10000", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", - "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": "2.0", }, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_rasp], @@ -355,7 +353,6 @@ class _Scenarios: "DD_API_SECURITY_SAMPLE_DELAY": "0.0", "DD_APPSEC_WAF_TIMEOUT": "10000000", "DD_APPSEC_TRACE_RATE_LIMIT": "10000", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, rc_api_enabled=True, doc=""" @@ -454,7 +451,6 @@ class _Scenarios: "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": "2.0", "DD_API_SECURITY_REQUEST_SAMPLE_RATE": "1.0", "DD_API_SECURITY_SAMPLE_DELAY": "0.0", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, agent_env={ "DD_INFRASTRUCTURE_MODE": "none", @@ -472,7 +468,6 @@ class _Scenarios: "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": "2.0", "DD_API_SECURITY_REQUEST_SAMPLE_RATE": "1.0", "DD_API_SECURITY_SAMPLE_DELAY": "0.0", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, agent_env={ "DD_INFRASTRUCTURE_MODE": "none", @@ -552,7 +547,7 @@ class _Scenarios: "REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES", rc_api_enabled=True, appsec_enabled=False, - weblog_env={"DD_REMOTE_CONFIGURATION_ENABLED": "true", "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, + weblog_env={"DD_REMOTE_CONFIGURATION_ENABLED": "true"}, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config, scenario_groups.essentials], ) @@ -565,7 +560,6 @@ class _Scenarios: "DD_DEBUGGER_ENABLED": "1", "DD_REMOTE_CONFIG_ENABLED": "true", "DD_INTERNAL_RCM_POLL_INTERVAL": "1000", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, doc="", scenario_groups=[scenario_groups.remote_config, scenario_groups.essentials], @@ -574,7 +568,7 @@ class _Scenarios: remote_config_mocked_backend_asm_dd = EndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD", rc_api_enabled=True, - weblog_env={"DD_APPSEC_RULES": None, "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, + weblog_env={"DD_APPSEC_RULES": None}, doc=""" The spec says that if DD_APPSEC_RULES is defined, then rules won't be loaded from remote config. In this scenario, we use remote config. By the spec, when remote config is available, rules file @@ -612,7 +606,6 @@ class _Scenarios: weblog_env={ "DD_APPSEC_ENABLED": "false", "DD_REMOTE_CONFIGURATION_ENABLED": "true", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config], @@ -671,7 +664,6 @@ class _Scenarios: "LIBRARY_CONF_CUSTOM_HEADER_TAGS", additional_trace_header_tags=(VALID_CONFIGS), rc_api_enabled=True, - weblog_env={"DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, doc="Scenario with custom headers to be used with DD_TRACE_HEADER_TAGS", ) library_conf_custom_header_tags_invalid = EndToEndScenario( @@ -705,7 +697,6 @@ class _Scenarios: "DD_TRACE_PROPAGATION_STYLE_EXTRACT": "datadog,tracecontext,b3multi,baggage", "DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT": "restart", "DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED": "true", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, appsec_enabled=False, # disable ASM to test non asm client ip tagging iast_enabled=False, @@ -762,7 +753,6 @@ class _Scenarios: "DD_LOGS_INJECTION": "true", "DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED": "false", "DD_TRACE_OTEL_ENABLED": "true", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, doc="", rc_api_enabled=True, @@ -862,7 +852,6 @@ class _Scenarios: "DD_DYNAMIC_INSTRUMENTATION_ENABLED": "1", "DD_EXCEPTION_REPLAY_ENABLED": "1", "DD_SYMBOL_DATABASE_UPLOAD_ENABLED": "1", - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5", }, library_interface_timeout=5, doc="Test scenario for checking debugger telemetry.", diff --git a/utils/_context/_scenarios/endtoend.py b/utils/_context/_scenarios/endtoend.py index 3b276ebf344..95f79df7e5a 100644 --- a/utils/_context/_scenarios/endtoend.py +++ b/utils/_context/_scenarios/endtoend.py @@ -309,6 +309,11 @@ def configure(self, config: pytest.Config): library = self.weblog_infra.library_name + if library == "nodejs": + self.weblog_infra.http_container.environment.setdefault( + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS", "0.5" + ) + if self._library_interface_timeout is None: if library == "java": self.library_interface_timeout = 25 diff --git a/utils/_remote_config.py b/utils/_remote_config.py index 3e216babe00..09b442388ef 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -141,7 +141,7 @@ def remote_config_applied(data: dict) -> bool: library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses - time.sleep(1) + time.sleep(1 if context.library.name == "nodejs" else 2) return current_states From d907741c4f8e5c0cdfd7c4a47fc1e48c37f465ee Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Fri, 24 Apr 2026 19:45:48 -0400 Subject: [PATCH 08/15] undo change --- utils/_context/_scenarios/__init__.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index f7ab27222da..d7276419b02 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -317,10 +317,7 @@ class _Scenarios: rc_api_enabled=True, appsec_enabled=False, iast_enabled=False, - weblog_env={ - "DD_APPSEC_WAF_TIMEOUT": "10000000", # 10 seconds - "DD_APPSEC_TRACE_RATE_LIMIT": "10000", - }, + weblog_env={"DD_APPSEC_WAF_TIMEOUT": "10000000", "DD_APPSEC_TRACE_RATE_LIMIT": "10000"}, # 10 seconds doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_rasp], ) @@ -603,10 +600,7 @@ class _Scenarios: remote_config_mocked_backend_asm_features_nocache = EndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE", rc_api_enabled=True, - weblog_env={ - "DD_APPSEC_ENABLED": "false", - "DD_REMOTE_CONFIGURATION_ENABLED": "true", - }, + weblog_env={"DD_APPSEC_ENABLED": "false", "DD_REMOTE_CONFIGURATION_ENABLED": "true"}, doc="", scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config], ) From fa0032ee583929844998fc3e5c625cde5e1397e7 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Fri, 24 Apr 2026 19:52:19 -0400 Subject: [PATCH 09/15] fix lint --- utils/_context/_scenarios/endtoend.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/utils/_context/_scenarios/endtoend.py b/utils/_context/_scenarios/endtoend.py index 95f79df7e5a..72e55c0af97 100644 --- a/utils/_context/_scenarios/endtoend.py +++ b/utils/_context/_scenarios/endtoend.py @@ -310,21 +310,19 @@ def configure(self, config: pytest.Config): library = self.weblog_infra.library_name if library == "nodejs": - self.weblog_infra.http_container.environment.setdefault( - "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS", "0.5" - ) + self.weblog_infra.http_container.environment.setdefault("DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS", "0.5") if self._library_interface_timeout is None: if library == "java": self.library_interface_timeout = 25 - elif library in ("golang",): + elif library == "golang": self.library_interface_timeout = 10 elif library in ("nodejs", "ruby"): self.library_interface_timeout = 0 - elif library in ("php",): + elif library == "php": # possibly something weird on obfuscator, let increase the delay for now self.library_interface_timeout = 10 - elif library in ("python",): + elif library == "python": self.library_interface_timeout = 5 else: self.library_interface_timeout = 40 From 1f59966fe2956818ead4cdda23d7913c33c8684d Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Sat, 25 Apr 2026 15:39:56 -0400 Subject: [PATCH 10/15] decrease poll interval and remove sleep for nodejs --- utils/_context/_scenarios/debugger.py | 1 + utils/_remote_config.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/_context/_scenarios/debugger.py b/utils/_context/_scenarios/debugger.py index 2d91293d594..613b3ef4d8a 100644 --- a/utils/_context/_scenarios/debugger.py +++ b/utils/_context/_scenarios/debugger.py @@ -39,6 +39,7 @@ def configure(self, config: pytest.Config): self.weblog_container.environment["DD_DYNAMIC_INSTRUMENTATION_UPLOAD_FLUSH_INTERVAL"] = "0.1" elif library == "nodejs": self.weblog_container.environment["DD_DYNAMIC_INSTRUMENTATION_UPLOAD_INTERVAL_SECONDS"] = "0.1" + self.weblog_container.environment["DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS"] = "0.2" elif library in ("java", "dotnet"): # Java and .NET use UPLOAD_FLUSH_INTERVAL in milliseconds self.weblog_container.environment["DD_DYNAMIC_INSTRUMENTATION_UPLOAD_FLUSH_INTERVAL"] = "100" diff --git a/utils/_remote_config.py b/utils/_remote_config.py index 09b442388ef..399f5302c23 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -141,7 +141,8 @@ def remote_config_applied(data: dict) -> bool: library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses - time.sleep(1 if context.library.name == "nodejs" else 2) + if context.library.name != "nodejs": + time.sleep(2) return current_states From 49571fddfc9e03fbcbf69cd6c2525b763f0a94d8 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Sat, 25 Apr 2026 16:48:38 -0400 Subject: [PATCH 11/15] add back tiny sleep --- utils/_remote_config.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/_remote_config.py b/utils/_remote_config.py index 399f5302c23..ebabcaca98d 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -141,8 +141,7 @@ def remote_config_applied(data: dict) -> bool: library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses - if context.library.name != "nodejs": - time.sleep(2) + time.sleep(0.1 if context.library.name == "nodejs" else 2) return current_states From bc70b59761e7e444336b4d6faded567c8f648829 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Sat, 25 Apr 2026 17:01:27 -0400 Subject: [PATCH 12/15] remove need for sleep --- .../test_debugger_inproduct_enablement.py | 18 +++++++++++------- utils/_remote_config.py | 3 ++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/debugger/test_debugger_inproduct_enablement.py b/tests/debugger/test_debugger_inproduct_enablement.py index d0c732ea753..4325d592f68 100644 --- a/tests/debugger/test_debugger_inproduct_enablement.py +++ b/tests/debugger/test_debugger_inproduct_enablement.py @@ -26,28 +26,32 @@ class Test_Debugger_InProduct_Enablement_Dynamic_Instrumentation(debugger.BaseDe """ def setup_inproduct_enablement_di(self): - def _send_config(*, enabled: bool | None = None, reset: bool = True): + def _configure(*, enabled: bool | None = None, reset: bool = True): probe = json.loads(self._probe_template) probe["id"] = debugger.generate_probe_id("log") self.set_probes([probe]) - self.send_rc_apm_tracing_and_probes(dynamic_instrumentation_enabled=enabled, reset=reset) - self.send_weblog_request("/debugger/log") self.initialize_weblog_remote_config() self.weblog_responses = [] self.rc_states = [] - _send_config() + _configure() + self.send_weblog_request("/debugger/log") self.di_initial_disabled = not self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) - _send_config(enabled=True, reset=False) + _configure(enabled=True, reset=False) + self.wait_for_all_probes(statuses=["INSTALLED"], timeout=TIMEOUT) + self.send_weblog_request("/debugger/log") self.di_explicit_enabled = self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) - _send_config(reset=False) + _configure(reset=False) + self.wait_for_all_probes(statuses=["INSTALLED"], timeout=TIMEOUT) + self.send_weblog_request("/debugger/log") self.di_empty_config = self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) - _send_config(enabled=False, reset=False) + _configure(enabled=False, reset=False) + self.send_weblog_request("/debugger/log") self.di_explicit_disabled = not self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) def test_inproduct_enablement_di(self): diff --git a/utils/_remote_config.py b/utils/_remote_config.py index ebabcaca98d..399f5302c23 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -141,7 +141,8 @@ def remote_config_applied(data: dict) -> bool: library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses - time.sleep(0.1 if context.library.name == "nodejs" else 2) + if context.library.name != "nodejs": + time.sleep(2) return current_states From 00fea28658524541337b9c948d3c76c1a6820f4c Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Sat, 25 Apr 2026 18:05:49 -0400 Subject: [PATCH 13/15] reduce polling observer timeout --- utils/_context/_scenarios/endtoend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/_context/_scenarios/endtoend.py b/utils/_context/_scenarios/endtoend.py index 72e55c0af97..b428e440042 100644 --- a/utils/_context/_scenarios/endtoend.py +++ b/utils/_context/_scenarios/endtoend.py @@ -121,7 +121,7 @@ def _ingest(self, event: FileSystemEvent): # lot of issue using the default OS dependant notifiers (not working on WSL, reaching some inotify watcher # limits on Linux) -> using the good old bare polling system - observer = PollingObserver() + observer = PollingObserver(timeout=0.1) for interface in interfaces: observer.schedule(Event(interface), path=interface.log_folder) From 73b9b1b529e1e706fe4d4057737a3f905a8d8a57 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Sat, 25 Apr 2026 18:10:35 -0400 Subject: [PATCH 14/15] scope optimization only for nodejs --- .../test_debugger_inproduct_enablement.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/debugger/test_debugger_inproduct_enablement.py b/tests/debugger/test_debugger_inproduct_enablement.py index 4325d592f68..56b57b73300 100644 --- a/tests/debugger/test_debugger_inproduct_enablement.py +++ b/tests/debugger/test_debugger_inproduct_enablement.py @@ -26,32 +26,29 @@ class Test_Debugger_InProduct_Enablement_Dynamic_Instrumentation(debugger.BaseDe """ def setup_inproduct_enablement_di(self): - def _configure(*, enabled: bool | None = None, reset: bool = True): + def _send_config(*, enabled: bool | None = None, reset: bool = True, wait_installed: bool = False): probe = json.loads(self._probe_template) probe["id"] = debugger.generate_probe_id("log") self.set_probes([probe]) self.send_rc_apm_tracing_and_probes(dynamic_instrumentation_enabled=enabled, reset=reset) + if wait_installed: + self.wait_for_all_probes(statuses=["INSTALLED"], timeout=TIMEOUT) + self.send_weblog_request("/debugger/log") self.initialize_weblog_remote_config() self.weblog_responses = [] self.rc_states = [] - _configure() - self.send_weblog_request("/debugger/log") + _send_config() self.di_initial_disabled = not self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) - _configure(enabled=True, reset=False) - self.wait_for_all_probes(statuses=["INSTALLED"], timeout=TIMEOUT) - self.send_weblog_request("/debugger/log") + _send_config(enabled=True, reset=False, wait_installed=context.library == "nodejs") self.di_explicit_enabled = self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) - _configure(reset=False) - self.wait_for_all_probes(statuses=["INSTALLED"], timeout=TIMEOUT) - self.send_weblog_request("/debugger/log") + _send_config(reset=False, wait_installed=context.library == "nodejs") self.di_empty_config = self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) - _configure(enabled=False, reset=False) - self.send_weblog_request("/debugger/log") + _send_config(enabled=False, reset=False) self.di_explicit_disabled = not self.wait_for_all_probes(statuses=["EMITTING"], timeout=TIMEOUT) def test_inproduct_enablement_di(self): From ee07ec97c2835db0d8221d371b07bb975b6662c3 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Sat, 25 Apr 2026 19:05:34 -0400 Subject: [PATCH 15/15] undo unfruitiful changes --- utils/_context/_scenarios/endtoend.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/_context/_scenarios/endtoend.py b/utils/_context/_scenarios/endtoend.py index b428e440042..662fd47dfe4 100644 --- a/utils/_context/_scenarios/endtoend.py +++ b/utils/_context/_scenarios/endtoend.py @@ -121,7 +121,7 @@ def _ingest(self, event: FileSystemEvent): # lot of issue using the default OS dependant notifiers (not working on WSL, reaching some inotify watcher # limits on Linux) -> using the good old bare polling system - observer = PollingObserver(timeout=0.1) + observer = PollingObserver() for interface in interfaces: observer.schedule(Event(interface), path=interface.log_folder) @@ -315,14 +315,14 @@ def configure(self, config: pytest.Config): if self._library_interface_timeout is None: if library == "java": self.library_interface_timeout = 25 - elif library == "golang": + elif library in ("golang",): self.library_interface_timeout = 10 elif library in ("nodejs", "ruby"): self.library_interface_timeout = 0 - elif library == "php": + elif library in ("php",): # possibly something weird on obfuscator, let increase the delay for now self.library_interface_timeout = 10 - elif library == "python": + elif library in ("python",): self.library_interface_timeout = 5 else: self.library_interface_timeout = 40