Skip to content

Commit 3aaeb87

Browse files
mnm-matinclaude
andcommitted
Keep the test suite out of the developer's real HyperView store
`Dataset(..., persist=False)` skips the dataset, but workspace state still went to whatever `StorageConfig` resolved from the environment -- by default the developer's own `~/.hyperview`. Four test modules redirected it themselves; the other thirty-three did not, so a test run wrote fixture workspaces into the same registry the demos and Static Space exports read from. On this machine that had accumulated 2,686 of them since April, against 62 real workspaces, and nothing stopped a fixture id from colliding with a real one. An autouse session fixture points both storage roots at a temporary directory. That covers every registry, not just datasets: `get_runtime_config_dir()` derives the config directory from `datasets_dir.parent`, so workspaces.json, providers.json and jobs.json move with it. A second fixture asserts the real registry's mtime is unchanged around every test, so a future code path that resolves the store some other way fails here instead of silently polluting the developer's machine again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 29de6ef commit 3aaeb87

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

‎tests/conftest.py‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""Keep the test suite out of the developer's real HyperView store.
2+
3+
`Dataset(..., persist=False)` skips writing the dataset, but workspace, provider
4+
and job state still land in the registry directories that `StorageConfig`
5+
resolves from the environment -- and those default to `~/.hyperview`. Without
6+
this fixture a test run silently accumulates fixture workspaces in the same
7+
registry the demos and Static Space exports read from, where a test's workspace
8+
id can collide with a real one.
9+
10+
Redirecting both storage roots at a per-session temporary directory pins every
11+
registry path with them: `get_runtime_config_dir()` derives the config directory
12+
from `datasets_dir.parent`, so workspaces.json, providers.json and jobs.json all
13+
follow the datasets directory here.
14+
"""
15+
16+
from __future__ import annotations
17+
18+
import os
19+
from pathlib import Path
20+
21+
import pytest
22+
23+
24+
@pytest.fixture(scope="session", autouse=True)
25+
def isolate_hyperview_store(tmp_path_factory: pytest.TempPathFactory):
26+
root = tmp_path_factory.mktemp("hyperview-store")
27+
datasets_dir = root / "datasets"
28+
media_dir = root / "media"
29+
datasets_dir.mkdir()
30+
media_dir.mkdir()
31+
32+
previous = {
33+
"HYPERVIEW_DATASETS_DIR": os.environ.get("HYPERVIEW_DATASETS_DIR"),
34+
"HYPERVIEW_MEDIA_DIR": os.environ.get("HYPERVIEW_MEDIA_DIR"),
35+
}
36+
os.environ["HYPERVIEW_DATASETS_DIR"] = str(datasets_dir)
37+
os.environ["HYPERVIEW_MEDIA_DIR"] = str(media_dir)
38+
try:
39+
yield root
40+
finally:
41+
for key, value in previous.items():
42+
if value is None:
43+
os.environ.pop(key, None)
44+
else:
45+
os.environ[key] = value
46+
47+
48+
@pytest.fixture(autouse=True)
49+
def guard_real_hyperview_store():
50+
"""Fail loudly if a test writes into the real store despite the redirect."""
51+
52+
registry = Path.home() / ".hyperview" / "workspaces.json"
53+
before = registry.stat().st_mtime_ns if registry.exists() else None
54+
yield
55+
after = registry.stat().st_mtime_ns if registry.exists() else None
56+
if before != after:
57+
raise AssertionError(
58+
f"test wrote to the real workspace registry at {registry}; "
59+
"it must go through the isolated store instead"
60+
)

0 commit comments

Comments
 (0)