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
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

231 lines
7.2 KiB
Python

"""
Test Registry Configuration
Project paths, environment setup, and global state management.
"""
import os
import json
import subprocess
from pathlib import Path
from typing import List, Dict, Any, Optional
from datetime import datetime
# Projekt-Basisverzeichnis - prüfe verschiedene Pfade
# 1. Docker mit Volume-Mount: /app/project
# 2. Lokale Entwicklung: /Users/benjaminadmin/Projekte/breakpilot-pwa
# 3. Fallback: Demo-Modus
DOCKER_PROJECT_PATH = Path("/app/project")
LOCAL_PROJECT_PATH = Path("/Users/benjaminadmin/Projekte/breakpilot-pwa")
if DOCKER_PROJECT_PATH.exists():
PROJECT_ROOT = DOCKER_PROJECT_PATH
RUN_MODE = "docker"
elif LOCAL_PROJECT_PATH.exists():
PROJECT_ROOT = LOCAL_PROJECT_PATH
RUN_MODE = "local"
else:
PROJECT_ROOT = LOCAL_PROJECT_PATH # Fallback für Demo
RUN_MODE = "demo"
# Pfad fuer persistierte Ergebnisse (Legacy JSON - wird noch als Fallback verwendet)
DATA_DIR = Path("/app/data")
RESULTS_FILE = DATA_DIR / "test_results.json"
# Deaktiviert - wir wollen IMMER echte Tests wenn Tools verfügbar sind
IS_DOCKER = False # Nie Demo-Modus verwenden
# Flag fuer PostgreSQL-Verfuegbarkeit
_use_postgres = True
# ==============================================================================
# In-Memory Storage
# ==============================================================================
# In-Memory Storage (wird parallel zu PostgreSQL gepflegt fuer Abwaertskompatibilitaet)
_test_runs: List[Dict] = []
_current_runs: Dict[str, Any] = {}
_running_tests: Dict[str, Dict] = {} # Progress-Tracking fuer laufende Tests
_persisted_results: Dict[str, Dict] = {} # Persistierte Testergebnisse (Legacy)
def get_test_runs() -> List[Dict]:
"""Get all test runs."""
return _test_runs
def get_current_runs() -> Dict[str, Any]:
"""Get currently running tests."""
return _current_runs
def get_running_tests() -> Dict[str, Dict]:
"""Get running test progress."""
return _running_tests
def get_persisted_results() -> Dict[str, Dict]:
"""Get persisted test results."""
return _persisted_results
def set_persisted_results(results: Dict[str, Dict]):
"""Set persisted test results."""
global _persisted_results
_persisted_results = results
def is_postgres_available() -> bool:
"""Check if PostgreSQL is available."""
return _use_postgres
def set_postgres_available(available: bool):
"""Set PostgreSQL availability flag."""
global _use_postgres
_use_postgres = available
# ==============================================================================
# Tool Availability Checks
# ==============================================================================
def check_go_available() -> bool:
"""Prüft ob Go installiert ist"""
try:
result = subprocess.run(["go", "version"], capture_output=True, timeout=5)
return result.returncode == 0
except:
return False
def check_pytest_available() -> bool:
"""Prüft ob pytest installiert ist"""
pytest_paths = ["/opt/venv/bin/pytest", "pytest"]
for path in pytest_paths:
try:
result = subprocess.run(path.split() + ["--version"], capture_output=True, timeout=5)
if result.returncode == 0:
return True
except:
continue
return False
def get_go_version() -> Optional[str]:
"""Gibt die Go-Version zurueck"""
try:
result = subprocess.run(["go", "version"], capture_output=True, text=True, timeout=5)
if result.returncode == 0:
# "go version go1.23.5 linux/arm64" -> "1.23.5"
parts = result.stdout.strip().split()
if len(parts) >= 3:
return parts[2].replace("go", "")
except:
pass
return None
def get_pytest_version() -> Optional[str]:
"""Gibt die pytest-Version zurueck"""
try:
result = subprocess.run(["/opt/venv/bin/pytest", "--version"], capture_output=True, text=True, timeout=5)
if result.returncode == 0:
# "pytest 8.x.x" -> "8.x.x"
return result.stdout.strip().split()[1] if result.stdout else None
except:
pass
return None
# ==============================================================================
# Persistence Functions
# ==============================================================================
def check_postgres_available() -> bool:
"""Prueft ob PostgreSQL verfuegbar ist."""
global _use_postgres
try:
from ..database import check_db_connection
_use_postgres = check_db_connection()
except Exception:
_use_postgres = False
return _use_postgres
def load_persisted_results():
"""Laedt persistierte Testergebnisse beim Start - erst aus DB, dann JSON als Fallback"""
global _persisted_results
# Versuche zuerst aus PostgreSQL zu laden
if check_postgres_available():
try:
from ..database import get_db_session
from ..repository import TestRepository
with get_db_session() as db:
repo = TestRepository(db)
stats = repo.get_all_service_stats()
for stat in stats:
_persisted_results[stat.service] = {
"total": stat.total_tests,
"passed": stat.passed_tests,
"failed": stat.failed_tests,
"last_run": stat.last_run_at.isoformat() if stat.last_run_at else None,
"status": stat.last_status or "unknown",
"failed_test_ids": [] # Wird spaeter nachgeladen
}
print(f"Test-Ergebnisse aus PostgreSQL geladen: {len(stats)} Services")
return
except Exception as e:
print(f"Fehler beim Laden aus PostgreSQL: {e}")
# Fallback: JSON-Datei
if RESULTS_FILE.exists():
try:
with open(RESULTS_FILE, "r") as f:
_persisted_results = json.load(f)
print(f"Test-Ergebnisse aus JSON geladen: {len(_persisted_results)} Services")
except Exception as e:
print(f"Fehler beim Laden der Testergebnisse: {e}")
_persisted_results = {}
def save_persisted_results():
"""Speichert Testergebnisse - in PostgreSQL und JSON als Backup"""
# JSON als Backup speichern
try:
DATA_DIR.mkdir(parents=True, exist_ok=True)
with open(RESULTS_FILE, "w") as f:
json.dump(_persisted_results, f, indent=2, default=str)
except Exception as e:
print(f"Fehler beim Speichern der JSON-Testergebnisse: {e}")
def migrate_json_to_postgres() -> int:
"""Migriert bestehende JSON-Daten nach PostgreSQL (einmalig)."""
if not _use_postgres:
return 0
if not _persisted_results:
return 0
try:
from ..database import get_db_session
from ..repository import TestRepository
with get_db_session() as db:
repo = TestRepository(db)
count = repo.migrate_from_json(_persisted_results)
print(f"Migration abgeschlossen: {count} Services migriert")
return count
except Exception as e:
print(f"Fehler bei Migration: {e}")
return 0
# Lade persistierte Ergebnisse beim Import
load_persisted_results()