personal memory agent
0

Configure Feed

Select the types of activity you want to include in your feed.

solstone / tests / test_fixture_leak_detector.py
3.8 kB 129 lines
1# SPDX-License-Identifier: AGPL-3.0-only 2# Copyright (c) 2026 sol pbc 3"""Canary for the fixture-leak detector in the project-root conftest.py.""" 4 5from __future__ import annotations 6 7import subprocess 8import sys 9from pathlib import Path 10 11import pytest 12 13pytest_plugins = ["pytester"] 14pytestmark = pytest.mark.xdist_group("fixture_leak_detector") 15 16_ROOT_CONFTEST = Path(__file__).resolve().parent.parent / "conftest.py" 17 18 19def _prime_git_repo(project_dir: Path) -> None: 20 """Initialise a miniature git repo with one tracked file under tests/fixtures/.""" 21 subprocess.run(["git", "init", "-q"], cwd=project_dir, check=True) 22 subprocess.run( 23 [ 24 "git", 25 "-c", 26 "commit.gpgsign=false", 27 "-c", 28 "user.email=canary@example.invalid", 29 "-c", 30 "user.name=canary", 31 "commit", 32 "--allow-empty", 33 "-q", 34 "-m", 35 "init", 36 ], 37 cwd=project_dir, 38 check=True, 39 ) 40 fixtures_dir = project_dir / "tests" / "fixtures" 41 fixtures_dir.mkdir(parents=True, exist_ok=True) 42 (fixtures_dir / "keep").write_text("kept\n", encoding="utf-8") 43 subprocess.run(["git", "add", "tests/fixtures/keep"], cwd=project_dir, check=True) 44 subprocess.run( 45 [ 46 "git", 47 "-c", 48 "commit.gpgsign=false", 49 "-c", 50 "user.email=canary@example.invalid", 51 "-c", 52 "user.name=canary", 53 "commit", 54 "-q", 55 "-m", 56 "fixtures", 57 ], 58 cwd=project_dir, 59 check=True, 60 ) 61 62 63def _install_detector(pytester: pytest.Pytester) -> None: 64 """Copy the real root conftest.py into the pytester project root.""" 65 pytester.makepyfile(conftest=_ROOT_CONFTEST.read_text(encoding="utf-8")) 66 67 68def _run_nested(pytester: pytest.Pytester) -> pytest.RunResult: 69 basetemp = pytester.path / "basetemp" 70 return pytester.run( 71 sys.executable, 72 "-mpytest", 73 "-q", 74 "-p", 75 "no:cacheprovider", 76 "--basetemp", 77 str(basetemp), 78 ) 79 80 81@pytest.mark.timeout(30) 82def test_detector_fires_on_leaked_file(pytester: pytest.Pytester) -> None: 83 _install_detector(pytester) 84 _prime_git_repo(pytester.path) 85 pytester.makepyfile( 86 test_leak=""" 87 from pathlib import Path 88 89 def test_writes_into_fixtures(tmp_path): 90 Path("tests/fixtures/leak_probe.tmp").write_text("x") 91 """ 92 ) 93 result = _run_nested(pytester) 94 assert result.ret != 0, result.stderr.str() + result.stdout.str() 95 combined = result.stderr.str() + result.stdout.str() 96 assert "solstone fixture-leak detector" in combined 97 assert "tests/fixtures/leak_probe.tmp" in combined 98 assert "journal_copy fixture" in combined 99 100 101@pytest.mark.timeout(30) 102def test_detector_silent_on_clean(pytester: pytest.Pytester) -> None: 103 _install_detector(pytester) 104 _prime_git_repo(pytester.path) 105 pytester.makepyfile( 106 test_clean=""" 107 def test_noop(): 108 assert True 109 """ 110 ) 111 result = _run_nested(pytester) 112 assert result.ret == 0, result.stderr.str() + result.stdout.str() 113 combined = result.stderr.str() + result.stdout.str() 114 assert "fixture-leak detector" not in combined 115 116 117@pytest.mark.timeout(30) 118def test_detector_skips_without_git_repo(pytester: pytest.Pytester) -> None: 119 _install_detector(pytester) 120 pytester.makepyfile( 121 test_clean=""" 122 def test_noop(): 123 assert True 124 """ 125 ) 126 result = _run_nested(pytester) 127 assert result.ret == 0, result.stderr.str() + result.stdout.str() 128 combined = result.stderr.str() + result.stdout.str() 129 assert "git unavailable" in combined