177 lines
11 KiB
Markdown
177 lines
11 KiB
Markdown
# Softwaretestbericht
|
|
|
|
Die hier dokumentierten Softwaretests führen keine
|
|
Proxmox-Installation aus und verändern keine Hostdatenträger, Paketquellen oder
|
|
Produktivdienste. Die noch offenen praktischen Prüfungen stehen in der
|
|
[Kompatibilitätsmatrix](compatibility.md).
|
|
|
|
## Gitea-Migration: 14. September 2026
|
|
|
|
Der aktuelle [Workflow](../.gitea/workflows/ci.yml) und die
|
|
[Einrichtungsanleitung](gitea-actions.md) verwenden Gitea Actions und die
|
|
Gitea Container Registry. Die Prüfung unter Windows mit Python 3.13.15 ergab:
|
|
|
|
- 120 CI-Skripttests bestanden: Veröffentlichungs-Opt-in, Ereignis- und Ref-Regeln,
|
|
Versionsabgleich, Registry-Adressen und Paket-Token sowie Build-, Smoke-,
|
|
Push- und Aufräumfehler. Der konstante Gitea-Wert `ref_protected=false`
|
|
verhindert bei gesetztem Opt-in keine Veröffentlichung mehr.
|
|
- 47 Anwendungstests bestanden; zwei Tests zur nativen Linux-Prozessüberwachung
|
|
wurden unter Windows übersprungen.
|
|
- Workflow-YAML, Shell-Syntax und JavaScript-Syntax wurden erfolgreich geprüft.
|
|
|
|
Im anschließenden [Gitea-Lauf 2](https://gitlab.bartelluis.de/BartelLuis/Proxmox-AIS-Server/actions/runs/2)
|
|
bestanden alle 169 Tests unter Linux; auch JavaScript- und Policy-Job waren
|
|
erfolgreich. Der JUnit-Upload scheiterte mit einem Timeout beim Aufruf von
|
|
`ArtifactService/CreateArtifact`. Der Workflow verwendet für alle Uploads nun
|
|
die vom Checkout erreichbare Gitea-URL statt der vom Runner gewählten
|
|
Artefakt- beziehungsweise Cache-Proxy-Adresse.
|
|
Diese Korrektur ist lokal geprüft; der erfolgreiche Artefakt-Upload sowie
|
|
Containerbuild und Registry-Push müssen im nächsten Gitea-Lauf bestätigt werden.
|
|
Die folgenden Ergebnisse dokumentieren den Stand vor dieser Migration.
|
|
|
|
## Automatisierte Prüfungen: 13. September 2026
|
|
|
|
Die 49 Anwendungstests wurden unter Windows mit Python 3.14 ausgeführt:
|
|
47 Tests bestanden; zwei Linux-spezifische Prozesstests wurden dort übersprungen.
|
|
Die 68 zusätzlichen CI-Skripttests bestanden unter Windows mit Git Bash.
|
|
Insgesamt enthält die Testsuite jetzt 117 Testfälle; der aktuelle Gesamtlauf
|
|
unter Windows/Python 3.14.7 ergab 115 bestandene und zwei übersprungene Tests.
|
|
Unter Linux/Python 3.13.15 bestanden alle 117 Tests über das migrierte
|
|
CI-Einstiegsskript `ci/python-tests.sh`, einschließlich der OpenSSH-Prüfung.
|
|
|
|
| Testgruppe | Umfang | Geprüftes Verhalten |
|
|
| --- | --- | --- |
|
|
| `tests/test_acceptance.py` | 14 bestanden | Authentifizierung, CSRF, Rollen und Vieraugenregel; Ablehnung unbekannter, gesperrter und widersprüchlicher Hosts; Gruppenzuordnung und Freigabeablauf; zehn parallele Antwortabrufe mit genau einem Lauf; unveränderliche Konfiguration; Enrollment, Signaturen, Nonce-Replay, fremde Läufe, Ereignisreihenfolge und Pflichtverifikation; Artefaktmanipulation; Verschlüsselung; Backup/Restore und Schlüsselprüfung; Abgleich verlassener Läufe erst nach Lease-Ablauf und ausdrücklicher lokaler Bestätigung |
|
|
| `tests/test_protocol.py` | 8 bestanden | Tatsächlicher Runner gegen die HTTP-API über einen Testtransport mit gültigen Ed25519-Signaturen; Check-/Apply-Abläufe, verlorene Abschlussantwort, simulierter Neustart, fehlgeschlagene Verifikation und Operatorfortsetzung, wiederholte Abbruchbestätigung, optionale Fehler mit verpflichtender Abschlussprüfung sowie redigierte Logs |
|
|
| `tests/test_runner.py` | Windows: 25 bestanden, 2 übersprungen; Linux-CI: 27 bestanden | Dauerhafte Checkpoints, Wiederaufnahme nach Unterbrechung, Ablauf von Leases, Rebootbudget, Queue- und Logbegrenzung, Secrets-Redigierung, Hashprüfung, TLS-Zwang, eigenständiger Starthelfer, lokale Hardwaremerkmale, echte OpenSSL-Signaturen, SSH-Schlüsselprüfung, Repositoryprüfung, Bash-Syntaxprüfung sowie Prozess-Timeout und Ausgaberedigierung |
|
|
| `tests/test_ci.py` | 68 bestanden | Veröffentlichung nur von geschützten Standardbranch-/Versions-Refs und erlaubten GitHub-Ereignissen; Release-Versionsabgleich; GHCR-Pfade; kein Push nach Build-/Smoke-Fehlern; Digest-Artefakte; temporäre Docker-Zugangsdaten und Image-Tags; Isolation nach Run-ID, Wiederholung und Job-ID; eigene Python-Testumgebung mit Aufräumen bei Erfolg und Fehlern; fehlende Host-Werkzeuge verhindern übersprungene Pflichtprüfungen |
|
|
|
|
Die API- und Protokolltests verwenden eine temporäre SQLite-Datenbank sowie
|
|
temporäre Schlüssel. Die Protokolltests führen die Runner-Steuerung und
|
|
Signaturprüfung aus; die eigentlichen Modulphasen werden simuliert. Runner-Tests
|
|
prüfen Bash-Syntax und eingebetteten Python-Code ohne Provisionierungsänderungen.
|
|
Das ist kein Nachweis für funktionierende Betriebssysteminstallation oder
|
|
erfolgreiche Konfiguration echter Proxmox-Dienste.
|
|
|
|
Unter Windows benötigt die Veröffentlichung von Bash-Modulen Git Bash.
|
|
Der vorhandene WSL-Bash-Starter ohne Linux-Distribution genügt nicht. Die Anwendung
|
|
erkennt die native Git-Bash-Installation für die Syntaxprüfung.
|
|
|
|
Alle Tests erneut ausführen:
|
|
|
|
```powershell
|
|
.\.venv\Scripts\python.exe -m pytest
|
|
```
|
|
|
|
Beim Testlauf können Upstream-DeprecationWarnings von Starlette/httpx und AnyIO
|
|
erscheinen. Sie sind von fehlgeschlagenen Tests zu unterscheiden.
|
|
|
|
## Containerprüfung
|
|
|
|
`proxmox-ais-server:0.1.0` wurde erfolgreich mit Python 3.13 und Debian slim
|
|
gebaut. Das Dockerfile fixiert die geprüfte Basis über den Digest
|
|
`sha256:9d2e5553305c7c7b0097999bb17187c69b921ccd6bc9d40e4bb5ebe652c00285`.
|
|
|
|
Ein kurzlebiger Container wurde mit schreibgeschütztem Dateisystem, deaktiviertem
|
|
Netzwerk und entfernten Linux-Capabilities gestartet. Die Prüfung ergab:
|
|
|
|
| Merkmal | Beobachtung |
|
|
| --- | --- |
|
|
| Benutzer | UID 10001 |
|
|
| Bash | `/usr/bin/bash`, GNU Bash 5.2.37 |
|
|
| OpenSSL | `/usr/bin/openssl`, OpenSSL 3.5.7 |
|
|
| CLI-Einstiegspunkt | `proxmox-ais`, Unterbefehle `init`, `serve`, `backup`, `restore` |
|
|
|
|
Auch Wheel-Erstellung und Installation wurden erfolgreich geprüft. In einem
|
|
früheren Linux-Testlauf im Anwendungsimage bestanden 48 Tests; ein Test wurde übersprungen, weil
|
|
`ssh-keygen` im Anwendungsimage nicht installiert ist. Die SSH-Schlüsselprüfung
|
|
wurde unter Windows ausgeführt. Der Linux-Lauf umfasste die POSIX-spezifischen
|
|
Prüfungen zur Prozessbeendigung nach Timeout und zur Redigierung von Ausgaben.
|
|
Der Testcontainer lief ohne Rootrechte, mit schreibgeschütztem Dateisystem,
|
|
entfernten Capabilities und `no-new-privileges`.
|
|
|
|
`tests/container_smoke.py` prüfte zusätzlich den installierten Dienst als echten
|
|
Prozess im Container: Anmeldung über TLS mit eigener vertrauenswürdiger Test-CA,
|
|
Ablehnung eines nicht vertrauten Zertifikats, CSRF, ausgelieferte Webdateien sowie
|
|
Erhalt von Hosts und Sitzungen nach einem Dienstneustart. Der Prozess lief als
|
|
UID 10001 mit schreibgeschütztem Root-Dateisystem, ohne Capabilities und mit
|
|
`no-new-privileges`; sämtliche Testdaten lagen in einem temporären Verzeichnis.
|
|
|
|
Die folgende Abfrage verändert weder Anwendungsdaten noch Konfiguration. Reproduzierbarer
|
|
Befehl für Bash unter Linux oder Git Bash:
|
|
|
|
```bash
|
|
docker run --rm --read-only --network none --cap-drop ALL \
|
|
--entrypoint python proxmox-ais-server:0.1.0 \
|
|
-c 'import os, shutil, subprocess; print(os.getuid()); print(shutil.which("bash")); print(shutil.which("openssl")); subprocess.run(["bash", "--version"], check=True); subprocess.run(["openssl", "version"], check=True)'
|
|
```
|
|
|
|
TLS-Reverse-Proxy, reale Provisionierungsnetze, Medienboot, Initialisierung und
|
|
Wiederherstellung in der späteren Betriebsumgebung müssen zusätzlich geprüft werden.
|
|
Ein erfolgreicher Image-Build allein ist keine Betriebsfreigabe.
|
|
|
|
## GitHub Actions und GHCR: historischer Stand
|
|
|
|
Der damalige Workflow verwendete GitHub-gehostete
|
|
Ubuntu-24.04-Runner, Python 3.13 und Node.js 24. Python- und JavaScript-Prüfung
|
|
müssen erfolgreich sein, bevor das Containerimage gebaut und getestet wird.
|
|
Die [Einrichtungsanleitung](github-actions.md) beschreibt Schutzregeln,
|
|
Paketberechtigungen und die erste Veröffentlichung.
|
|
|
|
Bei der Migration wurden die folgenden Prüfungen lokal ausgeführt:
|
|
|
|
- Die vollständige Windows-Testsuite bestand mit 115 erfolgreichen Tests;
|
|
zwei Linux-Prozesstests wurden plattformbedingt übersprungen.
|
|
- Unter Linux/Python 3.13.15 führte `ci/python-tests.sh` alle 117 Tests
|
|
erfolgreich als UID 10001 aus. Das Skript installierte die Abhängigkeiten
|
|
in einer eigenen virtuellen Umgebung, schrieb den JUnit-Bericht und
|
|
entfernte die Umgebung anschließend.
|
|
- Die 68 CI-Skripttests prüfen mit Docker- und Python-Testdoubles
|
|
GitHub-Ereignisse, geschützte Refs, Versionsabgleich, GHCR-Pfade,
|
|
Publish-Reihenfolge, Digest-Artefakte und Fehlerpfade. Run-ID, Wiederholung
|
|
und Job-ID isolieren temporäre Ressourcen. Ein Build- oder Smoke-Fehler
|
|
verhindert Registry-Anmeldung und Push.
|
|
- Die im Workflow eingebettete Veröffentlichungsentscheidung wurde mit
|
|
17 Fällen ausgeführt: geschützte Branches und Release-Tags, manueller Start,
|
|
andere Standardbranchnamen, Pull Requests, ungeschützte Refs, ungültige Tags
|
|
und Shell-Sonderzeichen im Ref-Namen.
|
|
- `actionlint` 1.7.12 prüfte den Workflow mit genau einer ausgenommenen
|
|
Schema-Meldung: Die aktuelle Version kennt `concurrency.queue` noch nicht.
|
|
`queue: max` wurde gegen die offizielle
|
|
[GitHub-Syntax](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency)
|
|
geprüft; die fehlende Linter-Unterstützung ist in
|
|
[actionlint #657](https://github.com/rhysd/actionlint/issues/657) dokumentiert.
|
|
Weitere Linter-Befunde gab es nicht.
|
|
- `node --check provisioner/static/app.js` und `docker compose config --quiet`
|
|
mit gesetzten Beispielwerten für Image und öffentliche URL waren erfolgreich.
|
|
- `ci/container.sh verify` lief mit GitHub-Umgebungsvariablen gegen den lokalen
|
|
Linux-Docker-Dienst 29.7.2. amd64-Build und Container-Smoke-Test bestanden:
|
|
vertrauenswürdiges TLS, Ablehnung eines fremden Zertifikats, Anmeldung,
|
|
CSRF, Webdateien sowie Erhalt von Hosts und Sitzungen beim Dienstneustart.
|
|
Das Skript erzeugte `build.env` und entfernte den temporären Image-Tag.
|
|
|
|
Ein tatsächlicher GitHub-Actions-Lauf einschließlich GHCR-Anmeldung,
|
|
Registry-Push und Artefakt-Upload wurde bei dieser lokalen Prüfung nicht
|
|
ausgeführt. Die Push-Fehlerpfade und Digest-Auswertung sind durch die
|
|
CI-Skripttests abgedeckt; die Paketberechtigungen und aktiven Schutzregeln
|
|
müssen im GitHub-Repository eingerichtet und beim ersten Lauf bestätigt werden.
|
|
|
|
## Browserprüfung
|
|
|
|
In Chromium wurden Anmeldung, alle neun Verwaltungsansichten, Hostanlage und
|
|
Hostbearbeitung, Geheimnisreferenzen, Gruppentoken, ISO-Registrierung und Buildbefehl,
|
|
Modulvorlagen, Skript- und Profilveröffentlichung, Installationsvorschau,
|
|
Freigabe, Abbruch, Laufabgleich, Benutzeranlage und Leserrechte durchgespielt.
|
|
Die mobile Ansicht bei 390 Pixeln wurde ebenfalls geprüft. Es traten keine
|
|
JavaScript- oder CSP-Fehler auf. Die separate Testkonfiguration verwendete
|
|
temporäre Daten und deaktivierte die Vieraugenregel für den Formulartest mit
|
|
einem Administrator; die Vieraugenregel wurde in den API-Tests geprüft.
|
|
|
|
## API-Artefakt
|
|
|
|
[openapi.json](openapi.json) wird über `create_app(Settings(...)).openapi()` aus
|
|
dem aktuellen Anwendungscode erzeugt. Der Export verwendet ausschließlich
|
|
temporäre Testverzeichnisse, keine produktiven Benutzer oder Schlüssel. Er
|
|
enthält Schemas und Endpunktbeschreibungen, keine Datenbankinhalte, Sessions oder
|
|
Geheimniswerte. Bei Änderungen an den API-Modellen muss der Export erneuert werden.
|