72 lines
4.3 KiB
Python
72 lines
4.3 KiB
Python
import importlib.util
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
spec = importlib.util.spec_from_file_location('catalog_drift', ROOT / 'scripts/check-app-catalog-drift.py')
|
|
drift = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(drift)
|
|
|
|
class CatalogCapabilities(unittest.TestCase):
|
|
def test_pinned_tailscale_version_and_internal_tor_dependency_are_preserved(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
target = Path(directory) / 'catalog.json'
|
|
subprocess.run(['bash', str(ROOT / 'scripts/generate-app-catalog.sh'), str(target)], check=True, capture_output=True)
|
|
catalog = json.loads(target.read_text())
|
|
tailscale = catalog['apps']['tailscale']
|
|
self.assertEqual(tailscale['version'], 'v1.104.4')
|
|
self.assertIn('@sha256:', tailscale['image'])
|
|
self.assertEqual(tailscale['image'], tailscale['manifest']['app']['container']['image'])
|
|
self.assertIn('lnd-tor', catalog['apps'])
|
|
public_ids = {app['id'] for app in json.loads((ROOT / 'app-catalog/catalog.json').read_text())['apps']}
|
|
self.assertNotIn('lnd-tor', public_ids)
|
|
self.assertIn('lnd-tor', drift.INTERNAL_MANIFEST_IDS)
|
|
|
|
def test_new_backup_app_has_only_a_capability_gated_manifest(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
target = Path(directory) / 'catalog.json'
|
|
subprocess.run(['bash', str(ROOT / 'scripts/generate-app-catalog.sh'), str(target)], check=True, capture_output=True)
|
|
catalog = json.loads(target.read_text())
|
|
entry = catalog['apps']['qortal']
|
|
self.assertNotIn('manifest', entry)
|
|
self.assertNotIn('image', entry)
|
|
self.assertNotIn('images', entry)
|
|
self.assertEqual(entry['manifest_variants'][0]['requires'], ['runtime-migration-backup-v1'])
|
|
self.assertTrue(drift.load_catalog(target)['qortal']['backup_before_runtime_change'])
|
|
entry['manifest_variants'][0]['requires'].append('unknown-capability')
|
|
target.write_text(json.dumps(catalog))
|
|
self.assertNotIn('container', drift.load_catalog(target)['qortal'])
|
|
|
|
def test_existing_entry_without_legacy_manifest_is_still_refused(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
baseline = json.loads((ROOT / 'releases/app-catalog.json').read_text())
|
|
baseline['apps']['qortal'] = {'version': '6.1.8'}
|
|
source = Path(directory) / 'baseline.json'
|
|
source.write_text(json.dumps(baseline))
|
|
target = Path(directory) / 'catalog.json'
|
|
result = subprocess.run(['bash', str(ROOT / 'scripts/generate-app-catalog.sh'), str(target)],
|
|
env={**os.environ, 'BASE_CATALOG': str(source)}, capture_output=True, text=True)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn('pre-migration BASE_CATALOG manifest is required', result.stderr)
|
|
|
|
def test_generated_npm_migration_requires_gateway_support_and_preserves_old_manifest(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
target = Path(directory) / 'catalog.json'
|
|
subprocess.run(['bash', str(ROOT / 'scripts/generate-app-catalog.sh'), str(target)], check=True, capture_output=True)
|
|
catalog = json.loads(target.read_text())
|
|
baseline = json.loads((ROOT / 'releases/app-catalog.json').read_text())
|
|
entry = catalog['apps']['nginx-proxy-manager']
|
|
self.assertEqual(entry['manifest'], baseline['apps']['nginx-proxy-manager']['manifest'])
|
|
self.assertEqual(set(entry['manifest_variants'][0]['requires']), {'runtime-migration-backup-v1', 'npm-legacy-host-gateway-v1'})
|
|
selected = drift.load_catalog(target)['nginx-proxy-manager']
|
|
self.assertEqual(selected['container']['network'], 'slirp4netns:allow_host_loopback=true,cidr=169.254.1.0/24')
|
|
entry['manifest_variants'][0]['requires'].append('future-unknown-capability')
|
|
target.write_text(json.dumps(catalog))
|
|
self.assertEqual(drift.load_catalog(target)['nginx-proxy-manager']['container'], entry['manifest']['app']['container'])
|
|
|
|
if __name__ == '__main__': unittest.main()
|