83 lines
3.8 KiB
Python
83 lines
3.8 KiB
Python
import json
|
|
import io
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import tarfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT / 'scripts'))
|
|
from public_app_policy import check_catalog, check_member, copy_public_tree, public_catalog
|
|
import release_payload
|
|
|
|
|
|
class PublicAppPolicyTests(unittest.TestCase):
|
|
def test_storefront_and_both_catalog_formats(self):
|
|
for apps in ([{'id': 'kithmoot'}, {'id': 'node-demo-v4v'}, {'id': 'podsteadr'}],
|
|
{'kithmoot': {}, 'v4v': {}, 'podsteadr': {}}):
|
|
original = {'apps': apps, 'storefront': {'popular': ['kithmoot', 'v4v', 'podsteadr']}}
|
|
with self.assertRaises(ValueError):
|
|
check_catalog(original)
|
|
filtered = public_catalog(original)
|
|
check_catalog(filtered)
|
|
self.assertEqual(filtered['storefront']['popular'], ['podsteadr'])
|
|
self.assertIn('podsteadr', json.dumps(filtered))
|
|
|
|
def test_payload_paths_and_embedded_catalog(self):
|
|
for app in ('kithmoot', 'v4v', 'node-demo-v4v'):
|
|
for folder in ('apps', 'docker'):
|
|
with self.assertRaises(ValueError):
|
|
check_member(f'archipelago-runtime/{folder}/{app}/manifest.yml')
|
|
with self.assertRaises(ValueError):
|
|
check_member('catalog.json', json.dumps({'apps': {app: {}}}).encode())
|
|
check_member('archipelago-runtime/apps/podsteadr/manifest.yml')
|
|
|
|
def test_iso_copy_excludes_private_apps_and_preserves_sources(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
source, dest = Path(tmp) / 'apps', Path(tmp) / 'stage'
|
|
for app in ('kithmoot', 'node-demo-v4v', 'v4v', 'podsteadr'):
|
|
path = source / app / 'manifest.yml'
|
|
path.parent.mkdir(parents=True)
|
|
path.write_text(app)
|
|
copy_public_tree(source, dest)
|
|
self.assertEqual([p.name for p in dest.iterdir()], ['podsteadr'])
|
|
self.assertEqual(len(list(source.iterdir())), 4)
|
|
with self.assertRaises(ValueError):
|
|
copy_public_tree(source, dest)
|
|
|
|
def test_real_registry_generator_does_not_reintroduce_manifest(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
output = Path(tmp) / 'catalog.json'
|
|
subprocess.run(['bash', str(ROOT / 'scripts/generate-app-catalog.sh'), str(output)],
|
|
check=True, capture_output=True)
|
|
catalog = json.loads(output.read_text())
|
|
check_catalog(catalog)
|
|
self.assertNotIn('kithmoot', catalog['apps'])
|
|
self.assertIn('podsteadr', catalog['apps'])
|
|
|
|
def test_archive_verifier_rejects_private_content_before_missing_payload(self):
|
|
# Exercise the actual streaming verifier, not just the policy helper.
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
for name, raw in (
|
|
('catalog.json', b'{"apps":{"kithmoot":{}}}'),
|
|
('archipelago-runtime/apps/node-demo-v4v/manifest.yml', b'app: {}'),
|
|
):
|
|
archive = root / 'payload.tar.gz'
|
|
with tarfile.open(archive, 'w:gz') as package:
|
|
info = tarfile.TarInfo(name)
|
|
info.mode = 0o644
|
|
info.size = len(raw)
|
|
package.addfile(info, io.BytesIO(raw))
|
|
with patch.object(release_payload, 'runtime_sources', return_value={}), \
|
|
patch.object(release_payload, 'regular', return_value=b''), \
|
|
self.assertRaisesRegex(ValueError, 'private test app'):
|
|
release_payload.check_archive(root, archive, '2.0.3-alpha', '0' * 40)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|