Files
ComfyUI-OpenClaw/scripts/run_backend_coverage.py

118 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""
Run backend unit tests under coverage.py and emit a JSON artifact for
coverage-governance reporting.
"""
from __future__ import annotations
import argparse
import importlib.util
import subprocess
import sys
from pathlib import Path
def _run_command(command: list[str]) -> int:
completed = subprocess.run(command, check=False)
return int(completed.returncode)
def _coverage_has_pyproject_toml_support() -> bool:
# IMPORTANT: keep this probe in sync with the CI/local bootstrap checks so
# Python 3.10 fails fast with a clear remediation instead of a coverage crash.
if sys.version_info >= (3, 11):
return True
return importlib.util.find_spec("tomli") is not None
def _build_unittest_args(args: argparse.Namespace) -> list[str]:
command = [
sys.executable,
"-m",
"coverage",
"run",
"scripts/run_unittests.py",
]
if args.module:
command.extend(["--module", args.module])
else:
command.extend(["--start-dir", args.start_dir, "--pattern", args.pattern])
if args.top_level_dir:
command.extend(["--top-level-dir", args.top_level_dir])
if args.enforce_skip_policy:
command.extend(["--enforce-skip-policy", args.enforce_skip_policy])
if args.max_skipped is not None:
command.extend(["--max-skipped", str(args.max_skipped)])
for module in args.no_skip_module:
command.extend(["--no-skip-module", module])
if args.skip_report:
command.extend(["--skip-report", args.skip_report])
return command
def run_backend_coverage(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
description="Run backend unit tests under coverage.py and emit a coverage JSON artifact."
)
parser.add_argument("--module", default=None)
parser.add_argument("--start-dir", default="tests")
parser.add_argument("--pattern", default="test_*.py")
parser.add_argument("--top-level-dir", default=None)
parser.add_argument("--enforce-skip-policy", default=None)
parser.add_argument("--max-skipped", type=int, default=None)
parser.add_argument("--no-skip-module", action="append", default=[])
parser.add_argument("--skip-report", default=None)
parser.add_argument(
"--coverage-json",
default=".tmp/coverage/backend_unit_coverage.json",
help="Path to write the coverage.py JSON artifact.",
)
args = parser.parse_args(argv)
coverage_json = Path(args.coverage_json)
coverage_json.parent.mkdir(parents=True, exist_ok=True)
if not _coverage_has_pyproject_toml_support():
# CRITICAL: coverage reads repo config from pyproject.toml; Python 3.10
# needs the TOML extra or CI/local coverage gates fail before tests run.
print(
"Coverage pyproject support is unavailable on this interpreter. "
"Install with `coverage[toml]` before running the backend coverage gate."
)
return 2
erase_cmd = [sys.executable, "-m", "coverage", "erase"]
if (code := _run_command(erase_cmd)) != 0:
return code
if (code := _run_command(_build_unittest_args(args))) != 0:
return code
json_cmd = [
sys.executable,
"-m",
"coverage",
"json",
"-o",
str(coverage_json),
]
if (code := _run_command(json_cmd)) != 0:
return code
report_cmd = [sys.executable, "-m", "coverage", "report"]
if (code := _run_command(report_cmd)) != 0:
return code
print(f"Coverage JSON: {coverage_json}")
return 0
def main() -> int:
return run_backend_coverage()
if __name__ == "__main__":
raise SystemExit(main())