diff --git a/scripts/build_nvattest_payload_facts.py b/scripts/build_nvattest_payload_facts.py index 0100260e4..117864f36 100644 --- a/scripts/build_nvattest_payload_facts.py +++ b/scripts/build_nvattest_payload_facts.py @@ -143,11 +143,11 @@ def build_payload_facts(target_key: str, work_dir: Path) -> tuple[Path, str]: def _render_all(work_dir: Path) -> dict[Path, str]: - return { - path: text - for target_key in TARGET_KEYS - for path, text in (build_payload_facts(target_key, work_dir),) - } + outputs: dict[Path, str] = {} + for target_key in TARGET_KEYS: + path, text = build_payload_facts(target_key, work_dir) + outputs[path] = text + return outputs def write_outputs() -> None: diff --git a/tests/test_nvattest_authority.py b/tests/test_nvattest_authority.py index 1e9454ceb..1b2891fd9 100644 --- a/tests/test_nvattest_authority.py +++ b/tests/test_nvattest_authority.py @@ -211,7 +211,36 @@ def test_payload_executable_bit_fixtures_match_authority() -> None: for target_key, target in payload["targets"].items(): artifact = target["artifact"] fixture_path = _payload_facts_fixture_path(str(artifact["name"])) - fixture = json.loads(fixture_path.read_text(encoding="utf-8")) + fixture_relpath = fixture_path.relative_to(REPO_ROOT).as_posix() + fixture_read_failure = None + try: + fixture_text = fixture_path.read_text(encoding="utf-8") + except FileNotFoundError: + fixture_read_failure = _drift_failure( + f"missing nvattest executable-bit fixture for {target_key}", + expected=fixture_relpath, + actual="", + ) + except OSError as exc: + fixture_read_failure = _drift_failure( + f"unreadable/invalid nvattest executable-bit fixture for {target_key}", + expected=f"readable JSON file at {fixture_relpath}", + actual=f"{type(exc).__name__}: {exc}", + ) + if fixture_read_failure is not None: + pytest.fail(fixture_read_failure, pytrace=False) + + fixture_parse_failure = None + try: + fixture = json.loads(fixture_text) + except json.JSONDecodeError as exc: + fixture_parse_failure = _drift_failure( + f"unreadable/invalid nvattest executable-bit fixture for {target_key}", + expected=f"valid JSON in {fixture_relpath}", + actual=f"{exc.msg} at line {exc.lineno} column {exc.colno}", + ) + if fixture_parse_failure is not None: + pytest.fail(fixture_parse_failure, pytrace=False) inventory = target["inventory"] expected_executable = { str(member["relpath"]): member["executable"] for member in inventory