lazyBoy/tests/mcp-restart.test.py

61 lines
3.1 KiB
Python
Raw Permalink Normal View History

2026-09-11 02:47:43 +00:00
"""Two phases around an actual Docker restart, orchestrated by the host gate."""
import json
import os
from pathlib import Path
import runpy
import sys
import uuid
if os.environ.get('LAZYBOY_RUNNER_TEST_CONTAINER') != '1' or not Path('/.dockerenv').exists():
raise SystemExit('requires the disposable Computer gate')
fixtures = runpy.run_path('/tmp/mcp-packages.test.py', run_name='restart_fixture')
case = fixtures['Packages']()
case.setUp()
proof_path = Path('/var/lib/lazyboy-runner/restart-proof.json')
if sys.argv[1] == 'prepare':
source = case.archive()
source['manifest']['share_immutable_package'] = False
case.call('package_install', source)
first = case.invoke(source['binding_id'])
target = case.archive(server=fixtures['SERVER'].replace("'count':value,", "'count':value,'version':'restart-v2',"))
target['manifest'].update(id=source['manifest']['id'], version='2.0.0', share_immutable_package=False)
case.call('package_install', target)
upgrade = {'binding_id':source['binding_id'], 'transition_id':uuid.uuid4().hex,
'expected_version':source['manifest']['version'], 'expected_sha256':source['manifest']['sha256'],
'target_manifest':target['manifest']}
receipt = case.call('package_switch', upgrade)
installed = case.invoke(source['binding_id'])
case.assertEqual(installed['version'], 'restart-v2')
case.assertEqual(installed['count'], 2)
rollback = dict(upgrade, transition_id=uuid.uuid4().hex, expected_version='2.0.0',
expected_sha256=target['manifest']['sha256'], target_manifest=source['manifest'])
proof_path.write_text(json.dumps({'source':source, 'target':target, 'upgrade':upgrade,
'rollback':rollback, 'receipt':receipt, 'uid':first['uid']}))
print('restart fixture prepared', flush=True)
elif sys.argv[1] == 'verify':
proof = json.loads(proof_path.read_text())
case.identity['generation'] = 2
binding = proof['source']['binding_id']
completed = json.loads(case.call('package_transition_status', proof['upgrade'])['stdout'])
case.assertTrue(completed['recorded'])
case.assertEqual(completed['version'], '2.0.0')
case.assertEqual(completed['sha256'], proof['target']['manifest']['sha256'])
pending = json.loads(case.call('package_transition_status', proof['rollback'])['stdout'])
case.assertFalse(pending['recorded'])
case.assertEqual(pending['version'], '2.0.0')
current = case.invoke(binding)
case.assertEqual(current['uid'], proof['uid'])
case.assertEqual(current['count'], 3)
case.assertEqual(current['version'], 'restart-v2')
case.call('package_switch', proof['rollback'])
case.assertEqual(case.call('package_switch', proof['upgrade']), proof['receipt'])
restored = case.invoke(binding)
case.assertNotIn('version', restored)
case.assertEqual(restored['uid'], proof['uid'])
case.assertEqual(restored['count'], 4)
proof_path.unlink()
print('actual Computer restart: receipt, immutable code, UID, state and rollback verified', flush=True)
else:
raise SystemExit('expected prepare or verify')