Skip to content

Commit 2ff9682

Browse files
feat(python): add mem_domain 3.14/3.15 gate scenarios
MEM-domain heap-space feature coverage (off by default). Stacks on gate-infra (PR-0), parallel to core gate scenarios (PR-0a).
1 parent b690416 commit 2ff9682

9 files changed

Lines changed: 133 additions & 36 deletions

File tree

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,29 @@
11
# Python downstream gate (dd-trace-py)
22

3-
Paired **3.14 (baseline)** and **3.15 (candidate)** prof-correctness scenarios
4-
exercise the Python profiling stack for the 3.14 → 3.15 migration. They are the
5-
intended default set when dd-trace-py triggers downstream CI on profiling changes.
6-
7-
**Scenarios land in follow-up PRs** (core families first, then feature-specific
8-
pairs). This directory is an index only — not a runnable scenario.
3+
Two prof-correctness scenarios exercise **MEM domain** heap profiling on **3.14
4+
(baseline)** and **3.15 (candidate)**. This is **feature coverage** (off by
5+
default: `DD_PROFILING_MEMORY_MEM_DOMAIN_ENABLED`), not default-profiler gate.
96

107
## Scenarios
118

12-
| Family | 3.14 (baseline) | 3.15 (candidate) | PR |
13-
|--------|-----------------|---------------------|-----|
14-
| _(pending)_ | | | Core scenarios in follow-up PRs |
9+
| Family | 3.14 (baseline) | 3.15 (candidate) |
10+
|--------|-------------------|------------------|
11+
| mem-domain | `python_mem_domain_3.14` | `python_mem_domain_3.15` |
1512

1613
## Default downstream regexp
1714

18-
Once scenarios are added, dd-trace-py should pass an explicit regexp (not the
19-
downstream workflow default of `python.*`). The regexp grows as families merge;
20-
see each PR for the current value.
21-
22-
Override via `workflow_dispatch``test_scenarios`, or when triggering
23-
[`downstream-python.yml`](../../.github/workflows/downstream-python.yml) manually.
15+
```
16+
python_mem_domain_3\.(14|15)
17+
```
2418

2519
## Wheel install
2620

27-
Every scenario builds against a **dd-trace-py wheel** via `DDTRACE_INSTALL_URL`
28-
(as `downstream-python.yml` does:
29-
`https://dd-trace-py-builds.s3.amazonaws.com/<sha>/install.sh`), pre-installed in
30-
the base image.
31-
32-
- **All `*_3.15` folders** — PyPI wheels may not be published for 3.15 yet;
33-
excluded from prof-correctness `main` CI (see `test_scenarios_exclude` in
34-
[`.github/workflows/ci.yml`](../../.github/workflows/ci.yml)).
35-
- **Wheel-only 3.14 folders** — scenarios that depend on unreleased ddtrace
36-
features are also excluded from `main` CI until the feature ships.
21+
- **3.15** — wheel-only (`DDTRACE_INSTALL_URL`); excluded from `main` CI.
22+
- **3.14** — runs on `main` CI against PyPI ddtrace.
3723

3824
## Local run
3925

