maturity scorecard generation

This commit is contained in:
2026-05-08 01:59:42 +02:00
parent b4f620533c
commit 3a94042ca3
14 changed files with 1385 additions and 95 deletions

View File

@@ -14,10 +14,20 @@ import os
import shutil
import shlex
import subprocess
import sys
import xml.etree.ElementTree as ET
from pathlib import Path
from typing import Any
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from open_cmis_tck.normalization import ( # noqa: E402
aggregate_case_result,
normalize_case_status,
parse_text_report,
result_counts,
)
def main() -> int:
parser = argparse.ArgumentParser()
@@ -215,6 +225,25 @@ def _normalize_tck_output(
if junit_files:
return _normalize_junit_result(junit_files[0], completed.returncode, selected_group)
text_cases = parse_text_report(completed.stdout, selected_group)
if text_cases:
counts = result_counts(text_cases)
return {
"result": aggregate_case_result(counts, completed.returncode),
"observations": [
f"OpenCMIS TCK group {selected_group!r} produced native TextReport output.",
"Normalized OpenCMIS TextReport case statuses: "
+ ", ".join(f"{key}: {value}" for key, value in counts.items())
+ ".",
],
"facts": {
"normalizer": "opencmis-text-report",
"result_counts": counts,
"cases": text_cases[:500],
},
"artifact_refs": [],
}
if completed.returncode == 0:
return {
"result": "pass",
@@ -254,17 +283,11 @@ def _normalize_json_result(
counts: dict[str, int] = {}
normalized_cases = []
for case in cases:
status = _normalize_case_status(str(case.get("status", "unknown")))
status = normalize_case_status(str(case.get("status", "unknown")))
counts[status] = counts.get(status, 0) + 1
normalized_cases.append(
{
"id": str(case.get("id", case.get("name", "unnamed"))),
"status": status,
"message": str(case.get("message", case.get("reason", ""))),
}
)
normalized_cases.append(_normalize_json_case(case, status))
return {
"result": _aggregate_result(counts, returncode),
"result": aggregate_case_result(counts, returncode),
"observations": [
f"OpenCMIS TCK group {selected_group!r} produced {sum(counts.values())} normalized case result(s)."
],
@@ -277,7 +300,7 @@ def _normalize_json_result(
"artifact_refs": artifact_refs,
}
result = _normalize_case_status(str(payload.get("result", "unknown")))
result = normalize_case_status(str(payload.get("result", "unknown")))
if returncode != 0 and result in {"pass", "warning", "skipped"}:
result = "infrastructure_error"
return {
@@ -313,7 +336,7 @@ def _normalize_junit_result(
}
counts = {key: value for key, value in counts.items() if value}
return {
"result": _aggregate_result(counts, returncode),
"result": aggregate_case_result(counts, returncode),
"observations": [
f"OpenCMIS TCK group {selected_group!r} produced JUnit-style XML results."
],
@@ -334,6 +357,30 @@ def _json_cases(payload: dict[str, Any]) -> list[dict[str, Any]]:
return []
def _normalize_json_case(case: dict[str, Any], status: str) -> dict[str, Any]:
normalized = {
"id": str(case.get("id", case.get("name", "unnamed"))),
"status": status,
"message": str(case.get("message", case.get("reason", ""))),
}
for key in [
"status_native",
"group_name",
"selected_check_group",
"test_name",
"class_name",
"group_class",
"group_classes",
"duration_ms",
"level",
"source",
"source_location",
]:
if key in case:
normalized[key] = case[key]
return normalized
def _artifact_refs_from_payload(payload: dict[str, Any]) -> list[str]:
refs = payload.get("artifact_refs", [])
if not isinstance(refs, list):
@@ -341,50 +388,6 @@ def _artifact_refs_from_payload(payload: dict[str, Any]) -> list[str]:
return [ref for ref in refs if isinstance(ref, str) and ref]
def _aggregate_result(counts: dict[str, int], returncode: int) -> str:
if counts.get("infrastructure_error"):
return "infrastructure_error"
if counts.get("fail"):
return "fail"
if counts.get("pass"):
return "pass"
if counts.get("expected_gap"):
return "expected_gap"
if counts.get("unsupported_by_design"):
return "unsupported_by_design"
if counts.get("skipped"):
return "skipped"
return "infrastructure_error" if returncode else "unknown"
def _normalize_case_status(value: str) -> str:
normalized = value.strip().lower().replace("-", "_").replace(" ", "_")
if normalized in {"ok", "success", "passed"}:
return "pass"
if normalized in {"failure", "failed", "error"}:
return "fail"
if normalized in {"skip", "skipped"}:
return "skipped"
if normalized in {"expected_skip", "expected_gap"}:
return "expected_gap"
if normalized in {"unsupported", "unsupported_by_design"}:
return "unsupported_by_design"
if normalized in {"infra", "infrastructure_error"}:
return "infrastructure_error"
if normalized in {
"pass",
"fail",
"warning",
"manual",
"not_applicable",
"waiver_applied",
"blocked",
"unknown",
}:
return normalized
return "unknown"
def _observations_from_payload(payload: dict[str, Any], selected_group: str | None) -> list[str]:
observations = payload.get("observations")
if isinstance(observations, list):