Skip to content

test(conftest): kill CCB tmux daemons leaked by subprocess ccb calls#189

Open
SevenX77 wants to merge 1 commit intobfly123:mainfrom
SevenX77:conftest-tmux-cleanup
Open

test(conftest): kill CCB tmux daemons leaked by subprocess ccb calls#189
SevenX77 wants to merge 1 commit intobfly123:mainfrom
SevenX77:conftest-tmux-cleanup

Conversation

@SevenX77
Copy link
Copy Markdown

Problem

Tests under test/test_v2_phase2_entrypoint.py invoke the ccb CLI via subprocess.run. That subprocess starts the CCB keeper, which wraps itself in an independent tmux daemon whose socket lives under tmp_path/.ccb/ccbd/tmux.sock or /run/user/$UID/ccb-runtime/tmux-*.sock.

The in-process app.shutdown() these tests run at teardown cannot reach the daemons that were started in a separate subprocess. Consequence: each such test leaks ≥1 tmux: server process. On a developer workstation running the test suite repeatedly, dozens of orphaned tmux daemons accumulate in ps, consuming memory and PIDs.

Observed on a dev box: pytest-of-sevenx/pytest-52,57,58 each held 25+ orphaned tmux: server with ETIME over 2 hours before cleanup.

Fix

Two autouse fixtures in test/conftest.py:

  • _cleanup_ccb_tmux_per_test (per-test scope): after each test, kills any .ccb/ccbd/tmux.sock daemon found under the test's own tmp_path (safe because tmp_path is exclusive per-test), plus any socket that newly appeared in /run/user/$UID/ccb-runtime/ during the test. The "newly appeared" check is a snapshot diff before/after yield, so existing user sockets in that dir are not touched.
  • _cleanup_ccb_tmux_session_end (session scope, belt-and-suspenders): after the whole pytest session, sweeps the pytest base tmp and the runtime dir diff in case any per-test cleanup was missed due to a fixture exception.

Missing tmux binary raises FileNotFoundError and is silently ignored (e.g. Windows CI where tmux is unavailable). Hung kill-server (subprocess timeout after 5s) is logged at WARNING level — loud enough to notice but not fatal. No bare except: / no silent error swallowing.

Dependencies added to conftest.py imports: glob, logging, subprocess (standard library only).

Tests

  • Verified on test_ccb_v2_project_lifecycle (real-adapter lifecycle test that definitely spawns the keeper subprocess): zero tmux: server processes remain on the host after the test run. Baseline before this patch: ≥1 per such test run.
  • No modifications to any production code.
  • No modifications to any existing test.

Scope

Test infrastructure only. Does not change runtime behavior of CCB. Does not modify any lib/ code. A single file touched: test/conftest.py (+63 lines, 0 deletions). No new test files.

Rollback

Single commit, revert with git revert if needed.

Tests in test_v2_phase2_entrypoint.py invoke the `ccb` CLI via
subprocess; that subprocess starts the CCB keeper, which wraps itself
in an independent tmux daemon with a socket under
`tmp_path/.ccb/ccbd/tmux.sock` (or
`/run/user/$UID/ccb-runtime/tmux-*.sock`). The in-process
`app.shutdown()` these tests run cannot reach those daemons, so each
such test leaks >=1 tmux server process. On repeated test runs the host
accumulates dozens of orphan `tmux: server` procs.

Add two autouse fixtures:
- per-test: after each test, kill any `.ccb/ccbd/tmux.sock` under the
  test's `tmp_path`, plus any socket newly appeared in
  `/run/user/$UID/ccb-runtime/` during the test (diff before/after
  snapshots, so we do not touch sockets that existed before the test).
- session-end: belt-and-suspenders sweep over the whole pytest base
  tmp.

Missing `tmux` binary (FileNotFoundError) is a no-op. Hung
`kill-server` after 5s is logged WARNING. No bare excepts.

Verified on `test_ccb_v2_project_lifecycle`: zero `tmux: server`
processes remain after the run (baseline pre-fix: >=1 per run).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant