Files
mlkem-sync/test_framework/run_all.py
FallenSigh 8fdf944555 feat: init mlkem project with Verilator test framework
- sync_rtl/common/: skid_buffer, pipeline_reg, defines (valid/ready)
- sync_rtl/mod_add/: modular adder example with Verilator C++ TB
- test_framework/: Python-driven Verilator compile/sim/compare pipeline
- test_framework/modules/mod_add/: 50-vector test plan, full鏈路 PASS
- .trellis/spec/: RTL and test_framework conventions documented
2026-06-24 19:43:29 +08:00

111 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""run_all.py - CLI entry point for the ML-KEM RTL test framework.
Usage:
python3 run_all.py # Run all modules
python3 run_all.py --module mod_add # Run specific module
python3 run_all.py --list # List all registered modules
python3 run_all.py --module mod_add --case basic # Run single case
python3 run_all.py --quick # Quick mode (reduced vectors)
"""
import os
import sys
import time
import argparse
from pathlib import Path
# Ensure test_framework/lib is on the path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from lib.test_runner import TestRunner
from lib.reporter import Reporter
def main():
parser = argparse.ArgumentParser(
description='ML-KEM RTL Test Framework'
)
parser.add_argument('--module', '-m', type=str, default=None,
help='Run specific module only')
parser.add_argument('--case', '-c', type=str, default=None,
help='Run specific test case only')
parser.add_argument('--list', '-l', action='store_true',
help='List all registered modules')
parser.add_argument('--quick', '-q', action='store_true',
help='Quick mode (reduced vectors)')
parser.add_argument('--config', type=str, default='test_framework/config.json',
help='Path to config.json')
args = parser.parse_args()
# Change to project root (parent of test_framework/)
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
os.chdir(project_root)
runner = TestRunner(config_path=args.config)
modules = runner.discover_modules()
if args.list:
print("\nRegistered test modules:")
if not modules:
print(" (none found)")
for name, plan in sorted(modules.items()):
num_cases = len(plan.get('cases', []))
print(f" {name}: {num_cases} case(s)")
for case in plan.get('cases', []):
print(f" - {case['id']}: {case.get('description', '')}")
print()
return 0
if not modules:
print("No test modules found in test_framework/modules/")
return 1
# Determine which modules to run
if args.module:
if args.module not in modules:
print(f"Error: Module '{args.module}' not found.")
print(f"Available: {', '.join(sorted(modules.keys()))}")
return 1
to_run = [args.module]
else:
to_run = sorted(modules.keys())
# Run tests
results = {}
total_start = time.time()
reporter = Reporter(runner.config.get('report_root', 'test_framework/reports'))
for module_name in to_run:
print(f"\n{'='*50}")
print(f" Testing: {module_name}")
print(f"{'='*50}")
result = runner.run_module(
module_name,
quick=args.quick,
single_case=args.case
)
results[module_name] = result
if result['status'] == 'COMPILE_ERROR':
print(f" ERROR: Verilator compilation failed for {module_name}")
elif result['status'] == 'ERROR':
print(f" ERROR: {result.get('error', 'Unknown error')}")
elif result['status'] == 'NOT_FOUND':
print(f" ERROR: {result.get('error', 'Module not found')}")
total_elapsed = time.time() - total_start
# Print summary
all_pass = reporter.print_summary(results, total_elapsed)
return 0 if all_pass else 1
if __name__ == '__main__':
sys.exit(main())