1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#!/usr/bin/env python3
"""Run the wall-contract registry (``harness/contracts.py``, docs/50).
Every solved wall is pinned as a contract over an existing tool entry point;
this CLI runs them and prints pass/fail per contract plus per-wall-class
coverage. Fast contracts are the suite default; slow ones run with ``--all``
(or by name).
Offline only: never touches a GPU, kernel module, mdev, guest or network.
Exit codes: 0 = every selected contract passed (or skipped for a missing
prerequisite), 1 = at least one failure, 2 = usage error.
"""
from __future__ import annotations
import argparse
import json
import os
import sys
TOOL_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if TOOL_ROOT not in sys.path:
sys.path.insert(0, TOOL_ROOT)
from harness.contracts import ( # noqa: E402
Contract,
all_contracts,
fast_contracts,
run_contracts,
summarize,
)
def _select(args: argparse.Namespace) -> tuple[list[Contract], list[str]]:
if args.name:
wanted = set(args.name)
chosen = [c for c in all_contracts() if c.name in wanted]
unknown = sorted(wanted - {c.name for c in chosen})
return chosen, unknown
return (all_contracts() if args.all else fast_contracts()), []
def _table(rows: list[tuple[str, ...]], headers: tuple[str, ...]) -> list[str]:
widths = [
max(len(headers[index]), *(len(row[index]) for row in rows))
for index in range(len(headers))
]
lines = [" ".join(head.ljust(widths[i]) for i, head in enumerate(headers))]
lines.append(" ".join("-" * width for width in widths))
for row in rows:
lines.append(" ".join(cell.ljust(widths[i]) for i, cell in enumerate(row)))
return lines
def _render(results, summary: dict) -> list[str]:
rows = [
(
result.name,
result.wall_class,
result.speed,
result.status.upper(),
f"{result.seconds:.2f}s",
result.detail,
)
for result in results
]
lines = _table(rows, ("contract", "class", "speed", "status", "time", "detail"))
lines.append("")
lines.append("wall-class coverage (selected):")
for domain in summary["domains"]:
lines.append(
f" {domain['wall_class']} {domain['domain']:<28} "
f"{domain['total']} contracts: {domain['pass']} pass, "
f"{domain['fail']} fail, {domain['skip']} skip"
)
counts = summary["counts"]
lines.append("")
lines.append(
f"total: {counts['pass']} pass, {counts['fail']} fail, {counts['skip']} skip "
f"-> {'OK' if summary['ok'] else 'FAIL'}"
)
return lines
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="run_contracts.py",
description=(
"Run the wall-contract registry: fast contracts by default, all "
"with --all (offline; never touches hardware)."
),
)
group = parser.add_mutually_exclusive_group()
group.add_argument(
"--fast", action="store_true", help="run fast contracts only (default)"
)
group.add_argument("--all", action="store_true", help="run fast and slow contracts")
parser.add_argument(
"--name",
action="append",
default=[],
metavar="NAME",
help="run one named contract (repeatable); overrides --fast/--all selection",
)
parser.add_argument("--json", metavar="PATH", help="write the run summary as JSON here")
return parser
def main(argv: list[str] | None = None) -> int:
parser = build_parser()
args = parser.parse_args(argv)
selected, unknown = _select(args)
if unknown:
parser.error("unknown contract name(s): " + ", ".join(unknown))
results = run_contracts(selected)
summary = summarize(results)
for line in _render(results, summary):
print(line)
if args.json:
out_path = os.path.abspath(args.json)
parent = os.path.dirname(out_path)
if parent:
os.makedirs(parent, exist_ok=True)
with open(out_path, "w", encoding="utf-8") as fh:
json.dump(summary, fh, indent=2, sort_keys=True)
fh.write("\n")
print(f"json: {out_path}")
return 0 if summary["ok"] else 1
if __name__ == "__main__":
raise SystemExit(main())
|