Files
Agent-System-Dev/tests/test_check_pins.py
T

118 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""check-pins.sh:治理 gitlink 只告警,运行时依赖仍严格校验。"""
import os
import shutil
import subprocess
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "check-pins.sh"
CONTAINERS = ("modules/backend", "deps/agent-native", "deps/agent-squad", "deps/agent-intent")
class CheckPinsTests(unittest.TestCase):
def setUp(self):
self.tmp = Path(tempfile.mkdtemp())
self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True)
cfg = self.tmp / "gitconfig"
cfg.write_text("")
self.env = dict(
os.environ,
GIT_CONFIG_GLOBAL=str(cfg),
GIT_CONFIG_NOSYSTEM="1",
GIT_AUTHOR_NAME="t",
GIT_AUTHOR_EMAIL="t@example.invalid",
GIT_COMMITTER_NAME="t",
GIT_COMMITTER_EMAIL="t@example.invalid",
)
self.dev = self.tmp / "dev"
(self.dev / "scripts").mkdir(parents=True)
shutil.copy(SCRIPT, self.dev / "scripts" / "check-pins.sh")
self.git(self.dev, "init", "-q")
def git(self, cwd, *args):
return subprocess.run(
["git", *args], cwd=cwd, env=self.env, check=True, capture_output=True, text=True
).stdout.strip()
def repo(self, rel, *contents):
"""在 Dev 内建嵌套仓,按内容逐次提交,返回各提交 SHA。"""
path = self.dev / rel
path.mkdir(parents=True)
self.git(path, "init", "-q")
shas = []
for text in contents:
(path / "f").write_text(text)
self.git(path, "add", "f")
self.git(path, "commit", "-qm", text)
shas.append(self.git(path, "rev-parse", "HEAD"))
return shas
def link(self, repo, rel, sha):
self.git(repo, "update-index", "--add", "--cacheinfo", f"160000,{sha},{rel}")
def build(self, backend_deps, dev_pins):
"""backend_deps/dev_pins:{deps 名: sha};其余容器无 deps。"""
for rel, sha in dev_pins.items():
self.link(self.dev, rel, sha)
for container in CONTAINERS:
path = self.dev / container
if not path.exists():
self.repo(container, container)
if container == "modules/backend":
for name, sha in backend_deps.items():
self.link(path, f"deps/{name}", sha)
self.git(path, "commit", "-qm", "deps")
self.link(self.dev, container, self.git(path, "rev-parse", "HEAD"))
def run_pins(self):
return subprocess.run(
["bash", "scripts/check-pins.sh"], cwd=self.dev, env=self.env, capture_output=True, text=True
)
def test_governance_mismatch_warns_and_passes(self):
g_old, g_new = self.repo("deps/development-guidelines", "g1", "g2")
m_old, m_new = self.repo("deps/development-manager", "m1", "m2")
self.build(
{"development-guidelines": g_old, "development-manager": m_old},
{"deps/development-guidelines": g_new, "deps/development-manager": m_new},
)
res = self.run_pins()
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn("warn: modules/backend deps/development-guidelines", res.stderr)
self.assertIn("warn: modules/backend deps/development-manager", res.stderr)
self.assertIn("pins ok", res.stdout)
def test_runtime_mismatch_fails(self):
old, new = self.repo("deps/error-code-system", "e1", "e2")
self.build({"error-code-system": old}, {"deps/error-code-system": new})
res = self.run_pins()
self.assertEqual(res.returncode, 1)
self.assertIn("pin: modules/backend deps/error-code-system is", res.stderr)
def test_runtime_match_passes(self):
(sha,) = self.repo("deps/error-code-system", "e1")
self.build({"error-code-system": sha}, {"deps/error-code-system": sha})
res = self.run_pins()
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn("ok modules/backend error-code-system", res.stdout)
def test_runtime_missing_object_fails(self):
(sha,) = self.repo("deps/error-code-system", "e1")
self.build({"error-code-system": "1" * 40}, {"deps/error-code-system": sha})
res = self.run_pins()
self.assertEqual(res.returncode, 1)
self.assertIn("is missing locally", res.stderr)
def test_runtime_without_dev_pin_fails(self):
(sha,) = self.repo("deps/logging-system", "l1")
self.build({"logging-system": sha}, {})
res = self.run_pins()
self.assertEqual(res.returncode, 1)
self.assertIn("has no Dev pin", res.stderr)
if __name__ == "__main__":
unittest.main()