Un controllo verde che non confrontava nulla
Per settimane un controllo ha segnalato un successo senza mai confrontare due elementi. La parte più costosa non era la lacuna, ma il segno di spunta sopra di essa.
Ogni modifica allo schema di questo database arriva come file nel repository e viene applicata al momento del merge. Per evitare che i file e la produzione divergano, viene eseguito ogni giorno un controllo chiamato «i file e il registro remoto corrispondono». Per settimane ha segnalato un successo.
Non confrontava nulla. Il comando eseguito stampa una tabella e termina con successo qualunque cosa dica la tabella. Un controllo il cui percorso di errore non viene mai eseguito non è un controllo: è un segno di spunta sul quale tutti fanno affidamento.
Che cosa avrebbe dovuto rilevare
Quando il repository è stato trasferito in un’organizzazione, l’integrazione del database è rimasta collegata al vecchio account. Quel pomeriggio sono state unite nove pull request e nessuna ha raggiunto il database. Nulla ha dato errore: i controlli erano verdi e i merge puliti. L’unico indizio era il confronto tra 110 file e 109 righe nel registro.
Una migrazione unita sembra applicata semplicemente perché il merge è riuscito.
Oggi il controllo legge le versioni applicate tramite la Management API, le confronta con i file e fallisce in tre casi: una versione applicata senza file, un file precedente alla versione applicata più recente che non è mai stato eseguito e un file unito ma mai applicato. Quando non può verificare, fallisce invece di limitarsi ad avvertire — perché un rilevatore cieco che segnala un successo è esattamente il problema che deve impedire.
Chi controlla il controllo
La seconda lezione era meno comoda. I controlli vengono eseguiti dallo stato del branch che stanno verificando. Una pull request può quindi indebolire una garanzia e riscrivere nello stesso diff il test che la protegge — per poi essere unita con tutti i controlli verdi. Dalla fine di agosto il piano di controllo — workflow, script, configurazione dei test e file delle dipendenze — viene giudicato da un controllo che non esegue mai il checkout del branch e prende la propria definizione dal branch principale. Una modifica che tocca questa superficie richiede un’etichetta applicata da una persona; un’etichetta applicata da un bot viene rifiutata, perché una volta ha funzionato proprio così.
Alla prima versione sono seguite sei correzioni, ciascuna derivata da una lacuna misurata. Una di queste: un test di completezza contava i nomi invece degli oggetti file e, poiché una rinomina produce due nomi, il conteggio sembrava completo mentre un file protetto passava senza essere controllato. La forma generale è la vera lezione: una calibrazione che può essere soddisfatta dalla quantità sbagliata equivale a nessuna calibrazione.
Punto aperto e registrato: questo controllo non è ancora configurato come obbligatorio. Segnala i problemi, ma non blocca nulla. È un elemento della lista, non una frase da omettere.