Files
Agent-System-Dev/tests/test_component_governance.py
T
weichen 98d08347bd Integrate current task recovery and accepted planning contracts
Why:
Preserve work merged by concurrent tasks while adopting versioned dependency workspaces.

Evidence:
SELF task receipts record conflict detection, all 96 task/recovery/cutover cases, all 33 evidence cases and 5 component identity cases. Documents links and requirements were replayed after preserving both planning entries.

Impact:
Keep upstream idempotent sync, local resume and source-external receipt rules; adapt fixed-guidelines readiness and ignored component identity validation. Remove only obsolete index links and retain their physical Git metadata.

Refs:
Authoritative main57bcb17ea212a531186b6e21617a7f3bea65a791; Documents4a26798000c39cc59ba0c2cc6328f5c8f10dcb32; dependency-workspace R15.
2026-10-13 17:38:24 +00:00

94 lines
4.8 KiB
Python

import importlib.util
import json
import os
from pathlib import Path
import subprocess
import tempfile
import unittest
SCRIPTS = Path(__file__).resolve().parents[1] / 'scripts'
class ComponentGovernanceTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name)
self.run_git(self.root, 'init', '-q')
self.run_git(self.root, 'config', 'user.name', 'Fixture')
self.run_git(self.root, 'config', 'user.email', 'fixture@example.test')
self.child = self.root / '.workspace/Provider'
self.child.mkdir(parents=True)
self.run_git(self.child, 'init', '-q')
self.run_git(self.child, 'config', 'user.name', 'Fixture')
self.run_git(self.child, 'config', 'user.email', 'fixture@example.test')
(self.child/'value').write_text('one')
self.run_git(self.child, 'add', 'value')
self.run_git(self.child, 'commit', '-qm', 'Add value')
(self.root/'.gitignore').write_text('.workspace/\n')
(self.root/'components.json').write_text(json.dumps({'schema':1,'components':[{
'id':'Provider','repo':self.child.as_uri(),'path':'.workspace/Provider',
'role':'documentation','modules':[],'target':'main'}]}))
self.run_git(self.root, 'add', '.gitignore', 'components.json')
self.run_git(self.root, 'commit', '-qm', 'Add component mapping')
self.old = Path.cwd()
os.chdir(self.root)
self.addCleanup(os.chdir,self.old)
def run_git(self,root,*args):
return subprocess.check_output(['git','-C',str(root),*args],stderr=subprocess.STDOUT,text=True)
def snapshot(self):
spec=importlib.util.spec_from_file_location('component_evidence',SCRIPTS/'evidence.py')
module=importlib.util.module_from_spec(spec); spec.loader.exec_module(module)
return module.snapshot()
def test_evidence_captures_ignored_component_revision_and_dirty_bytes(self):
first=self.snapshot()
(self.child/'value').write_text('two')
second=self.snapshot()
self.assertIn('components',first,'receipts must identify ordinary ignored component checkouts')
self.assertNotEqual(first['components'],second['components'])
self.run_git(self.child,'commit','-qam','Change value')
third=self.snapshot()
self.assertNotEqual(second['components'],third['components'])
self.assertEqual(first['head'],third['head'])
def test_before_sync_rejects_component_git_lock(self):
(self.child/'.git/index.lock').write_text('active owner')
result=subprocess.run(['python3',str(SCRIPTS/'check-worktree.py'),'before-sync'],cwd=self.root,capture_output=True,text=True)
self.assertNotEqual(result.returncode,0,'a hidden component writer must block synchronization')
self.assertTrue((self.child/'.git/index.lock').exists())
def test_startup_receipt_rejects_changed_ignored_component_objects(self):
spec=importlib.util.spec_from_file_location('component_evidence_validation',SCRIPTS/'evidence.py')
module=importlib.util.module_from_spec(spec); spec.loader.exec_module(module)
self.run_git(self.root,'update-ref','refs/remotes/origin/main','HEAD')
before=module.snapshot()
receipt=module.create_receipt('make precheck','[verdict] READY\n',0,before,before,
timestamp='2026-10-13T00:00:00+00:00',cwd=str(self.root),
git_common_dir=module.common_dir())
module.validate_precheck(receipt)
(self.child/'value').write_text('changed after startup')
with self.assertRaises(module.EvidenceError):
module.validate_precheck(receipt)
def test_new_layout_cannot_use_receipt_without_component_identity(self):
spec=importlib.util.spec_from_file_location('component_evidence_legacy',SCRIPTS/'evidence.py')
module=importlib.util.module_from_spec(spec); spec.loader.exec_module(module)
self.run_git(self.root,'update-ref','refs/remotes/origin/main','HEAD')
before=module.snapshot();before.pop('components')
receipt=module.create_receipt('make precheck','[verdict] READY\n',0,before,before,
timestamp='2026-10-13T00:00:00+00:00',cwd=str(self.root),
git_common_dir=module.common_dir())
with self.assertRaises(module.EvidenceError):
module.validate_precheck(receipt)
def test_receipts_reject_component_path_escape(self):
data=json.loads((self.root/'components.json').read_text())
data['components'][0]['path']='../outside'
(self.root/'components.json').write_text(json.dumps(data))
with self.assertRaises(Exception):
self.snapshot()
if __name__=='__main__': unittest.main()