S19: establish engineering repository

This commit is contained in:
2026-11-08 15:15:50 +01:00
commit c25ce11a1b
84 changed files with 6599 additions and 0 deletions

95
tests/test_bootstrap.py Normal file
View File

@@ -0,0 +1,95 @@
"""Exercise release pinning, drift detection, replacement and recovery without network."""
import importlib.util
import json
from pathlib import Path
import shutil
import subprocess
import tempfile
import unittest
HOME = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location('bootstrap', HOME / 'bootstrap.py')
bootstrap = importlib.util.module_from_spec(spec)
spec.loader.exec_module(bootstrap)
class BootstrapTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary.cleanup)
self.root = Path(self.temporary.name)
self.source = self.root / 'engineering'
self.source.mkdir()
self.git('init', '-q')
self.git('config', 'user.email', 'test@example.invalid')
self.git('config', 'user.name', 'Engineering test')
(self.source / 'resources').mkdir()
(self.source / 'resources/tool').write_text('version one\n')
self.commit = self.release('v1.0.0')
self.project = self.root / 'consumer'
self.project.mkdir()
self.lock = {'repository': str(self.source), 'tag': 'v1.0.0', 'commit': self.commit}
self.save_lock()
def git(self, *args):
return subprocess.check_output(['git', '-C', str(self.source), *args], text=True, stderr=subprocess.DEVNULL).strip()
def release(self, tag):
self.git('add', '.')
self.git('commit', '-qm', tag)
self.git('tag', tag)
return self.git('rev-parse', 'HEAD')
def save_lock(self):
(self.project / 'engineering.lock.json').write_text(json.dumps(self.lock))
def test_absent_generated_and_repeat_are_deterministic(self):
bootstrap.materialize(self.project)
first = bootstrap.files(self.project / 'generated')
bootstrap.materialize(self.project)
self.assertEqual(first, bootstrap.files(self.project / 'generated'))
bootstrap.materialize(self.project, True)
def test_drift_includes_modified_added_and_missing_files(self):
bootstrap.materialize(self.project)
target = self.project / 'generated/tool'
for operation in ('modify', 'remove', 'add'):
with self.subTest(operation=operation):
bootstrap.materialize(self.project)
if operation == 'modify': target.write_text('hand edit')
elif operation == 'remove': target.unlink()
else: (target.parent / 'extra').write_text('untracked')
before = bootstrap.files(target.parent)
with self.assertRaisesRegex(ValueError, 'differ'):
bootstrap.materialize(self.project, True)
self.assertEqual(before, bootstrap.files(target.parent))
def test_update_removes_obsolete_files_and_preserves_project_files(self):
bootstrap.materialize(self.project)
(self.project / 'pom.xml').write_text('owned by project')
(self.source / 'resources/tool').unlink()
(self.source / 'resources/new').write_text('new release')
self.lock.update(tag='v1.1.0', commit=self.release('v1.1.0'))
self.save_lock()
bootstrap.materialize(self.project)
self.assertFalse((self.project / 'generated/tool').exists())
self.assertEqual('owned by project', (self.project / 'pom.xml').read_text())
def test_moved_tag_fails_before_replacing_existing_content(self):
bootstrap.materialize(self.project)
before = bootstrap.files(self.project / 'generated')
(self.source / 'resources/tool').write_text('different commit')
self.release('v1.1.0')
self.git('tag', '-f', 'v1.0.0')
with self.assertRaisesRegex(ValueError, 'tag moved'):
bootstrap.materialize(self.project)
self.assertEqual(before, bootstrap.files(self.project / 'generated'))
def test_symlink_output_is_rejected(self):
(self.project / 'generated').symlink_to(self.source / 'resources', target_is_directory=True)
with self.assertRaisesRegex(ValueError, 'symlink'):
bootstrap.materialize(self.project)
if __name__ == '__main__':
unittest.main()