Private
Public Access
docs(simulations): update live_gui fixture signature to _LiveGuiHandle
The live_gui fixture in tests/conftest.py:467 now yields a _LiveGuiHandle object (not a tuple). The handle exposes: - .process, .gui_script, .workspace (Path to per-run workspace) - .is_alive(), .ensure_alive(), .respawn_count - __iter__ and __getitem__ for backward-compatible tuple unpacking Also document the xdist O_EXCL file-lock coordination pattern and the PYTEST_XDIST_WORKER env var owner/client role split.
This commit is contained in:
@@ -28,12 +28,14 @@ Defined in `tests/conftest.py`, this session-scoped fixture manages the lifecycl
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]:
|
def live_gui(request) -> Generator["_LiveGuiHandle", None, None]:
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
["uv", "run", "python", "-u", gui_script, "--enable-test-hooks"],
|
["uv", "run", "python", "-u", gui_script, "--enable-test-hooks"],
|
||||||
stdout=log_file, stderr=log_file, text=True,
|
stdout=log_file, stderr=log_file, text=True,
|
||||||
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0
|
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0
|
||||||
)
|
)
|
||||||
|
# ... (readiness polling + xdist coordination) ...
|
||||||
|
yield _LiveGuiHandle(process, gui_script, workspace=temp_workspace)
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`-u` flag**: Disables output buffering for real-time log capture.
|
- **`-u` flag**: Disables output buffering for real-time log capture.
|
||||||
@@ -69,7 +71,20 @@ finally:
|
|||||||
|
|
||||||
Sends `reset_session()` via `ApiHookClient` before killing to prevent stale state files.
|
Sends `reset_session()` via `ApiHookClient` before killing to prevent stale state files.
|
||||||
|
|
||||||
**Yield value:** `(process: subprocess.Popen, gui_script: str)`.
|
**Yield value:** A `_LiveGuiHandle` object (defined in `tests/conftest.py:416-465`):
|
||||||
|
|
||||||
|
| Property | Type | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `.process` | `subprocess.Popen` | The sloppy.py subprocess. |
|
||||||
|
| `.gui_script` | `str` | Absolute path to `sloppy.py` that was launched. |
|
||||||
|
| `.workspace` | `Path` | Absolute path to the per-run workspace under `tests/artifacts/live_gui_workspace_<timestamp>/`. |
|
||||||
|
| `.is_alive()` | `() -> bool` | True if the subprocess is still running. |
|
||||||
|
| `.ensure_alive()` | `() -> None` | Stub — increments `respawn_count` if dead; full respawn is between test sessions. |
|
||||||
|
| `.respawn_count` | `int` | Diagnostic counter for subprocess deaths. |
|
||||||
|
|
||||||
|
**Backward compatibility:** The handle supports tuple unpacking (`process, gui_script = handle`) via `__iter__`, and indexing (`handle[0]` = process, `handle[1]` = gui_script) via `__getitem__`. Tests written against the old tuple-yielding fixture still work without modification.
|
||||||
|
|
||||||
|
**Xdist coordination:** The fixture uses an `O_EXCL`-atomic file lock at `tests/artifacts/live_gui_workspace_*/.live_gui_owner.lock`. The first xdist worker to acquire it spawns the subprocess; other workers wait and yield a null handle (`process=None`). Worker ID is read from `PYTEST_XDIST_WORKER`.
|
||||||
|
|
||||||
### Session Isolation
|
### Session Isolation
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user