Skip to content

Add comprehensive race condition & state conflict xfail test suite#627

Draft
tony wants to merge 3 commits into
masterfrom
tests/race-conditions
Draft

Add comprehensive race condition & state conflict xfail test suite#627
tony wants to merge 3 commits into
masterfrom
tests/race-conditions

Conversation

@tony

@tony tony commented Feb 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Add tests/test_race_conditions.py with 17 tests (15 xfail, 2 passing) documenting every discoverable state conflict in libtmux
  • Covers 5 categories: create-query races, object staleness after external mutation, DX frustrations, query/filter edge cases, and ID recycling after server restart
  • Each xfail test documents one specific failure mode, its root cause, and which layer (tmux C, Python subprocess, libtmux ORM) is responsible

Categories

Category 1 — Create-query races (6 xfail): Two-step "create → query" pattern fails when state changes between the tmux command and the follow-up list query.

Category 2 — Object staleness after external mutation (3 xfail, 1 pass): Cached Python objects become invalid after the underlying tmux object is killed externally. Includes killed session/window/pane access patterns.

Category 3 — DX frustrations (3 xfail, 1 pass): Natural API usage patterns that produce confusing or silent failures — dead server sessions returning [], inconsistent error handling between sessions/windows/panes properties.

Category 4 — Query/filter edge cases (2 xfail): QueryList.filter() with typo field names silently returns empty lists; fetch_obj by mutable keys fails after renames.

Category 5 — ID recycling after server restart (1 xfail): Stale Python refs with recycled $0 IDs silently match wrong objects after server restart.

Test plan

  • uv run pytest tests/test_race_conditions.py -v — 2 passed, 15 xfailed
  • uv run ruff check tests/test_race_conditions.py — no errors
  • uv run mypy tests/test_race_conditions.py — no errors
  • uv run pytest — full suite passes (874 passed, 1 skipped, 15 xfailed)
@codecov

codecov Bot commented Feb 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 47.23%. Comparing base (3a6fb89) to head (384c69f).
⚠️ Report is 133 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #627      +/-   ##
==========================================
+ Coverage   47.02%   47.23%   +0.21%     
==========================================
  Files          23       23              
  Lines        3296     3296              
  Branches      709      709              
==========================================
+ Hits         1550     1557       +7     
+ Misses       1384     1379       -5     
+ Partials      362      360       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
@tony tony force-pushed the tests/race-conditions branch from 9d931f6 to f0435d4 Compare April 26, 2026 11:17
tony added 3 commits May 10, 2026 10:44
why: Document known vulnerability where two-step "create → query" pattern
in new_session(), new_window(), and split() can fail if tmux state changes
between the creation command and the subsequent list-* query (#624).

what:
- Add tests/test_race_conditions.py with 6 strict xfail tests
- 3 tests for server crash between create and query (Mode A)
- 3 tests for stale empty list-* response (Mode B)
- All tests are parallel-safe (unique sockets, function-scoped monkeypatch)
- Tests will flip to XPASS when creation methods construct objects directly
  from -P output instead of re-querying
… ID recycling

why: Extend the race condition test suite into a comprehensive almanac
of every discoverable state conflict in libtmux, beyond the initial 6
create-query tests.
what:
- Add Category 2: Object staleness after external mutation
  - Killed session active_window gives raw LibTmuxException
  - Killed session refresh correctly raises TmuxObjectDoesNotExist (passing)
  - Killed window panes gives raw LibTmuxException
  - Dead pane send_keys silently swallows error
- Add Category 3: DX frustrations
  - Dead server sessions silently returns [] (bare except:pass)
  - Context manager rename works correctly (passing positive test)
  - Dead server windows/panes raise raw LibTmuxException (inconsistent)
- Add Category 4: Query/filter edge cases
  - Filter typo field silently returns empty list
  - fetch_obj by mutable session_name fails after rename
- Add Category 5: ID recycling after server restart
  - Stale ref with recycled $0 silently returns wrong session data
…ests

why: #625 (released v0.53.1) eliminated the second list-sessions query
in Server.new_session by parsing session data directly from
'tmux new-session -P -F<format>' output via parse_output(session_stdout).
The two strict-xfail tests in this file that patched
neo.fetch_objs(list_cmd='list-sessions') were unreachable after that
fix and could only XPASS — failing the suite when run with --reruns=0.
what:
- remove test_new_session_server_crash and test_new_session_stale_list
- replace with NOTE comments explaining why and pointing to #625
- new_window/split variants stay; those creation paths still re-query
@tony tony force-pushed the tests/race-conditions branch from f0435d4 to 384c69f Compare May 10, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant