Test porovnává vlastní výstup místo commitnutého artefaktu
import { Aside } from ‘@astrojs/starlight/components’;
Symptom
Sekce “Symptom”Izolovaná validační suite (síťové namespaces) hlásila 100 % zelených testů pro přechod firewallového profilu. Nezávislý audit ale zjistil, že testovací prostředí mělo klíčová pravidla na jiných pozicích než commitnutý očekávaný manifest — a test si toho nevšiml. Po opravě se ukázalo, že commitnutá predikce pozic byla špatně o jedna a produkční okno by skončilo STOPem ochranné brány.
Root cause
Sekce “Root cause”Dvě vrstvy téhož problému:
- Sebe-potvrzující smyčka: test si očekávaný manifest vygeneroval z živého stavu testovacího prostředí a vzápětí proti němu tentýž stav ověřil. Jakákoli chyba se reprodukuje na obou stranách porovnání → vždy zelená.
# ŠPATNĚE: derive čte živý stav → apply porovnává týž živý stavdump_state > pre.txtderive-expected pre.txt outdir/ # očekávání vzniká ZA BĚHUapply --verify-against outdir/ # „ověřeno“ = tautologie- Skrytý off-by-one: predikce pozic pravidel po
ufw reloadpočítala s tím, že jump na uživatelský řetěz je součástíbefore.rules. Není — framework ho přidává až za obsah souboru. Pár vložený na konec souboru tedy skončí na pozicích 13/14 (jump 15), ne 14/15 (jump 16). Dvojznačná inventurní věta „13 pravidel → jump“ (12 + jump počítáno jako 13) chybu založila; tautologický test ji zakonzervoval.
Fix
Sekce “Fix”- Testovací prostředí přestavěno na věrnou repliku produkční transformace (pravidla v pořadí konfiguračního souboru, framework-jump přidán až za ně, reálná velikost ipsetů) a všechny brány běží proti commitnutým manifestům z gitu:
# SPRÁVNĚ: očekávání je fixní artefakt z repacp "$REPO/manifests/"* "$MDIR/"dump_state > measured.txtcmp <(strip_header measured.txt) <(strip_header "$MDIR/EXPECTED.txt") # byte-shodaapply --verify-against "$MDIR" # brána = artefakt-
Generátor očekávaných manifestů zůstal, ale jen jako explicitní gen-mode (
GEN_DIR=… test.sh), který se ukončí bez validačních tvrzení a jehož výstup se musí commitnout a auditovat — běh s generací nikdy neplatí jako důkaz. -
Predikce pozic korigována měřením: hash konfiguračního souboru zapsán do testu, pořadí „obsah souboru → framework-jump“ doloženo živým stavem.
Lekce
Sekce “Lekce”- Zelená suite nic neznamená, pokud očekávání vzniká ve stejném běhu jako měření.
- Off-by-one v predikci pozic vzniká snadno z dvojznačného počítání „N pravidel + jump“.
- Framework-managed pravidla (ufw, docker) se do konfiguračních souborů nepromítají — pořadí po reloadu je nutné doložit měřením, ne odhadem.