Files
pyramid/docs/TESTS_UND_BENCHMARKS.md
T
Bernd SteckmeisterandClaude Opus 5.5 e90b954348 fix: Abmelden ohne verspaetete Sync-Antwort (SDK-Wettlauf) + Live-Regressionstest
logoutWithoutStraySync (lib/core/session_logout.dart): Sync-Schleife
anhalten, laufenden Long-Poll per Account-Daten wecken und auslaufen lassen,
erst dann abmelden - es ist keine Anfrage mit altem Token mehr unterwegs,
die per 401 ein zweites clear() ausloesen koennte. Genutzt an allen drei
Abmelde-Stellen (Einstellungen, Ueber, Konto geloescht) und im E2E-Live-Test.
Live gemessen: die verspaetete 401 tritt real auf, kam aber stets vor dem
Abschluss einer Neuanmeldung an - Risiko war klein, ist jetzt ausgeschlossen.
test/live_logout_race_test.dart in scripts/test.ps1 -Live.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 17:39:37 +02:00

8.0 KiB
Raw Blame History

Tests & Benchmarks

Stand: 2026-10-07. Alles läuft mit einem Befehl aus dem Projektordner:

pwsh scripts/test.ps1            # Analyse + Unit-Tests (~1 min) – vor jedem Commit
pwsh scripts/test.ps1 -Live      # + Live-Test gegen steggi-matrix.work (Test-Account)
pwsh scripts/test.ps1 -Bench     # + Benchmarks (Datenbank/Verschlüsselung, Migration)
pwsh scripts/test.ps1 -Ui        # + UI-Durchlauf im Handy-Format mit Screenshots
pwsh scripts/test.ps1 -All       # alles (~4 min)

Am Ende steht eine Zusammenfassung mit OK/FEHLER je Schritt. Fehlt die SQLCipher-Bibliothek (frischer Checkout), baut das Skript einmalig flutter build windows --debug.

Für Bernd in einem Satz: Die Tests prüfen automatisch die heiklen Stellen (Login-/Logout-Schutz, Verschlüsselung der Datenbank, Suche, Einstellungen), die Benchmarks messen, ob die App dabei langsamer wird. Was man nur mit Klicken oder zwei echten Geräten prüfen kann, steht weiterhin in docs/PC_TESTPLAN.md.

Tests (test/)

Datei Prüft Läuft wann
app_database_test.dart SQLCipher: Bibliothek echt, Header-Erkennung, Klartext→verschlüsselt-Migration, falscher Schlüssel, Fehlschlag lässt Daten unangetastet immer (braucht die DLL aus dem Windows-Build)
soft_logout_guard_test.dart Uta-Random-Logout-Fix: Token-Refresh-Fehler enden nie im stillen Logout immer
auth_log_test.dart Login-Protokoll (Diagnose für Logout-Bugs) immer
power_levels_safety_test.dart Space-Admin kann sich nicht selbst aussperren immer
settings_prefs_test.dart VoicePrefs-Fassade (gespeicherte Spracheinstellungen) immer
streaming_presets_test.dart 60-FPS-Streaming-Presets (Auflösung/FPS/Bitrate) immer
local_message_search_test.dart Lokale Nachrichtensuche (Strg+K): Treffer, Sortierung, Groß-/Kleinschreibung inkl. Umlaute, Medien-Filter, Trefferdeckel immer (neu 2026-10-07)
live_encryption_e2e_test.dart Echter Login (pyramidtest1) → Platte verschlüsselt → Neustart → Logout → Re-Login → alte Nachricht lesbar; Utas Update-Fall mit echter Session nur mit -Live
live_logout_race_test.dart Abmelden + sofortige Neuanmeldung auf demselben Client: neue Session muss bleiben (SDK-Wettlauf, logoutWithoutStraySync); mit PYRAMID_LIVE_RACE_PROOF=1 zusätzlich Nachweis mit altem Weg nur mit -Live
live_ui_fixture_test.dart Kein Test im engeren Sinn: legt Testinhalte (DM + Gruppe mit Bildern) für den UI-Durchlauf an nur manuell mit PYRAMID_LIVE_TEST=1
live_call_setup_test.dart Kein Test im engeren Sinn: legt den Voice-Testraum für GUI-Call-Tests mit zwei Test-Accounts an nur manuell mit PYRAMID_LIVE_TEST=1

test/support/synthetic_matrix_data.dart erzeugt synthetische Räume und Nachrichten über die echte SDK-Speicherschicht – komplett offline, ohne Konten. Tests und Benchmarks nutzen sie gemeinsam.

Live-Tests: Zugangsdaten liegen AUSSERHALB des Repos (%USERPROFILE%\.pyramid-autopilot\test-accounts.txt bzw. PYRAMID_TEST_ACCOUNTS). Es sind die Test-Accounts pyramidtest1/2, nie Bernds oder Utas Konten.

UI-Durchlauf (integration_test/, seit 2026-10-07)

