diff --git a/base_images/Dockerfile.python-3.12 b/base_images/Dockerfile.python-3.12 new file mode 100644 index 0000000..56e5436 --- /dev/null +++ b/base_images/Dockerfile.python-3.12 @@ -0,0 +1,13 @@ +FROM python:3.12 AS base + +# When set, download and run this install script to pre-install ddtrace. +# Used by upstream dd-trace-py CI to test with just-built wheels from S3. +ARG DDTRACE_INSTALL_URL="" +RUN if [ -n "$DDTRACE_INSTALL_URL" ]; then \ + curl -fsSL "$DDTRACE_INSTALL_URL" | bash; \ + fi + +ENV DD_PROFILING_ENABLED=true +ENV DD_TRACE_ENABLED=false +# ENV DD_TRACE_DEBUG=true +ENV DD_PROFILING_OUTPUT_PPROF="/app/data/profiles" diff --git a/scenarios/python_cpu_sleep_gevent_3.12/Dockerfile b/scenarios/python_cpu_sleep_gevent_3.12/Dockerfile new file mode 100644 index 0000000..748f305 --- /dev/null +++ b/scenarios/python_cpu_sleep_gevent_3.12/Dockerfile @@ -0,0 +1,15 @@ +ARG BASE_IMAGE="prof-python-3.12" +FROM $BASE_IMAGE + +WORKDIR /usr/src/app + +COPY ./scenarios/python_cpu_sleep_gevent_3.12/ /usr/src/app + +RUN chmod 644 /usr/src/app/main.py +RUN pip install --no-cache-dir -r requirements.txt + +ENV EXECUTION_TIME_SEC=30 +ENV DD_PROFILING_MEMORY_ENABLED=false +ENV _DD_PROFILING_STACK_ADAPTIVE_SAMPLING_ENABLED=0 + +CMD ddtrace-run python main.py diff --git a/scenarios/python_cpu_sleep_gevent_3.12/expected_profile.json b/scenarios/python_cpu_sleep_gevent_3.12/expected_profile.json new file mode 100644 index 0000000..6a5ec53 --- /dev/null +++ b/scenarios/python_cpu_sleep_gevent_3.12/expected_profile.json @@ -0,0 +1,21 @@ +{ + "test_name": "python_cpu_sleep_gevent_3.12", + "scale_by_duration": true, + "stacks": [ + { + "profile-type": "cpu-time", + "stack-content": [ + { + "regular_expression": ".*", + "value": 667000000, + "error_margin": 25 + }, + { + "regular_expression": ".*cpu_burst.*", + "percent": 80, + "error_margin": 10 + } + ] + } + ] +} diff --git a/scenarios/python_cpu_sleep_gevent_3.12/main.py b/scenarios/python_cpu_sleep_gevent_3.12/main.py new file mode 100644 index 0000000..e23b233 --- /dev/null +++ b/scenarios/python_cpu_sleep_gevent_3.12/main.py @@ -0,0 +1,42 @@ +from gevent import monkey + +monkey.patch_all() + +import os # noqa: E402 +import time # noqa: E402 + +import gevent # noqa: E402 + + +def cpu_burst(target_seconds: float) -> int: + deadline = time.monotonic() + target_seconds + x = 0x1234 + while time.monotonic() < deadline: + x = (x * 48271) % 2147483647 + return x + + +def slot(cpu_seconds: float, off_cpu: float, deadline: float) -> None: + while time.monotonic() < deadline: + time.sleep(off_cpu) + cpu_burst(cpu_seconds) + + +def main() -> None: + execution_time_sec = float(os.environ.get("EXECUTION_TIME_SEC", "30")) + cpu_seconds = 0.01 + off_cpu = 0.05 + concurrency = 4 + stagger = 0.01 + + deadline = time.monotonic() + execution_time_sec + greenlets = [] + for i in range(concurrency): + if i > 0: + gevent.sleep(stagger) + greenlets.append(gevent.spawn(slot, cpu_seconds, off_cpu, deadline)) + gevent.joinall(greenlets) + + +if __name__ == "__main__": + main() diff --git a/scenarios/python_cpu_sleep_gevent_3.12/requirements.txt b/scenarios/python_cpu_sleep_gevent_3.12/requirements.txt new file mode 100644 index 0000000..296856b --- /dev/null +++ b/scenarios/python_cpu_sleep_gevent_3.12/requirements.txt @@ -0,0 +1,2 @@ +ddtrace +gevent>=24.0