Enginetoets

De enginetoets vergelijkt twee commits van dezelfde branch op hun uitkomst, onder dezelfde instellingen en dezelfde data, zodat elk verschil een verschil in de rekenwijze of de invoer is. Hij vervangt het lezen van de code als beoordeling van een wijziging: wie de code niet kan lezen, kan wel een instellingentabel, een lijst van commits en een gemeten verschil in modeltermen beoordelen.

Drie klassen wijziging, drie soorten bewijs

Een wijziging in de configuratie valt in een van drie klassen, en elke klasse heeft een eigen bewijs.

klasse bewijs wie beoordeelt
instelling een tabel met per instelling het pad, de oude waarde en de nieuwe waarde de opdrachtgever, per regel
data de lijst van leveringen met hun datum de opdrachtgever, bevestigt
engine het gemeten verschil onder bevroren instellingen en data, in modelindicatoren de ontwikkelaar levert het, de opdrachtgever leest het

De eerste twee komen uit de tekst van de configuratie, zonder run. De derde vraagt een run, en die is alleen zuiver wanneer instellingen en data vastliggen. Daarvoor dient de baseline.

Een branch, een log

Een project is een branch van de repo, en de toets vergelijkt alleen binnen die branch: een commit tegen de commit ervoor, of een groep commits tegen de groep ervoor. Elke branch heeft een eigen baseline en een eigen log; over branches heen vergelijken geeft alleen verwarring, want dan verschillen instellingen, data en code tegelijk.

De baseline

De baseline van een branch is de commit van de laatste productierun. Hij bestaat uit een git-tag (baseline/<datum>), het profiel van die commit (de waarde van alle instellingen onder ModelParameters en VariantParameters, inclusief de leveringsdatums, zodat ook de data vastligt) en de bewaarde uitvoer van de toetsrun van die commit. Elke latere toets van de branch rekent onder het profiel van de baseline, dus met de instellingen van de productierun, ook als een latere commit een instelling heeft veranderd. Een instelling die een latere commit heeft weggehaald of verplaatst kent het profiel niet meer; het rapport meldt dat.

De uitvoer die bewaard blijft is de standtifs per zichtjaar en per variant, de controlewaarden van het diagnoseharnas en de basisjaarstand. De baseline staat buiten de repo, in een map per branch in de LocalData van de machine; de tag staat in git.

Het testprofiel

Een toetsrun is klein, zodat hij na elke groep commits kan draaien: een provincie als studiegebied, een of twee zichtjaren, en de varianten en sectoren die de productierun ook draait. Het profiel ligt vast in een csv per branch (enginetoets/profielen/<branch>.csv in de repo RS-testomgeving) en wordt over het baselineprofiel heen gelegd. Onder een bevroren profiel is de allocatie deterministisch: twee runs van dezelfde commit geven byte-gelijke standtifs en gelijke controlewaarden, dus de bandbreedte van de toets is nul en elk gemeld verschil is rekenwijze of invoer.

Wat het testprofiel niet dekt, blijft tot de volle run onzichtbaar: een sector die uitstaat, een zichtjaar na het laatste, een variant die niet meedraait. Welke provincie, zichtjaren en varianten een toepassing in haar testprofiel zet, hoort bij die toepassing.

Groepen commits als ketting

Een branch verandert in groepen: een opschoning, een reparatie aan een sector, een nieuwe indicator. De toets rekent elke groep door en legt hem naast de groep ervoor, zodat het log van een branch leest als een ketting van baseline tot de laatste commit, met per schakel wat er in de commits zat en wat dat met de uitkomst deed. Alle schakels rekenen onder hetzelfde baselineprofiel; alleen de code en de invoer verschillen per schakel. De runs van de groepen zijn onafhankelijk en kunnen naast elkaar draaien; de rapporten volgen daarna in de volgorde van de ketting.

Het rapport

Het log geeft per schakel een oordeel in een woord. IDENTIEK: stand en controlewaarden gelijk. STAND GELIJK: alle standtifs byte-gelijk en alleen controlewaarden anders; dan is de meetlat veranderd en niet de allocatie. VERSCHILT: de stand is anders.

