Files
chimera-gfx-Public/tests/test_phase10at_fd_deadline_model.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

118 lines
5.0 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
"""Failure injection for Phase-1.0AT descriptor ownership."""
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 phase10aq_worker_result_record import * # noqa: E402,F403
from phase10at_fd_deadline_model import * # noqa: E402,F403
PRECOMMIT = WorkerPrecommit(b"a" * 16, b"b" * 16, 101, 202, 7, 4096)
RAW = encode_record(PRECOMMIT, STATUS_SUCCESS, 4096)
def success_events() -> list[FakeFdEvent]:
return [FakeFdEvent(CREATE_PIPE, OK),
FakeFdEvent(SET_PARENT_READ_NONBLOCK, OK),
FakeFdEvent(SPAWN_RFFDG, OK),
FakeFdEvent(PARENT_CLOSE_WRITE, OK),
FakeFdEvent(CHILD_CLOSE_READ, OK),
FakeFdEvent(CHILD_CLOSE_WRITE, OK),
FakeFdEvent(REAP_CHILD, OK),
FakeFdEvent(PARENT_CLOSE_READ, OK)]
class FdDeadlineTests(unittest.TestCase):
def test_success_with_partial_reads_eintr_and_would_block(self) -> None:
reads = (FakeRead(EINTR), FakeRead(WOULD_BLOCK),
FakeRead(DATA, RAW[:40]), FakeRead(EINTR),
FakeRead(DATA, RAW[40:]))
result = run_fd_transaction(
PRECOMMIT, FakeFdFacade(tuple(success_events())), reads)
self.assertTrue(result.success and result.rffdg_used)
self.assertEqual(result.eintr_count, 2)
self.assertEqual(result.parent_fds_open + result.child_fds_open, 0)
self.assertFalse(result.worker_alive or result.live_fd_present)
def test_every_setup_failure_closes_only_acquired_resources(self) -> None:
expected_cleanup = {
0: [],
1: [PARENT_CLOSE_WRITE, PARENT_CLOSE_READ],
2: [PARENT_CLOSE_WRITE, PARENT_CLOSE_READ],
3: [TERMINATE_CHILD, CHILD_CLOSE_READ, CHILD_CLOSE_WRITE,
REAP_CHILD, PARENT_CLOSE_WRITE, PARENT_CLOSE_READ],
4: [TERMINATE_CHILD, CHILD_CLOSE_READ, CHILD_CLOSE_WRITE,
REAP_CHILD, PARENT_CLOSE_READ],
}
baseline = success_events()[:5]
for index, event in enumerate(baseline):
prefix = baseline[:index] + [FakeFdEvent(event.operation, ERROR)]
prefix += [FakeFdEvent(operation, OK)
for operation in expected_cleanup[index]]
with self.subTest(index=index):
result = run_fd_transaction(
PRECOMMIT, FakeFdFacade(tuple(prefix)),
(FakeRead(DATA, RAW),))
self.assertFalse(result.success)
self.assertEqual(result.parent_fds_open + result.child_fds_open, 0)
def test_deadline_eof_overflow_and_bad_record_contain_worker(self) -> None:
scripts = (
(FakeRead(DATA, RAW[:10], ticks=252), FakeRead(DATA, RAW[10:])),
(FakeRead(DATA, RAW[:10]), FakeRead(EOF)),
(FakeRead(DATA, RAW[:100]), FakeRead(DATA, RAW[100:] + b"x")),
(FakeRead(DATA, RAW), FakeRead(WOULD_BLOCK)),
(FakeRead(DATA, bytes(bytearray(RAW[:1]) + RAW[1:])),),
)
# Make the final script genuinely invalid.
damaged = bytearray(RAW)
damaged[0] ^= 1
scripts = scripts[:-1] + ((FakeRead(DATA, bytes(damaged)),),)
cleanup = [FakeFdEvent(TERMINATE_CHILD, OK),
FakeFdEvent(CHILD_CLOSE_WRITE, OK),
FakeFdEvent(REAP_CHILD, OK),
FakeFdEvent(PARENT_CLOSE_READ, OK)]
for reads in scripts:
events = success_events()[:5] + cleanup
with self.subTest(reads=reads):
result = run_fd_transaction(
PRECOMMIT, FakeFdFacade(tuple(events)), reads)
self.assertFalse(result.success or result.worker_alive)
self.assertTrue(result.containment_required)
def test_cleanup_failure_and_unused_operations_are_hard_errors(self) -> None:
events = [FakeFdEvent(CREATE_PIPE, OK),
FakeFdEvent(SET_PARENT_READ_NONBLOCK, ERROR),
FakeFdEvent(PARENT_CLOSE_WRITE, ERROR)]
with self.assertRaises(FdModelError):
run_fd_transaction(PRECOMMIT, FakeFdFacade(tuple(events)),
(FakeRead(DATA, RAW),))
with self.assertRaises(FdModelError):
run_fd_transaction(
PRECOMMIT,
FakeFdFacade(tuple(success_events() +
[FakeFdEvent(PARENT_CLOSE_READ, OK)])),
(FakeRead(DATA, RAW),))
def test_invalid_read_and_boundary_are_rejected(self) -> None:
with self.assertRaises(FdModelError):
FakeRead(DATA, b"")
with self.assertRaises(FdModelError):
run_fd_transaction(PRECOMMIT, FakeFdFacade(tuple(success_events())), ())
if __name__ == "__main__":
unittest.main(argv=[__file__])