Normalt forventer man, at hvis a + b giver c, så vil a + b altid give c.  I programmering skal man have en vis tolerance mht. præcision, når man bruger doubles og floats, men hvis a + b giver c i et program, forventer man samme resultat, uanset hvornår man laver beregningen indenfor samme proces.

Sådan troede jeg det var indtil fornylig, hvor én af vores unit tests fejlede – tilsyneladende lidt tilfældigt.  For kørte jeg den pågældende unit test alene, var der ingen fejl.  Kørte jeg den sammen med de andre unit tests i projektet, fejlede den.  Jeg fik ret hurtigt identificeret, hvilke andre unit tests, der drillede, og den fejlende unit test havde absolut intet med de andre unit tests at gøre.  Der var ingen fælles kode.

For nemheds skyld vil jeg kalde den fejlende unit test for A, og kalde de andre unit tests, som forårsagede fejlen i A for B. 

Test A tester kode indeholdende komplekse beregninger (Nelder-Mead), og fejlen gjorde, at det endelige resultat endte med en difference på 0.5!  Det er meget i min verden.

Test B er lidt speciel.  Den tester funktionalitet til at indlæse data fra et regneark.  Dvs. koden, som B tester, benytter Microsoft’s ACE driver. Efter en del test af denne driver, og noget der ligner to dages riven i mit eget hår, var jeg i stand til at genskabe problematikken med et simpelt eksempel, hvor resultat af et gangestykke med doubles gave forskellige resultater før og efter kald til ACE driveren.

Et spørgsmål på StackOverflow affødte en forklaring: “… unmanaged code may be tinkering with the FPU control word and change the way it calculates”.  Der blev også foreslået en løsning, nemlig et kald til _fpreset, som “resets the floating point package”.

Den foreslåede løsning virker, men jeg føler mig ikke overbevist om, at jeg egentlig har lyst til at bruge ACE driveren direkte i vores produktionskode.  En rådslagning med Daniel (også kendt er på sitet som ne0san) førte frem til en anden løsning, nemlig at spawn en ny process, som indlæser data fra regnearket, og kommunikerer data tilbage til hovedprocessen vha. named pipes (måske et emne for en kommende dotninjas blog).  Det virker.  Om det er en bedre løsning end _fpreset er svært at sige.

Dette er starten på en lille artikelserie om Continuous Integration med Cruise Control .Net (herefter blot CC). Continuous Integration (herefter blot CI) stammer egentlig fra Extreme Programming, men bruges også af folk som ikke kender til XP. Der er mest tale om en proces som giver en række fordele hvis man bider ind i konceptet. Med denne artikel serie vil vi bruge en række værktøjer til at få

  • Vores .net projekter under et source kontrol system
  • Bygget koden automatisk når vi checker ændringer ind
  • Kørt vores unit-tests automatisk
  • Nemt overblik over status på vores builds

Målet er at man vælger at checke ændringer ind tidligt og ofte, fordi man hurtigt kan se effekten på hele projektet. Det kan betale sig lige at se Martin Fowler's Artikel om Continuous Integration hvis man ikke har kendskab til emnet. Ikke noget med at ha' flere moduler liggende på en udvikler computer som ta' nogle dage at integrere i resten af projektet.

Det kan lyde af meget for en hobby programmør, men selvom du (endnu) ikke skal arbejde sammen med andre end dig selv, så er dele af processen stadig en fordel. Versions styring bør være nemt nok til at alle kan bruge det og man bør alligevel få sig et build script så snart projektet vokser til flere solutions. Brug CI som inspiration i din process og ta' de ting med dig du kan bruge.

Til denne artikelserie skal du bruge:

Jeg har installeret CC på min WHS og det kræver derfor jeg installerer et Windows SDK. Hvis du bruger en maskine som har installeret Visual Studio, så har du sikkert allerede det SDK du skal bruge. Hvis ikke, kan du løbe ind i nogle problemer lige som mig, men dem løser vi. Hvis du bruger din WHS så husk at installere på D drevet.

Du kan lige så godt komme igang med at downloade programmerne og få dem installeret på din build server (lad os kalde den BS til ære for B.S.) med det samme. Jeg vil ikke gå videre i dybden med hvordan man bruger SVN, NAnt eller NUnit. Der findes mange spændende tutorials på nettet om de emner, du kan læse mens jeg arbejder på flere artikler i serien.

Listen over planlagte artikler ser således ud:

Når der kommer nye indlæg vil jeg linke til dem fra denne side.