/* 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);