"""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')