Files
.pouch/skills/ack/scripts/select_regression.py
laily ad6695245b feat(ack): bind test env to deployer and add regression mode
ACK 0.19.0 hands test-environment deploys to the deployer skill,
documents bug-fix as a first-class scenario, and adds
docs/ack/regression.yaml harvest plus a /ack regression run.
2026-08-25 14:41:05 +08:00

133 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""选择 ACK 回归目录中的 active 用例。
默认返回 smoke 套件。本脚本只输出数据,不执行 steps 或 automationRef。
用法:
python3 select_regression.py docs/ack/regression.yaml
python3 select_regression.py docs/ack/regression.yaml --suite full
python3 select_regression.py docs/ack/regression.yaml --case-id REG-login-001
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Any
from validate_regression import ID_RE, load_yaml, validate_builtin
DEFAULT_LIMIT = 50
MAX_LIMIT = 200
def select_cases(
data: dict[str, Any],
*,
suite: str,
case_ids: list[str],
limit: int,
) -> list[dict[str, Any]]:
cases = data.get("cases")
if not isinstance(cases, list):
raise ValueError("cases 必须是列表")
wanted = set(case_ids)
selected: list[dict[str, Any]] = []
for case in cases:
if not isinstance(case, dict):
continue
if case.get("status") != "active":
continue
case_id = case.get("id")
if wanted:
if case_id not in wanted:
continue
elif suite == "smoke" and case.get("suite") != "smoke":
continue
selected.append(case)
missing = wanted - {
case.get("id") for case in selected if isinstance(case.get("id"), str)
}
if missing:
raise ValueError("找不到 active 用例: " + ", ".join(sorted(missing)))
if len(selected) > limit:
raise ValueError(
f"命中 {len(selected)} 条,超过 --limit {limit}"
"请用 --suite / --case-id 缩小范围"
)
return selected
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="选择 ACK 回归用例")
parser.add_argument(
"regression", nargs="?", default="docs/ack/regression.yaml"
)
parser.add_argument(
"--suite",
choices=("smoke", "full"),
default="smoke",
help="smoke 只返回 suite=smokefull 返回全部 active 用例",
)
parser.add_argument("--case-id", action="append", default=[], dest="case_ids")
parser.add_argument("--limit", type=int, default=DEFAULT_LIMIT)
parser.add_argument(
"--format", choices=("json", "ids"), default="json", dest="output_format"
)
args = parser.parse_args(argv)
regression_path = Path(args.regression)
if not regression_path.is_file():
sys.stderr.write(f"找不到回归目录: {regression_path}\n")
return 2
if not 1 <= args.limit <= MAX_LIMIT:
sys.stderr.write(f"--limit 必须在 1..{MAX_LIMIT} 之间\n")
return 2
for case_id in args.case_ids:
if ID_RE.fullmatch(case_id) is None:
sys.stderr.write(f"--case-id 必须使用 REG-<id> 格式: {case_id}\n")
return 2
data = load_yaml(regression_path, "回归目录")
errors = validate_builtin(data)
if errors:
sys.stderr.write(f"回归目录无效,拒绝选择,共 {len(errors)} 项:\n")
for error in errors:
sys.stderr.write(f" - {error}\n")
return 1
try:
selected = select_cases(
data,
suite=args.suite,
case_ids=args.case_ids,
limit=args.limit,
)
except ValueError as exc:
sys.stderr.write(f"回归选择失败: {exc}\n")
return 1
ids = [case.get("id") for case in selected]
if args.output_format == "ids":
if ids:
sys.stdout.write("\n".join(str(item) for item in ids) + "\n")
return 0
payload = {
"count": len(selected),
"limit": args.limit,
"suite": args.suite,
"ids": ids,
"cases": selected,
}
sys.stdout.write(json.dumps(payload, ensure_ascii=False, indent=2) + "\n")
return 0
if __name__ == "__main__":
raise SystemExit(main())