docs: Wiederaufnahme 2026-10-07 - Tests/Benchmarks dokumentiert, SDK-Wettlauf + Abhaengigkeiten in ROADMAP
Neue Punkte: SDK-Sync-Wettlauf (Logout-Pfad pruefen), Abhaengigkeits-Updates (sqlcipher_flutter_libs EOL - nie auf 0.7.0 heben, matrix 6.2 -> 13, flutter_markdown eingestellt; WebRTC-Audio-Fix weiterhin nicht upstream). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
df1b392ed8
commit
dbc0340eeb
+49
@@ -13,6 +13,55 @@ Schritt (und beim Abbruch mitten im Schritt den Zwischenstand). Format:
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-07 – Wiederaufnahme nach Pause: Bestandsaufnahme, Test-Runner, Benchmarks, Live-Test stabilisiert
|
||||
|
||||
**Erledigt:**
|
||||
- **Bestandsaufnahme:** Repo synchron mit Gitea (0 vor/0 hinter), Arbeitsbaum
|
||||
war sauber, Toolchain unverändert (Flutter 3.44.4 / Dart 3.12.2).
|
||||
`flutter analyze` sauber (nur bekannter onUpdate-Hinweis), 36 Unit-Tests
|
||||
grün. Autopilot (PC + Pi) weiterhin pausiert.
|
||||
- **Lokale Suche als Modul:** `_localMessageSearch` aus `search_modal.dart`
|
||||
nach `lib/features/search/local_message_search.dart` verschoben – gleiche
|
||||
Deckel (1500/Raum, 60 Treffer, 500er-Blöcke), gleiche Schleife, nur der
|
||||
Medien-Filter kommt jetzt als Parameter. 5 Vertragstests
|
||||
(`test/local_message_search_test.dart`) auf der echten SDK-DB-Schicht.
|
||||
- **Benchmarks** (`benchmark/`, `docs/TESTS_UND_BENCHMARKS.md`): Klartext vs.
|
||||
SQLCipher (Sync-Schreiben, App-Start, Chat öffnen, Suche) + Migrationsdauer;
|
||||
JSON-Berichte, Baseline in `benchmark/baseline/`, Regressionswarnung >25 %.
|
||||
Ergebnis: SQLCipher-Aufschlag im Rauschen (±5–10 %), Migration ≈ 42 ms/MB,
|
||||
Suche (Worst Case) 64 ms für 10 000 Nachrichten.
|
||||
- **`scripts/test.ps1`:** Analyse + Unit-Tests (+ `-Live`, `-Bench`, `-All`,
|
||||
`-UpdateBaseline`) mit Zusammenfassung; baut die SQLCipher-DLL bei Bedarf.
|
||||
- **Live-Test sporadisch rot → Ursache gefunden, Test stabilisiert:** siehe
|
||||
Befund unten. `live_encryption_e2e_test.dart` meldet sich jetzt über
|
||||
`_logoutWithoutStraySync` ab (Sync anhalten, laufenden Long-Poll
|
||||
auslaufen lassen, dann Logout). Danach 3 Läufe in Folge grün (Ergebnis
|
||||
siehe unten).
|
||||
|
||||
**Befund (neu in ROADMAP, M1-Bereich):** matrix 6.2 `_innerSync` wirft den
|
||||
Fehler einer Sync-Antwort, bevor geprüft wird, ob die Anfrage noch aktuell
|
||||
ist. Die 401 eines alten Long-Polls nach einem Logout löst ein erneutes
|
||||
`clear()` aus – nach einem schnellen Re-Login auf demselben Client würde das
|
||||
die neue Session löschen. Im Test trat es als „databaseFactory not
|
||||
initialized" nach `dispose()` auf. Upstream `main` unverändert (geprüft).
|
||||
App-Logout-Pfad noch NICHT angefasst (heilig, braucht Gerätetest).
|
||||
|
||||
**Offen/Nächster Schritt:** Bernds Rückmeldungen aus der Beta-Testphase
|
||||
(v0.1.36) einsammeln, dann Prioritäten setzen: Klick-Tests aus
|
||||
`docs/PC_TESTPLAN.md`, App-Logout-Pfad gegen den SDK-Wettlauf prüfen,
|
||||
Abhängigkeits-Updates (ROADMAP M2, Achtung `sqlcipher_flutter_libs` EOL).
|
||||
|
||||
**Stolperfallen:** (1) sqflite liefert für denselben Pfad dieselbe
|
||||
Verbindung zurück – ein zweites Öffnen+Schließen kappt die erste
|
||||
(Benchmark-„database_closed"). (2) Benchmark-Reihenfolge: der Dart-JIT wird
|
||||
während des Laufs schneller, der zuerst gemessene Modus verlor ±20 % →
|
||||
großer Aufwärm-Durchlauf + A-B-B-A. (3) `dart format` NUR auf neue Dateien
|
||||
anwenden – Bestandsdateien sind nicht formatiert, sonst riesiger Diff.
|
||||
(4) Vor einer Aussage nachmessen: Schreibkosten hängen NICHT nennenswert von
|
||||
der Raumgröße ab (250 vs. 4000 Nachrichten/Raum ≈ +15 %).
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-06 – Nacht-Session (C+B): 60-FPS-Streaming + Call mit ZWEI echten Test-Accounts real durchgeklickt
|
||||
|
||||
**Erledigt:** Fokus (C) Streaming und (B) Calls – beides mit zwei echten
|
||||
|
||||
@@ -25,6 +25,7 @@ für die unterstützte Dart-Version).
|
||||
flutter pub get
|
||||
flutter run -d windows # schnellster Praxistest während der Entwicklung
|
||||
flutter analyze # muss sauber bleiben
|
||||
pwsh scripts/test.ps1 # Analyse + Tests (-Live, -Bench, -All: siehe docs/TESTS_UND_BENCHMARKS.md)
|
||||
```
|
||||
|
||||
Unterstützte Zielplattformen: Android, Windows, Linux, iOS, macOS (Ordner
|
||||
@@ -52,5 +53,6 @@ lib/
|
||||
|
||||
- `CLAUDE.md` – Arbeitsregeln und Infrastruktur für die Zusammenarbeit mit Claude
|
||||
- `ROADMAP.md` / `PROGRESS.md` – aktueller Stand und nächste Schritte
|
||||
- `docs/TESTS_UND_BENCHMARKS.md` – Tests, Live-Tests, Benchmarks (ein Befehl)
|
||||
- `docs/NOTIFICATIONS.md` – Push-Architektur (native Anzeige vs. Hintergrund-Entschlüsselung)
|
||||
- `docs/matrix-sdk/` – Hinweise zum verwendeten Matrix-SDK
|
||||
|
||||
+38
@@ -169,6 +169,21 @@ Punkte abhaken (`[x]`), wenn erledigt UND in `PROGRESS.md` protokolliert.
|
||||
E2EE-Empfang live belegt, auth_log unauffällig; App läuft seit 12:43
|
||||
für die Langzeit-Beobachtung weiter. **Offen (Klick/Bernd):**
|
||||
Senden, Logout-Warnung, Re-Login mit Lesbarkeits-Check.
|
||||
- [ ] **SDK-Wettlauf: verspätete 401 einer alten Sync-Anfrage löscht ggf. die
|
||||
NEUE Session** (gefunden 2026-10-07 über einen sporadisch roten
|
||||
Live-Test, siehe PROGRESS.md). matrix 6.2 `Client._innerSync` wirft den
|
||||
Fehler einer Sync-Antwort, BEVOR geprüft wird, ob die Anfrage noch
|
||||
aktuell ist (`_currentSyncId`). Läuft beim Logout noch ein Long-Poll
|
||||
(bis 30 s) mit dem alten Token, kommt dessen M_UNKNOWN_TOKEN danach an
|
||||
und das SDK ruft `clear()` – nach einem schnellen Re-Login auf
|
||||
demselben Client wäre das ein „Random-Logout" direkt nach dem Login.
|
||||
Upstream (famedly/matrix-dart-sdk `main`, 2026-10-07) unverändert;
|
||||
neuere SDKs versuchen bei vorhandenem Refresh-Token aber zuerst einen
|
||||
Refresh statt `clear()` (entschärft). Im Live-Test per
|
||||
`_logoutWithoutStraySync` umgangen. **Offen:** App-Logout-Pfad prüfen
|
||||
(läuft der Re-Login auf demselben Client-Objekt? dann vor
|
||||
`client.logout()` Sync anhalten + laufenden Long-Poll abwarten) –
|
||||
heiliger Pfad, nur mit Gerätetest; ggf. Upstream-Issue melden.
|
||||
|
||||
## M2 – Das große Refactoring (erst nach M0/M1!)
|
||||
|
||||
@@ -253,6 +268,29 @@ lassen, ohne dass andere Module angefasst werden müssen.
|
||||
prüfen), siehe „Fragen an Bernd"/Nächster-Schritt in den jeweiligen
|
||||
PROGRESS.md-Einträgen)
|
||||
- [ ] Nach JEDEM Schritt: App läuft, Kernflows getestet, Commit
|
||||
- [x] Test-/Benchmark-Gerüst: `scripts/test.ps1` (Analyse, Unit-, Live-Tests,
|
||||
Benchmarks mit einem Befehl), `benchmark/` mit Baseline, lokale Suche
|
||||
als testbares Modul (`lib/features/search/`). Siehe
|
||||
`docs/TESTS_UND_BENCHMARKS.md`, PROGRESS.md 2026-10-07.
|
||||
- [ ] **Abhängigkeiten aktualisieren (3 Monate Stand, 119 Pakete veraltet)** –
|
||||
einzeln, jeweils mit `scripts/test.ps1 -All` abgesichert:
|
||||
- **`sqlcipher_flutter_libs` ist EOL:** 0.7.0 ist ein leerer Platzhalter
|
||||
(pub.dev). Unsere Bindung `^0.6.8` schließt ihn aus – NIEMALS per
|
||||
`pub upgrade --major-versions` mitziehen, sonst fehlt SQLCipher und
|
||||
die App kann die verschlüsselte DB nicht mehr öffnen
|
||||
(`AppDatabase` wirft dann bewusst, kein Datenverlust, aber Aussperren).
|
||||
Nachfolger: `sqlite3` 3.x mit `hooks: user_defines: sqlite3: source:
|
||||
sqlcipher` – Kompatibilität mit `sqflite_common_ffi` und Android
|
||||
vorher klären; Migrations-/DB-Tests + Gerätetest Pflicht.
|
||||
- `matrix` 6.2 → 13.x (großer Sprung, Breaking Changes; heiliger
|
||||
Login-/Krypto-Pfad), `flutter_vodozemac` 0.5 → 0.8 gehört dazu.
|
||||
- `livekit_client` 2.7 → 2.13 (innerhalb der Bindung möglich),
|
||||
`flutter_webrtc`-Override 1.4.1 → 1.6.2: der Windows-Audiogeräte-Fix
|
||||
(libwebrtc #142) ist auch in 1.6.2+hotfix.4 NICHT enthalten
|
||||
(Changelog geprüft 2026-10-07) → Dummy-PeerConnection-Workaround
|
||||
bleibt nötig.
|
||||
- `flutter_markdown` ist eingestellt (pub: „replaced by
|
||||
flutter_markdown_plus“) → umstellen (Markdown-Vorschau im Dokument-Viewer).
|
||||
|
||||
## M3 – Calls: Logik, UI & Audio (Discord als Referenz)
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ Schnellster Weg: `flutter run -d windows`.
|
||||
VoicePrefs-Vertragstests in `test/settings_prefs_test.dart`),
|
||||
mehrfach gelaufen (vor/nach jedem Umbau des Tages).
|
||||
|
||||
- [x] **Seit 2026-10-07: alles Automatisierbare mit EINEM Befehl** –
|
||||
`pwsh scripts/test.ps1 -All` (Analyse, 41 Unit-Tests, Live-Test mit
|
||||
Test-Account, Benchmarks). Details: `docs/TESTS_UND_BENCHMARKS.md`.
|
||||
|
||||
## 1. Härtetest Login/Krypto (M1 – PFLICHT, zuerst!)
|
||||
|
||||
Deckt die Fixes 63e4919, 9dc83f7, 891f348 ab (Uta-Random-Logout + Guard).
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
# 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 -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_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.
|
||||
|
||||
## 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`).
|
||||
Reference in New Issue
Block a user