Files
pyramid/scripts/test.ps1
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

139 lines
5.7 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#Requires -Version 7.0
# Pyramid – Tests & Benchmarks mit einem Befehl
#
# pwsh scripts/test.ps1 Analyse + Unit-Tests (Standard, ~2 min)
# pwsh scripts/test.ps1 -Live + Live-Test gegen steggi-matrix.work
# (Test-Accounts pyramidtest1/2, NICHT Bernd/Uta)
# pwsh scripts/test.ps1 -Bench + Benchmarks (Datenbank/Verschlüsselung, Migration)
# pwsh scripts/test.ps1 -Ui + UI-Durchlauf im Handy-Format mit Screenshots
# (echte App, Testprofil pyramidtest1 → build/ui_screens/)
# pwsh scripts/test.ps1 -All alles zusammen
# pwsh scripts/test.ps1 -Bench -UpdateBaseline
# Benchmark-Werte als neue Baseline speichern
# (nach bewusster Änderung / auf neuer Hardware)
# -SkipAnalyze flutter analyze überspringen
#
# Details: docs/TESTS_UND_BENCHMARKS.md
param(
[switch]$Live,
[switch]$Bench,
[switch]$Ui,
[switch]$All,
[switch]$UpdateBaseline,
[switch]$SkipAnalyze
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
# Immer aus dem Projektordner arbeiten, egal von wo das Skript aufgerufen wird.
Set-Location (Split-Path $PSScriptRoot -Parent)
if ($All) { $Live = $true; $Bench = $true; $Ui = $true }
$results = [System.Collections.Generic.List[object]]::new()
function Invoke-Step([string]$Name, [scriptblock]$Action) {
Write-Host ""
Write-Host "━━ $Name" -ForegroundColor Cyan
$watch = [Diagnostics.Stopwatch]::StartNew()
$global:LASTEXITCODE = 0
& $Action
$ok = ($LASTEXITCODE -eq 0)
$results.Add([pscustomobject]@{
Schritt = $Name
Ergebnis = if ($ok) { "OK" } else { "FEHLER" }
Dauer = "{0:n0} s" -f $watch.Elapsed.TotalSeconds
})
if (-not $ok) { Write-Host "✗ $Name fehlgeschlagen (Exit-Code $LASTEXITCODE)" -ForegroundColor Red }
}
function Add-Skipped([string]$Name, [string]$Reason) {
Write-Host ""
Write-Host "━━ $Name – übersprungen: $Reason" -ForegroundColor Yellow
$results.Add([pscustomobject]@{ Schritt = $Name; Ergebnis = "ÜBERSPRUNGEN"; Dauer = "–" })
}
# ── SQLCipher-Bibliothek ─────────────────────────────────────────────────────
# Die Datenbank-Tests und Benchmarks benutzen dieselbe sqlite3.dll (SQLCipher)
# wie die App – sie entsteht beim Windows-Build. Fehlt sie, einmal bauen.
$cipherDll = Get-ChildItem "build/windows/x64/runner/*/sqlite3.dll" -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $cipherDll) {
Invoke-Step "Windows-Build (einmalig, liefert die SQLCipher-DLL)" {
flutter build windows --debug
}
}
if (-not $SkipAnalyze) {
# Infos (z. B. der bekannte onUpdate-Hinweis) werden angezeigt, lassen den
# Lauf aber nicht scheitern – Warnungen und Fehler schon.
Invoke-Step "Statische Analyse (flutter analyze)" { flutter analyze --no-fatal-infos }
}
Invoke-Step "Unit-Tests (test/)" { flutter test }
if ($Live) {
$accounts = if ($env:PYRAMID_TEST_ACCOUNTS) { $env:PYRAMID_TEST_ACCOUNTS }
else { Join-Path $env:USERPROFILE ".pyramid-autopilot\test-accounts.txt" }
if (-not (Test-Path $accounts)) {
Add-Skipped "Live-Test (echter Homeserver)" "Zugangsdatei fehlt: $accounts"
} else {
$env:PYRAMID_LIVE_TEST = "1"
try {
Invoke-Step "Live-Test: SQLCipher mit echtem Login (pyramidtest1)" {
flutter test test/live_encryption_e2e_test.dart --concurrency=1
}
Invoke-Step "Live-Test: Logout + sofortiger Re-Login (SDK-Wettlauf)" {
flutter test test/live_logout_race_test.dart --concurrency=1
}
} finally {
Remove-Item Env:PYRAMID_LIVE_TEST -ErrorAction SilentlyContinue
}
}
}
if ($Bench) {
if ($UpdateBaseline) { $env:PYRAMID_BENCH_UPDATE_BASELINE = "1" }
try {
# concurrency=1: Benchmarks dürfen sich nicht gegenseitig die CPU klauen.
Invoke-Step "Benchmarks (benchmark/)" { flutter test benchmark --concurrency=1 }
} finally {
Remove-Item Env:PYRAMID_BENCH_UPDATE_BASELINE -ErrorAction SilentlyContinue
}
Write-Host "Benchmark-Berichte: build/benchmarks/*.json (Baseline: benchmark/baseline/)"
}
if ($Ui) {
$uiProfile = Join-Path $env:USERPROFILE ".pyramid-autopilot\profile1"
if (-not (Test-Path (Join-Path $uiProfile "pyramid.sqlite"))) {
Add-Skipped "UI-Durchlauf (Handy-Format)" "Testprofil fehlt: $uiProfile"
} elseif (Get-Process pyramid -ErrorAction SilentlyContinue) {
# Nie zwei Matrix-Clients auf derselben DB – und Bernds Fenster nicht stören.
Add-Skipped "UI-Durchlauf (Handy-Format)" "Pyramid läuft gerade – erst beenden"
} else {
$env:PYRAMID_PROFILE_DIR = $uiProfile
try {
Invoke-Step "UI-Durchlauf (Handy-Format, Testprofil)" {
flutter test integration_test/mobile_ui_screens_test.dart -d windows
}
} finally {
Remove-Item Env:PYRAMID_PROFILE_DIR -ErrorAction SilentlyContinue
}
Write-Host "Screenshots: build/ui_screens/ (Testinhalte ggf. mit test/live_ui_fixture_test.dart anlegen)"
}
}
Write-Host ""
Write-Host "━━ Zusammenfassung" -ForegroundColor Cyan
$results | Format-Table -AutoSize | Out-String | Write-Host
$failed = @($results | Where-Object { $_.Ergebnis -eq "FEHLER" })
if ($failed.Count -gt 0) {
Write-Host "✗ $($failed.Count) Schritt(e) fehlgeschlagen." -ForegroundColor Red
exit 1
}
Write-Host "✓ Alles grün." -ForegroundColor Green
exit 0