A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
278 lines
7.8 KiB
Python
278 lines
7.8 KiB
Python
"""
|
|
Test Registry Data Models
|
|
|
|
Definiert die Datenstrukturen fuer das zentrale Test-Dashboard.
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import Optional, List, Dict, Any
|
|
|
|
|
|
class TestFramework(str, Enum):
|
|
GO_TEST = "go_test"
|
|
PYTEST = "pytest"
|
|
JEST = "jest"
|
|
PLAYWRIGHT = "playwright"
|
|
BQAS_GOLDEN = "bqas_golden"
|
|
BQAS_RAG = "bqas_rag"
|
|
BQAS_SYNTHETIC = "bqas_synthetic"
|
|
|
|
|
|
class TestCategory(str, Enum):
|
|
UNIT = "unit"
|
|
INTEGRATION = "integration"
|
|
E2E = "e2e"
|
|
BQAS = "bqas"
|
|
SECURITY = "security"
|
|
PERFORMANCE = "performance"
|
|
|
|
|
|
class TestStatus(str, Enum):
|
|
PENDING = "pending"
|
|
RUNNING = "running"
|
|
PASSED = "passed"
|
|
FAILED = "failed"
|
|
SKIPPED = "skipped"
|
|
ERROR = "error"
|
|
|
|
|
|
class RunStatus(str, Enum):
|
|
QUEUED = "queued"
|
|
RUNNING = "running"
|
|
COMPLETED = "completed"
|
|
FAILED = "failed"
|
|
CANCELLED = "cancelled"
|
|
|
|
|
|
@dataclass
|
|
class TestCase:
|
|
"""Einzelner Testfall"""
|
|
id: str
|
|
name: str
|
|
file_path: str
|
|
line_number: Optional[int] = None
|
|
framework: TestFramework = TestFramework.GO_TEST
|
|
category: TestCategory = TestCategory.UNIT
|
|
duration_ms: Optional[float] = None
|
|
status: TestStatus = TestStatus.PENDING
|
|
error_message: Optional[str] = None
|
|
output: Optional[str] = None
|
|
|
|
|
|
@dataclass
|
|
class TestSuite:
|
|
"""Test-Suite eines Services"""
|
|
id: str
|
|
service: str
|
|
name: str
|
|
framework: TestFramework
|
|
category: TestCategory
|
|
base_path: str
|
|
pattern: str # z.B. "*_test.go" oder "test_*.py"
|
|
tests: List[TestCase] = field(default_factory=list)
|
|
total_tests: int = 0
|
|
passed_tests: int = 0
|
|
failed_tests: int = 0
|
|
skipped_tests: int = 0
|
|
duration_ms: float = 0.0
|
|
coverage_percent: Optional[float] = None
|
|
last_run: Optional[datetime] = None
|
|
status: TestStatus = TestStatus.PENDING
|
|
|
|
|
|
@dataclass
|
|
class TestRun:
|
|
"""Ein Test-Durchlauf"""
|
|
id: str
|
|
suite_id: str
|
|
service: str
|
|
started_at: datetime
|
|
completed_at: Optional[datetime] = None
|
|
status: RunStatus = RunStatus.QUEUED
|
|
total_tests: int = 0
|
|
passed_tests: int = 0
|
|
failed_tests: int = 0
|
|
skipped_tests: int = 0
|
|
duration_seconds: float = 0.0
|
|
git_commit: Optional[str] = None
|
|
git_branch: Optional[str] = None
|
|
coverage_percent: Optional[float] = None
|
|
triggered_by: str = "manual"
|
|
output: Optional[str] = None
|
|
failed_test_ids: List[str] = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class CoverageReport:
|
|
"""Coverage-Bericht fuer einen Service"""
|
|
service: str
|
|
framework: TestFramework
|
|
line_coverage: float
|
|
branch_coverage: Optional[float] = None
|
|
function_coverage: Optional[float] = None
|
|
statement_coverage: Optional[float] = None
|
|
uncovered_files: List[str] = field(default_factory=list)
|
|
timestamp: datetime = field(default_factory=datetime.now)
|
|
|
|
|
|
@dataclass
|
|
class ServiceTestInfo:
|
|
"""Aggregierte Test-Informationen fuer einen Service"""
|
|
service: str
|
|
display_name: str
|
|
port: Optional[int] = None
|
|
language: str = "unknown"
|
|
total_tests: int = 0
|
|
passed_tests: int = 0
|
|
failed_tests: int = 0
|
|
skipped_tests: int = 0
|
|
pass_rate: float = 0.0
|
|
coverage_percent: Optional[float] = None
|
|
last_run: Optional[datetime] = None
|
|
status: TestStatus = TestStatus.PENDING
|
|
suites: List[TestSuite] = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class TestRegistryStats:
|
|
"""Gesamtstatistik des Test-Registrys"""
|
|
total_tests: int = 0
|
|
total_passed: int = 0
|
|
total_failed: int = 0
|
|
total_skipped: int = 0
|
|
overall_pass_rate: float = 0.0
|
|
average_coverage: Optional[float] = None
|
|
services_count: int = 0
|
|
last_full_run: Optional[datetime] = None
|
|
by_category: Dict[str, int] = field(default_factory=dict)
|
|
by_framework: Dict[str, int] = field(default_factory=dict)
|
|
|
|
|
|
# Service-Definitionen mit Test-Informationen
|
|
SERVICE_DEFINITIONS = [
|
|
{
|
|
"service": "consent-service",
|
|
"display_name": "Consent Service",
|
|
"port": 8081,
|
|
"language": "go",
|
|
"base_path": "/consent-service",
|
|
"test_pattern": "*_test.go",
|
|
"framework": TestFramework.GO_TEST,
|
|
},
|
|
{
|
|
"service": "backend",
|
|
"display_name": "Python Backend",
|
|
"port": 8000,
|
|
"language": "python",
|
|
"base_path": "/backend/tests",
|
|
"test_pattern": "test_*.py",
|
|
"framework": TestFramework.PYTEST,
|
|
},
|
|
{
|
|
"service": "voice-service",
|
|
"display_name": "Voice Service",
|
|
"port": 8091,
|
|
"language": "python",
|
|
"base_path": "/app/tests",
|
|
"test_pattern": "test_*.py",
|
|
"framework": TestFramework.PYTEST,
|
|
"container_name": "breakpilot-pwa-voice-service",
|
|
"run_in_container": True,
|
|
"pytest_args": "--ignore=/app/tests/bqas", # Exclude BQAS tests - run separately
|
|
},
|
|
{
|
|
"service": "klausur-service",
|
|
"display_name": "Klausur Service",
|
|
"port": 8086,
|
|
"language": "python",
|
|
"base_path": "/app/tests",
|
|
"test_pattern": "test_*.py",
|
|
"framework": TestFramework.PYTEST,
|
|
"container_name": "breakpilot-pwa-klausur-service",
|
|
"run_in_container": True,
|
|
},
|
|
{
|
|
"service": "billing-service",
|
|
"display_name": "Billing Service",
|
|
"port": 8082,
|
|
"language": "go",
|
|
"base_path": "/billing-service",
|
|
"test_pattern": "*_test.go",
|
|
"framework": TestFramework.GO_TEST,
|
|
},
|
|
{
|
|
"service": "school-service",
|
|
"display_name": "School Service",
|
|
"port": 8084,
|
|
"language": "go",
|
|
"base_path": "/school-service",
|
|
"test_pattern": "*_test.go",
|
|
"framework": TestFramework.GO_TEST,
|
|
},
|
|
{
|
|
"service": "edu-search-service",
|
|
"display_name": "Edu Search Service",
|
|
"port": 8088,
|
|
"language": "go",
|
|
"base_path": "/edu-search-service",
|
|
"test_pattern": "*_test.go",
|
|
"framework": TestFramework.GO_TEST,
|
|
},
|
|
{
|
|
"service": "ai-compliance-sdk",
|
|
"display_name": "AI Compliance SDK",
|
|
"port": None,
|
|
"language": "go",
|
|
"base_path": "/ai-compliance-sdk",
|
|
"test_pattern": "*_test.go",
|
|
"framework": TestFramework.GO_TEST,
|
|
},
|
|
{
|
|
"service": "geo-service",
|
|
"display_name": "Geo Service",
|
|
"port": 8089,
|
|
"language": "mixed",
|
|
"base_path": "/geo-service",
|
|
"test_pattern": "*_test.go",
|
|
"framework": TestFramework.GO_TEST,
|
|
"disabled": True, # Keine Tests vorhanden - Verzeichnis ist leer
|
|
"disabled_reason": "Keine Test-Dateien vorhanden",
|
|
},
|
|
{
|
|
"service": "website",
|
|
"display_name": "Website (Jest)",
|
|
"port": 3000,
|
|
"language": "typescript",
|
|
"base_path": "/website",
|
|
"test_pattern": "*.test.{ts,tsx}",
|
|
"framework": TestFramework.JEST,
|
|
"requires_setup": True, # Erfordert npm install im Website-Verzeichnis
|
|
"setup_note": "Fuehren Sie 'npm install' im website-Verzeichnis aus, um Tests lokal auszufuehren",
|
|
},
|
|
# Website E2E entfernt - keine Playwright-Tests vorhanden
|
|
{
|
|
"service": "bqas-golden",
|
|
"display_name": "BQAS Golden Suite",
|
|
"port": 8091,
|
|
"language": "python",
|
|
"base_path": "/app/tests/bqas/test_golden.py",
|
|
"test_pattern": "test_*.py",
|
|
"framework": TestFramework.PYTEST,
|
|
"container_name": "breakpilot-pwa-voice-service",
|
|
"run_in_container": True,
|
|
},
|
|
{
|
|
"service": "bqas-rag",
|
|
"display_name": "BQAS RAG Tests",
|
|
"port": 8091,
|
|
"language": "python",
|
|
"base_path": "/app/tests/bqas/test_rag.py",
|
|
"test_pattern": "test_*.py",
|
|
"framework": TestFramework.PYTEST,
|
|
"container_name": "breakpilot-pwa-voice-service",
|
|
"run_in_container": True,
|
|
},
|
|
]
|