This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/backend/api/tests/models.py
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
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>
2026-02-09 09:51:32 +01:00

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,
},
]