integration_test/mobile_ui_screens_test.dart startet die ECHTE App (Windows-Build) mit dem Testprofil pyramidtest1 (PYRAMID_PROFILE_DIR=%USERPROFILE%\.pyramid-autopilot\profile1) in simulierter Handy-Größe (1080×2340, Statusleiste 24 dp, Gestenleiste 16 dp), tippt sich durch Chatliste → Chat → Bild und prüft dabei: Vollansicht öffnet, Tippen daneben schließt, Tippen aufs Bild schließt nicht, Doppeltipp zoomt, Wischen nach unten schließt. Screenshots landen in build/ui_screens/ – damit lassen sich UI-Änderungen ohne Handy ansehen.

  • Testinhalte (DM von pyramidtest2 mit langem Text, Antwort, Hoch- und Querformat-Bild) legt test/live_ui_fixture_test.dart an (PYRAMID_LIVE_TEST=1).
  • Läuft nur, wenn keine Pyramid-Instanz offen ist (nie zwei Clients auf einer Datenbank) – das Skript prüft das.
  • Simulierte Fensterklicks (PostMessage) erreichen Flutter unter Windows NICHT; deshalb dieser Weg über integration_test.

Benchmarks (benchmark/)

Laufen bewusst NICHT im normalen flutter test mit (nur -Bench bzw. flutter test benchmark --concurrency=1).

Suite Misst
db_benchmark_test.dart Klartext- vs. SQLCipher-DB mit derselben Bibliothek: Sync-Schreiben (Transaktionen wie beim echten Sync), App-Start (DB öffnen + Raumliste), Chat öffnen (50 Nachrichten), lokale Suche (ohne Treffer = Worst Case, mit Treffern)
migration_benchmark_test.dart Dauer der einmaligen Klartext→SQLCipher-Migration beim ersten Start nach dem Update (exakt der App-Codepfad), danach Vollständigkeitsprüfung

Wie gemessen wird: DB im eigenen Isolate wie in der App; ungemessener Aufwärm-Durchlauf; Modi abwechselnd A-B-B-A (ohne das gewann einfach der später gemessene Modus um ±20 %, weil der Dart-JIT während des Laufs schneller wird); Median mehrerer Durchläufe.

Baseline & Regressionen: Jeder Lauf schreibt build/benchmarks/<suite>.json und vergleicht mit benchmark/baseline/<suite>.json. Mehr als 25 % langsamer (und bei Zeiten mehr als 2 ms absolut) wird als „⚠ LANGSAMER" markiert. Umgebungsvariablen:

  • -UpdateBaseline bzw. PYRAMID_BENCH_UPDATE_BASELINE=1 – aktuelle Werte als neue Baseline speichern (nach bewusster Änderung oder auf neuer Hardware). Die Baseline gilt nur für den Rechner, auf dem sie entstand.
  • PYRAMID_BENCH_STRICT=1 – Regressionen lassen den Lauf scheitern.
  • PYRAMID_BENCH_SCALE=0.2 – kleinere Datenmenge für einen schnellen Probelauf (andere Mengen sind mit der Baseline nicht vergleichbar).

Erste Ergebnisse (2026-10-07, Bernds PC, 12 Kerne, Commit b2413ef)

20 Räume × 500 Nachrichten (DB-Suite), 20 × 1000 (Migration):

Messung Klartext SQLCipher
Sync-Schreiben je Nachricht 0,25 ms 0,26 ms
App-Start (DB + Raumliste) 4,1 ms 4,3 ms
Chat öffnen (50 Nachrichten) 0,33 ms 0,32 ms
Suche ohne Treffer (10 000 Nachrichten) 64 ms 64 ms
Suche mit Treffern 32 ms 32 ms
Migration Klartext → SQLCipher – 325 ms für 7,8 MB (≈ 42 ms/MB)

Was das heißt:

  • Die Verschlüsselung kostet praktisch nichts. Alle Unterschiede liegen im Messrauschen (±5–10 %, zwei Läufe hintereinander). Die Kosten stecken im Matrix-SDK selbst (JSON-Verarbeitung), nicht in SQLCipher.
  • Sync-Schreiben liegt bei ~0,26 ms pro Nachricht und hängt kaum von der Raumgröße ab (nachgemessen: 250 vs. 4 000 Nachrichten pro Raum ≈ +15 %).
  • Suche wächst linear mit der Zahl der gespeicherten Nachrichten (gedeckelt auf 1 500 pro Raum). Hochrechnung, nicht gemessen: 100 aktive Räume am Deckel ≈ 150 000 Nachrichten ≈ 1 s pro Suche auf diesem PC – auf Handys entsprechend länger. Kandidat für einen Suchindex (FTS), falls das in der Praxis stört.
  • Migration: Hochrechnung für eine 100-MB-DB ≈ 4 s einmalig auf diesem PC; auf Utas Handy vermutlich ein Mehrfaches davon (nicht gemessen).

Bekannte Grenzen (ehrlich)

  • Synthetische Daten: unverschlüsselte Räume, keine Olm/Megolm-Sessions (vodozemac läuft im Host-Test nicht). Die DB-Struktur ist aber die echte.
  • Gemessen auf Windows im JIT-Modus von flutter test; die Release-App läuft AOT-kompiliert und ist eher schneller. Für Vergleiche über die Zeit taugt das, für absolute Aussagen über Handys nicht.
  • Nicht automatisiert: alles mit Klicks, echte Calls/Audio, 60-FPS-Streaming zwischen zwei Geräten, Android-Push → docs/PC_TESTPLAN.md.

Nächste sinnvolle Messungen

  • Streaming (M4 „Ursache messen"): WebRTC-getStats() des Senders auswerten (framesPerSecond, qualityLimitationReason, Encoder-Name) – zeigt direkt, ob CPU, Bandbreite oder Encoder bremst. Braucht eine kleine Diagnose-Anzeige im Call und zwei echte Geräte.
  • UI-Flüssigkeit: integration_test mit Frame-Timing beim Scrollen der Raumliste/Timeline (Windows, Test-Account-Profil über PYRAMID_PROFILE_DIR).