Private
Public Access
0
0

test(tests): TDD for test_live_gui_workspace_exists xdist race (failing test)

Captures the xdist race condition in the live_gui_workspace fixture.
In batched runs (pytest-xdist), the owner worker's live_gui fixture
teardown can rmtree the shared workspace path before a client worker's
test asserts live_gui_workspace.exists(). The test simulates this race
by pointing the handle at a fresh, never-existed path (Windows file
locks block rmtree on the live workspace) and asserting that the
live_gui_workspace fixture recreates the directory before returning
the path.

This test FAILS on the current commit because the fixture is just
'return handle.workspace' without ensuring the path exists. The fix
(in tests/conftest.py:727) will add workspace.mkdir(parents=True,
exist_ok=True) before the return.
This commit is contained in:
2026-06-18 14:26:12 -04:00
parent ff40138f84
commit 3fdb259249
+33
View File
@@ -1,4 +1,6 @@
"""Tests for the live_gui_workspace fixture (Phase 3, Task 3.2)."""
import importlib.util
import shutil
from pathlib import Path
@@ -29,3 +31,34 @@ def test_live_gui_workspace_writable(live_gui_workspace) -> None:
test_file = live_gui_workspace / "test_write.txt"
test_file.write_text("hello", encoding="utf-8")
assert test_file.read_text(encoding="utf-8") == "hello"
def test_live_gui_workspace_recreates_missing_workspace(live_gui) -> None:
"""[TDD red] Captures the xdist race in live_gui_workspace: when the owner
worker's live_gui teardown rmtree's the shared workspace between client
workers' tests, a client worker calling live_gui_workspace must recreate
the directory before returning the path. The current fixture returns the
path without mkdir, so the returned path does not exist after rmtree.
NOTE: on Windows, the live_gui subprocess holds the live workspace as its
CWD, which blocks shutil.rmtree on the live path. We instead point the
handle at a fresh, never-existed path under tests/artifacts/ to simulate
the post-teardown state deterministically on all platforms.
"""
import time
fake_workspace = Path(f"tests/artifacts/_live_gui_workspace_race_sim_{int(time.time() * 1000000)}")
assert not fake_workspace.exists(), f"sanity: fake workspace must not exist pre-call: {fake_workspace}"
original_workspace = live_gui._workspace
live_gui._workspace = fake_workspace
try:
spec = importlib.util.spec_from_file_location(
"tests.conftest",
str(Path(__file__).parent / "conftest.py"),
)
conftest = importlib.util.module_from_spec(spec)
spec.loader.exec_module(conftest)
result = conftest.live_gui_workspace.__wrapped__(live_gui)
assert result.exists(), f"live_gui_workspace did not recreate missing workspace at {result}"
finally:
live_gui._workspace = original_workspace
if fake_workspace.exists():
shutil.rmtree(fake_workspace, ignore_errors=True)