Add sanity_check_tool/src/sanity_check_tool/core.py
This commit is contained in:
parent
f540ca5f9b
commit
dfd7a69c92
1 changed files with 80 additions and 0 deletions
80
sanity_check_tool/src/sanity_check_tool/core.py
Normal file
80
sanity_check_tool/src/sanity_check_tool/core.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
from __future__ import annotations
|
||||
import json
|
||||
from typing import Any, Dict, List
|
||||
|
||||
|
||||
class SanityCheckError(Exception):
|
||||
"""Custom exception for sanity check processing errors."""
|
||||
pass
|
||||
|
||||
|
||||
def _validate_run_data_structure(run_data: Dict[str, Any]) -> None:
|
||||
required_keys = {"runs", "sanity_checks"}
|
||||
if not isinstance(run_data, dict):
|
||||
raise SanityCheckError("run_data must be a dictionary.")
|
||||
if not required_keys.issubset(run_data.keys()):
|
||||
missing = required_keys - run_data.keys()
|
||||
raise SanityCheckError(f"run_data missing required keys: {', '.join(missing)}")
|
||||
if not isinstance(run_data["runs"], list):
|
||||
raise SanityCheckError("'runs' must be a list.")
|
||||
if not isinstance(run_data["sanity_checks"], list):
|
||||
raise SanityCheckError("'sanity_checks' must be a list.")
|
||||
|
||||
|
||||
def perform_sanity_checks(run_data: Dict[str, Any]) -> Dict[str, int]:
|
||||
"""Führt einfache Sanity-Checks auf Run-Daten aus und gibt strukturierte Ergebnisse zurück.
|
||||
|
||||
Args:
|
||||
run_data: JSON-ähnliche Struktur mit Feldern 'runs' und 'sanity_checks'.
|
||||
|
||||
Returns:
|
||||
Dict mit Zählern für verschiedene Sanity-Checks.
|
||||
"""
|
||||
_validate_run_data_structure(run_data)
|
||||
|
||||
runs: List[Dict[str, Any]] = run_data.get("runs", [])
|
||||
|
||||
missing_pairs = 0
|
||||
broken_ids = 0
|
||||
empty_fields = 0
|
||||
clock_switch_count = 0
|
||||
|
||||
# Fehlende write_pre/write_post-Paare
|
||||
write_pre_events = [r for r in runs if r.get("event_type") == "write_pre"]
|
||||
write_post_events = [r for r in runs if r.get("event_type") == "write_post"]
|
||||
diff = abs(len(write_pre_events) - len(write_post_events))
|
||||
missing_pairs = diff
|
||||
|
||||
# Gebrochene corr_id-Ketten
|
||||
seen_ids = set()
|
||||
for run in runs:
|
||||
cid = run.get("corr_id")
|
||||
if cid is None:
|
||||
broken_ids += 1
|
||||
elif cid in seen_ids:
|
||||
broken_ids += 1
|
||||
else:
|
||||
seen_ids.add(cid)
|
||||
|
||||
# Leere Felder prüfen
|
||||
for run in runs:
|
||||
for key, val in run.items():
|
||||
if val in (None, "", []):
|
||||
empty_fields += 1
|
||||
|
||||
# Clocksource-Switch-Events zählen
|
||||
for run in runs:
|
||||
if run.get("event_type") == "clocksource_switch":
|
||||
clock_switch_count += 1
|
||||
|
||||
results: Dict[str, int] = {
|
||||
"missing_pairs": missing_pairs,
|
||||
"broken_ids": broken_ids,
|
||||
"empty_fields": empty_fields,
|
||||
"clock_switch_count": clock_switch_count,
|
||||
}
|
||||
|
||||
# CI-Assertion: Sicherstellen, dass alle Werte int sind
|
||||
assert all(isinstance(v, int) for v in results.values()), "All result values must be integers"
|
||||
|
||||
return results
|
||||
Loading…
Reference in a new issue