4026
```sh
4127
export DDTRACE_INSTALL_URL="https://dd-trace-py-builds.s3.amazonaws.com/<commit-sha>/install.sh"
42-
TEST_SCENARIOS='<gate-regexp>' go test -v -run TestScenarios
28+
TEST_SCENARIOS='python_mem_domain_3\.(14|15)' go test -v -run TestScenarios
4329
```
44-
45-
## Gate lifecycle
46-
47-
This gate tests the **migration delta** (3.14 → 3.15). It is time-boxed: retire
48-
the paired 14v15 framing at 3.15 GA and fold workloads into steady-state
49-
prof-correctness on {oldest, newest} supported Python versions.
50-
51-
## Further reading
52-
53-
- prof-correctness downstream wiring: [README](../../README.md#downstream-from-dd-trace-py)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
ARG BASE_IMAGE="prof-python-3.14"
2+
FROM $BASE_IMAGE
3+
4+
COPY ./scenarios/python_mem_domain_3.14/requirements.txt /app/requirements.txt
5+
RUN pip install -r /app/requirements.txt
6+
7+
COPY ./scenarios/python_mem_domain_3.14/main.py /app/main.py
8+
WORKDIR /app
9+
10+
ENV EXECUTION_TIME_SEC=15
11+
ENV DD_PROFILING_HEAP_ENABLED=true
12+
ENV DD_PROFILING_MEMORY_MEM_DOMAIN_ENABLED=true
13+
ENV DD_PROFILING_HEAP_SAMPLE_SIZE=524288
14+
ENV DD_PROFILING_UPLOAD_INTERVAL=5
15+
ENV DD_PROFILING_STACK_ENABLED=false
16+
ENV DD_PROFILING_LOCK_ENABLED=false
17+
18+
CMD python main.py
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"test_name": "python_mem_domain_3.14",
3+
"pprof-regex": "profiles\\.([2-9]|[1-9][0-9]+)\\..*\\.pprof$",
4+
"allow_first_profile_failure": true,
5+
"stacks": [
6+
{
7+
"profile-type": "heap-space",
8+
"stack-content": [
9+
{
10+
"regular_expression": ".*allocate_mem_domain_buffer.*",
11+
"percent": 50,
12+
"error_margin": 50
13+
}
14+
]
15+
}
16+
],
17+
"scale_by_duration": false
18+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import os
2+
import time
3+
4+
from ddtrace.profiling import Profiler
5+
6+
# Keep MEM-domain allocations live across heap snapshot uploads.
7+
LIVE: list[bytearray] = []
8+
9+
BUF_BYTES = 16 * 1024 * 1024
10+
11+
12+
def allocate_mem_domain_buffer() -> None:
13+
LIVE.append(bytearray(BUF_BYTES))
14+
15+
16+
if __name__ == "__main__":
17+
prof = Profiler()
18+
prof.start()
19+
20+
allocate_mem_domain_buffer()
21+
time.sleep(int(os.environ.get("EXECUTION_TIME_SEC", "15")))
22+
23+
prof.stop()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ddtrace
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
ARG BASE_IMAGE="prof-python-3.15"
2+
FROM $BASE_IMAGE
3+
4+
# ddtrace is pre-installed in the base image when DDTRACE_INSTALL_URL is set
5+
# (dd-trace-py downstream CI). Do not pip-install here — PyPI wheels may not
6+
# exist for 3.15 yet.
7+
8+
COPY ./scenarios/python_mem_domain_3.15/main.py /app/main.py
9+
WORKDIR /app
10+
11+
ENV EXECUTION_TIME_SEC=15
12+
ENV DD_PROFILING_HEAP_ENABLED=true
13+
ENV DD_PROFILING_MEMORY_MEM_DOMAIN_ENABLED=true
14+
ENV DD_PROFILING_HEAP_SAMPLE_SIZE=524288
15+
ENV DD_PROFILING_UPLOAD_INTERVAL=5
16+
ENV DD_PROFILING_STACK_ENABLED=false
17+
ENV DD_PROFILING_LOCK_ENABLED=false
18+
19+
CMD python main.py
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"test_name": "python_mem_domain_3.15",
3+
"pprof-regex": "profiles\\.([2-9]|[1-9][0-9]+)\\..*\\.pprof$",
4+
"allow_first_profile_failure": true,
5+
"stacks": [
6+
{
7+
"profile-type": "heap-space",
8+
"stack-content": [
9+
{
10+
"regular_expression": ".*allocate_mem_domain_buffer.*",
11+
"percent": 50,
12+
"error_margin": 50
13+
}
14+
]
15+
}
16+
],
17+
"scale_by_duration": false
18+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import os
2+
import time
3+
4+
from ddtrace.profiling import Profiler
5+
6+
# Keep MEM-domain allocations live across heap snapshot uploads.
7+
LIVE: list[bytearray] = []
8+
9+
BUF_BYTES = 16 * 1024 * 1024
10+
11+
12+
def allocate_mem_domain_buffer() -> None:
13+
LIVE.append(bytearray(BUF_BYTES))
14+
15+
16+
if __name__ == "__main__":
17+
prof = Profiler()
18+
prof.start()
19+
20+
allocate_mem_domain_buffer()
21+
time.sleep(int(os.environ.get("EXECUTION_TIME_SEC", "15")))
22+
23+
prof.stop()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ddtrace

0 commit comments

Comments
 (0)