Skip to content

Commit

Permalink
add smoke test for crash logs from python [INPLAT-36] (#3243)
Browse files Browse the repository at this point in the history
Co-authored-by: Tony Hsu <tony.hsu@datadoghq.com>
Co-authored-by: brettlangdon <me@brett.is>
Co-authored-by: Brett Langdon <brett.langdon@datadoghq.com>
  • Loading branch information
4 people authored Nov 13, 2024
1 parent f242dd6 commit f5a1cb7
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ def index(request):
return HttpResponse("test")


def crashme(request):
import ctypes

ctypes.string_at(0)


urlpatterns = [
path("", index),
path("crashme", crashme),
]
4 changes: 3 additions & 1 deletion manifests/dd_apm_inject.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
tests/:
docker_ssi/:
test_docker_ssi.py:
TestDockerSSIFeatures: v0.19.1
TestDockerSSIFeatures: v0.19.1
test_docker_ssi_crash.py:
TestDockerSSICrash: v0.19.1
49 changes: 49 additions & 0 deletions tests/docker_ssi/test_docker_ssi_crash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from urllib.parse import urlparse

from utils import (
bug,
scenarios,
features,
context,
interfaces,
)
from utils import weblog
from utils.tools import logger


@scenarios.docker_ssi
class TestDockerSSICrash:
"""Test the ssi in a simulated host injection environment (docker container + test agent)
We test scenarios when the application crashes and sends a crash report."""

_r = None

def setup_crash(self):
if TestDockerSSICrash._r is None:
parsed_url = urlparse(context.scenario.weblog_url + "/crashme")
logger.info(f"Setting up Docker SSI installation WEBLOG_URL {context.scenario.weblog_url}")
TestDockerSSICrash._r = weblog.request(
"GET", parsed_url.path, domain=parsed_url.hostname, port=parsed_url.port
)
logger.info(f"Setup Docker SSI installation {TestDockerSSICrash._r}")

self.r = TestDockerSSICrash._r

@features.ssi_crashtracking
@bug(condition=context.library != "python", reason="INPLAT-11")
def test_crash(self):
"""Validate that a crash report is generated when the application crashes"""
logger.info(f"Testing Docker SSI crash tracking: {context.scenario.library.library}")
assert (
self.r.status_code is None
), f"Response from request {context.scenario.weblog_url + '/crashme'} was supposed to fail: {self.r}"

# No traces should have been generated
assert not interfaces.test_agent.get_traces(
self.r
), f"Traces found for request {context.scenario.weblog_url + '/crashme'}"

# Crash report should have been generated
crash_reports = interfaces.test_agent.get_crash_reports()
assert crash_reports, "No crash report found"
assert len(crash_reports) == 1, "More than one crash report found"
10 changes: 7 additions & 3 deletions utils/_context/_scenarios/docker_ssi.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@ def fill_context(self, json_tested_components):
logger.stdout(f"{key}: {self._tested_components[key]}")

def post_setup(self):
logger.stdout("--- Waiting for all traces to be sent to test agent ---")
time.sleep(5) # wait for the traces to be sent to the test agent
interfaces.test_agent.collect_data(f"{self.host_log_folder}/interfaces/test_agent")
logger.stdout("--- Waiting for all traces and telemetry to be sent to test agent ---")
data = None
attempts = 0
while attempts < 30 and not data:
attempts += 1
data = interfaces.test_agent.collect_data(f"{self.host_log_folder}/interfaces/test_agent")
time.sleep(5)

@property
def library(self):
Expand Down
10 changes: 10 additions & 0 deletions utils/_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -2407,6 +2407,16 @@ def ssi_guardrails(test_object):
pytest.mark.features(feature_id=322)(test_object)
return test_object

@staticmethod
def ssi_crashtracking(test_object):
"""
Docker ssi crashtracking
https://feature-parity.us1.prod.dog/#/?feature=340
"""
pytest.mark.features(feature_id=340)(test_object)
return test_object

@staticmethod
def ssi_service_naming(test_object):
"""
Expand Down
18 changes: 18 additions & 0 deletions utils/interfaces/_test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ def get_telemetry_for_runtime(self, runtime_id):

return telemetry_msgs

def get_crashlog_for_runtime(self, runtime_id):
logger.debug(f"Try to find a crashlog related to runtime-id {runtime_id}")
assert runtime_id is not None, "Runtime ID not found"
return [l for l in self.get_telemetry_logs() if l["runtime_id"] == runtime_id]

def get_telemetry_for_autoinject(self):
logger.debug("Try to find telemetry data related to autoinject")
injection_metrics = []
Expand All @@ -79,3 +84,16 @@ def get_telemetry_for_autoinject_library_entrypoint(self):
if str(series["metric"]).startswith("library_entrypoint.")
]
return injection_metrics

def get_telemetry_logs(self):
logger.debug("Try to find telemetry data related to logs")
return [t for t in self._data_telemetry_list if t["request_type"] == "logs"]

def get_crash_reports(self):
logger.debug("Try to find telemetry data related to crash reports")
return [
p
for t in self.get_telemetry_logs()
for p in t["payload"]
if "signame" in p.get("tags", "") or "signum" in p.get("tags", "")
]

0 comments on commit f5a1cb7

Please sign in to comment.