This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""Dormant Phase-1.0AC adapter driven only by exact built-in fake syscalls.
|
||||
|
||||
The module has no socket, selector, address, DNS, CLI, real clock or file
|
||||
output. It exercises one nonblocking lifecycle with synthetic outcomes and
|
||||
the existing passive batch/result contract.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import math
|
||||
|
||||
from phase10z_passive_batch_contract import (
|
||||
PassiveBatch,
|
||||
PassiveContractError,
|
||||
PassiveResultAccumulator,
|
||||
)
|
||||
|
||||
|
||||
MAX_FAKE_STEPS = 1024
|
||||
MAX_STEP_ADVANCE_SECONDS = 60.0
|
||||
MAX_RECEIVE_BYTES = 65536
|
||||
|
||||
CREATE_STREAM = "CREATE_STREAM"
|
||||
SET_NONBLOCKING = "SET_NONBLOCKING"
|
||||
START_CONNECT = "START_CONNECT"
|
||||
WAIT_WRITE = "WAIT_WRITE"
|
||||
GET_SO_ERROR = "GET_SO_ERROR"
|
||||
WRITE_BYTES = "WRITE_BYTES"
|
||||
WAIT_READ = "WAIT_READ"
|
||||
READ_BYTES = "READ_BYTES"
|
||||
|
||||
OK = "OK"
|
||||
IMMEDIATE = "IMMEDIATE"
|
||||
PENDING = "PENDING"
|
||||
READY = "READY"
|
||||
INTERRUPTED = "INTERRUPTED"
|
||||
TIMEOUT = "TIMEOUT"
|
||||
ZERO = "ZERO"
|
||||
NONZERO = "NONZERO"
|
||||
PROGRESS = "PROGRESS"
|
||||
EOF = "EOF"
|
||||
ERROR = "ERROR"
|
||||
|
||||
ALLOWED_RESULTS = {
|
||||
CREATE_STREAM: {OK, ERROR},
|
||||
SET_NONBLOCKING: {OK, ERROR},
|
||||
START_CONNECT: {IMMEDIATE, PENDING, ERROR},
|
||||
WAIT_WRITE: {READY, INTERRUPTED, TIMEOUT, ERROR},
|
||||
GET_SO_ERROR: {ZERO, NONZERO, ERROR},
|
||||
WRITE_BYTES: {PROGRESS, ZERO, ERROR},
|
||||
WAIT_READ: {READY, INTERRUPTED, TIMEOUT, ERROR},
|
||||
READ_BYTES: {PROGRESS, EOF, ERROR},
|
||||
}
|
||||
|
||||
|
||||
class DormantAdapterError(RuntimeError):
|
||||
"""Normalized synthetic adapter failure without supplied bytes."""
|
||||
|
||||
|
||||
class FakeSyscallError(RuntimeError):
|
||||
"""Exact fake-facade state or script failure."""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FakeSyscallStep:
|
||||
"""One synthetic syscall outcome; never an operating-system call."""
|
||||
|
||||
operation: str
|
||||
result: str
|
||||
value: int = 0
|
||||
data: bytes = b""
|
||||
advance_seconds: float = 0.0
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.operation not in ALLOWED_RESULTS or \
|
||||
self.result not in ALLOWED_RESULTS[self.operation]:
|
||||
raise FakeSyscallError("fake syscall operation/result is invalid")
|
||||
if not isinstance(self.value, int) or isinstance(self.value, bool) or \
|
||||
self.value < 0:
|
||||
raise FakeSyscallError("fake syscall value is invalid")
|
||||
if not isinstance(self.data, bytes):
|
||||
raise FakeSyscallError("fake syscall data is invalid")
|
||||
advance = self.advance_seconds
|
||||
if not isinstance(advance, (int, float)) or isinstance(advance, bool) or \
|
||||
not math.isfinite(advance) or not 0.0 <= advance <= \
|
||||
MAX_STEP_ADVANCE_SECONDS:
|
||||
raise FakeSyscallError("fake syscall time advance is invalid")
|
||||
if self.operation == WRITE_BYTES and self.result == PROGRESS:
|
||||
if self.value <= 0 or self.data:
|
||||
raise FakeSyscallError("fake write progress is invalid")
|
||||
elif self.operation == READ_BYTES and self.result == PROGRESS:
|
||||
if not self.data or self.value != len(self.data):
|
||||
raise FakeSyscallError("fake read progress is invalid")
|
||||
elif self.value != 0 or self.data:
|
||||
raise FakeSyscallError("fake syscall carries unexpected data")
|
||||
|
||||
|
||||
class OfflineFakeClock:
|
||||
"""Explicit synthetic monotonic value; never reads the host clock."""
|
||||
|
||||
def __init__(self, initial: float = 0.0) -> None:
|
||||
if not isinstance(initial, (int, float)) or isinstance(initial, bool) or \
|
||||
not math.isfinite(initial):
|
||||
raise FakeSyscallError("fake clock initial value is invalid")
|
||||
self._value = float(initial)
|
||||
|
||||
def monotonic(self) -> float:
|
||||
return self._value
|
||||
|
||||
def advance(self, seconds: float) -> None:
|
||||
if not isinstance(seconds, (int, float)) or isinstance(seconds, bool) or \
|
||||
not math.isfinite(seconds) or not 0.0 <= seconds <= \
|
||||
MAX_STEP_ADVANCE_SECONDS:
|
||||
raise FakeSyscallError("fake clock advance is invalid")
|
||||
self._value += float(seconds)
|
||||
|
||||
|
||||
class OfflineFakeSyscallFacade:
|
||||
"""Closed fake facade; it cannot retain a target or create a capability."""
|
||||
|
||||
def __init__(
|
||||
self, clock: OfflineFakeClock, steps: tuple[FakeSyscallStep, ...],
|
||||
close_result: str = OK,
|
||||
) -> None:
|
||||
if type(clock) is not OfflineFakeClock:
|
||||
raise FakeSyscallError("only the exact fake clock is accepted")
|
||||
if not isinstance(steps, tuple) or not 1 <= len(steps) <= MAX_FAKE_STEPS \
|
||||
or any(type(step) is not FakeSyscallStep for step in steps):
|
||||
raise FakeSyscallError("fake syscall script is invalid")
|
||||
if close_result not in {OK, ERROR}:
|
||||
raise FakeSyscallError("fake close result is invalid")
|
||||
self.clock = clock
|
||||
self._steps = list(steps)
|
||||
self._close_result = close_result
|
||||
self.state = "NEW"
|
||||
self.invoke_count = 0
|
||||
self.close_count = 0
|
||||
self.discarded_steps = 0
|
||||
self.trace: list[str] = []
|
||||
|
||||
def invoke(self, operation: str) -> FakeSyscallStep:
|
||||
if self.state == "CLOSED" or not self._steps:
|
||||
raise FakeSyscallError("fake syscall script is exhausted")
|
||||
step = self._steps.pop(0)
|
||||
if step.operation != operation:
|
||||
raise FakeSyscallError("fake syscall ordering is invalid")
|
||||
self.clock.advance(step.advance_seconds)
|
||||
self.invoke_count += 1
|
||||
self.trace.append(f"{operation}:{step.result}")
|
||||
self.state = "ACTIVE"
|
||||
return step
|
||||
|
||||
def close_once(self) -> None:
|
||||
if self.state == "CLOSED" or self.close_count != 0:
|
||||
raise FakeSyscallError("fake facade cannot close")
|
||||
self.close_count = 1
|
||||
self.discarded_steps = len(self._steps)
|
||||
self._steps.clear()
|
||||
self.trace.append(f"LOCAL_CLOSE:{self._close_result}")
|
||||
self.state = "CLOSED"
|
||||
if self._close_result != OK:
|
||||
raise FakeSyscallError("synthetic local close failed")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DormantAdapterOutcome:
|
||||
classification: str
|
||||
result_classification: str
|
||||
exact_identity: bool
|
||||
batch_bytes_sent: int
|
||||
received_bytes: int
|
||||
write_calls: int
|
||||
read_calls: int
|
||||
interrupted_waits: int
|
||||
timed_out_waits: int
|
||||
discarded_steps_after_close: int
|
||||
trace: tuple[str, ...]
|
||||
target_retained: bool = False
|
||||
live_transport_present: bool = False
|
||||
device_behavior_proven: bool = False
|
||||
|
||||
|
||||
def _before_deadline(clock: OfflineFakeClock, deadline: float) -> None:
|
||||
if clock.monotonic() >= deadline:
|
||||
raise DormantAdapterError("synthetic deadline reached")
|
||||
|
||||
|
||||
def _wait_until_ready(
|
||||
facade: OfflineFakeSyscallFacade,
|
||||
clock: OfflineFakeClock,
|
||||
deadline: float,
|
||||
operation: str,
|
||||
) -> tuple[bool, int, int]:
|
||||
interrupted = 0
|
||||
timed_out = 0
|
||||
while True:
|
||||
_before_deadline(clock, deadline)
|
||||
step = facade.invoke(operation)
|
||||
if clock.monotonic() >= deadline:
|
||||
if step.result == READY:
|
||||
raise DormantAdapterError(
|
||||
"synthetic deadline won readiness race")
|
||||
if step.result == INTERRUPTED:
|
||||
return False, interrupted + 1, timed_out
|
||||
if step.result == TIMEOUT:
|
||||
return False, interrupted, timed_out + 1
|
||||
raise DormantAdapterError("synthetic wait failed at deadline")
|
||||
if step.result == READY:
|
||||
return True, interrupted, timed_out
|
||||
if step.result == INTERRUPTED:
|
||||
interrupted += 1
|
||||
continue
|
||||
if step.result == TIMEOUT:
|
||||
timed_out += 1
|
||||
continue
|
||||
raise DormantAdapterError("synthetic readiness failed")
|
||||
|
||||
|
||||
def run_dormant_adapter(
|
||||
batch: PassiveBatch,
|
||||
facade: OfflineFakeSyscallFacade,
|
||||
clock: OfflineFakeClock,
|
||||
receipt_precommitted: bool,
|
||||
) -> DormantAdapterOutcome:
|
||||
"""Run one target-free fake-syscall lifecycle and normalize all failure."""
|
||||
if type(batch) is not PassiveBatch or \
|
||||
type(facade) is not OfflineFakeSyscallFacade or \
|
||||
type(clock) is not OfflineFakeClock or facade.clock is not clock or \
|
||||
receipt_precommitted is not True:
|
||||
raise DormantAdapterError("dormant adapter boundary is invalid")
|
||||
|
||||
start = clock.monotonic()
|
||||
deadline = start + batch.deadline_seconds
|
||||
accumulator: PassiveResultAccumulator
|
||||
try:
|
||||
accumulator = PassiveResultAccumulator(batch)
|
||||
except PassiveContractError as error:
|
||||
raise DormantAdapterError("passive batch is invalid") from error
|
||||
|
||||
sent = 0
|
||||
received = 0
|
||||
write_calls = 0
|
||||
read_calls = 0
|
||||
interrupted_waits = 0
|
||||
timed_out_waits = 0
|
||||
opened = False
|
||||
sanitized = None
|
||||
primary_failure: DormantAdapterError | None = None
|
||||
|
||||
try:
|
||||
_before_deadline(clock, deadline)
|
||||
if facade.invoke(CREATE_STREAM).result != OK:
|
||||
raise DormantAdapterError("synthetic stream creation failed")
|
||||
opened = True
|
||||
_before_deadline(clock, deadline)
|
||||
if facade.invoke(SET_NONBLOCKING).result != OK:
|
||||
raise DormantAdapterError("synthetic nonblocking setup failed")
|
||||
_before_deadline(clock, deadline)
|
||||
connect_result = facade.invoke(START_CONNECT).result
|
||||
if connect_result == PENDING:
|
||||
ready, interrupted, timed_out = _wait_until_ready(
|
||||
facade, clock, deadline, WAIT_WRITE)
|
||||
interrupted_waits += interrupted
|
||||
timed_out_waits += timed_out
|
||||
if not ready:
|
||||
raise DormantAdapterError(
|
||||
"synthetic connect reached deadline")
|
||||
if facade.invoke(GET_SO_ERROR).result != ZERO:
|
||||
raise DormantAdapterError("synthetic pending connect failed")
|
||||
_before_deadline(clock, deadline)
|
||||
elif connect_result != IMMEDIATE:
|
||||
raise DormantAdapterError("synthetic immediate connect failed")
|
||||
|
||||
while sent < len(batch.payload):
|
||||
ready, interrupted, timed_out = _wait_until_ready(
|
||||
facade, clock, deadline, WAIT_WRITE)
|
||||
interrupted_waits += interrupted
|
||||
timed_out_waits += timed_out
|
||||
if not ready:
|
||||
raise DormantAdapterError("synthetic write reached deadline")
|
||||
step = facade.invoke(WRITE_BYTES)
|
||||
write_calls += 1
|
||||
if step.result != PROGRESS or step.value > len(batch.payload) - sent:
|
||||
raise DormantAdapterError("synthetic write made invalid progress")
|
||||
sent += step.value
|
||||
_before_deadline(clock, deadline)
|
||||
|
||||
while clock.monotonic() < deadline:
|
||||
ready, interrupted, timed_out = _wait_until_ready(
|
||||
facade, clock, deadline, WAIT_READ)
|
||||
interrupted_waits += interrupted
|
||||
timed_out_waits += timed_out
|
||||
if not ready:
|
||||
break
|
||||
step = facade.invoke(READ_BYTES)
|
||||
read_calls += 1
|
||||
if step.result == EOF:
|
||||
raise DormantAdapterError("synthetic EOF is not completion")
|
||||
if step.result != PROGRESS or received + len(step.data) > \
|
||||
MAX_RECEIVE_BYTES:
|
||||
raise DormantAdapterError("synthetic read is invalid")
|
||||
if clock.monotonic() >= deadline:
|
||||
raise DormantAdapterError("synthetic data reached deadline")
|
||||
try:
|
||||
accumulator.feed_supplied_chunk(step.data)
|
||||
except PassiveContractError as error:
|
||||
raise DormantAdapterError("passive result rejected input") from error
|
||||
received += len(step.data)
|
||||
|
||||
if clock.monotonic() < deadline or received == 0:
|
||||
raise DormantAdapterError("synthetic deadline result is incomplete")
|
||||
try:
|
||||
sanitized = accumulator.seal_at_hard_deadline(True)
|
||||
except PassiveContractError as error:
|
||||
raise DormantAdapterError("passive deadline result is invalid") from error
|
||||
except Exception as error: # noqa: BLE001 - exact fake boundary normalization
|
||||
primary_failure = DormantAdapterError("dormant fake-syscall run failed")
|
||||
primary_failure.__cause__ = error
|
||||
finally:
|
||||
if opened:
|
||||
try:
|
||||
facade.close_once()
|
||||
except FakeSyscallError as error:
|
||||
if primary_failure is None:
|
||||
primary_failure = DormantAdapterError(
|
||||
"dormant fake-syscall cleanup failed")
|
||||
primary_failure.__cause__ = error
|
||||
|
||||
if primary_failure is not None:
|
||||
raise primary_failure
|
||||
if sanitized is None or facade.close_count != 1:
|
||||
raise DormantAdapterError("dormant fake-syscall result is incomplete")
|
||||
return DormantAdapterOutcome(
|
||||
classification="OFFLINE_DORMANT_FAKE_SYSCALL_ADAPTER_COMPLETE",
|
||||
result_classification=str(sanitized["classification"]),
|
||||
exact_identity=bool(sanitized["exact_identity"]),
|
||||
batch_bytes_sent=sent,
|
||||
received_bytes=received,
|
||||
write_calls=write_calls,
|
||||
read_calls=read_calls,
|
||||
interrupted_waits=interrupted_waits,
|
||||
timed_out_waits=timed_out_waits,
|
||||
discarded_steps_after_close=facade.discarded_steps,
|
||||
trace=("CONSUMED_RECEIPT_PREEXISTS", *facade.trace),
|
||||
)
|
||||
Reference in New Issue
Block a user