81 lines
3.9 KiB
Python
81 lines
3.9 KiB
Python
import gzip
|
|
import importlib.util
|
|
import json
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
REPO = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def module(name, path):
|
|
spec = importlib.util.spec_from_file_location(name, path)
|
|
value = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(value)
|
|
return value
|
|
|
|
|
|
launcher = module('launcher', REPO / 'lib/launcher.py')
|
|
audit = module('audit', REPO / 'tools/audit-packages.py')
|
|
|
|
|
|
class ReleaseTests(unittest.TestCase):
|
|
def bundle(self, repo):
|
|
for name in ('go.mod', 'go.sum', 'VERSION'):
|
|
(repo / name).write_text('fixture')
|
|
root = repo / 'assets/bin'; root.mkdir(parents=True)
|
|
data = b'fixture-binary'
|
|
archive = gzip.compress(data, mtime=0)
|
|
(root / 'fiw-dots.gz').write_bytes(archive)
|
|
metadata = {'source_sha256': launcher.source_hash(repo), 'binaries': {
|
|
'linux-amd64': {'file': 'fiw-dots.gz', 'size': len(data),
|
|
'sha256': launcher.digest(data), 'gzip_sha256': launcher.digest(archive)}}}
|
|
(root / 'tui.json').write_text(json.dumps(metadata))
|
|
return data
|
|
|
|
def test_bundle_runs_without_go_and_replaces_a_damaged_cache(self):
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
repo = Path(temp); data = self.bundle(repo)
|
|
cache = repo / 'build/fiw-dots'; cache.parent.mkdir(); cache.write_bytes(b'damaged')
|
|
with patch.object(launcher.platform, 'system', return_value='Linux'), patch.object(launcher.platform, 'machine', return_value='x86_64'), patch.object(launcher.shutil, 'which', return_value=None), patch.object(launcher.os, 'chdir'), patch.dict(launcher.os.environ, {'FIW_DOTS_SOURCE': '0'}), patch.object(launcher.subprocess, 'run') as run:
|
|
self.assertEqual(launcher.launch(repo), cache)
|
|
self.assertEqual(cache.read_bytes(), data)
|
|
self.assertTrue(cache.stat().st_mode & 0o111)
|
|
run.assert_not_called()
|
|
|
|
def test_changed_frontend_and_modified_archives_are_rejected(self):
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
repo = Path(temp); self.bundle(repo)
|
|
cache = repo / 'build/fiw-dots'
|
|
with patch.object(launcher.platform, 'system', return_value='Linux'), patch.object(launcher.platform, 'machine', return_value='x86_64'):
|
|
archive = repo / 'assets/bin/fiw-dots.gz'
|
|
original = archive.read_bytes(); archive.write_bytes(original + b'modified')
|
|
with self.assertRaises(RuntimeError):
|
|
launcher.bundled(repo, cache)
|
|
archive.write_bytes(original)
|
|
(repo / 'cmd/dots').mkdir(parents=True)
|
|
(repo / 'cmd/dots/main.go').write_text('changed frontend')
|
|
with self.assertRaises(RuntimeError):
|
|
launcher.bundled(repo, cache)
|
|
self.assertFalse(cache.exists())
|
|
|
|
def test_audit_expands_only_selected_sets_and_preserves_java_slots(self):
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
root = Path(temp); sets = root / 'sets'; sets.mkdir()
|
|
world, selected = root / 'world', root / 'world_sets'
|
|
world.write_text('=app-editors/vscode-1.0::old\n')
|
|
selected.write_text('@desktop\n')
|
|
(sets / 'desktop').write_text('app-editors/vscode\n@java\n')
|
|
(sets / 'java').write_text('dev-java/openjdk-bin:21\n')
|
|
(sets / 'not-selected').write_text('dev-libs/dependency-only\n')
|
|
result, unresolved = audit.explicit(world, selected, sets)
|
|
self.assertEqual(set(result), {'app-editors/vscode', 'dev-java/openjdk-bin:21'})
|
|
self.assertEqual(unresolved, [])
|
|
(sets / 'java').write_text('@desktop\n')
|
|
with self.assertRaises(ValueError):
|
|
audit.explicit(world, selected, sets)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|