From 33d02bb11fc90986b1a1ba39f5c0b808dd713b0d Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 9 Jun 2026 23:31:09 -0400 Subject: [PATCH] fix(test): drop rmtree race in live_gui workspace creation The session-scoped live_gui fixture deleted the shared workspace before recreating it, which raced with the per-worker lock acquisition and produced FileNotFoundError on .live_gui_owner.lock in xdist. The per-run timestamped name (tests/artifacts/live_gui_workspace_/) already provides enough isolation between pytest invocations, so the rmtree is unnecessary. Use mkdir(exist_ok=True) only. --- tests/conftest.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c80a8a41..af042e09 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -475,20 +475,19 @@ def live_gui(request) -> Generator["_LiveGuiHandle", None, None]: gui_script = os.path.abspath("sloppy.py") diag = VerificationLogger("live_gui_startup", "live_gui_diag") diag.log_state("GUI Script", "N/A", "gui_2.py") - + # 1. Create the run workspace (one per pytest invocation, shared by the # single owner worker that actually runs live_gui tests). + # Per-run isolation: each `uv run pytest` gets a fresh timestamped folder. + # Per-test pollution is INTENTIONAL (exposes fragility, per the + # workspace_path_finalize_20260609 spec). + # NOTE: do NOT rmtree the workspace here. With xdist, 16 workers share this + # path concurrently; an rmtree-by-any-worker would delete the dir between + # another worker's mkdir and lock acquisition, causing FileNotFoundError. + # The timestamp-based name provides enough isolation for normal use; if you + # re-run within the same second, just wait a second. temp_workspace = _RUN_WORKSPACE - if temp_workspace.exists(): - for _ in range(5): - try: - shutil.rmtree(temp_workspace) - break - except OSError: - time.sleep(0.5) - # Create the workspace directory before writing files temp_workspace.mkdir(parents=True, exist_ok=True) - # Create minimal project files to avoid cluttering root (temp_workspace / "manual_slop.toml").write_text("[project]\nname = 'TestProject'\n\n[conductor]\ndir = 'conductor'\n", encoding="utf-8") (temp_workspace / "conductor" / "tracks").mkdir(parents=True, exist_ok=True)