Mutantenstufe der Plankritik nach der Pruefung vom 2026-09-28: Netzsperre per unshare, ungepufferte Ausgabe, Zeitlimit je Mutant 120 s, Aufraeumen bei SIGTERM, Modus-Zeile, mutanten_status, Faelle und Treiberfall 35
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
bc9b4f4497
commit
b1ad461acf
8 files changed
+336
-49
No files matched your search
@@ -125,6 +125,10 @@ Die Meldung ist `longrepr.reprcrash.message`, wenn es das gibt, sonst die erste
|
||||
| `ZEIT` | Zeitlimit überschritten |
|
||||
| `MUSTER` | Muster nicht genau einmal gefunden, nichts gefahren |
|
||||
|
||||
**Modus-Zeile (seit 2026-09-28, Nachbesserung N5):** Der Wrapper `mutanten_lauf_kopie.sh` schreibt vor dem eigentlichen Lauf eine eigene Zeile, unabhängig von `mutanten_lauf.py` selbst: `modus: voll` oder `modus: muster (nur Musterpruefung, kein Mutant gefahren)`. Damit weiß eine Linse, die nur die Rohausgabe sieht, ob überhaupt ein Mutant gefahren ist, bevor sie ein `OK` bewertet.
|
||||
|
||||
**SIGTERM (seit 2026-09-28, Nachbesserung N4):** `mutanten_lauf.py` registriert einen eigenen Handler für `SIGTERM`, der eine Ausnahme auslöst, damit die laufenden `finally`-Blöcke greifen: der zuletzt angewendete Mutant wird per SHA-Probe zurückgesetzt, ein laufender pytest-Prozess wird über seine Prozessgruppe beendet, und die Temp-Ordner (`mutanten_lauf_home_*`, `mutanten_lauf_plugin_*`) sowie die Ergebnisdatei werden geräumt. Vor dem Ende steht die Zeile `ABBRUCH: SIGTERM, Mutant <id> zurueckgesetzt` (oder ohne den Mutant-Teil, wenn beim Signal noch keiner lief). Der Exit-Code ist in diesem Fall 3. Geprüft durch Treiber-Fall 35.
|
||||
|
||||
Ausgabe auf stdout, UTF-8, je Mutant eine Zeile: `D1 OK DA::test_x=ROT(<meldung, 120 Zeichen>) …`. Tests erscheinen in der Kurzform aus `rot_bei`. Ein vorhandener `hinweis` folgt in der nächsten Zeile, eingerückt. Oben stehen Wurzel, Mutantendatei, Anzahl gesamt und ausgewählt und je Interpreter die Python-Version. Unten eine gerechnete Zusammenfassung: `ergebnis: <n> Mutanten, <a> OK, <b> LUECKE, <c> UNKLAR, <d> ZEIT, <e> MUSTER`.
|
||||
|
||||
`--bericht` schreibt dasselbe als JSON: `{"wurzel", "mutanten_datei", "befunde": [...], "grundlinie": {knoten: {ergebnis, meldung}}, "mutanten": [{"id", "datei", "status", "hinweis", "treffer", "tests": [{"eintrag", "knoten", "ergebnis", "meldung"}]}], "zusammenfassung": {...}}`. Der Bericht wird auch bei einem Abbruch geschrieben, mit allem, was bis dahin feststand.
|
||||
@@ -146,6 +150,8 @@ Jeder pytest-Aufruf bekommt eine Kopie der Umgebung mit diesen Änderungen:
|
||||
- `http_proxy`, `https_proxy`, `all_proxy` und dieselben in Großschrift zeigen auf `http://127.0.0.1:9`; `no_proxy` und `NO_PROXY` werden entfernt. Bibliotheken, die Proxy-Variablen lesen, laufen damit gegen einen geschlossenen Port.
|
||||
- `PYTHONDONTWRITEBYTECODE=1`, `COLUMNS=300`, `MUTANTEN_LAUF_ERGEBNIS=<temp-datei>`, `PYTHONPATH` mit dem Plugin-Ordner vorn.
|
||||
|
||||
**Netzsperre (seit 2026-09-28, Nachbesserung N1):** Der Wrapper `mutanten_lauf_kopie.sh` startet `mutanten_lauf.py` selbst unter `unshare --map-current-user --net`, nicht erst den einzelnen pytest-Aufruf. Gemessen in WSL Debian als Benutzer `claude` (util-linux 2.41.5): Die UID bleibt innen wie außen 1000, es gibt nur die Schnittstelle `lo`, `connect` auf eine Adresse außerhalb von localhost endet mit `OSError` (errno 101) oder `gaierror`. Nicht `-r` (macht UID 0, könnte Rechte-Tests der Mutanten selbst verfälschen). Fehlt `unshare` ohne Netz, bricht der Wrapper vorher mit `MUTANTEN_LAUF_FEHLER: unshare ohne Netz nicht moeglich` ab, statt einen ungesperrten Lauf durchzulassen.
|
||||
|
||||
**Was das nicht abdichtet:** einen Unterprozess mit absolutem Pfad (so kam der Vorfall vom 2026-09-26 zustande), einen Socket ohne Proxy, einen Client mit `trust_env=False` oder mit eigenem Transport, Dateien mit absolutem Pfad außerhalb von `HOME`. Die eigentliche Sperre bleibt die Netzsperre der Testdateien selbst und eine Kopie ohne Geheimnisdateien (`ohne`).
|
||||
|
||||
Alle Temp-Ordner liegen außerhalb der Wurzel und werden am Ende entfernt, auch nach einem Abbruch.
|
||||
@@ -190,6 +196,7 @@ Der Treiber baut in einem Temp-Ordner ein kleines Projekt (ein Modul, eine Testd
|
||||
| 32 | Abdichtung: ein Test prüft, dass `HOME` nicht das echte ist und `https_proxy` gesetzt ist | Grundlinie grün, Exit 0 |
|
||||
| 33 | `--bericht` schreibt gültiges JSON mit den Status aus Fall 2 | Datei lesbar, Status stimmt |
|
||||
| 34 | `python_je_datei` setzt für eine Testdatei einen zweiten Interpreter (derselbe Pfad über einen anderen Namen, etwa eine Verknüpfung im Temp) | Exit 0 |
|
||||
| 35 | ein Mutant hängt, der Läufer bekommt nach drei Sekunden SIGTERM (eigenes `TMPDIR`), seit 2026-09-28 | Zeile `ABBRUCH: SIGTERM`, kein Prozess mit `HOME` im Fall-Tmpdir, keine `mutanten_lauf_*`-Reste, Zieldatei byte-gleich |
|
||||
|
||||
Der Treiber gibt je Fall eine Zeile aus (`Fall 5 ok` oder `Fall 5 FEHLER: erwartet …, bekommen …`) und am Ende die gerechnete Zahl der Fehler. Exit 0 nur, wenn alle Fälle wie erwartet ausgehen und jedes Mal byte-gleich zurückgesetzt wurde.
|
||||
|
||||
|
||||
Reference in new issue
Block a user