Files
chimera-gfx-Public/tests/test_phase10ak_hybrid_composition.py
T
Chimera GFX release export a6037502d7
phase0-ci / build-and-audit (push) Successful in 2m14s
Publish Chimera GFX source
2026-09-03 03:27:14 +02:00

121 lines
5.8 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
"""Exhaustive ownership tests for Phase-1.0AK."""
from __future__ import annotations
import argparse
from pathlib import Path
import sys
import unittest
PARSER = argparse.ArgumentParser()
PARSER.add_argument("--root", type=Path, required=True)
ROOT = PARSER.parse_args().root
sys.path.insert(0, str(ROOT / "tools"))
from phase10ak_hybrid_composition import * # noqa: E402,F403
def happy(count: int = 2) -> list[FakeEvent]:
events = [FakeEvent(CREATE_CHILD, OK), FakeEvent(RESERVE_REGION, OK),
FakeEvent(CREATE_MIRROR, OK)]
for segment in range(count):
events += [FakeEvent(CREATE_JIT_MASTER, OK, segment),
FakeEvent(MAP_EXECUTABLE, OK, segment),
FakeEvent(CREATE_JIT_ALIAS, OK, segment),
FakeEvent(MAP_HOST_ALIAS, OK, segment),
FakeEvent(MAP_REMOTE_ALIAS, OK, segment),
FakeEvent(COPY_ALIAS, OK, segment),
FakeEvent(UNMAP_REMOTE_ALIAS, OK, segment),
FakeEvent(UNMAP_HOST_ALIAS, OK, segment),
FakeEvent(CLOSE_JIT_ALIAS, OK, segment),
FakeEvent(CLOSE_JIT_MASTER, OK, segment)]
return events + [FakeEvent(FINALIZE_IMAGE, OK), FakeEvent(RELEASE_MIRROR, OK)]
def cleanup_for(prefix: list[FakeEvent]) -> list[FakeEvent]:
acquired = {name: set() for name in ("masters", "aliases", "host", "remote")}
child = region = mirror = False
for event in prefix:
if event.result != OK:
break
if event.operation == CREATE_CHILD: child = True
elif event.operation == RESERVE_REGION: region = True
elif event.operation == CREATE_MIRROR: mirror = True
elif event.operation == CREATE_JIT_MASTER: acquired["masters"].add(event.segment)
elif event.operation == CREATE_JIT_ALIAS: acquired["aliases"].add(event.segment)
elif event.operation == MAP_HOST_ALIAS: acquired["host"].add(event.segment)
elif event.operation == MAP_REMOTE_ALIAS: acquired["remote"].add(event.segment)
elif event.operation == UNMAP_REMOTE_ALIAS: acquired["remote"].remove(event.segment)
elif event.operation == UNMAP_HOST_ALIAS: acquired["host"].remove(event.segment)
elif event.operation == CLOSE_JIT_ALIAS: acquired["aliases"].remove(event.segment)
elif event.operation == CLOSE_JIT_MASTER: acquired["masters"].remove(event.segment)
elif event.operation == RELEASE_MIRROR: mirror = False
result: list[FakeEvent] = []
for key, operation in (("remote", UNMAP_REMOTE_ALIAS),
("host", UNMAP_HOST_ALIAS),
("aliases", CLOSE_JIT_ALIAS),
("masters", CLOSE_JIT_MASTER)):
result += [FakeEvent(operation, OK, item)
for item in sorted(acquired[key], reverse=True)]
if mirror: result.append(FakeEvent(RELEASE_MIRROR, OK))
if region: result.append(FakeEvent(UNMAP_REGION, OK))
if child: result.append(FakeEvent(KILL_AND_REAP_CHILD, OK))
return result
class HybridCompositionTests(unittest.TestCase):
def test_success_releases_every_temporary_resource(self) -> None:
outcome = run_composition(CompositionPlan(2), FakeFacade(tuple(happy())))
self.assertTrue(outcome.success and outcome.child_alive and outcome.image_retained)
self.assertEqual(outcome.resources_open, 0)
self.assertFalse(outcome.target_action_performed or outcome.firmware_behavior_proven)
def test_every_forward_failure_terminates_fail_closed(self) -> None:
baseline = happy()
for index, original in enumerate(baseline):
failed = baseline[:index] + [FakeEvent(original.operation, ERROR,
original.segment)]
failed += cleanup_for(failed)
with self.subTest(index=index, operation=original.operation):
outcome = run_composition(CompositionPlan(2), FakeFacade(tuple(failed)))
self.assertFalse(outcome.success or outcome.child_alive)
self.assertEqual(outcome.fail_closed_termination, index > 0)
self.assertEqual(outcome.resources_open, 0)
def test_cleanup_failure_is_contained_by_child_termination(self) -> None:
failed = happy()[:9]
original = failed[-1]
failed[-1] = FakeEvent(original.operation, ERROR, original.segment)
cleanup = cleanup_for(failed)
cleanup[0] = FakeEvent(cleanup[0].operation, ERROR, cleanup[0].segment)
outcome = run_composition(CompositionPlan(2), FakeFacade(tuple(failed + cleanup)))
self.assertEqual(outcome.classification,
"OFFLINE_FAIL_CLOSED_AFTER_CLEANUP_FAILURE")
self.assertFalse(outcome.child_alive)
def test_failed_termination_is_a_hard_error(self) -> None:
events = [FakeEvent(CREATE_CHILD, OK), FakeEvent(RESERVE_REGION, ERROR),
FakeEvent(KILL_AND_REAP_CHILD, ERROR)]
with self.assertRaises(CompositionError):
run_composition(CompositionPlan(1), FakeFacade(tuple(events)))
def test_bounds_wrong_order_deadline_and_unused_events(self) -> None:
for value in (0, 9, True):
with self.subTest(value=value), self.assertRaises(CompositionError):
CompositionPlan(value)
events = happy(1)
events[0] = FakeEvent(CREATE_CHILD, OK, ticks=256)
events = events[:2] + [FakeEvent(KILL_AND_REAP_CHILD, OK)]
outcome = run_composition(CompositionPlan(1), FakeFacade(tuple(events)))
self.assertFalse(outcome.success)
with self.assertRaises(CompositionError):
run_composition(CompositionPlan(1), FakeFacade(tuple(
happy(1) + [FakeEvent(KILL_AND_REAP_CHILD, OK)])))
if __name__ == "__main__":
unittest.main(argv=[__file__])