Het rapport van een schakel begint met wat er in de commits zit, in een of twee zinnen. Dan Hoe anders: per variant een koptabel in modeltermen (de stand van woningen en banen, de claimrealisatie, het nieuwe stedelijke areaal, het aandeel inbreiding, nieuwe natuur, waterberging op veen, sloop, woningwaarde, koolstof) en per sector het patroon op de kaart: cellen erbij, cellen eraf en cellen met een ander aantal, en voor de landgebruiks- en de subsectorkaart het aantal cellen met een andere klasse. Dan Waarom, in een paar zinnen: wat verschuift, welke commit of instelling dat kan verklaren, op welke sector de wijziging mikt en wat verdringing is. Een commit die alleen toelichting raakt heeft dezelfde rekenvorm en kan de uitkomst niet veranderen; een commit in de indicatorsjablonen verandert de meetlat en niet de allocatie; een commit die het schrijfwerk anders over de rekenstappen verdeelt hoort de uitkomst niet te raken. Of de verschuiving het bedoelde effect is, blijft aan de lezer: het rapport zegt waar te zoeken, niet of het goed is.

Verder kijken bevat de rest, ingeklapt: de commits met per commit wat hij raakt, per tif het aantal afwijkende cellen, de sommen en de grootste celafwijking, alle controlewaarden die verschillen, de bestanden per commit en de technische gegevens van beide runs (GeoDMS-versie, profiel, rekentijd, geheugen).

De acceptatie

Voor een oplevering draait de kandidaat vol, met zijn eigen instellingen. Dat rapport legt de instellingen en de leveringen tussen baseline en kandidaat naast elkaar, verwijst naar de schakels van de ketting ertussen, en zet de volle run naast de baseline in de controlewaarden. Is het akkoord, dan wordt de kandidaat de nieuwe baseline van de branch.

De opdrachten

pwsh <RS-testomgeving>\enginetoets\Toets.ps1                                    HEAD tegen de baseline, met het testprofiel van de branch
pwsh <RS-testomgeving>\enginetoets\Toets.ps1 -Commit <sha> -Van <sha ervoor>     een groep commits tegen de toetsrun van de groep ervoor
pwsh <RS-testomgeving>\enginetoets\Toets.ps1 -Commit <sha> -ZonderVergelijking   alleen rekenen; het rapport later met -AlleenRapport -Van
pwsh <RS-testomgeving>\enginetoets\Baseline.ps1 -Commit <sha> -Omschrijving ...  de commit van de laatste productierun tot baseline maken
pwsh <RS-testomgeving>\enginetoets\Setup.ps1                                     zegt of een machine alles heeft

De scripts staan in de repo ObjectVision/RS-testomgeving, map enginetoets, buiten de modelrepo; alleen de baseline-tag staat in de modelrepo. Ze draaien vanuit de werkkopie van het model, of met -Repo naar die werkkopie. Toets.ps1 zet de commit in een eigen git-worktree met een eigen LocalData, legt de profielen op met Profiel.py, draait batch/Run2120.ps1 van die kopie met de GeoDMS-versie die dat script zelf noemt, en maakt het rapport met Toetsrapport.py. Elke toets komt genummerd als regel in het toetslog.csv van de branch, en Toetslog.py maakt daar een pagina van met alle rapporten eronder. Met -Repo toetst het script een andere werkkopie, met -Patch gaat een fix mee die daar nog niet in zit, met -Samenvatting komt in een of twee zinnen in het log wat er in de commits zit.

Verantwoording

  • pbl-nl/model-RSopen#16: het ontwerp van de toets, de scheiding tussen enginetoets en acceptatie, de baseline per branch en de ketting van groepen.
  • #833: het diagnoseharnas met normen, waarvan de controlewaarden de koptabel van het rapport leveren.
  • #562: een provincie als studiegebied, de voorwaarde voor een klein testprofiel.