Files
dogfather-universe/tools/alles-pruefen.mjs
T
DogFatherGitandClaude Opus 5 15cfee1078 Gesamtlauf aller Pruefungen -- und eine Pruefung, die nichts geprueft hat
Auf "CHECK MAL AB, DASS ALLES PERFEKT LAEUFT. ALLES."

Ergebnis: 29 von 29 Pruefdateien in Ordnung, 1178 von 1178 Einzelpunkten
bestanden. Der Server laeuft ohne Neustart, alle 33 oeffentlichen Seiten
antworten, keine Schnittstelle gibt ohne Anmeldung etwas heraus.

DER EIGENTLICHE FUND WAR EINE PRUEFUNG, DIE NICHTS GEPRUEFT HAT.

tools/alles-pruefen.mjs zaehlt nicht nur gruen/rot, sondern die ANZAHL
der Einzelpruefungen je Datei -- und pruef-kopf-messen.mjs kam auf NULL.
Sie war nie eine Pruefung, sondern ein reines Messwerkzeug: Sie druckte
Zahlen und endete IMMER mit Exitcode 0. Weil sie "pruef-..." heisst, lief
sie bei jedem Gesamtlauf mit und meldete brav "bestanden". Sie konnte
gar nicht fehlschlagen.

Mit blossem Auge war das nicht zu sehen: Der Lauf war gruen, die Datei
stand unauffaellig zwischen den anderen. Aufgefallen ist es nur, weil
die Zahl mitgezaehlt wurde -- ein gruener Lauf ist eben kein Beweis,
solange nicht auch die Anzahl stimmt.

ZWEI KONSEQUENZEN:

1. Die Datei prueft jetzt wirklich. Die beiden Zahlen, um die es geht,
   wurden laengst gemessen und werden nun auch beurteilt:
     UEBERSTAND          muss 0 sein
     ABMELDEN ERREICHBAR muss wahr sein -- es ist der einzige Weg wieder
                         heraus; liegt er ausserhalb des Bildes, sitzt
                         man fest.
   Die Messwerte bleiben in der Ausgabe: Sie sagen bei einem Fehlschlag
   sofort, WELCHES Teil zu breit ist.
   Gegenprobe gemacht: Mit einer unerfuellbaren Bedingung meldet sie
   "3 Breiten gemessen, 3 beanstandet" und endet mit 1. Sie kann also
   anschlagen -- vorher nicht.

2. Der Laeufer wertet "0 Pruefungen" ab jetzt als FEHLER, nicht als
   Erfolg. Sonst haette dieselbe Falle beim naechsten Mal wieder
   jemanden getaeuscht.

Der Laeufer selbst bleibt im Ordner tools/: Er faengt einen Fehlschlag
je Datei ab (statt beim ersten abzubrechen), zeigt die Dauer mit -- eine
Pruefung, die ploetzlich dreimal so lange braucht, wartet meist auf
etwas, das es nicht mehr gibt -- und druckt am Ende die Gesamtzahl.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 21:59:36 +02:00

86 lines
3.4 KiB
JavaScript

/* Laesst JEDE Pruefung laufen und zaehlt mit.
WARUM EIN EIGENER LAeUFER und nicht eine Zeile in der Shell:
1. DIE ANZAHL MUSS STIMMEN. Ein gruener Lauf ist kein Beweis, solange
nicht auch die Zahl der Pruefungen stimmt -- eine Datei, die still
nicht startet, faellt sonst niemandem auf. Hier wird jede Datei
einzeln gezaehlt, und die Gesamtzahl der Einzelpruefungen steht am
Ende.
2. EIN FEHLSCHLAG DARF DEN LAUF NICHT ABBRECHEN. Sonst sieht man den
ersten Fehler und weiss nichts ueber die restlichen zwanzig.
3. DIE DAUER GEHOeRT DAZU. Eine Pruefung, die ploetzlich dreimal so
lange braucht, ist meist eine, die auf etwas wartet, das es nicht
mehr gibt.
*/
import { readdirSync } from "node:fs";
import { spawn } from "node:child_process";
import { join } from "node:path";
const ORDNER = "server";
const dateien = readdirSync(ORDNER)
.filter((n) => n.startsWith("pruef-") && n.endsWith(".mjs"))
.sort();
console.log(`${dateien.length} Pruefdateien gefunden\n`);
const laufen = (datei) => new Promise((fertig) => {
const start = Date.now();
const kind = spawn(process.execPath, [join(ORDNER, datei)], {
stdio: ["ignore", "pipe", "pipe"],
});
let aus = "";
kind.stdout.on("data", (d) => { aus += d; });
kind.stderr.on("data", (d) => { aus += d; });
kind.on("close", (code) => {
const sek = Math.round((Date.now() - start) / 100) / 10;
const einzeln = (aus.match(/^\s{2}(ok|FEHL)\s/gm) || []).length;
const schlecht = (aus.match(/^\s{2}FEHL\s/gm) || []).length;
fertig({ datei, code, sek, einzeln, schlecht, aus });
});
});
let gesamt = 0, kaputt = 0, einzelnGesamt = 0, einzelnSchlecht = 0;
const fehlerhafte = [];
for (const datei of dateien) {
const r = await laufen(datei);
gesamt++;
einzelnGesamt += r.einzeln;
einzelnSchlecht += r.schlecht;
/* NULL PRUEFUNGEN IST EIN FEHLER, KEIN ERFOLG.
Beim ersten Lauf stand hier nur `code === 0 && schlecht === 0` --
und pruef-kopf-messen.mjs kam damit als "ok" durch, obwohl sie
ueberhaupt nichts geprueft hat (sie war ein reines Messwerkzeug und
endete immer mit 0). Genau so sieht eine Pruefung aus, die immer
bestaetigt: gruen, und wertlos. */
const gut = r.code === 0 && r.schlecht === 0 && r.einzeln > 0;
if (!gut) { kaputt++; fehlerhafte.push(r); }
console.log(
`${gut ? " ok " : " FEHL "} ${r.datei.padEnd(30)}`
+ `${String(r.einzeln).padStart(4)} Pruefungen`
+ `${r.schlecht ? `, ${r.schlecht} FEHLGESCHLAGEN` : ""}`
+ ` ${String(r.sek).padStart(6)} s`
+ (r.einzeln === 0 ? " KEINE PRUEFUNG GELAUFEN" : ""));
}
console.log("\n" + "=".repeat(64));
console.log(`Dateien: ${gesamt - kaputt} von ${gesamt} in Ordnung`);
console.log(`Einzelpunkte: ${einzelnGesamt - einzelnSchlecht} von ${einzelnGesamt} bestanden`);
/* Eine Datei ohne eine einzige Pruefung ist ein Fehler, kein Erfolg. */
const leer = dateien.length && einzelnGesamt === 0;
if (leer) console.log("ACHTUNG: keine einzige Pruefung ist gelaufen.");
for (const r of fehlerhafte) {
console.log("\n" + "-".repeat(64));
console.log(`### ${r.datei} (Exitcode ${r.code})`);
const zeilen = r.aus.split("\n").filter((z) => /FEHL|Error|error:/.test(z));
console.log(zeilen.slice(0, 12).join("\n") || r.aus.slice(-800));
}
console.log("\n" + (kaputt || leer ? "NICHT in Ordnung." : "Alles in Ordnung."));
process.exit(kaputt || leer ? 1 : 0);