This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""Validate the consumed Phase-1.0G one-shot result record."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
PHASE = "PHASE_1_0G_INTERVAL_ONE_SHOT_DEVICE_RESULT"
|
||||
STATUS = "ONE_SHOT_AUTHORIZATION_CONSUMED_RESULT_INCOMPLETE"
|
||||
ARTIFACT_SHA256 = "e8bfc01c61bfb14b5814280a6e5442f1a5ad05ace5439d1c09e7e5ee00cd0055"
|
||||
TRACE_SHA256 = "eb73611d98e602b89b3cdb3a0e94ec97b9410c5845b0449a07bf2aa6fdec7249"
|
||||
RECEIPT_SHA256 = "aeb402cb45c16adea8d79d856633a76280895828b8d32822d9bc183fc7251442"
|
||||
STDOUT_SHA256 = "0b56b42dabf2661233bbb57a63a520d791c13debd5da6839feeb30b534ad315f"
|
||||
AUTH_FIELDS = (
|
||||
"ps5_connection_authorized", "device_transfer_authorized",
|
||||
"device_execution_authorized", "result_receive_authorized",
|
||||
"installation_authorized", "autoload_authorized",
|
||||
"device_write_authorized", "automatic_retry",
|
||||
)
|
||||
|
||||
|
||||
def load(path: Path) -> dict[str, Any]:
|
||||
value = json.loads(path.read_text(encoding="utf-8"))
|
||||
if not isinstance(value, dict):
|
||||
raise ValueError("result manifest is not an object")
|
||||
return value
|
||||
|
||||
|
||||
def all_false(record: dict[str, Any]) -> bool:
|
||||
return all(record.get(field) is False for field in AUTH_FIELDS)
|
||||
|
||||
|
||||
def transport_is_exact(record: dict[str, Any]) -> bool:
|
||||
return (
|
||||
record.get("connect_count") == 1
|
||||
and record.get("sendall_count") == 1
|
||||
and record.get("bytes_sent") == 1845152
|
||||
and record.get("shutdown_write_count") == 1
|
||||
and record.get("recv_call_count") == 5
|
||||
and record.get("received_byte_count") == 3669
|
||||
and record.get("raw_stream_stored_bytes") == 3669
|
||||
and record.get("raw_stream_truncated") is False
|
||||
and record.get("retry_count") == 0
|
||||
and record.get("reconnect_count") == 0
|
||||
and record.get("close_called") is True
|
||||
and record.get("remote_eof_observed") is True
|
||||
and record.get("timeout_observed") is False
|
||||
)
|
||||
|
||||
|
||||
def protocol_is_exact(record: dict[str, Any]) -> bool:
|
||||
return (
|
||||
record.get("magic") == "CHD10F01"
|
||||
and record.get("frame_size") == 64
|
||||
and record.get("frame_count") == 7
|
||||
and record.get("stages") == ["D00", "D01", "D02", "I00", "I01", "I02", "I03"]
|
||||
and record.get("d02_raw0") == 0
|
||||
and record.get("parser_errors") == []
|
||||
and record.get("terminal_stage") is None
|
||||
and record.get("last_proven_stage") == "I03"
|
||||
and record.get("first_unproven_stage") == "I04"
|
||||
and record.get("classification")
|
||||
== "REMOTE_PAYLOAD_OUTPUT_PROVEN_INCOMPLETE_AFTER_I03_BEFORE_I04"
|
||||
)
|
||||
|
||||
|
||||
def validate(root: Path) -> list[str]:
|
||||
errors: list[str] = []
|
||||
path = root / "manifests/retroarch/phase-1.0g-device-result.json"
|
||||
doc = root / "docs/retroarch/phase-1.0g-device-result.md"
|
||||
if not path.is_file() or not doc.is_file():
|
||||
return ["Phase-1.0G result deliverables are missing"]
|
||||
try:
|
||||
record = load(path)
|
||||
except (OSError, ValueError, json.JSONDecodeError) as error:
|
||||
return [str(error)]
|
||||
if record.get("phase") != PHASE or record.get("status") != STATUS:
|
||||
errors.append("phase/status mismatch")
|
||||
artifact = record.get("artifact", {})
|
||||
if not (
|
||||
artifact.get("size") == 1845152
|
||||
and artifact.get("sha256") == ARTIFACT_SHA256
|
||||
and artifact.get("execution_eligible") is False
|
||||
and artifact.get("transfer_eligible") is False
|
||||
and artifact.get("installation_eligible") is False
|
||||
and artifact.get("tracked") is False
|
||||
):
|
||||
errors.append("artifact is changed, eligible or tracked")
|
||||
authorization = record.get("authorization", {})
|
||||
if not (
|
||||
authorization.get("consumed") is True
|
||||
and authorization.get("authority_inherited_by_future_action") is False
|
||||
and authorization.get("attempt_receipt_sha256") == RECEIPT_SHA256
|
||||
):
|
||||
errors.append("authorization is not permanently consumed")
|
||||
if not all_false(record.get("current_authorizations", {})):
|
||||
errors.append("a current authorization remains active")
|
||||
actions = record.get("performed_actions", {})
|
||||
if not all(actions.get(field) is True for field in (
|
||||
"ps5_connected", "device_request_performed", "files_transferred",
|
||||
"target_execution_performed", "result_received_from_device"
|
||||
)):
|
||||
errors.append("authorized performed actions are incomplete")
|
||||
if not all(actions.get(field) is False for field in (
|
||||
"device_write_performed", "installation_performed",
|
||||
"autoload_performed", "reboot_performed"
|
||||
)):
|
||||
errors.append("a forbidden action is recorded")
|
||||
if not transport_is_exact(record.get("transport", {})):
|
||||
errors.append("transport counters violate the one-shot trace")
|
||||
if not protocol_is_exact(record.get("protocol_result", {})):
|
||||
errors.append("frame sequence or bounded classification mismatch")
|
||||
if record.get("trace", {}).get("sha256") != TRACE_SHA256:
|
||||
errors.append("trace hash mismatch")
|
||||
stdout = record.get("ordinary_stdout", {})
|
||||
if not (
|
||||
stdout.get("byte_count") == 3221
|
||||
and stdout.get("sha256") == STDOUT_SHA256
|
||||
and stdout.get("key_message")
|
||||
== "No arguments supplied and no menu built-in, displaying help..."
|
||||
):
|
||||
errors.append("ordinary stdout evidence mismatch")
|
||||
binding = record.get("source_binding", {})
|
||||
if not (
|
||||
binding.get("cause") == "DETERMINISTIC_NO_ARGUMENT_NO_MENU_EXIT"
|
||||
and binding.get("profile_have_menu") is False
|
||||
and binding.get("sdl_videoout_reached") is False
|
||||
and binding.get("rendering_reached") is False
|
||||
and binding.get("terminal_cleanup_proven") is False
|
||||
):
|
||||
errors.append("source cause is missing or runtime progress is overclaimed")
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
errors = validate(args.root.resolve())
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(f"ERROR: {error}")
|
||||
return 1
|
||||
print("Phase-1.0G consumed device result validation passed")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user