| from __future__ import annotations |
|
|
| import csv |
| import json |
| from collections import Counter |
| from pathlib import Path |
|
|
| import pytest |
|
|
| from scripts.netron_capture_common import discover_slots, sha256 |
| from scripts.validate_netron_exports import png_structure |
|
|
|
|
| ROOT = Path(__file__).resolve().parents[1] |
| REPORT = ROOT / "reports/graphs/netron" |
| pytestmark = pytest.mark.skipif( |
| not (REPORT / "netron_capture_inventory.csv").is_file(), |
| reason="optional Netron export package is not retained in the compact repository", |
| ) |
|
|
|
|
| def read_csv(name: str) -> list[dict[str, str]]: |
| with (REPORT / name).open(newline="", encoding="utf-8") as handle: |
| return list(csv.DictReader(handle)) |
|
|
|
|
| def test_input_inventory_has_42_onnx_variants() -> None: |
| rows = discover_slots(ROOT) |
| assert len(rows) == 42 |
| assert len({row["model_id"] for row in rows}) == 21 |
| assert Counter(row["artifact_status"] for row in rows) == {"AVAILABLE": 42} |
| assert Counter(row["format"] for row in rows if row["artifact_status"] == "AVAILABLE") == { |
| "onnx": 42, |
| } |
|
|
|
|
| def test_capture_inventory_and_canonical_pair_are_complete() -> None: |
| rows = read_csv("netron_capture_inventory.csv") |
| assert len(rows) == 42 |
| assert Counter(row["capture_status"] for row in rows) == {"PASS": 42} |
| assert Counter(row["format"] for row in rows if row["capture_status"] == "PASS") == { |
| "onnx": 42, |
| } |
| canonical = [row for row in rows if row["canonical_s7_selected"].lower() == "true"] |
| assert len(canonical) == 42 |
| assert all(row["capture_status"] == "PASS" for row in canonical) |
|
|
|
|
| def test_all_netron_exports_have_valid_png_chunks_and_metadata() -> None: |
| rows = read_csv("netron_capture_inventory.csv") |
| for row in rows: |
| metadata_path = ROOT / row["metadata_json"] |
| metadata = json.loads(metadata_path.read_text(encoding="utf-8")) |
| assert sha256(metadata_path) == row["metadata_json_sha256"] |
| if row["capture_status"] != "PASS": |
| assert metadata["status"] == "NOT_AVAILABLE" |
| continue |
| assert metadata["status"] == "PASS" |
| assert metadata["tool_versions"]["netron"] == "9.2.0" |
| assert metadata["policy"]["conversion_performed"] is False |
| assert metadata["policy"]["tflite_to_onnx_for_netron"] is False |
| assert metadata["policy"]["allocator_work_performed"] is False |
| output = ROOT / row["output_png"] |
| ui = ROOT / row["ui_proof_png"] |
| graph_png = png_structure(output) |
| ui_png = png_structure(ui) |
| assert sha256(output) == row["output_png_sha256"] |
| assert (graph_png["width"], graph_png["height"]) == ( |
| int(row["output_png_width"]), |
| int(row["output_png_height"]), |
| ) |
| assert (ui_png["width"], ui_png["height"]) == (1920, 1080) |
|
|
|
|
| def test_report_describes_direct_netron_export() -> None: |
| summary = json.loads((REPORT / "netron_capture_summary.json").read_text(encoding="utf-8")) |
| validation = json.loads((REPORT / "validation.json").read_text(encoding="utf-8")) |
| report = (REPORT / "netron_capture_report.md").read_text(encoding="utf-8") |
| assert summary["status"] == "PASS" |
| assert summary["counts"]["netron_exports_pass"] == 42 |
| assert validation["status"] == "PASS" |
| assert validation["checks_failed"] == 0 |
| assert "21개 모델의 FP32·공개 양자화 ONNX 42개" in report |
|
|
|
|
| def test_model_matrix_has_21_canonical_passes() -> None: |
| rows = read_csv("netron_model_matrix.csv") |
| assert len(rows) == 21 |
| assert Counter(row["pair_netron_status"] for row in rows) == {"PASS": 21} |
|
|
|
|
| def test_artifact_manifest_checksums_are_current() -> None: |
| manifest_path = REPORT / "artifact_manifest.json" |
| manifest = json.loads(manifest_path.read_text(encoding="utf-8")) |
| assert manifest["status"] == "PASS" |
| assert manifest["failure_code"] is None |
| assert manifest["category_counts"]["netron_export_png"] == 42 |
| assert manifest["category_counts"]["netron_ui_proof_png"] == 42 |
| assert manifest["category_counts"]["capture_metadata"] == 42 |
| assert "original_capture_log" not in manifest["category_counts"] |
| for record in manifest["files"]: |
| path = ROOT / record["path"] |
| assert path.is_file(), record["path"] |
| assert path.stat().st_size == record["bytes"], record["path"] |
| assert sha256(path) == record["sha256"], record["path"] |
| checksum_lines = (REPORT / "artifacts.sha256").read_text(encoding="utf-8").splitlines() |
| checksum_map = {line.split(" ", 1)[1]: line.split(" ", 1)[0] for line in checksum_lines} |
| assert checksum_map["reports/graphs/netron/artifact_manifest.json"] == sha256(manifest_path) |
|
|