"""The one test that proves the timeout is real. `bash -c "sleep N & sleep N"` is a miniature helm: a process that forks a child and waits on another. Kill the direct child only and the backgrounded `sleep` reparents to init and keeps running — which, when the process is helm, means a timed-out task retries while the original helm is still mutating the same release. This test needs a real process tree, so it lives in integration/. It needs no database: the `pool` fixture in conftest is not autouse. """ from __future__ import annotations import asyncio import os import subprocess import pytest from svcforge_core.adapters.helm import _run # A duration nothing else on the machine will be sleeping for, derived from the pid so two # concurrent runs cannot collide either. # # The obvious version of this test hardcodes `sleep 300` and then asserts # `pgrep -f "sleep 300"` is empty. That assertion is machine-global: it matches ANY process # whose command line contains the string, including a leftover from an earlier run of this # same test, an unrelated `sleep 300` somewhere on the box, and — the subtle one — the shell # that is running pgrep, whose own command line contains the pattern it is searching for. # The result is a test that fails for reasons that have nothing to do with the code, which # is as useless as one that cannot fail at all. Observed: three spurious matches on a # developer box, and a red run blamed on a Python upgrade that was innocent. _SLEEP_S = 30000 + (os.getpid() % 1000) _PATTERN = f"sleep {_SLEEP_S}" def _survivors() -> list[str]: """PIDs still matching this run's unique sleep. Empty means the group really died.""" out = subprocess.run( # noqa: S603 ["pgrep", "-f", _PATTERN], # noqa: S607 - resolved via PATH, fixed argv capture_output=True, text=True, check=False, ) return [line for line in out.stdout.split() if line.strip()] @pytest.mark.asyncio async def test_timeout_kills_the_whole_process_group() -> None: # Guard the guard: if the pattern already matches something, the assertion below would # be meaningless. Fail loudly rather than report a false negative. assert not _survivors(), f"{_PATTERN!r} matched before the test started; pick another marker" argv = ["bash", "-c", f"{_PATTERN} & {_PATTERN}"] # child forks a grandchild with pytest.raises(TimeoutError): await _run(argv, timeout_s=1) await asyncio.sleep(0.5) assert not _survivors(), "grandchild survived: you killed the child, not the group"