test_k7_footprint.py python
119 lines 4.5 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
1 """Unit tests for K7 muse+git-mirror footprint (§K7.8 unit tier)."""
2
3 from __future__ import annotations
4
5 import re
6 import stat
7 from pathlib import Path
8
9 import pytest
10
11 from adapters.config import load_config
12 from adapters.errors import ConfigError
13 from adapters.templating import ALLOWED_TOKENS, render_template
14 from cli.footprint import (
15 EXECUTABLE_FOOTPRINT_DESTINATIONS,
16 MUSE_BRIDGE_DEPLOY_DEST,
17 MUSE_BRIDGE_WORKFLOW_DEST,
18 resolve_footprint,
19 )
20 from cli.footprint_writes import FOOTPRINT_EXECUTABLE_MODE, write_footprint_bytes
21 from cli.kit_root import kit_root
22 from tests.support import FIXTURES
23
24
25 def test_muse_git_mirror_footprint_includes_bridge_assets(muse_git_mirror_config) -> None:
26 dests = {f.destination for f in resolve_footprint(muse_git_mirror_config)}
27 assert MUSE_BRIDGE_WORKFLOW_DEST in dests
28 assert MUSE_BRIDGE_DEPLOY_DEST in dests
29
30
31 def test_git_only_footprint_omits_bridge_assets(git_only_config) -> None:
32 dests = {f.destination for f in resolve_footprint(git_only_config)}
33 assert MUSE_BRIDGE_WORKFLOW_DEST not in dests
34 assert MUSE_BRIDGE_DEPLOY_DEST not in dests
35
36
37 def test_muse_only_footprint_omits_bridge_assets(muse_only_config) -> None:
38 dests = {f.destination for f in resolve_footprint(muse_only_config)}
39 assert MUSE_BRIDGE_WORKFLOW_DEST not in dests
40 assert MUSE_BRIDGE_DEPLOY_DEST not in dests
41
42
43 def test_overseer_kit_dogfood_config_matrix_loads() -> None:
44 config = load_config(FIXTURES / "config-overseer-kit-dogfood.yaml")
45 assert config.vcs.regime == "muse+git-mirror"
46 assert config.vcs.canonical == "muse"
47 assert config.vcs.git.mirror_branch == "muse-mirror"
48 assert config.docs.coordination is None
49 assert config.vcs.muse.working_dir is None
50 dests = {f.destination for f in resolve_footprint(config)}
51 assert MUSE_BRIDGE_WORKFLOW_DEST in dests
52
53
54 def test_bridge_templates_use_only_allowed_tokens(muse_git_mirror_config) -> None:
55 templates_dir = kit_root() / "templates"
56 for name in (
57 "MUSE-BRIDGE-WORKFLOW.template.md",
58 "scripts/muse-bridge-deploy.sh.template",
59 ):
60 raw = (templates_dir / name).read_text(encoding="utf-8")
61 found = set(re.findall(r"\{\{([a-z][a-z0-9_.]*)\}\}", raw))
62 assert found.issubset(ALLOWED_TOKENS), f"unexpected tokens in {name}: {found - ALLOWED_TOKENS}"
63 rendered = render_template(templates_dir / name, muse_git_mirror_config)
64 assert "{{" not in rendered
65
66
67 def test_rendered_deploy_script_safety_invariants(muse_git_mirror_config) -> None:
68 script = render_template(
69 kit_root() / "templates" / "scripts" / "muse-bridge-deploy.sh.template",
70 muse_git_mirror_config,
71 )
72 assert "set -euo pipefail" in script
73 assert "mirror directory equals repo root" in script
74 assert "muse-bridge-sentinel" in script
75 assert 'muse -C "${MUSE_ROOT}" bridge git-export' in script
76 assert '--git-dir "${MIRROR_ABS}"' in script
77 assert "origin" in script
78 assert "muse-mirror" in script
79 assert "main" in script
80 assert 'push "${GIT_REMOTE}" "${MIRROR_BRANCH}"' in script
81 assert "GIT_REMOTE_URL=" in script
82 assert '--commit-message "${COMMIT_MSG}"' in script
83 assert "--message " not in script
84 assert "--no-push" not in script
85 assert 'git push origin main' not in script
86 assert 'push "${GIT_REMOTE}" "${MAIN_BRANCH}"' not in script
87 for token in (
88 "{{vcs.git.remote}}",
89 "{{vcs.git.mirror_branch}}",
90 "{{vcs.git.main_branch}}",
91 ):
92 assert token not in script
93
94
95 def test_rendered_workflow_hard_rules(muse_git_mirror_config) -> None:
96 doc = render_template(
97 kit_root() / "templates" / "MUSE-BRIDGE-WORKFLOW.template.md",
98 muse_git_mirror_config,
99 )
100 assert "muse bridge git-export --git-dir ." in doc
101 assert "git push origin main" in doc
102 assert "muse-mirror" in doc
103 assert "./scripts/muse-bridge-deploy.sh" in doc
104
105
106 def test_unknown_token_in_bridge_template_fails_closed(muse_git_mirror_config, tmp_path: Path) -> None:
107 bad = tmp_path / "bad.template.md"
108 bad.write_text("{{evil.token}}\n", encoding="utf-8")
109 with pytest.raises(ConfigError, match="unknown or unmapped template token"):
110 render_template(bad, muse_git_mirror_config)
111
112
113 def test_write_footprint_bytes_sets_executable_on_deploy_script(tmp_path: Path) -> None:
114 dest = MUSE_BRIDGE_DEPLOY_DEST
115 assert dest in EXECUTABLE_FOOTPRINT_DESTINATIONS
116 path = tmp_path / dest
117 write_footprint_bytes(path, b"#!/usr/bin/env bash\necho ok\n", destination=dest)
118 mode = path.stat().st_mode
119 assert stat.S_IMODE(mode) == FOOTPRINT_EXECUTABLE_MODE
File History 2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 53 days ago