Files
archy/tests/apps/podsteadr/test_fixture_manifests.py

105 lines
5.9 KiB
Python

#!/usr/bin/env python3
"""Pure manifest preparation tests, not installed-manager acceptance."""
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
from fixture_manifests import manifests
ROOT = Path(__file__).resolve().parent
class FixtureManifests(unittest.TestCase):
def args(self):
return ['a'*64,'b'*64,'c'*64,'d'*64,'/var/lib/archipelago/fixture-podsteadr-test']
def render(self):
return manifests(*self.args())
def test_requires_exact_images_and_explicit_public_service_key(self):
for index, invalid in ((0,'app:latest'),(1,'abc123'),(2,''),(3,''),(3,'npub1invalid'),(3,'d'*64+'\nOTHER=value')):
args = self.args(); args[index] = invalid
with self.subTest(index=index, invalid=invalid), self.assertRaises(ValueError):
manifests(*args)
def test_live_paths_and_traversal_refused(self):
for value in ('/var/lib/archipelago/podsteadr','/var/lib/archipelago/fixture-podsteadr-test/../live','relative','/tmp/other'):
args = self.args(); args[4] = value
with self.subTest(value=value), self.assertRaises(ValueError): manifests(*args)
def test_all_three_pin_images_nonroot_data_and_loopback_ports(self):
rendered = self.render()
self.assertEqual(set(rendered),{'podsteadr','podsteadr-mediamtx','podsteadr-blossom'})
for document in rendered.values():
app = document['app']
self.assertEqual(app['container']['pull_policy'],'never')
self.assertTrue(app['container']['image'].startswith('sha256:'))
self.assertEqual(app['container']['data_uid'],'1000:1000')
self.assertNotIn('user',app['container'], 'No unsupported runtime-user field')
self.assertEqual(app['security']['capabilities'],[])
self.assertTrue(app['security']['readonly_root'])
self.assertTrue(app['security']['no_new_privileges'])
self.assertNotIn('hooks',app)
self.assertNotIn('secret_env',app['container'])
self.assertNotIn('generated_secrets',app['container'])
self.assertTrue(all(port['bind']=='127.0.0.1' for port in app['ports']))
self.assertTrue(all(not file['overwrite'] for file in app.get('files',[])))
def test_native_admin_and_distinct_service_key_bindings(self):
docs = self.render()
app = docs['podsteadr']['app']; blossom = docs['podsteadr-blossom']['app']
self.assertEqual(app['container']['derived_env'],[{'key':'PODSTEADR_ADMIN_PUBKEYS','template':'{{NODE_IDENTITY_PUBKEYS}}'}])
self.assertEqual(blossom['container']['derived_env'],[{'key':'ARCHY_BLOSSOM_PUBKEYS','template':'{{NODE_IDENTITY_PUBKEYS}},'+'d'*64}])
self.assertNotIn('server-nostr-key',json.dumps(docs))
self.assertIn('NOSTR_RELAYS=',app['environment'])
self.assertIn('CASHU_MINT_URL_DEFAULT=http://127.0.0.1:9996',app['environment'])
def test_matching_paths_recording_permissions_and_no_root_copy_hook(self):
docs = self.render()
volumes = {key:{v['target']:v for v in doc['app']['volumes']} for key,doc in docs.items()}
self.assertEqual(volumes['podsteadr']['/recordings']['options'],['ro'])
self.assertEqual(volumes['podsteadr-mediamtx']['/recordings']['options'],['rw'])
self.assertEqual(volumes['podsteadr']['/recordings']['source'],volumes['podsteadr-mediamtx']['/recordings']['source'])
blossom = volumes['podsteadr-blossom']
self.assertEqual(blossom['/config/config.json']['options'],['ro'])
self.assertEqual(blossom['/bridge']['options'],['ro'])
self.assertNotIn('/app/data',blossom)
config = docs['podsteadr-mediamtx']['app']['files'][0]['content']
self.assertIn('authHTTPAddress: http://podsteadr-app:8095/api/mediamtx/auth',config)
self.assertIn('recordPath: /recordings/',config)
self.assertNotIn('runOn',config)
def test_canonical_parser_samples_match_generator_exactly(self):
for app_id, expected in self.render().items():
actual = json.loads((ROOT/'manifest-samples'/app_id/'manifest.yml').read_text())
self.assertEqual(actual, expected)
def test_large_upload_is_explicit_and_does_not_change_other_services(self):
baseline = self.render()
large = manifests(*self.args(), large_upload_candidate=True)
self.assertEqual(baseline['podsteadr-blossom']['app']['environment'], [])
self.assertEqual(large['podsteadr-blossom']['app']['environment'], ['ARCHY_BLOSSOM_MAX_UPLOAD_BYTES=2147483648'])
self.assertEqual(large['podsteadr-blossom']['app']['version'], '6.4.1-fixture.large1')
for service in ('podsteadr', 'podsteadr-mediamtx'):
self.assertEqual(large[service], baseline[service])
self.assertEqual(large['podsteadr-blossom']['app']['container'], baseline['podsteadr-blossom']['app']['container'])
def test_cli_refuses_existing_output_and_leaves_it_untouched(self):
with tempfile.TemporaryDirectory() as directory:
args = self.args()
command = [sys.executable,str(ROOT/'fixture_manifests.py')]
for name,value in zip(('app-image','mtx-image','blossom-image','server-pubkey','data-root'),args): command += ['--'+name,value]
command += ['--output',directory]
first = subprocess.run(command,capture_output=True,text=True)
self.assertEqual(first.returncode,0,first.stderr)
before = {str(p.relative_to(directory)):p.read_bytes() for p in Path(directory).rglob('manifest.yml')}
self.assertEqual(len(before),3)
second = subprocess.run(command,capture_output=True,text=True)
self.assertNotEqual(second.returncode,0)
self.assertEqual(before,{str(p.relative_to(directory)):p.read_bytes() for p in Path(directory).rglob('manifest.yml')})
if __name__ == '__main__': unittest.main()