ad6695245b
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.
133 lines
3.9 KiB
Python
133 lines
3.9 KiB
Python
#!/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=smoke;full 返回全部 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())
|