test_footprint_integrity_stress.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago
| 1 | """Stress: `check_footprint_integrity` stays bounded with a large declared footprint (§KH3.8).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import time |
| 6 | from pathlib import Path |
| 7 | |
| 8 | from cli.version_lock import ORIGIN_KIT, FootprintEntry, build_version_lock_from_entries |
| 9 | from tools.footprint_integrity import check_footprint_integrity |
| 10 | |
| 11 | ENTRY_COUNT = 5_000 |
| 12 | |
| 13 | |
| 14 | def test_large_declared_footprint_resolves_in_bounded_time(tmp_path: Path) -> None: |
| 15 | entries = [ |
| 16 | FootprintEntry( |
| 17 | path=f"generated/file_{i:05d}.mdc", |
| 18 | source=f"cursor/rules/file_{i:05d}.mdc", |
| 19 | sha256="0" * 64, |
| 20 | origin=ORIGIN_KIT, |
| 21 | ) |
| 22 | for i in range(ENTRY_COUNT) |
| 23 | ] |
| 24 | # Half exist on disk, half do not — exercises both branches at scale. |
| 25 | generated_dir = tmp_path / "generated" |
| 26 | generated_dir.mkdir() |
| 27 | for i in range(0, ENTRY_COUNT, 2): |
| 28 | (generated_dir / f"file_{i:05d}.mdc").write_text("x", encoding="utf-8") |
| 29 | |
| 30 | lock = build_version_lock_from_entries( |
| 31 | kit_version="0.1.0", |
| 32 | config_version=1, |
| 33 | entries=entries, |
| 34 | installed_at="2026-01-01T00:00:00Z", |
| 35 | ) |
| 36 | |
| 37 | started = time.monotonic() |
| 38 | report = check_footprint_integrity(tmp_path, lock=lock) |
| 39 | elapsed = time.monotonic() - started |
| 40 | |
| 41 | assert report.state == "missing" |
| 42 | assert len(report.missing) == ENTRY_COUNT // 2 |
| 43 | # One Path.is_file() per entry only — no hashing, no per-file content read. |
| 44 | assert elapsed < 5.0 |
| 45 | |
| 46 | |
| 47 | def test_missing_count_scales_linearly_not_quadratically(tmp_path: Path) -> None: |
| 48 | """A doubled entry count should not blow up runtime disproportionately (O(n), not O(n^2)).""" |
| 49 | def _time_for(count: int) -> float: |
| 50 | entries = [ |
| 51 | FootprintEntry(path=f"f_{i}.mdc", source="s", sha256="0" * 64, origin=ORIGIN_KIT) |
| 52 | for i in range(count) |
| 53 | ] |
| 54 | lock = build_version_lock_from_entries( |
| 55 | kit_version="0.1.0", |
| 56 | config_version=1, |
| 57 | entries=entries, |
| 58 | installed_at="2026-01-01T00:00:00Z", |
| 59 | ) |
| 60 | started = time.monotonic() |
| 61 | check_footprint_integrity(tmp_path, lock=lock) |
| 62 | return time.monotonic() - started |
| 63 | |
| 64 | small = _time_for(500) |
| 65 | large = _time_for(5_000) |
| 66 | # Generous bound — guards against accidental quadratic behavior, not micro-timing noise. |
| 67 | assert large < small * 50 + 1.0 |
File History
1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago