Naar de inhoud

Blog ·

Een run die zijn eigen fout afdrukte

De verificatieronde schreef elke exitcode in een samenvatting en schreef daarna hoe dan ook DONE. Een release ging over een rode regel die niemand las.

Door Provibr

Vóór een release draaien we één script. Het voert de webtestsuite uit, de suites van de packages, de gateway en de tools, tien typecontroles, de lint, de contentcontrole, de protocollint en de protocolcodegeneratie, en het schrijft per stap één regel in een samenvattingsbestand: de naam van de stap en zijn exitcode. Daarna schrijft het DONE.

Het schreef DONE ook als sommige van die exitcodes niet nul waren.

Op zeven september ging er een release uit terwijl er in de samenvatting een regel stond die luidde bun test packages/gateway/tools exit 1. Ik had de tellers voor geslaagd en gefaald van twee suites gelezen en die van de derde niet. Er ging niets stuk: de falende test was een bewaking op de kopregels van meetscripts, dus het product werd niet geraakt en de klant heeft nooit iets gezien. De uitkomst was prima en de vorm was fout, en de vorm is het enige deel dat het waard is om op te schrijven.

De tellers zijn de poort niet

Dat dit gênant is en niet alleen pech, komt doordat de faalvorm in onze eigen aantekeningen een naam heeft, en die naam is vacuüs groen: een controle die niet aan een beslissing vastzit wordt niet gelezen, en een controle die met het oog gelezen wordt, wordt gelezen zoals een mens leest, namelijk zoekend naar wat hij verwacht te zien.

De samenvatting was gemaakt om overheen te scannen. Elke suite drukt zijn eigen totalen ergens hoger af, dus de natuurlijke beweging is om naar "4515 pass, 0 fail" te kijken en zich klaar te voelen. De exitcodes stonden één scherm lager in een bestand waarvan de laatste regel DONE zei.

De reparatie is vier woorden shell. Na alle stappen grept het script zijn eigen samenvatting op elke exitcode tussen één en negen, en vindt het er een, dan zet het er een regel achter die met FAIL: begint. De regel die daarbij hoort is dat een DONE zonder FAIL de poort is, en dat de tellers dat niet zijn. De tweede helft van die regel telt zwaarder dan de eerste: wie een goedkoop en juist signaal heeft, houdt op met dure gewoontes bouwen rond een onbetrouwbaar signaal.

Er hoort een tweede regel bij: een deploycommando deelt nooit een shellketen met een verificatie die alleen afdrukt. Kan de verificatie de keten niet laten falen, dan is ze documentatie.

Wat er werkelijk rood stond

De bewaking die faalde hoort bij een familie, en het is de moeite waard hem te beschrijven omdat hij ongewoon goedkoop is voor wat hij oplevert.

In de gatewaymap staan de meetscripts: browsersweeps, layoutprobes, zaai- en opruimgereedschap, de dingen die een ronde schrijft om iets te bewijzen en daarna achterlaat. Het zijn er vandaag ruim vijfhonderd. Het zijn kale scripts zonder typecontrole, wat betekent dat het enige dat tussen hen en verrotting staat is dat iemand er toevallig een draait.

Vier zeven lopen er in een gewone testsuite overheen:

  1. Elk script parseert, met de runtime die het werkelijk draait.
  2. Elke relatieve import komt uit op een bestand dat bestaat. Dat is de vorm van dood die een parser niet kan zien: het script klopt syntactisch en valt bij het draaien om op de eerste regel.
  3. Elk script draagt een kopregel met proza erin. Zonder uitleg is een gereedschap van vier rondes geleden niet te onderscheiden van een dat er nog toe doet.
  4. Elke kopregel noemt de ronde waar hij uit komt, in precies een van twee vaste vormen.

De vierde stond rood. Drie scripts uit de documentatieronde hadden kopregels, goede zelfs, en geen rondemarkering. Dat is het hele incident: een naamgevingsafspraak, gevangen door een bewaking die bestaat zodat vijfhonderd scripts leesbaar blijven, in een samenvattingsregel die niemand las.

Waarom onbekend een commit-hash moet kosten

De vierde zeef accepteert twee vormen en verder niets. Of de kopregel noemt de rondenaam met een datum en waar die toeschrijving vandaan komt, of hij zegt dat de ronde onbekend is en draagt de commit-hash van de eerste commit van het bestand, met een datum.

De naam mag uitdrukkelijk niet het woord onbekend zijn. Zonder die uitsluiting is "ronde onbekend, 2026-09-04" een volstrekt geldige naam-met-datum, en is de dure tak met één woord te vermijden. Zoals het nu staat kost het toegeven dat je het niet weet jou een hash die iemand moet gaan opzoeken, en tegen de tijd dat hij hem opgezocht heeft kent hij de ronde meestal.

De datum is verplicht om een andere reden. Een kale naam is proza en geen markering: een zin als "de ronde die ook het kopregelwerk raakte" bevat een rondenaam en beweert niets over het bestand waarin hij staat. Met een datum erbij wordt het een bewering over dit script, gedaan op een dag, en dat is het kleinste waar je iemand aan kunt houden.

Een poort moet op nul kunnen staan

De voor de hand liggende vraag bij vijfhonderd ongetypeerde scripts is waarom we ze niet typecontroleren. Dat hebben we gemeten, en het antwoord is leerzaam.

De configuratie bestaat. Ze is een instrument en geen poort, en ze draait niet in het verificatiescript. Gemeten over de scripts zoals ze waren:

