Viewing files at commit a9e8fa39d0a0Commit detailsView latest

Browse files
tests/test_make_monorepo_fixture.py 125 lines · 5.0 KB · python
1
from __future__ import annotations
2
3
import json
4
import shutil
5
import subprocess
6
import sys
7
import tempfile
8
import unittest
9
from pathlib import Path
10
11
ROOT = Path(__file__).resolve().parents[1]
12
GENERATOR = ROOT / "scripts" / "make_monorepo_fixture.py"
13
14
sys.path.insert(0, str(ROOT / "scripts"))
15
16
import bench  # noqa: E402
17
from oakbench.fixture_registry import load_fixture_registry  # noqa: E402
18
19
QUICK_ARGS = ["--quick", "--files", "50", "--commits", "20", "--refs", "5", "--tags", "2"]
20
21
22
def run_generator(out: Path, seed: str) -> subprocess.CompletedProcess:
23
    return subprocess.run(
24
        [sys.executable, str(GENERATOR), "--out", str(out), "--seed", seed, *QUICK_ARGS],
25
        capture_output=True, text=True,
26
    )
27
28
29
def git_out(repo: Path, *args: str) -> str:
30
    return subprocess.run(["git", "-C", str(repo), *args], check=True,
31
                          capture_output=True, text=True).stdout.strip()
32
33
34
class MakeMonorepoFixtureTest(unittest.TestCase):
35
    @classmethod
36
    def setUpClass(cls) -> None:
37
        if shutil.which("git") is None:
38
            raise unittest.SkipTest("git not available")
39
        cls.tmp = tempfile.TemporaryDirectory()
40
        cls.addClassCleanup(cls.tmp.cleanup)
41
        base = Path(cls.tmp.name)
42
        cls.repo_a = base / "a"
43
        cls.repo_b = base / "b"
44
        cls.repo_c = base / "c"
45
        for repo, seed in ((cls.repo_a, "test-v1"), (cls.repo_b, "test-v1"),
46
                           (cls.repo_c, "test-v2")):
47
            proc = run_generator(repo, seed)
48
            if proc.returncode != 0:
49
                raise AssertionError(
50
                    f"generator failed for {repo} (exit {proc.returncode}):\n"
51
                    f"{proc.stdout}\n{proc.stderr}")
52
53
    def test_creates_git_repo(self) -> None:
54
        self.assertTrue((self.repo_a / ".git").is_dir())
55
56
    def test_commit_count_matches(self) -> None:
57
        self.assertEqual(git_out(self.repo_a, "rev-list", "--count", "HEAD"), "20")
58
59
    def test_branch_count_is_main_plus_requested(self) -> None:
60
        heads = git_out(self.repo_a, "for-each-ref", "--format=%(refname)",
61
                        "refs/heads").splitlines()
62
        self.assertEqual(len(heads), 6)  # refs/heads/main + branch-0..4
63
        self.assertIn("refs/heads/main", heads)
64
        self.assertEqual(git_out(self.repo_a, "symbolic-ref", "HEAD"), "refs/heads/main")
65
66
    def test_tag_count_matches(self) -> None:
67
        tags = git_out(self.repo_a, "for-each-ref", "--format=%(refname)",
68
                       "refs/tags").splitlines()
69
        self.assertEqual(len(tags), 2)
70
71
    def test_manifest_records_head_sha(self) -> None:
72
        manifest = json.loads((self.repo_a / "HISTORY_MANIFEST.json").read_text())
73
        self.assertEqual(manifest["schema_version"], 1)
74
        self.assertEqual(manifest["seed"], "test-v1")
75
        self.assertEqual(manifest["files"], 50)
76
        self.assertEqual(manifest["commits"], 20)
77
        self.assertEqual(manifest["refs"], 5)
78
        self.assertEqual(manifest["tags"], 2)
79
        self.assertEqual(manifest["generator_version"], "monorepo-v1")
80
        self.assertEqual(manifest["head_sha"], git_out(self.repo_a, "rev-parse", "HEAD"))
81
82
    def test_same_seed_yields_identical_history(self) -> None:
83
        self.assertEqual(git_out(self.repo_a, "rev-parse", "HEAD"),
84
                         git_out(self.repo_b, "rev-parse", "HEAD"))
85
86
    def test_different_seed_yields_different_history(self) -> None:
87
        self.assertNotEqual(git_out(self.repo_a, "rev-parse", "HEAD"),
88
                            git_out(self.repo_c, "rev-parse", "HEAD"))
89
90
91
class FixtureRegistryEntriesTest(unittest.TestCase):
92
    def test_new_fixture_ids_registered(self) -> None:
93
        registry = load_fixture_registry()
94
        for fixture_id in ("xl-tree-500k-v1", "xl-history-50k-v1", "xl-refs-25k-v1",
95
                           "monorepo-tree-1m-v1", "monorepo-history-100k-v1",
96
                           "monorepo-refs-100k-v1"):
97
            self.assertIn(fixture_id, registry)
98
            spec = registry[fixture_id]
99
            self.assertEqual(spec.generator, "scripts/make_monorepo_fixture.py")
100
            self.assertEqual(spec.license, "synthetic")
101
            self.assertIsNone(spec.manifest)
102
            self.assertEqual(spec.hosting, ("local",))
103
            self.assertEqual(spec.status, "planned")
104
105
    def test_monorepo_fixtures_are_registry_declarations_not_active_bench_profiles(self) -> None:
106
        scenario_names = {scenario.name for profile in bench.PROFILES.values() for scenario in profile}
107
        self.assertFalse(any("monorepo" in name or name.startswith("xl_") for name in scenario_names))
108
109
        registry = load_fixture_registry()
110
        planned = {fixture_id for fixture_id, spec in registry.items() if spec.status == "planned"}
111
        self.assertGreaterEqual(
112
            planned,
113
            {
114
                "xl-tree-500k-v1",
115
                "xl-history-50k-v1",
116
                "xl-refs-25k-v1",
117
                "monorepo-tree-1m-v1",
118
                "monorepo-history-100k-v1",
119
                "monorepo-refs-100k-v1",
120
            },
121
        )
122
123
124
if __name__ == "__main__":
125
    unittest.main()