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]>
This commit is contained in:
2026-09-01 21:59:36 +02:00
co-authored by Claude Opus 5
parent da49a227f1
commit 15cfee1078
17 changed files with 124 additions and 4 deletions
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 984 KiB

After

Width:  |  Height:  |  Size: 984 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 921 KiB

After

Width:  |  Height:  |  Size: 921 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 KiB

After

Width:  |  Height:  |  Size: 757 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 890 KiB

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 KiB

After

Width:  |  Height:  |  Size: 858 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1014 KiB

After

Width:  |  Height:  |  Size: 1013 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 KiB

After

Width:  |  Height:  |  Size: 924 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 KiB

After

Width:  |  Height:  |  Size: 324 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

+39 -4
View File
@@ -1,5 +1,25 @@
/* Misst die einzelnen Teile der Kopfleiste auf dem Handy -- damit die
Reparatur an der richtigen Stelle ansetzt und nicht geraten wird. */
/* Misst die einzelnen Teile der Kopfleiste auf dem Handy -- damit eine
Reparatur an der richtigen Stelle ansetzt und nicht geraten wird.
SIE PRUEFT SEIT DEM 01.09.2026 AUCH, statt nur zu messen.
Vorher war sie ein reines Messwerkzeug: Sie druckte Zahlen und endete
IMMER mit Exitcode 0. Damit stand sie als "pruef-..." im Ordner der
Pruefungen, lief bei jedem Gesamtlauf mit, meldete "in Ordnung" --
und konnte gar nicht fehlschlagen. Aufgefallen ist das erst, als der
Gesamtlauf die ANZAHL der Einzelpruefungen mitzaehlte: Diese Datei
kam auf null.
Eine Pruefung, die immer bestaetigt, bestaetigt nichts. Die beiden
Zahlen, um die es geht, wurden laengst gemessen -- sie werden jetzt
auch beurteilt:
UEBERSTAND muss 0 sein (waagerechtes Scrollen ist auf
einem Handy der schlimmste Fehler)
ABMELDEN ERREICHBAR muss wahr sein -- es ist der einzige Weg wieder
heraus; liegt er ausserhalb des Bildes, sitzt
man fest.
Die Messwerte werden weiterhin gedruckt: Sie sagen bei einem
Fehlschlag sofort, WELCHES Teil zu breit ist. */
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
@@ -18,6 +38,9 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(
await import("./index.js");
await new Promise((r) => setTimeout(r, 700));
const BASIS = "http://127.0.0.1:4179";
let fehler = 0;
let geprueft = 0;
setTimeout(() => { console.log("ABBRUCH"); process.exit(1); }, 120_000).unref?.();
await fetch(BASIS + "/workspace/api/anmelden", {
@@ -66,7 +89,13 @@ for (const breite of [320, 390, 430]) {
})(),
};
});
console.log(`\n--- ${breite}px (Überstand ${r.ueber}px, Abmelden erreichbar: ${r.abmeldenSichtbar})`);
/* Erst beurteilen, dann drucken -- die Messwerte darunter sind die
Begründung, falls es schiefgeht. */
geprueft++;
const gut = r.ueber <= 0 && r.abmeldenSichtbar === true;
if (!gut) fehler++;
console.log(` ${gut ? "ok " : "FEHL"} ${breite}px: Überstand ${r.ueber}px, `
+ `Abmelden erreichbar: ${r.abmeldenSichtbar}`);
for (const t of r.kinder) console.log(` ${t.was.padEnd(34)} b=${String(t.breite).padStart(4)} rechts=${t.rechts}`);
console.log(" darin:");
for (const t of r.rechtsKinder) console.log(` ${t.was.padEnd(32)} b=${String(t.breite).padStart(4)} rechts=${t.rechts}`);
@@ -74,4 +103,10 @@ for (const breite of [320, 390, 430]) {
}
await browser.close();
try { rmSync(ordner, { recursive: true, force: true }); } catch {}
process.exit(0);
/* Die Anzahl gehoert in die BEDINGUNG, nicht nur in den Meldetext:
Waere die Schleife nie gelaufen, waere "0 Fehler" sonst ein Erfolg. */
console.log(`
${geprueft} Breiten gemessen, ${fehler} beanstandet.`);
if (!geprueft) { console.log(" FEHL keine einzige Breite gemessen"); fehler++; }
console.log(fehler ? "NICHT in Ordnung." : "Alles in Ordnung.");
process.exit(fehler ? 1 : 0);
+85
View File
@@ -0,0 +1,85 @@
/* 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);