ConfiguratieFouten
Met de strikte instellingen van deze workspace3180
Zonder strikt398
Zonder strikt, nadat één gedeeld bestand typeerbaar was gemaakt159

Een poort moet op nul staan, en die resterende 159 zijn grotendeels geen defecten. Twee families zijn nagelopen en allebei bleken ze artefacten van ongetypeerde code typeren: een parameter zonder standaardwaarde die uit de afgeleide vorm valt, en een destructurerende lus over een gemengde array die tot een union verbreedt. Zevenentwintig ervan zijn een en dezelfde diagnose, over het importeren van een TypeScript-bestand vanuit een script dat onder een loader draait die daar prima mee omgaat.

Wat het instrument wel opleverde is de stap van 398 naar 159. Eén regel in een gedeelde browserhulp, een constructor die zijn argumenten in bulk op de instantie zet, hield 239 fouten in leven, want elke eigenschapstoegang op dat object in elk script was onherleidbaar. Eén reparatie, 239 fouten weg. Dat is een goed rendement voor een meting die niet nul mag zijn, en het is precies het soort rendement dat je van een poort niet krijgt, want een poort waaraan niet te voldoen is wordt uitgezet.

De controle die zijn eigen runtime mat

De parsecontrole aan de praat krijgen kostte twee pogingen, en allebei faalden ze op manieren die eruitzagen als productproblemen.

De eerste versie vroeg de huidige runtime om elk bestand te controleren. Onder onze testloper is de huidige runtime niet de runtime waar de scripts onder draaien, en zijn controlevlag betekent iets heel anders. Het resultaat was 301 meldingen van syntactisch kapotte bestanden, met bronregels geciteerd als fouttekst. Elk van die bestanden was in orde.

De tweede versie noemde de juiste runtime uitdrukkelijk en faalde alsnog, anders: de testloper ruimt kindprocessen op die bij een test horen, en vanaf ongeveer halverwege de lijst kwam elke aanroep terug met een null-status. Gedood door een signaal, geen parsefout. Een bewaking die willekeurig rood wordt is geen bewaking.

De versie die werkt start één kindproces dat de bestanden zelf controleert, acht tegelijk, in ongeveer negen tiende seconde toen dat gemeten werd. Wat er beweerd wordt is onveranderd: of de runtime die deze scripts draait ze accepteert.

Het parallellisme is ook geen aardigheidje. Serieel gedraaid liep de controle over de tijdslimiet per test heen, en een bewaking die een timeout krijgt leest als een kapotte bewaking en niet als een trage.

De ondergrens waar niemand om vraagt

Er staat in dat bestand een vijfde test die alleen beweert dat er meer dan vijftig scripts te controleren zijn.

Een mappenlezer die niets vindt maakt elke bewering erna triviaal waar. Hernoem de map, wijzig het extensiefilter, breek de lezer, en vier groene zeven rapporteren over een lege lijst. De ondergrens ligt bewust ver onder het werkelijke aantal, want het doel is niet opruimen tegenhouden; het doel is het verschil tussen "er is niets mis" en "er is niets onderzocht" zichtbaar maken.

Datzelfde testbestand is eerlijk over zijn grenzen, en die eerlijkheid hoort bij het ontwerp. Geen van de vier zeven bewijst dat een script nog steeds meet wat het beweert te meten. Een selector die niet meer bestaat, een route die verhuisd is, een kolom die geschrapt is: alle vier de controles slagen. Het is een vloer en geen typecontrole, en dat in het bestand zeggen weerhoudt de volgende persoon ervan een groene run voor meer aan te zien dan hij is.

Wat we zouden opschrijven

  1. Een verificatie die alleen afdrukt is geen poort. Ze moet datgene wat erna komt kunnen laten falen.
  2. Schrijf de faalregel, niet alleen de exitcodes. De poort is een woord waar iemand op kan grepen, op een vaste plek, en geen getal dat hij moet opmerken.
  3. Zet nooit een deploy achter een controle die hem niet kan tegenhouden. De keten is de belofte.
  4. Tellers zijn een samenvatting, geen oordeel. Mensen lezen het getal dat ze verwachten te zien.
  5. Een poort moet op nul kunnen staan. Kan een meting dat niet, houd haar dan als instrument en zeg dat erbij, anders wordt ze uitgezet en daarna genegeerd.
  6. Maak de goedkope ontsnapping uit een regel duur. Kost onwetendheid toegeven één woord, dan schrijft iedereen dat woord.
  7. Een controle die willekeurig faalt is geen controle. Jaag op de wispelturigheid voordat je het signaal vertrouwt.
  8. Beweer een ondergrens over wat de mappenlezer vond. Vier groene controles over een lege lijst zien er precies zo uit als vier groene controles.

Voor de duidelijkheid over wat dit is: de faalregel zit in het script dat in de repository staat, en hij heeft sindsdien over merges gelopen die groen waren. Hij is nog niet bewezen door een rode run in dagelijks gebruik, alleen door de samenvatting waartegen hij geschreven is. De typeringscijfers komen uit één meting op één dag en het aantal bestanden verschuift elke nacht.

Uit het platformwerk aan Provibr. Een andere bewaking die haar eigen nul moest bewijzen staat in een toegankelijkheidsuitzondering die zichzelf meet, en een veld dat stilletjes een intentie droeg in plaats van een feit staat in een datum in de toekomst is geen agenda.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.