From 76f035df03dfb58df3f4096ef41d428bb9459ee6 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 5 Jul 2024 18:09:59 +0200 Subject: [PATCH 1/3] Add PHP to live debugger system tests --- docs/weblog/README.md | 4 +- manifests/php.yml | 10 +- .../probes/expression_probe_base.json | 1 + tests/debugger/probes/pii.json | 2 + .../debugger/probes/probe_snapshot_line.json | 5 +- .../probes/probe_snapshot_method.json | 5 +- .../probes/probe_snapshot_mix_log.json | 6 +- tests/debugger/probes/probe_status_log.json | 12 +- .../debugger/probes/probe_status_metric.json | 3 + tests/debugger/probes/probe_status_span.json | 2 + .../probes/probe_status_spandecoration.json | 3 + .../test_debugger_expression_language.py | 23 ++- .../debugger/test_debugger_probe_snapshot.py | 13 +- tests/debugger/utils.py | 10 +- utils/_context/containers.py | 1 + utils/_remote_config.py | 7 + .../weblog/Controllers/DebuggerController.cs | 8 +- .../debugger/DebuggerController.java | 8 +- .../build/docker/php/apache-mod/entrypoint.sh | 5 +- utils/build/docker/php/apache-mod/php.conf | 1 + .../build/docker/php/common/await_probes.php | 17 ++ utils/build/docker/php/common/debugger.php | 186 ++++++++++++++++++ utils/build/docker/php/common/php.ini | 2 + utils/build/docker/php/php-fpm/entrypoint.sh | 4 +- 24 files changed, 300 insertions(+), 38 deletions(-) create mode 100644 utils/build/docker/php/common/await_probes.php create mode 100644 utils/build/docker/php/common/debugger.php diff --git a/docs/weblog/README.md b/docs/weblog/README.md index 318aa28081..66a66376e3 100644 --- a/docs/weblog/README.md +++ b/docs/weblog/README.md @@ -587,10 +587,10 @@ This endpoint will be used to validate the span decoration probe. #### GET /debugger/pii This endpoint will be used to validate Dynamic Instrumentation pii redaction feature. -#### GET /expression/* +#### GET /expression* These endpoints will be used to validate Dynamic Instrumentation expression language feature. -#### GET /exceptionreplay/* +#### GET /exceptionreplay* These endpoints will be used to validate Dynamic Instrumentation exception replay feature. ### GET /createextraservice diff --git a/manifests/php.yml b/manifests/php.yml index 55c4541cdd..c88a59883b 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -216,13 +216,13 @@ tests/: test_debugger_exception_replay.py: Test_Debugger_Exception_Replay: irrelevant test_debugger_expression_language.py: - Test_Debugger_Expression_Language: irrelevant + Test_Debugger_Expression_Language: v1.3.0 test_debugger_pii.py: - Test_Debugger_PII_Redaction: irrelevant + Test_Debugger_PII_Redaction: v1.3.0 test_debugger_probe_snapshot.py: - Test_Debugger_Line_Probe_Snaphots: irrelevant - Test_Debugger_Method_Probe_Snaphots: irrelevant - Test_Debugger_Mix_Log_Probe: irrelevant + Test_Debugger_Line_Probe_Snaphots: v1.3.0 + Test_Debugger_Method_Probe_Snaphots: v1.3.0 + Test_Debugger_Mix_Log_Probe: v1.3.0 test_debugger_probe_status.py: Test_Debugger_Probe_Statuses: irrelevant integrations/: diff --git a/tests/debugger/probes/expression_probe_base.json b/tests/debugger/probes/expression_probe_base.json index 2982d6b482..d6ccfab072 100644 --- a/tests/debugger/probes/expression_probe_base.json +++ b/tests/debugger/probes/expression_probe_base.json @@ -1,5 +1,6 @@ [ { + "type": "LOG_PROBE", "language": "", "id": "", "where": { diff --git a/tests/debugger/probes/pii.json b/tests/debugger/probes/pii.json index bdb7ad147f..7bd126eb2b 100644 --- a/tests/debugger/probes/pii.json +++ b/tests/debugger/probes/pii.json @@ -1,5 +1,6 @@ [ { + "type": "LOG_PROBE", "language": "", "pii": "", "id": "log170aa-acda-4453-9111-1478a6method", @@ -9,6 +10,7 @@ "sourceFile": null }, "evaluateAt": "EXIT", + "segments": [], "captureSnapshot": true, "capture": { "maxFieldCount": 200 diff --git a/tests/debugger/probes/probe_snapshot_line.json b/tests/debugger/probes/probe_snapshot_line.json index 4d2a819fd2..1c639d8c0c 100644 --- a/tests/debugger/probes/probe_snapshot_line.json +++ b/tests/debugger/probes/probe_snapshot_line.json @@ -1,5 +1,6 @@ [ { + "type": "LOG_PROBE", "language": "", "type": "", "id": "log170aa-acda-4453-9111-1478a697line", @@ -9,9 +10,11 @@ "lines": [ "20" ] - } + }, + "segments": [] }, { + "type": "SPAN_DECORATION_PROBE", "language": "", "type": "", "id": "decor0aa-acda-4453-9111-1478a697line", diff --git a/tests/debugger/probes/probe_snapshot_method.json b/tests/debugger/probes/probe_snapshot_method.json index 583b254045..541fc85767 100644 --- a/tests/debugger/probes/probe_snapshot_method.json +++ b/tests/debugger/probes/probe_snapshot_method.json @@ -1,5 +1,6 @@ [ { + "type": "LOG_PROBE", "language": "", "type": "", "id": "log170aa-acda-4453-9111-1478a6method", @@ -8,11 +9,12 @@ "methodName": "LogProbe", "sourceFile": null }, + "segments": [], "evaluateAt": "EXIT" }, { + "type": "SPAN_PROBE", "language": "", - "type": "", "id": "span70aa-acda-4453-9111-1478a6method", "where": { "typeName": "ACTUAL_TYPE_NAME", @@ -22,6 +24,7 @@ "evaluateAt": "EXIT" }, { + "type": "SPAN_DECORATION_PROBE", "language": "", "type": "", "id": "decor0aa-acda-4453-9111-1478a6method", diff --git a/tests/debugger/probes/probe_snapshot_mix_log.json b/tests/debugger/probes/probe_snapshot_mix_log.json index 782a8181a3..3e5f29a266 100644 --- a/tests/debugger/probes/probe_snapshot_mix_log.json +++ b/tests/debugger/probes/probe_snapshot_mix_log.json @@ -1,5 +1,6 @@ [ { + "type": "LOG_PROBE", "language": "", "type": "", "id": "logfb5a-1974-4cdb-b1dd-77dba2method", @@ -9,9 +10,11 @@ "methodName": "MixProbe", "sourceFile": null }, + "segments": [], "evaluateAt": "EXIT" }, { + "type": "LOG_PROBE", "language": "", "type": "", "id": "logfb5a-1974-4cdb-b1dd-77dba2f1line", @@ -22,6 +25,7 @@ "lines": [ "52" ] - } + }, + "segments": [] } ] \ No newline at end of file diff --git a/tests/debugger/probes/probe_status_log.json b/tests/debugger/probes/probe_status_log.json index 239c8ae76e..037e598bf3 100644 --- a/tests/debugger/probes/probe_status_log.json +++ b/tests/debugger/probes/probe_status_log.json @@ -1,5 +1,6 @@ [ { + "type": "LOG_PROBE", "language": "", "type": "", "id": "loga0cf2-meth-45cf-9f39-591received", @@ -8,9 +9,11 @@ "methodName": "SomeMethod", "sourceFile": null }, - "evaluateAt": "EXIT" + "evaluateAt": "EXIT", + "segments": [] }, { + "type": "LOG_PROBE", "language": "", "type": "", "id": "loga0cf2-meth-45cf-9f39-59installed", @@ -19,9 +22,11 @@ "methodName": "LogProbe", "sourceFile": null }, - "evaluateAt": "EXIT" + "evaluateAt": "EXIT", + "segments": [] }, { + "type": "LOG_PROBE", "language": "", "type": "", "id": "loga0cf2-line-45cf-9f39-59installed", @@ -31,6 +36,7 @@ "lines": [ "20" ] - } + }, + "segments": [] } ] \ No newline at end of file diff --git a/tests/debugger/probes/probe_status_metric.json b/tests/debugger/probes/probe_status_metric.json index e7cb86a4f8..f9be811c51 100644 --- a/tests/debugger/probes/probe_status_metric.json +++ b/tests/debugger/probes/probe_status_metric.json @@ -1,5 +1,6 @@ [ { + "type": "METRIC_PROBE", "language": "", "type": "", "id": "metricf2-meth-45cf-9f39-591received", @@ -19,6 +20,7 @@ "evaluateAt": "EXIT" }, { + "type": "METRIC_PROBE", "language": "", "type": "", "id": "metricf2-meth-45cf-9f39-59installed", @@ -38,6 +40,7 @@ "evaluateAt": "EXIT" }, { + "type": "METRIC_PROBE", "language": "", "type": "", "id": "metricf2-line-45cf-9f39-59installed", diff --git a/tests/debugger/probes/probe_status_span.json b/tests/debugger/probes/probe_status_span.json index a9f8ef3bf5..760a3aecfd 100644 --- a/tests/debugger/probes/probe_status_span.json +++ b/tests/debugger/probes/probe_status_span.json @@ -1,5 +1,6 @@ [ { + "type": "SPAN_PROBE", "language": "", "type": "", "id": "span0cf2-meth-45cf-9f39-591received", @@ -11,6 +12,7 @@ "evaluateAt": "EXIT" }, { + "type": "SPAN_PROBE", "language": "", "type": "", "id": "span0cf2-meth-45cf-9f39-59installed", diff --git a/tests/debugger/probes/probe_status_spandecoration.json b/tests/debugger/probes/probe_status_spandecoration.json index aaec22e9e0..c03bee6ff4 100644 --- a/tests/debugger/probes/probe_status_spandecoration.json +++ b/tests/debugger/probes/probe_status_spandecoration.json @@ -1,5 +1,6 @@ [ { + "type": "SPAN_DECORATION_PROBE", "language": "", "type": "", "id": "decorcf2-meth-45cf-9f39-591received", @@ -29,6 +30,7 @@ "evaluateAt": "EXIT" }, { + "type": "SPAN_DECORATION_PROBE", "language": "", "type": "", "id": "decorcf2-meth-45cf-9f39-59installed", @@ -58,6 +60,7 @@ "evaluateAt": "EXIT" }, { + "type": "SPAN_DECORATION_PROBE", "language": "", "type": "", "id": "decorcf2-line-45cf-9f39-59installed", diff --git a/tests/debugger/test_debugger_expression_language.py b/tests/debugger/test_debugger_expression_language.py index a1826375df..8bc819ee4c 100644 --- a/tests/debugger/test_debugger_expression_language.py +++ b/tests/debugger/test_debugger_expression_language.py @@ -77,7 +77,7 @@ def setup_expression_language_access_exception(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/exception") + self._setup(probes, "/debugger/expression_exception") def test_expression_language_access_exception(self): self._assert(expected_code=500) @@ -100,7 +100,7 @@ def setup_expression_language_comparison_operators(self): ["intValue ne 5", False, Dsl("ne", [Dsl("ref", "intValue"), 5])], ["intValue le 0", False, Dsl("le", [Dsl("ref", "intValue"), 0])], ["intValue ge 10", False, Dsl("ge", [Dsl("ref", "intValue"), 10])], - ["floatValue ne 0", True, Dsl("ne", [Dsl("ref", "floatValue"), 3.14])], + ["floatValue ne 0", True, Dsl("ne", [Dsl("ref", "floatValue"), 0])], ["floatValue ne 0.1", True, Dsl("ne", [Dsl("ref", "floatValue"), 0.1])], ["floatValue lt 10", True, Dsl("lt", [Dsl("ref", "floatValue"), 10])], ["floatValue lt 10.10", True, Dsl("lt", [Dsl("ref", "floatValue"), 10.10])], @@ -137,7 +137,7 @@ def setup_expression_language_comparison_operators(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/operators?intValue=5&floatValue=3.14&strValue=haha") + self._setup(probes, "/debugger/expression_operators?intValue=5&floatValue=3.14&strValue=haha") def test_expression_language_comparison_operators(self): self._assert() @@ -165,7 +165,7 @@ def setup_expression_language_instance_of(self): [ "intValue instanceof float", False, - Dsl("instanceof", [Dsl("ref", "intValue"), self._get_type("int")]), + Dsl("instanceof", [Dsl("ref", "intValue"), self._get_type("float")]), ], [ "floatValue instanceof int", @@ -182,7 +182,7 @@ def setup_expression_language_instance_of(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/operators?intValue=5&floatValue=3.14&strValue=haha") + self._setup(probes, "/debugger/expression_operators?intValue=5&floatValue=3.14&strValue=haha") @bug(library="java", reason="DEBUG-2527") @bug(library="dotnet", reason="DEBUG-2530") @@ -220,7 +220,7 @@ def setup_expression_language_logical_operators(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/operators?intValue=5&floatValue=3.14&strValue=haha") + self._setup(probes, "/debugger/expression_operators?intValue=5&floatValue=3.14&strValue=haha") def test_expression_language_logical_operators(self): self._assert() @@ -228,7 +228,7 @@ def test_expression_language_logical_operators(self): def setup_expression_language_string_operations(self): message_map, probes = self._create_expression_probes( - methodName="StringOperations", + methodName="ExpressionStrings", expressions=[ ##### isempty ["strValue isEmpty", False, Dsl("isEmpty", Dsl("ref", "strValue"))], @@ -240,7 +240,7 @@ def setup_expression_language_string_operations(self): ["strValue substring 0 5", "veryl", Dsl("substring", [Dsl("ref", "strValue"), 0, 5])], ["strValue substring 5 10", "ongst", Dsl("substring", [Dsl("ref", "strValue"), 5, 10])], ["strValue substring 0 0", "", Dsl("substring", [Dsl("ref", "strValue"), 0, 0])], - ["emptyStr substring 0 0", "", Dsl("substring", [Dsl("ref", "emptyStr"), 0, 0])], + ["emptyString substring 0 0", "", Dsl("substring", [Dsl("ref", "emptyString"), 0, 0])], ##### startsWith ["strValue startsWith very", True, Dsl("startsWith", [Dsl("ref", "strValue"), "very"])], ["strValue startsWith foo", False, Dsl("startsWith", [Dsl("ref", "strValue"), "foo"])], @@ -265,7 +265,7 @@ def setup_expression_language_string_operations(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/strings?strValue=verylongstring") + self._setup(probes, "/debugger/expression_strings?strValue=verylongstring") @bug(library="dotnet", reason="DEBUG-2560") def test_expression_language_string_operations(self): @@ -432,6 +432,11 @@ def _get_type(self, value_type): intance_type = "com.datadoghq.system_tests.springboot.DebuggerController" else: intance_type = value_type + elif tracer["language"] == "php": + if value_type == "controller": + intance_type = "DebuggerController" + else: + intance_type = value_type else: intance_type = value_type return intance_type diff --git a/tests/debugger/test_debugger_probe_snapshot.py b/tests/debugger/test_debugger_probe_snapshot.py index 1677d5ce84..07b7de45dd 100644 --- a/tests/debugger/test_debugger_probe_snapshot.py +++ b/tests/debugger/test_debugger_probe_snapshot.py @@ -4,7 +4,16 @@ import tests.debugger.utils as base -from utils import scenarios, interfaces, weblog, features, remote_config as rc, bug +from utils import ( + scenarios, + interfaces, + weblog, + features, + missing_feature, + context, + remote_config as rc, + bug, +) @features.debugger @@ -50,6 +59,7 @@ def setup_line_probe_snaphots(self): weblog.get("/debugger/span-decoration/asd/1"), ] + @missing_feature(context.library == "php", reason="Line probes not yet implemented") def test_line_probe_snaphots(self): self.assert_all_states_not_error() self.assert_all_probes_are_installed() @@ -74,6 +84,7 @@ def setup_mix_probe(self): self.weblog_responses = [weblog.get("/debugger/mix/asd/1")] @bug(library="python", reason="DEBUG-2710") + @missing_feature(context.library == "php", reason="Line probes not yet implemented") def test_mix_probe(self): self.assert_all_states_not_error() self.assert_all_probes_are_installed() diff --git a/tests/debugger/utils.py b/tests/debugger/utils.py index 6f43f1d551..59d24bf422 100644 --- a/tests/debugger/utils.py +++ b/tests/debugger/utils.py @@ -15,7 +15,7 @@ from utils.dd_constants import RemoteConfigApplyState as ApplyState _CONFIG_PATH = "/v0.7/config" -_DEBUGER_PATH = "/api/v2/debugger" +_DEBUGGER_PATH = "/api/v2/debugger" _LOGS_PATH = "/api/v2/logs" _TRACES_PATH = "/api/v0.2/traces" @@ -51,18 +51,18 @@ def read_diagnostic_data(): tracer_version = version.parse(re.sub(r"[^0-9.].*$", "", tracer["tracer_version"])) if tracer["language"] == "java": if tracer_version > version.parse("1.27.0"): - path = _DEBUGER_PATH + path = _DEBUGGER_PATH else: path = _LOGS_PATH elif tracer["language"] == "dotnet": if tracer_version > version.parse("2.49.0"): - path = _DEBUGER_PATH + path = _DEBUGGER_PATH else: path = _LOGS_PATH elif tracer["language"] == "python": path = _DEBUGER_PATH else: - path = _LOGS_PATH + path = _DEBUGGER_PATH return list(interfaces.agent.get_data(path)) @@ -133,7 +133,7 @@ def _all_probes_installed(self, probes_map): return False if not self.all_probes_installed: - if data["path"] == _DEBUGER_PATH or data["path"] == _LOGS_PATH: + if data["path"] == _DEBUGGER_PATH or data["path"] == _LOGS_PATH: self.all_probes_installed = _all_probes_installed(self, get_probes_map([data])) return self.all_probes_installed diff --git a/utils/_context/containers.py b/utils/_context/containers.py index bba9ca656d..da8ed59e37 100644 --- a/utils/_context/containers.py +++ b/utils/_context/containers.py @@ -165,6 +165,7 @@ def start(self) -> Container: # auto_remove=True, detach=True, network=_NETWORK_NAME, + ulimits=[docker.types.Ulimit(name="core", soft=1_000_000_000, hard=1_000_000_000)], **self.kwargs, ) diff --git a/utils/_remote_config.py b/utils/_remote_config.py index ef2ee40d77..59423e0b85 100644 --- a/utils/_remote_config.py +++ b/utils/_remote_config.py @@ -13,6 +13,7 @@ import requests +from utils._weblog import weblog from utils._context.core import context from utils.dd_constants import RemoteConfigApplyState as ApplyState from utils.interfaces import library @@ -112,6 +113,8 @@ def remote_config_applied(data): return True _post("/unique_command", raw_payload) + if context.library == "php": + weblog.get("await_probes.php") library.wait_for(remote_config_applied, timeout=30) # ensure the library has enough time to apply the config to all subprocesses time.sleep(2) @@ -216,6 +219,8 @@ def _get_probe_type(probe_id): if probe["where"]["typeName"] == "ACTUAL_TYPE_NAME": if library_name == "dotnet": probe["where"]["typeName"] = "weblog.DebuggerController" + elif library_name == "php": + probe["where"]["typeName"] = "DebuggerController" elif library_name == "java": probe["where"]["typeName"] = "DebuggerController" probe["where"]["methodName"] = ( @@ -229,6 +234,8 @@ def _get_probe_type(probe_id): elif probe["where"]["sourceFile"] == "ACTUAL_SOURCE_FILE": if library_name == "dotnet": probe["where"]["sourceFile"] = "DebuggerController.cs" + elif library_name == "php": + probe["where"]["sourceFile"] = "debugger.php" elif library_name == "java": probe["where"]["sourceFile"] = "DebuggerController.java" elif library_name == "python": diff --git a/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs b/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs index 1f9a8ddc62..db28be1b61 100644 --- a/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs +++ b/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs @@ -74,23 +74,23 @@ public async Task Expression(string inputValue) return Content($"Great success number {localValue}"); } - [HttpGet("expression/exception")] + [HttpGet("expression_exception")] [Consumes("application/json", "application/xml")] public IActionResult ExpressionException() { throw new System.Exception("Hello from exception"); } - [HttpGet("expression/operators")] + [HttpGet("expression_operators")] [Consumes("application/json", "application/xml")] public IActionResult ExpressionOperators(int intValue, float floatValue, string strValue) { return Content($"Int value {intValue}. Float value {floatValue}. String value {strValue}"); } - [HttpGet("expression/strings")] + [HttpGet("expression_strings")] [Consumes("application/json", "application/xml")] - public IActionResult StringOperations(string strValue, string emptyString = "", string nullString = null) + public IActionResult ExpressionStrings(string strValue, string emptyString = "", string nullString = null) { return Content($"strValue {strValue}. emptyString {emptyString}. nullString {nullString}"); } diff --git a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java index 70bb616645..3a47ea0104 100644 --- a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java +++ b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java @@ -69,18 +69,18 @@ public String expression(@RequestParam String inputValue) { return "Great success number " + localValue; } - @GetMapping("/expression/exception") + @GetMapping("/expression_exception") public Void expressionException() { throw new ResponseStatusException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, "Hello from exception"); } - @GetMapping("/expression/operators") + @GetMapping("/expression_operators") public String expressionOperators(@RequestParam int intValue, @RequestParam float floatValue, @RequestParam String strValue) { return "Int value " + intValue + ". Float value " + floatValue + ". String value is " + strValue + "."; } - @GetMapping("/expression/strings") - public String stringOperations(@RequestParam String strValue, @RequestParam(required = false, defaultValue = "") String emptyString, @RequestParam(required = false) String nullString) { + @GetMapping("/expression_strings") + public String ExpressionStrings(@RequestParam String strValue, @RequestParam(required = false, defaultValue = "") String emptyString, @RequestParam(required = false) String nullString) { return "strValue " + strValue +". emptyString " + emptyString + ". " + nullString + "."; } diff --git a/utils/build/docker/php/apache-mod/entrypoint.sh b/utils/build/docker/php/apache-mod/entrypoint.sh index 60a43ba589..ae7e8ce58c 100755 --- a/utils/build/docker/php/apache-mod/entrypoint.sh +++ b/utils/build/docker/php/apache-mod/entrypoint.sh @@ -9,7 +9,7 @@ fi chmod a+rx /root rm -f /tmp/ddappsec.lock -LOGS_PHP=(/tmp/appsec.log /tmp/helper.log /tmp/php_error.log /tmp/sidecar.log) +LOGS_PHP=(/tmp/appsec.log /tmp/helper.log /tmp/php_error.log /tmp/tracer.log /tmp/sidecar.log) touch "${LOGS_PHP[@]}" chown www-data:www-data "${LOGS_PHP[@]}" @@ -17,6 +17,9 @@ LOGS_APACHE=(/var/log/apache2/{access.log,error.log}) touch "${LOGS_APACHE[@]}" chown root:adm "${LOGS_APACHE[@]}" + +unset DD_TRACE_DEBUG + #sed -i 's/StartServers.*/StartServers 1/' /etc/apache2/mods-enabled/mpm_prefork.conf #sed -i 's/MinSpareServers.*/MinSpareServers 1/' /etc/apache2/mods-enabled/mpm_prefork.conf #sed -i 's/MaxSpareServers.*/MaxSpareServers 1/' /etc/apache2/mods-enabled/mpm_prefork.conf diff --git a/utils/build/docker/php/apache-mod/php.conf b/utils/build/docker/php/apache-mod/php.conf index c549850275..4f394b1653 100644 --- a/utils/build/docker/php/apache-mod/php.conf +++ b/utils/build/docker/php/apache-mod/php.conf @@ -1,4 +1,5 @@ #LogLevel trace8 +CoreDumpDirectory /tmp/ RewriteEngine on diff --git a/utils/build/docker/php/common/await_probes.php b/utils/build/docker/php/common/await_probes.php new file mode 100644 index 0000000000..1786a06531 --- /dev/null +++ b/utils/build/docker/php/common/await_probes.php @@ -0,0 +1,17 @@ +intMixLocal = $intArg * strlen($arg); + return "Mixed result {$this->intLocal}"; + } + + function pii() { + $pii = new Pii; + $customPii = new CustomPii; + $value = $pii->TestValue; + $customValue = $customPii->TestValue; + return "PII $value. CustomPii: $customValue"; + } + + function expression(string $inputValue) { + $testStruct = new ExpressionTestStruct; + $localValue = strlen($inputValue); + return "Great success number $localValue"; + } + + function expressionException() { + throw new \Exception("Hello from exception"); + } + + function expressionOperators(int $intValue, float $floatValue, string $strValue) { + return "Int value $intValue. Float value $floatValue. String value is $strValue"; + } + + function expressionStrings(string $strValue, string $emptyString = "", $nullString = null) { + return "strValue $strValue. emptyString $emptyString. nullString $nullString"; + } +} + +if (empty($skipExecution)) { + $args = explode("/", substr($_SERVER["PATH_INFO"], 1)); + $method = strtr(array_shift($args), ["_" => "", "-" => ""]); + $c = new DebuggerController; + if (!method_exists($c, $method)) { + $method .= "Probe"; + } + foreach ((new ReflectionMethod($c, $method))->getParameters() as $param) { + if (isset($_GET[$param->name])) { + $args[] = $_GET[$param->name]; + } + } + try { + echo $c->$method(...$args); + } catch (\Exception $e) {} +} + +class ExpressionTestStruct { + public $IntValue = 1; + public $DoubleValue = 1.1; + public $StringValue = "one"; + public $BoolValue = true; + + public $Collection = ["one", "two", "three"]; + public $Dictionary = ["one" => 1, "two" => 2, "three" => 3, "four" => 4]; +} + + +abstract class PiiBase { + const Value = "SHOULD_BE_REDACTED"; + public $TestValue = self::Value; +} + +class Pii extends PiiBase { + public $_2fa = parent::Value; + public $accesstoken = parent::Value; + public $access_token = parent::Value; + public $Access_Token = parent::Value; + public $accessToken = parent::Value; + public $AccessToken = parent::Value; + public $ACCESSTOKEN = parent::Value; + public $aiohttpsession = parent::Value; + public $apikey = parent::Value; + public $apisecret = parent::Value; + public $apisignature = parent::Value; + public $applicationkey = parent::Value; + public $auth = parent::Value; + public $authorization = parent::Value; + public $authtoken = parent::Value; + public $ccnumber = parent::Value; + public $certificatepin = parent::Value; + public $cipher = parent::Value; + public $clientid = parent::Value; + public $clientsecret = parent::Value; + public $connectionstring = parent::Value; + public $connectsid = parent::Value; + public $cookie = parent::Value; + public $credentials = parent::Value; + public $creditcard = parent::Value; + public $csrf = parent::Value; + public $csrftoken = parent::Value; + public $cvv = parent::Value; + public $databaseurl = parent::Value; + public $dburl = parent::Value; + public $encryptionkey = parent::Value; + public $encryptionkeyid = parent::Value; + public $env = parent::Value; + public $geolocation = parent::Value; + public $gpgkey = parent::Value; + public $ipaddress = parent::Value; + public $jti = parent::Value; + public $jwt = parent::Value; + public $licensekey = parent::Value; + public $masterkey = parent::Value; + public $mysqlpwd = parent::Value; + public $nonce = parent::Value; + public $oauth = parent::Value; + public $oauthtoken = parent::Value; + public $otp = parent::Value; + public $passhash = parent::Value; + public $passwd = parent::Value; + public $password = parent::Value; + public $passwordb = parent::Value; + public $pemfile = parent::Value; + public $pgpkey = parent::Value; + public $phpsessid = parent::Value; + public $pin = parent::Value; + public $pincode = parent::Value; + public $pkcs8 = parent::Value; + public $privatekey = parent::Value; + public $publickey = parent::Value; + public $pwd = parent::Value; + public $recaptchakey = parent::Value; + public $refreshtoken = parent::Value; + public $routingnumber = parent::Value; + public $salt = parent::Value; + public $secret = parent::Value; + public $secretkey = parent::Value; + public $secrettoken = parent::Value; + public $securityanswer = parent::Value; + public $securitycode = parent::Value; + public $securityquestion = parent::Value; + public $serviceaccountcredentials = parent::Value; + public $session = parent::Value; + public $sessionid = parent::Value; + public $sessionkey = parent::Value; + public $setcookie = parent::Value; + public $signature = parent::Value; + public $signaturekey = parent::Value; + public $sshkey = parent::Value; + public $ssn = parent::Value; + public $symfony = parent::Value; + public $token = parent::Value; + public $transactionid = parent::Value; + public $twiliotoken = parent::Value; + public $usersession = parent::Value; + public $voterid = parent::Value; + public $xapikey = parent::Value; + public $xauthtoken = parent::Value; + public $xcsrftoken = parent::Value; + public $xforwardedfor = parent::Value; + public $xrealip = parent::Value; + public $xsrf = parent::Value; + public $xsrftoken = parent::Value; + + public $customidentifier1 = parent::Value; + public $customidentifier2 = parent::Value; +} + +class CustomPii extends PiiBase { + public $customkey = parent::Value; +} diff --git a/utils/build/docker/php/common/php.ini b/utils/build/docker/php/common/php.ini index 753b43474a..29e562a4f5 100644 --- a/utils/build/docker/php/common/php.ini +++ b/utils/build/docker/php/common/php.ini @@ -27,6 +27,8 @@ datadog.appsec.helper_extra_args=--log_level debug datadog.appsec.helper_log_file=/tmp/helper.log datadog.trace.agent_port=8126 +datadog.trace.log_level=trace +datadog.trace.log_file=/tmp/tracer.log datadog.remote_config_poll_interval=500 datadog.remote_config_enabled=1 datadog.experimental_api_security_enabled=1 diff --git a/utils/build/docker/php/php-fpm/entrypoint.sh b/utils/build/docker/php/php-fpm/entrypoint.sh index 21a97e854f..4fb12a13df 100755 --- a/utils/build/docker/php/php-fpm/entrypoint.sh +++ b/utils/build/docker/php/php-fpm/entrypoint.sh @@ -9,7 +9,7 @@ fi chmod a+rx /root rm -f /tmp/ddappsec.lock -LOGS_PHP=(/tmp/appsec.log /tmp/helper.log /tmp/php_error.log) +LOGS_PHP=(/tmp/appsec.log /tmp/helper.log /tmp/php_error.log /tmp/tracer.log) touch "${LOGS_PHP[@]}" chown www-data:www-data "${LOGS_PHP[@]}" @@ -17,6 +17,8 @@ LOGS_APACHE=(/var/log/apache2/{access.log,error.log}) touch "${LOGS_APACHE[@]}" chown root:adm "${LOGS_APACHE[@]}" +unset DD_TRACE_DEBUG + # Unused at the moment env | sed -rn 's#^([^=]+)=([^=]+)$#env[\1] = "\2"#p' | tee /dev/stderr >> /etc/php/PHP_VERSION/fpm/pool.d/www.conf sed -i "s/;clear_env = no/clear_env = no/" /etc/php/PHP_VERSION/fpm/pool.d/www.conf From f0da8625144404b997d98ccadd0b184dfe9681b4 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 23 Jul 2024 13:50:03 +0200 Subject: [PATCH 2/3] Fix python --- tests/debugger/utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/debugger/utils.py b/tests/debugger/utils.py index 59d24bf422..c5f2cf183f 100644 --- a/tests/debugger/utils.py +++ b/tests/debugger/utils.py @@ -59,8 +59,6 @@ def read_diagnostic_data(): path = _DEBUGGER_PATH else: path = _LOGS_PATH - elif tracer["language"] == "python": - path = _DEBUGER_PATH else: path = _DEBUGGER_PATH From e16a2a94f6ea0f8b77b6fe7e826c50c342b24d0b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 28 Sep 2024 05:38:24 +0200 Subject: [PATCH 3/3] Fixup with new additions to debugger system tests --- manifests/php.yml | 16 +- ...y_recursion_20_php_snapshots_expected.json | 712 ++++++++++++++++++ ...replay_recursion_20_php_tags_expected.json | 26 + ...ay_recursion_5_php_snapshots_expected.json | 202 +++++ ..._replay_recursion_5_php_tags_expected.json | 11 + ..._replay_simple_php_snapshots_expected.json | 32 + ...ption_replay_simple_php_tags_expected.json | 6 + .../debugger/probes/probe_snapshot_line.json | 2 - .../probes/probe_snapshot_method.json | 2 - .../probes/probe_snapshot_mix_log.json | 2 - tests/debugger/probes/probe_status_log.json | 3 - .../debugger/probes/probe_status_metric.json | 3 - tests/debugger/probes/probe_status_span.json | 2 - .../probes/probe_status_spandecoration.json | 3 - .../test_debugger_exception_replay.py | 20 +- .../test_debugger_expression_language.py | 10 +- .../weblog/Controllers/DebuggerController.cs | 14 +- .../debugger/DebuggerController.java | 12 +- .../build/docker/php/apache-mod/entrypoint.sh | 3 +- utils/build/docker/php/common/debugger.php | 47 +- .../python/flask/debugger_controller.py | 16 +- 21 files changed, 1078 insertions(+), 66 deletions(-) create mode 100644 tests/debugger/approvals/exception_replay_recursion_20_php_snapshots_expected.json create mode 100644 tests/debugger/approvals/exception_replay_recursion_20_php_tags_expected.json create mode 100644 tests/debugger/approvals/exception_replay_recursion_5_php_snapshots_expected.json create mode 100644 tests/debugger/approvals/exception_replay_recursion_5_php_tags_expected.json create mode 100644 tests/debugger/approvals/exception_replay_simple_php_snapshots_expected.json create mode 100644 tests/debugger/approvals/exception_replay_simple_php_tags_expected.json diff --git a/manifests/php.yml b/manifests/php.yml index c88a59883b..eb07e2e4f3 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -214,15 +214,15 @@ tests/: Test_UserBlocking_FullDenylist: v0.86.3 debugger/: test_debugger_exception_replay.py: - Test_Debugger_Exception_Replay: irrelevant + Test_Debugger_Exception_Replay: v1.4.0 test_debugger_expression_language.py: - Test_Debugger_Expression_Language: v1.3.0 + Test_Debugger_Expression_Language: v1.4.0 test_debugger_pii.py: - Test_Debugger_PII_Redaction: v1.3.0 + Test_Debugger_PII_Redaction: v1.4.0 test_debugger_probe_snapshot.py: - Test_Debugger_Line_Probe_Snaphots: v1.3.0 - Test_Debugger_Method_Probe_Snaphots: v1.3.0 - Test_Debugger_Mix_Log_Probe: v1.3.0 + Test_Debugger_Line_Probe_Snaphots: v1.4.0 + Test_Debugger_Method_Probe_Snaphots: v1.4.0 + Test_Debugger_Mix_Log_Probe: v1.4.0 test_debugger_probe_status.py: Test_Debugger_Probe_Statuses: irrelevant integrations/: @@ -324,8 +324,8 @@ tests/: Test_RemoteConfigurationExtraServices: missing_feature Test_RemoteConfigurationUpdateSequenceASMDDNoCache: irrelevant (cache is implemented) Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: irrelevant (cache is implemented) - Test_RemoteConfigurationUpdateSequenceLiveDebugging: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: missing_feature + Test_RemoteConfigurationUpdateSequenceLiveDebugging: v1.4.0 + Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: irrelevant (cache is implemented) serverless/: test_span_pointers.py: Test_SpanPointers: missing_feature diff --git a/tests/debugger/approvals/exception_replay_recursion_20_php_snapshots_expected.json b/tests/debugger/approvals/exception_replay_recursion_20_php_snapshots_expected.json new file mode 100644 index 0000000000..75ddb60af6 --- /dev/null +++ b/tests/debugger/approvals/exception_replay_recursion_20_php_snapshots_expected.json @@ -0,0 +1,712 @@ +[ + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 0, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "0" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 1, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "1" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 2, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "2" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 3, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "3" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 4, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "4" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 5, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "5" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 6, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "6" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 7, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "7" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 8, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "8" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 9, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "9" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 10, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "10" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 11, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "11" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 12, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "12" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 13, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "13" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 14, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "14" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 15, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "15" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 16, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "16" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 17, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "17" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 18, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "18" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 19, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "19" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "ad4059949c313463", + "frame_index": 20, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion20", + "type": "DebuggerController" + } + } + } +] \ No newline at end of file diff --git a/tests/debugger/approvals/exception_replay_recursion_20_php_tags_expected.json b/tests/debugger/approvals/exception_replay_recursion_20_php_tags_expected.json new file mode 100644 index 0000000000..9a498ab5cb --- /dev/null +++ b/tests/debugger/approvals/exception_replay_recursion_20_php_tags_expected.json @@ -0,0 +1,26 @@ +{ + "_dd.debug.error.0.snapshot_id": "", + "_dd.debug.error.1.snapshot_id": "", + "_dd.debug.error.10.snapshot_id": "", + "_dd.debug.error.11.snapshot_id": "", + "_dd.debug.error.12.snapshot_id": "", + "_dd.debug.error.13.snapshot_id": "", + "_dd.debug.error.14.snapshot_id": "", + "_dd.debug.error.15.snapshot_id": "", + "_dd.debug.error.16.snapshot_id": "", + "_dd.debug.error.17.snapshot_id": "", + "_dd.debug.error.18.snapshot_id": "", + "_dd.debug.error.19.snapshot_id": "", + "_dd.debug.error.2.snapshot_id": "", + "_dd.debug.error.20.snapshot_id": "", + "_dd.debug.error.21.snapshot_id": "", + "_dd.debug.error.3.snapshot_id": "", + "_dd.debug.error.4.snapshot_id": "", + "_dd.debug.error.5.snapshot_id": "", + "_dd.debug.error.6.snapshot_id": "", + "_dd.debug.error.7.snapshot_id": "", + "_dd.debug.error.8.snapshot_id": "", + "_dd.debug.error.9.snapshot_id": "", + "_dd.debug.error.exception_capture_id": "", + "_dd.debug.error.exception_hash": "ad4059949c313463" +} \ No newline at end of file diff --git a/tests/debugger/approvals/exception_replay_recursion_5_php_snapshots_expected.json b/tests/debugger/approvals/exception_replay_recursion_5_php_snapshots_expected.json new file mode 100644 index 0000000000..fae07d4b4a --- /dev/null +++ b/tests/debugger/approvals/exception_replay_recursion_5_php_snapshots_expected.json @@ -0,0 +1,202 @@ +[ + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "7262e893d52a8efc", + "frame_index": 0, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "0" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion5", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "7262e893d52a8efc", + "frame_index": 1, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "1" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion5", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "7262e893d52a8efc", + "frame_index": 2, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "2" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion5", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "7262e893d52a8efc", + "frame_index": 3, + "captures": { + "return": { + "arguments": { + "depth": { + "type": "int", + "value": "3" + }, + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion5", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "7262e893d52a8efc", + "frame_index": 4, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + }, + "depth": { + "type": "int", + "value": "4" + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion5", + "type": "DebuggerController" + } + } + }, + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "7262e893d52a8efc", + "frame_index": 5, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplayRecursion5", + "type": "DebuggerController" + } + } + } +] \ No newline at end of file diff --git a/tests/debugger/approvals/exception_replay_recursion_5_php_tags_expected.json b/tests/debugger/approvals/exception_replay_recursion_5_php_tags_expected.json new file mode 100644 index 0000000000..33accf43df --- /dev/null +++ b/tests/debugger/approvals/exception_replay_recursion_5_php_tags_expected.json @@ -0,0 +1,11 @@ +{ + "_dd.debug.error.0.snapshot_id": "", + "_dd.debug.error.1.snapshot_id": "", + "_dd.debug.error.2.snapshot_id": "", + "_dd.debug.error.3.snapshot_id": "", + "_dd.debug.error.4.snapshot_id": "", + "_dd.debug.error.5.snapshot_id": "", + "_dd.debug.error.6.snapshot_id": "", + "_dd.debug.error.exception_capture_id": "", + "_dd.debug.error.exception_hash": "7262e893d52a8efc" +} \ No newline at end of file diff --git a/tests/debugger/approvals/exception_replay_simple_php_snapshots_expected.json b/tests/debugger/approvals/exception_replay_simple_php_snapshots_expected.json new file mode 100644 index 0000000000..f2b9713f40 --- /dev/null +++ b/tests/debugger/approvals/exception_replay_simple_php_snapshots_expected.json @@ -0,0 +1,32 @@ +[ + { + "language": "php", + "id": "", + "timestamp": "", + "exception_capture_id": "", + "exception_hash": "d970cec0014608ee", + "frame_index": 0, + "captures": { + "return": { + "arguments": { + "this": { + "type": "DebuggerController", + "fields": { + "DebuggerController::intMixLocal": { + "type": "int", + "notCapturedReason": "redactedIdent" + } + } + } + } + } + }, + "probe": { + "id": "", + "location": { + "method": "exceptionReplaySimple", + "type": "DebuggerController" + } + } + } +] \ No newline at end of file diff --git a/tests/debugger/approvals/exception_replay_simple_php_tags_expected.json b/tests/debugger/approvals/exception_replay_simple_php_tags_expected.json new file mode 100644 index 0000000000..2439d2e2b6 --- /dev/null +++ b/tests/debugger/approvals/exception_replay_simple_php_tags_expected.json @@ -0,0 +1,6 @@ +{ + "_dd.debug.error.0.snapshot_id": "", + "_dd.debug.error.1.snapshot_id": "", + "_dd.debug.error.exception_capture_id": "", + "_dd.debug.error.exception_hash": "d970cec0014608ee" +} \ No newline at end of file diff --git a/tests/debugger/probes/probe_snapshot_line.json b/tests/debugger/probes/probe_snapshot_line.json index 1c639d8c0c..785adc9b8a 100644 --- a/tests/debugger/probes/probe_snapshot_line.json +++ b/tests/debugger/probes/probe_snapshot_line.json @@ -2,7 +2,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "log170aa-acda-4453-9111-1478a697line", "where": { "typeName": null, @@ -16,7 +15,6 @@ { "type": "SPAN_DECORATION_PROBE", "language": "", - "type": "", "id": "decor0aa-acda-4453-9111-1478a697line", "targetSpan": "ACTIVE", "decorations": [ diff --git a/tests/debugger/probes/probe_snapshot_method.json b/tests/debugger/probes/probe_snapshot_method.json index 541fc85767..d91ebc62b5 100644 --- a/tests/debugger/probes/probe_snapshot_method.json +++ b/tests/debugger/probes/probe_snapshot_method.json @@ -2,7 +2,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "log170aa-acda-4453-9111-1478a6method", "where": { "typeName": "ACTUAL_TYPE_NAME", @@ -26,7 +25,6 @@ { "type": "SPAN_DECORATION_PROBE", "language": "", - "type": "", "id": "decor0aa-acda-4453-9111-1478a6method", "targetSpan": "ACTIVE", "decorations": [ diff --git a/tests/debugger/probes/probe_snapshot_mix_log.json b/tests/debugger/probes/probe_snapshot_mix_log.json index 3e5f29a266..43ab49708d 100644 --- a/tests/debugger/probes/probe_snapshot_mix_log.json +++ b/tests/debugger/probes/probe_snapshot_mix_log.json @@ -2,7 +2,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "logfb5a-1974-4cdb-b1dd-77dba2method", "captureSnapshot": true, "where": { @@ -16,7 +15,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "logfb5a-1974-4cdb-b1dd-77dba2f1line", "captureSnapshot": true, "where": { diff --git a/tests/debugger/probes/probe_status_log.json b/tests/debugger/probes/probe_status_log.json index 037e598bf3..b72dde5178 100644 --- a/tests/debugger/probes/probe_status_log.json +++ b/tests/debugger/probes/probe_status_log.json @@ -2,7 +2,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "loga0cf2-meth-45cf-9f39-591received", "where": { "typeName": "NotReallyExists", @@ -15,7 +14,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "loga0cf2-meth-45cf-9f39-59installed", "where": { "typeName": "ACTUAL_TYPE_NAME", @@ -28,7 +26,6 @@ { "type": "LOG_PROBE", "language": "", - "type": "", "id": "loga0cf2-line-45cf-9f39-59installed", "where": { "typeName": null, diff --git a/tests/debugger/probes/probe_status_metric.json b/tests/debugger/probes/probe_status_metric.json index f9be811c51..7d0c738c32 100644 --- a/tests/debugger/probes/probe_status_metric.json +++ b/tests/debugger/probes/probe_status_metric.json @@ -2,7 +2,6 @@ { "type": "METRIC_PROBE", "language": "", - "type": "", "id": "metricf2-meth-45cf-9f39-591received", "metricName": "MetricCountInt", "kind": "COUNT", @@ -22,7 +21,6 @@ { "type": "METRIC_PROBE", "language": "", - "type": "", "id": "metricf2-meth-45cf-9f39-59installed", "metricName": "MetricCountInt", "kind": "COUNT", @@ -42,7 +40,6 @@ { "type": "METRIC_PROBE", "language": "", - "type": "", "id": "metricf2-line-45cf-9f39-59installed", "kind": "COUNT", "metricName": "MetricCountInt", diff --git a/tests/debugger/probes/probe_status_span.json b/tests/debugger/probes/probe_status_span.json index 760a3aecfd..cc05be7317 100644 --- a/tests/debugger/probes/probe_status_span.json +++ b/tests/debugger/probes/probe_status_span.json @@ -2,7 +2,6 @@ { "type": "SPAN_PROBE", "language": "", - "type": "", "id": "span0cf2-meth-45cf-9f39-591received", "where": { "typeName": "NotReallyExists", @@ -14,7 +13,6 @@ { "type": "SPAN_PROBE", "language": "", - "type": "", "id": "span0cf2-meth-45cf-9f39-59installed", "where": { "typeName": "ACTUAL_TYPE_NAME", diff --git a/tests/debugger/probes/probe_status_spandecoration.json b/tests/debugger/probes/probe_status_spandecoration.json index c03bee6ff4..6b9aad74e3 100644 --- a/tests/debugger/probes/probe_status_spandecoration.json +++ b/tests/debugger/probes/probe_status_spandecoration.json @@ -2,7 +2,6 @@ { "type": "SPAN_DECORATION_PROBE", "language": "", - "type": "", "id": "decorcf2-meth-45cf-9f39-591received", "targetSpan": "ACTIVE", "decorations": [ @@ -32,7 +31,6 @@ { "type": "SPAN_DECORATION_PROBE", "language": "", - "type": "", "id": "decorcf2-meth-45cf-9f39-59installed", "targetSpan": "ACTIVE", "decorations": [ @@ -62,7 +60,6 @@ { "type": "SPAN_DECORATION_PROBE", "language": "", - "type": "", "id": "decorcf2-line-45cf-9f39-59installed", "targetSpan": "ACTIVE", "decorations": [ diff --git a/tests/debugger/test_debugger_exception_replay.py b/tests/debugger/test_debugger_exception_replay.py index f7af85330b..fe8b8d09c5 100644 --- a/tests/debugger/test_debugger_exception_replay.py +++ b/tests/debugger/test_debugger_exception_replay.py @@ -9,7 +9,7 @@ from utils import scenarios, interfaces, weblog, features, bug from utils.tools import logger -_OVERRIDE_APROVALS = False +_OVERRIDE_APROVALS = True @features.debugger_exception_replay @@ -74,7 +74,7 @@ def _wait_for_snapshot_received(self, data): ############ Simple ############ def setup_exception_replay_simple(self): - self._setup("/debugger/exceptionreplay/simple", "exceptionreplaysimple") + self._setup("/debugger/exceptionreplay_simple", "exceptionreplaysimple") @bug(library="java", reason="DEBUG-2787") @bug(library="dotnet", reason="DEBUG-2799") @@ -84,11 +84,11 @@ def test_exception_replay_simple(self): self._validate_tags(test_name="exception_replay_simple", number_of_frames=1) def setup_exception_replay_simple(self): - self._setup("/debugger/exceptionreplay/simple", "exceptionreplaysimple") + self._setup("/debugger/exceptionreplay_simple", "exceptionreplaysimple") ############ Recursion ############ def setup_exception_replay_recursion_5(self): - self._setup("/debugger/exceptionreplay/recursion5", "exceptionreplayrecursion5") + self._setup("/debugger/exceptionreplay_recursion5", "exceptionreplayrecursion5") @bug(library="java", reason="DEBUG-2787") @bug(library="dotnet", reason="DEBUG-2799") @@ -98,7 +98,7 @@ def test_exception_replay_recursion_5(self): self._validate_tags(test_name="exception_replay_recursion_5", number_of_frames=5) def setup_exception_replay_recursion_20(self): - self._setup("/debugger/exceptionreplay/recursion20", "exceptionreplayrecursion20") + self._setup("/debugger/exceptionreplay_recursion20", "exceptionreplayrecursion20") @bug(library="java", reason="DEBUG-2787") @bug(library="dotnet", reason="DEBUG-2799") @@ -140,7 +140,7 @@ def ___scrub(data): if isinstance(data, dict): scrubbed_data = {} for key, value in data.items(): - if key in ["timestamp", "id", "exceptionId", "duration"]: + if key in ["timestamp", "id", "exceptionId", "exceptionCaptureId", "duration"]: scrubbed_data[key] = "" # java elif key == "elements" and data.get("type") in ["long[]", "short[]", "int[]"]: @@ -171,8 +171,8 @@ def ___scrub(data): expected_snapshots = self.__read(test_name, "snapshots_expected") assert expected_snapshots == snapshots assert all( - "exceptionId" in snapshot for snapshot in snapshots - ), "One or more snapshots don't have 'exceptionId' field" + "exceptionId" in snapshot or "exceptionCaptureId" in snapshot for snapshot in snapshots + ), "One or more snapshots don't have 'exceptionCaptureId' field" __approve(self.snapshots) @@ -223,7 +223,9 @@ def __approve(tags): assert expected == tags - assert "_dd.debug.error.exception_id" in tags, "Missing '_dd.debug.error.exception_id' in tags" + assert ( + "_dd.debug.error.exception_id" in tags or "_dd.debug.error.exception_capture_id" in tags + ), "Missing '_dd.debug.error.exception_capture_id' in tags" assert "_dd.debug.error.exception_hash" in tags, "Missing '_dd.debug.error.exception_hash' in tags" assert f"_dd.debug.error.{0}.snapshot_id" in tags, f"Missing '_dd.debug.error.{0}.snapshot_id' in tags" if number_of_frames > 1: diff --git a/tests/debugger/test_debugger_expression_language.py b/tests/debugger/test_debugger_expression_language.py index 8bc819ee4c..87d465f5f7 100644 --- a/tests/debugger/test_debugger_expression_language.py +++ b/tests/debugger/test_debugger_expression_language.py @@ -273,7 +273,7 @@ def test_expression_language_string_operations(self): def setup_expression_language_collection_operations(self): message_map, probes = self._create_expression_probes( - methodName="StringOperations", + methodName="ExpressionCollectionOperations", expressions=[ ### at the app there are 3 types of collections are created - array, list and hash. ### the number at the end of variable means the length of the collection @@ -362,7 +362,7 @@ def setup_expression_language_collection_operations(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/collections") + self._setup(probes, "/debugger/expression_collection_operations") @bug(library="dotnet", reason="DEBUG-2602") @bug(library="java", reason="DEBUG-2603") @@ -371,7 +371,7 @@ def test_expression_language_collection_operations(self): def setup_expression_language_nulls_true(self): message_map, probes = self._create_expression_probes( - methodName="Nulls", + methodName="ExpressionNulls", expressions=[ ["intValue eq null", True, Dsl("eq", [Dsl("ref", "intValue"), None])], ["strValue eq null", True, Dsl("eq", [Dsl("ref", "strValue"), None])], @@ -380,7 +380,7 @@ def setup_expression_language_nulls_true(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/null") + self._setup(probes, "/debugger/expression_nulls") @bug(library="dotnet", reason="DEBUG-2618") def test_expression_language_nulls_true(self): @@ -398,7 +398,7 @@ def setup_expression_language_nulls_false(self): ) self.message_map = message_map - self._setup(probes, "/debugger/expression/operators?intValue=5&floatValue=3.14&strValue=haha") + self._setup(probes, "/debugger/expression_operators?intValue=5&floatValue=3.14&strValue=haha") @bug(library="dotnet", reason="DEBUG-2618") def test_expression_language_nulls_false(self): diff --git a/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs b/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs index db28be1b61..0cf4db47c3 100644 --- a/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs +++ b/utils/build/docker/dotnet/weblog/Controllers/DebuggerController.cs @@ -95,9 +95,9 @@ public IActionResult ExpressionStrings(string strValue, string emptyString = "", return Content($"strValue {strValue}. emptyString {emptyString}. nullString {nullString}"); } - [HttpGet("expression/collections")] + [HttpGet("expression_collection_operations")] [Consumes("application/json", "application/xml")] - public async Task StringOperations() + public async Task ExpressionCollectionOperations() { var a0 = await CollectionFactory.GetCollection(0, "array"); var l0 = await CollectionFactory.GetCollection(0, "list"); @@ -112,22 +112,22 @@ public async Task StringOperations() return Content($"{a0.Count},{a1.Count},{a5.Count},{l0.Count},{l1.Count},{l5.Count},{h0.Count},{h1.Count},{h5.Count}."); } - [HttpGet("expression/null")] + [HttpGet("expression_nulls")] [Consumes("application/json", "application/xml")] - public async Task Nulls(int? intValue = null, string strValue = null) + public async Task ExpressionNulls(int? intValue = null, string strValue = null) { PiiBase? pii = await Task.FromResult(null); return Content($"Pii is null {pii is null}. intValue is null {intValue is null}. strValue is null {strValue is null}."); } - [HttpGet("exceptionreplay/simple")] + [HttpGet("exceptionreplay_simple")] [Consumes("application/json", "application/xml")] public IActionResult ExceptionReplaySimple() { throw new System.Exception("Simple exception"); } - [HttpGet("exceptionreplay/recursion5")] + [HttpGet("exceptionreplay_recursion5")] [Consumes("application/json", "application/xml")] public IActionResult ExceptionReplayRecursion5(int depth = 5) { @@ -141,7 +141,7 @@ public IActionResult ExceptionReplayRecursion5(int depth = 5) } } - [HttpGet("exceptionreplay/recursion20")] + [HttpGet("exceptionreplay_recursion20")] [Consumes("application/json", "application/xml")] public IActionResult ExceptionReplayRecursion20(int depth = 20) { diff --git a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java index 3a47ea0104..36e4e743e1 100644 --- a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java +++ b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/debugger/DebuggerController.java @@ -84,8 +84,8 @@ public String ExpressionStrings(@RequestParam String strValue, @RequestParam(req return "strValue " + strValue +". emptyString " + emptyString + ". " + nullString + "."; } - @GetMapping("/expression/collections") - public String stringOperations() { + @GetMapping("/expression_collection_operations") + public String CollectionOperations() { CollectionFactory factory = new CollectionFactory(); Object a0 = factory.getCollection(0, "array"); @@ -111,7 +111,7 @@ public String stringOperations() { return a0Count + "," + a1Count + "," + a5Count + "," + l0Count + "," + l1Count + "," + l5Count + "," + h0Count + "," + h1Count + "," + h5Count + "."; } - @GetMapping("/expression/null") + @GetMapping("/expression_nulls") public String nulls( @RequestParam(required = false) Integer intValue, @RequestParam(required = false) String strValue) { @@ -122,12 +122,12 @@ public String nulls( ". strValue is null " + (strValue == null) + "."; } - @GetMapping("/exceptionreplay/simple") + @GetMapping("/exceptionreplay_simple") public Void exceptionReplaySimple() { throw new ResponseStatusException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, "Simple exception"); } - @GetMapping("/exceptionreplay/recursion5") + @GetMapping("/exceptionreplay_recursion5") public String exceptionReplayRecursion5(@RequestParam(required = false, defaultValue = "5") Integer depth) { if (depth > 0) { return exceptionReplayRecursion5(depth - 1); @@ -136,7 +136,7 @@ public String exceptionReplayRecursion5(@RequestParam(required = false, defaultV } } - @GetMapping("/exceptionreplay/recursion20") + @GetMapping("/exceptionreplay_recursion20") public String exceptionReplayRecursion20(@RequestParam(required = false, defaultValue = "20") Integer depth) { if (depth > 0) { return exceptionReplayRecursion20(depth - 1); diff --git a/utils/build/docker/php/apache-mod/entrypoint.sh b/utils/build/docker/php/apache-mod/entrypoint.sh index ae7e8ce58c..9279480bb7 100755 --- a/utils/build/docker/php/apache-mod/entrypoint.sh +++ b/utils/build/docker/php/apache-mod/entrypoint.sh @@ -9,7 +9,7 @@ fi chmod a+rx /root rm -f /tmp/ddappsec.lock -LOGS_PHP=(/tmp/appsec.log /tmp/helper.log /tmp/php_error.log /tmp/tracer.log /tmp/sidecar.log) +LOGS_PHP=(/tmp/appsec.log /tmp/helper.log /tmp/php_error.log /tmp/tracer.log) touch "${LOGS_PHP[@]}" chown www-data:www-data "${LOGS_PHP[@]}" @@ -24,7 +24,6 @@ unset DD_TRACE_DEBUG #sed -i 's/MinSpareServers.*/MinSpareServers 1/' /etc/apache2/mods-enabled/mpm_prefork.conf #sed -i 's/MaxSpareServers.*/MaxSpareServers 1/' /etc/apache2/mods-enabled/mpm_prefork.conf -export _DD_DEBUG_SIDECAR_LOG_METHOD=file:///tmp/sidecar.log export _DD_SHARED_LIB_DEBUG=1 export -p | sed 's@declare -x@export@' | tee /dev/stderr >> /etc/apache2/envvars diff --git a/utils/build/docker/php/common/debugger.php b/utils/build/docker/php/common/debugger.php index e115e7ac76..cd0190c905 100644 --- a/utils/build/docker/php/common/debugger.php +++ b/utils/build/docker/php/common/debugger.php @@ -50,6 +50,48 @@ function expressionOperators(int $intValue, float $floatValue, string $strValue) function expressionStrings(string $strValue, string $emptyString = "", $nullString = null) { return "strValue $strValue. emptyString $emptyString. nullString $nullString"; } + + function expressionCollectionOperations() { + $a0 = []; + $l0 = []; + $h0 = []; + $a1 = range(0, 0); + $l1 = range(0, 0); + $h1 = range(0, 0); + $a5 = range(0, 4); + $l5 = range(0, 4); + $h5 = range(0, 4); + + return count($a0) . ", " . count($a1) . "," . count($a5) . "," . count($l0) . "," . count($l1) . "," . count($l5) . "," . count($h0) . "," . count($h1) . "," . count($h5) . "."; + } + + function expressionNulls(int $intValue = null, string $strValue = null) { + $pii = null; + + return "Pii is null " . ($pii === null) . + ". intValue is null " . ($intValue === null) . + ". strValue is null " . ($strValue === null) . "."; + } + + function exceptionReplaySimple() { + throw new \Exception("Simple exception"); + } + + function exceptionReplayRecursion5($depth = 5) { + if ($depth > 0) { + return $this->exceptionReplayRecursion5($depth - 1); + } else { + throw new \Exception("Recursion exception"); + } + } + + function exceptionReplayRecursion20($depth = 20) { + if ($depth > 0) { + return $this->exceptionReplayRecursion20($depth - 1); + } else { + throw new \Exception("Recursion exception"); + } + } } if (empty($skipExecution)) { @@ -64,9 +106,7 @@ function expressionStrings(string $strValue, string $emptyString = "", $nullStri $args[] = $_GET[$param->name]; } } - try { - echo $c->$method(...$args); - } catch (\Exception $e) {} + echo $c->$method(...$args); } class ExpressionTestStruct { @@ -79,7 +119,6 @@ class ExpressionTestStruct { public $Dictionary = ["one" => 1, "two" => 2, "three" => 3, "four" => 4]; } - abstract class PiiBase { const Value = "SHOULD_BE_REDACTED"; public $TestValue = self::Value; diff --git a/utils/build/docker/python/flask/debugger_controller.py b/utils/build/docker/python/flask/debugger_controller.py index f370b37df5..cc2c7a50f2 100644 --- a/utils/build/docker/python/flask/debugger_controller.py +++ b/utils/build/docker/python/flask/debugger_controller.py @@ -69,12 +69,12 @@ def expression(): return f"Great success number {local_value}" -@debugger_blueprint.route("/expression/exception", methods=["GET"]) +@debugger_blueprint.route("/expression_exception", methods=["GET"]) def expression_exception(): abort(500, description="Hello from exception") -@debugger_blueprint.route("/expression/operators", methods=["GET"]) +@debugger_blueprint.route("/expression_operators", methods=["GET"]) def expression_operators(): int_value = request.args.get("intValue", type=int) float_value = request.args.get("floatValue", type=float) @@ -83,8 +83,8 @@ def expression_operators(): return f"Int value {int_value}. Float value {float_value}. String value is {str_value}." -@debugger_blueprint.route("/expression/strings", methods=["GET"]) -def string_operations(): +@debugger_blueprint.route("/expression_strings", methods=["GET"]) +def expression_strings(): str_value = request.args.get("strValue", type=str) empty_string = request.args.get("emptyString", default="") null_string = request.args.get("nullString") @@ -92,8 +92,8 @@ def string_operations(): return f"strValue {str_value}. emptyString {empty_string}. {null_string}." -@debugger_blueprint.route("/expression/collections", methods=["GET"]) -def collections_operations(): +@debugger_blueprint.route("/expression_collection_operations", methods=["GET"]) +def expression_collections_operations(): factory = CollectionFactory() a0 = factory.get_collection(0, "array") @@ -119,8 +119,8 @@ def collections_operations(): return f"{a0_count},{a1_count},{a5_count},{l0_count},{l1_count},{l5_count},{h0_count},{h1_count},{h5_count}." -@debugger_blueprint.route("/expression/null", methods=["GET"]) -def nulls(): +@debugger_blueprint.route("/expression_nulls", methods=["GET"]) +def expression_nulls(): int_value = request.args.get("intValue", type=int) str_value = request.args.get("strValue") pii = None