Skip to content

Commit 6d742a8

Browse files
test(internal): add lifecycle stress / fuzzing harness for PeriodicThread (#18183)
## Description Adds `tests/internal/test_periodic_stress.py` — a randomized lifecycle fuzzer for `PeriodicThread` that interleaves create / start / stop / join / awake / drop-last-ref / fork / gc / thread-churn across a pool of `PeriodicThread` and `PeriodicService` objects. This is the harness that surfaced #17707 and #18040 (`PeriodicThread.awake()` blocking forever after `stop()`). ### What's in the file - `test_periodic_thread_lifecycle_stress` — the randomized fuzzer. Default budget kept short for CI (`DD_STRESS_ITERS=200`, ~10s). Documented env vars for soaks (`DD_STRESS_ITERS`, `DD_STRESS_SECONDS`, `DD_STRESS_SEED`, `DD_STRESS_POOL`, `DD_STRESS_FORK_EVERY`, `DD_STRESS_TRACE_FILE`). Seed is printed on every run so a failing random seed can be pinned with `DD_STRESS_SEED=N`. - `test_periodic_thread_concurrent_dealloc_race` — focused regression for #17485 (refcount TOCTOU between `std::thread` creation and the lambda acquiring the GIL). - `test_periodic_thread_stop_without_join_then_fork_repeat` — focused regression for #16955 (`pthread_t` recycling after stop-without-join then fork). ### How to run it when modifying the periodic thread framework The module docstring documents the exact commands. tl;dr: ``` # ~30s soak DD_STRESS_ITERS=10000 scripts/run-tests -- -- tests/internal/test_periodic_stress.py # 120s wall-clock soak (recommended under ASan/TSan) DD_STRESS_SECONDS=120 scripts/run-tests -- -- tests/internal/test_periodic_stress.py # Reproduce a failing seed (the seed is printed to stderr by every run) DD_STRESS_SEED=12345 scripts/run-tests -- -- tests/internal/test_periodic_stress.py ``` ## Testing All three tests pass locally on Python 3.13 in the testrunner image: ``` tests/internal/test_periodic_stress.py::test_periodic_thread_lifecycle_stress PASSED tests/internal/test_periodic_stress.py::test_periodic_thread_concurrent_dealloc_race PASSED tests/internal/test_periodic_stress.py::test_periodic_thread_stop_without_join_then_fork_repeat PASSED ``` ## Risks None — test-only addition. Existing test discovery and CI suites are unchanged. `changelog/no-changelog` — test-only. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: brettlangdon <brett.langdon@datadoghq.com> Co-authored-by: erwan.viollet <erwan.viollet@datadoghq.com>
1 parent 5ea55b2 commit 6d742a8

1 file changed

Lines changed: 462 additions & 0 deletions

File tree

0 commit comments

Comments
 (0)