Det å få noe til å høres vanskeligere ut enn det egentlig er, er lett om man kan de rette utrykkene. Denne strategien er herlig eksemplifisert av bilmekanikeren Reidar i tegneserien Pondus, som gjerne utbryter ”Aiaiai, svinghjulet har punktert” eller ”Oida, dobbelt fustasjeoppheng!” før han nikker megetsigende til en skrekkslagen bileier. Hva har så dette med leveranser å gjøre?
Jeg har sett leveranser som har vært svært krevende og har vært utsatt for lange sjekklister, manuell utrulling og script-kjøring inn i evigheten. Dette har ført til kode- og utrullingsrutiner som til stadighet er utdatert og må fikses på. Man gjør tross alt bare en leveranse en gang i måneden, om ikke enda sjeldnere. På det verste har jeg sett applikasjoner som det har tatt tre dager å levere, fordi noe har gått galt. Når den da endelig er levert er man fortsatt på tuppa fordi man egentlig ikke vet om det faktisk fungerer. Slikt koster utrolig mye tid, ressurser og ikke minst penger.
Så hva kan man gjøre for å unngå disse fellene og unødvendig tidsbruk? Det enkle svaret er å automatisere, gjenta prosessen til den er uten feil og forenkle utrullingen. På kjøpet får man trygghet, kontroll og ikke minst langt bedre kvalitet!
Jeg bruker selskapet Aladdin Oil som eksempel. Det har vokst fra å være et lite selskap som både har og har hatt disse utfordringene. Det er tre områder som gir utfordringer når man vokser og ikke tar hensyn til at utvikler- og kodemassen vokser. Flere systemer blir koblet på, og kompleksiteten øker. Har man da ikke tenkt på konsekvensene, kan det bli unødvendig komplekst når flere utviklere og testere skal inn i koden og videreføre leveransene. De er tre områder jeg mener man da bør fokusere på:
- Kodekvalitet
- Automatisert testing
- Automatisert utrulling (deployment)
Kodekvaliteten blir raskt dårligere når man ikke har tenkt på teknisk gjeld på en stund, og man ikke har en gjennomtenkt arkitektur og design for hvordan koden i leveransen skal se ut. Med dette ute av fokus, får man fort MYE teknisk gjeld å ta igjen. Utviklere som får lov til å gjøre som de vil, gjør gjerne det. Da kan man fort få like mange løsninger som det er utviklere i teamet.
Aladdin Oil installerte Sonar for å få en oversikt over sin kodekvalitet. Med det fikk de et godt bilde av nå-situasjonen. Gjennom rapporteringsmekanismene i Sonar så man at mye var bra, men mye var også dårlig. For eksempel var det en testdekning på 0.8% - det er et svært lavt tall. Situasjonen var også den at man hadde mange webservice-integrasjoner som man benyttet seg av. Mange av feilene som kom inn var kritiske og blokkerte videre fremdrift og måtte derfor fikses asap. Et eksempel er en tjeneste som behandlet telefonnummer. Noen hadde gjort en endring, den var levert til produksjon og det begynte plutselig å feile. Ingen visste hvorfor. Løsningen på dette problemet bringer meg over på neste tema:
Automatisert testing
Løsningen på dette konkrete problemet var å finne rotårsaken ved å lage en eller flere enhetstester (for eksempel jUnit). Dette manglet for området som feilet og derigjennom verifisere at feilen fortsatt eksisterer. Deretter rettes feilen ved å oppdatere koden, så testen blir verifisert til ok. Resultatet er at testdekningen har økt, man har fått kontroll på en bug, og skjer det igjen får man tidligere varsel om at noe er galt. Det er en billig måte å øke testdekningen på, og man får en bedre kontroll på teknisk gjeld. Disse testene blir kjørt automatisk og prosessen gjentas hver eneste gang koden blir bygd. Dette igjen fører til at man får repetert testene hver eneste gang man legger til eller endrer kode i den gitte modulen. Oppstår feilen igjen, vil enhetstesten feile, og man ser at man må sjekke hva som er galt. Kode hvor enhetstester ikke er godkjent blir ikke sluppet videre til høyere testmiljøer.
I dette tilfellet var det en webservice som feilet, og da kan man bruke for eksempel Soap UI for å få testet de eksterne integrasjonspunktene. Soap UI er et visuelt verktøy for å lage xml-baserte tester. Ved å legge inn ønskede parametre kan man enkelt få et resultat tilbake fra API og få bekreftet at returen er som ønsket. SoapUI støtter Maven, et verktøy for automatisering av bygg med mer. Ved å bruke et slikt verktøy kan man sy sammen et fullt automatisert testmiljø med både enhets- og integrasjonstester (nå har ikke jeg nevnt funksjonelle tester her, men de kan også automatiseres). Med automatisering repeteres de så ofte at man raskt vil finne feil. Jo tidligere man finner feil, jo billigere er det å rette dem. Da gjenstår det ett punkt som jeg også mener er viktig for å få bedret leveransen enda et hakk:
Automatisert utrulling (deployment)
Det å levere for eksempel en pakket web-applikasjon til en server, skal ikke være komplekst. Det finnes verktøy som gjør dette enkelt og automatiserer denne prosessen. I tilfellet Aladdin Oil hadde han som var ansvarlig funnet ut at et Python script var smart, for det kunne han. De brukte tross alt Linux. Til å begynne med ser man ikke noe problem her. Men tiden går og vår kjære Python-guru slutter. Ingen andre kan Python og man sitter igjen med en haug med problemer når ting slutter å virke. Løsningen ble å bytte ut scriptet med Maven, som vi nevnte isted. Det er en standard som er generelt godt kjent blant utviklere, og det finnes en mengde plugins for dette verktøyet for å lette automatisering av for eksempel deployment-aktiviteter. Jenkins og Puppet ble også installert og tatt i bruk. Puppet er et verktøy som kontrollerer miljøer og sørger for at de er riktig satt opp. Etter at dette var gjort, klarte man å levere kode på under 10 minutter. Før gikk mye rett i produksjon, fordi man ikke hadde sikkelige rutiner og testmiljøer. Nå finnes det både et integrasjonsmiljø og et systemtestmiljø. Man kunne plutselig begynne å snakke om at man gikk mot en prosess med flere av elementene i Continuous Delivery. Igjen ser man at automatisering fører til at man får ned antall feil i utrullingen; ved å repetere, går utrulling som smurt hver gang. Feilene er luket ut på forhånd. Dette gjør at jeg kommer til følgende:
Resultatet
Ved å binde alt dette sammen og bruke en kombinasjon av Maven, Jenkins og Puppet, har man fått kontroll på bygg, utrulling og miljøer. Jenkins henter koden fra Subversion, kompilerer den, generer en pakke og deployer denne på en integrasjonsserver. Jenkins starter så en soapUI xml-fil gjennom Maven som gjør kall mot eksterne og interne integrasjoner og API-er. Dette igjen verifiserer at web-servicene leverer det kontrakten har sagt den skal. I vårt tilfelle har vi valgt å kjøre tester en gang i timen. Vi får da raskt oversikt over endringer og feil som vi ikke hadde kontroll på før. Når noen nå klager på at testmiljøet ikke er oppe, så vet vi det allerede fordi vi bruker elementer fra Continuous Delivery.
Nå har Aladdin Oil en langt bedre prosess rundt det å deploye til produksjon da vi gjenbruker de samme scriptene som mot systemtest og produksjon. Den største gevinsten er at vi nå bruker mindre tid på å finne feil, produksjonssette kode, og ikke minst forbedrer vi kode som ikke før var testet! Dette er noen små endringer som har gjort Aladdin Oils hverdag langt bedre, de har spart penger, funnet feilen tidligere og har langt mer fornøyde kunder! Prøv dette du også, det hjelper virkelig!


















