Follow Us on Twitter

Continuous Integration met Oracle Fusion Middleware

December 2012 - Een omgeving gebaseerd op de Oracle Fusion Middleware stack (FMW), zoals de Oracle SOA Suite of BPM Suite, wordt naarmate die verder groeit steeds complexer. In de FMW worden nieuwe services, processen en applicaties ontwikkeld en in productie genomen. Deze componenten kennen onderlinge afhankelijkheden die de complexiteit van de omgeving vergroot. Om in dergelijke omgevingen te kunnen ontwikkelen, is het noodzakelijk er voor te zorgen dat nieuwe componenten de werking van de omgeving niet verstoren. Hierdoor is testen belangrijk, specifiek integratietesten. Hoe werken nieuwe componenten binnen de bestaande omgeving? Werken bestaande services en applicaties nog nadat de nieuwe componenten zijn toegevoegd? Dit zijn vragen die integratietesten moeten beantwoorden.

Tijdens het ontwikkelen met FMW producten is het mogelijk dat meerdere ontwikkelaars tegelijkertijd aan van elkaar afhankelijke componenten werken. Dit betekent dat de componenten uiteindelijk samengevoegd moeten worden en er moet worden getest of zij onderling goed functioneren.

Als er voor wordt gekozen om de integratietesten in een laat stadium te laten plaatsvinden, bijvoorbeeld wanneer alle componenten uit een project klaar zijn, is de kans zeer groot dat de integratie moeizaam verloopt. Mogelijke integratieproblemen zijn problemen die ontstaan als de diverse componenten binnen de FMW niet correct kunnen samenwerken. Denk bijvoorbeeld aan een webservice die net op een andere manier werkt dan verwacht of een BPEL proces dat niet goed met een nieuwe service kan communiceren. Dergelijke problemen komen vaak pas naar voren als de verschillende componenten zijn samengevoegd. Hoe langer het geleden is dat een dergelijk component is gemaakt, hoe groter de kans dat herstelwerkzaamheden langer zullen duren. De verantwoordelijke ontwikkelaar kan bijvoorbeeld op een ander project zitten of zelfs weg zijn.

Om de hiervoor genoemde problemen te voorkomen is het van belang om de code zo snel mogelijk te integreren en te testen. Dit kan met behulp van Continuous Integration (CI). Dit Whitebook gaat in op de mogelijkheden van Continuous Integration in combinatie met de Oracle SOA Suite.

Continuous integration

Continuous integration staat voor "Het dagelijks samenvoegen van alle, door verschillende ontwikkelaars, ontwikkelde code. Met als doel om zo snel mogelijk (integratie) problemen op te sporen en verhelpen."

Bij CI staat één versie van de code centraal. Dit is de versie waaraan elke ontwikkelaar zijn aanpassingen moet toevoegen. Met andere woorden dit is de enige waarheid, code bestaat pas wanneer het is toegevoegd aan de centrale versie. Deze centrale versie moet altijd functioneren. Zodra code wordt toegevoegd, moet worden getest dat alles nog correct werkt. In het kort houdt dit in dat er getest moet worden of de integratie goed is gegaan en of het geheel nog goed functioneert (regressie-testing).

Buildserver

Een buildserver is de lijm binnen Continuous Integration die de verschillende losse componenten van CI aan elkaar verbindt. Deze server is verantwoordelijk voor het proces binnen CI, de “build-cyclus”. Binnen een build-cyclus wordt de laatste versie van de code gepakt, op een testomgeving geplaatst en vervolgens automatisch getest. Een build-cyclus is afgerond als alles goed is gegaan en de testen succesvol zijn afgerond.

In de voorbeelden in dit Whitebook is gebruik gemaakt van een Hudson buildserver. Dit is een veel gebruikte (opensource) buildserver met een groot scala aan plugins. De plugins kunnen gebruikt worden om reeds gebruikte producten, zoals een repository, te koppelen aan Hudson. Dankzij deze plugins is Hudson zeer breed inzetbaar en biedt het de mogelijkheid om CI verder te laten groeien.

Overzicht van jobs (build cylus) in Hudson met daarbij de status van de build-cyclus
Afbeelding 1: Een overzicht van jobs (build cylus) in Hudson met daarbij de status van de build-cyclus.

Om een job (build-cyclus) te realiseren moet een buildserver over drie componenten beschikken:

  • een centrale repository waarin alles wordt opgeslagen;
  • deployments scripts;
  • testscripts (unittesting, integratie testing, regressie-testing);

Repository

Een veel gebruikte en breed geaccepteerde manier om je code op te slaan, is het gebruik van een centrale repository. Dergelijke repositories bieden functionaliteiten om je code zo goed en efficiënt mogelijk op te slaan. Denk aan versiebeheer, accountcontrol (elke gebruiker heeft zijn eigen account), beveiliging etc. SVN en GIT zijn twee voorbeelden van repositories die veel gebruikt worden.

De repository is de plek binnen Continuous Integration waar de enige "bestaande" code wordt bewaard. Staat het niet in de repository dan bestaat de code niet. Hierbij is het van belang dat ontwikkelaars, zodra de code af is, deze zorgvuldig inchecken. Dit heeft twee belangrijke voordelen: de code wordt meteen getest (regressie en integration test) en het voorkomt lastige merge trajecten.

Uitgecheckte code, waarin aanpassingen zijn gedaan, wijkt af van de laatste versie in de repository. Niet alleen de uitgecheckte code maar ook de code in de repository wordt namelijk steeds verder ontwikkeld. Uiteindelijk moet de code weer worden toegevoegd aan de repository, dit proces heet merging. Hoe groter de afwijking, hoe lastiger het is om de code te mergen. Het is daarom belangrijk om de uitgecheckte code zo snel mogelijk weer in te checken.

Overzicht van een project in een SVN repository gezien vanuit een webbrowser
Afbeelding 2: Overzicht van een project in een SVN repository gezien vanuit een webbrowser

Deployment

Deployen (installeren) kan veel tijd in beslag nemen, vooral wanneer het dagelijks of elke keer dat men code incheckt gebeurt. Tijdens de levenscyclus van een FMW omgeving, neemt het aantal componenten en daarmee ook de complexiteit van de omgeving toe. Hierdoor wordt het installeren en testen van een omgeving steeds moeilijker en kost het steeds meer tijd.

Continuous Integration heeft een zeer intensieve deploy cyclus. Dit kan 1 of meerdere keren per dag plaatsvinden. Het is van belang dat het gehele deployment proces zoveel mogelijk en het liefst geheel automatisch gebeurt. Binnen de FMW stack zijn er deployment scripts (ANT Tasks) beschikbaar die gebruikt kunnen worden om een project te deployen naar een omgeving. Met die tasks is het mogelijk om SCAs (Service Composite Application), OSB proxies en ADF projecten automatisch te deployen. Hiervoor kan gebruik gemaakt worden van ANT of MAVEN, beide "tools" zijn gecreëerd met als doel om deployments te automatiseren. Omdat in de FMW stack standaard ANT tasks worden meegeleverd, is er in dit Whitebook gekozen om de voorbeelden met ANT uit te werken.

Het aanroepen van een ANT Task middels ant, waarbij waardes worden gebruikt uit een property-bestand
Afbeelding 3: Het aanroepen van een ANT Task middels ant, waarbij waardes worden gebruikt uit een property-bestand

Let er op dat hoewel de antscripts (tasks) worden meegeleverd bij een installatie van de SOA Suite, er toch gebruik wordt gemaakt van de onderliggende deploymentscripts en libaries van Jdeveloper. Dit betekent dat de buildserver bij een installatie moet kunnen van Jdeveloper.

Omdat het om een automatische deployment gaat, heeft het script een aantal property-bestanden nodig. Deze bestanden moeten onder andere gegevens bevatten over de te deployen onderdelen en de server waar de implementatie op moet komen te staan. De eerste variabelen zijn dusdanig afhankelijk van het project dat deze in het voorbeeld bij het project worden opgeslagen. De omgevingsvariabelen zijn echter minder specifiek en kunnen veelal hergebruikt worden door de verschillende projecten. Dit betekent dat ze bijvoorbeeld op de build server zelf kunnen staan.

Omgevingsvariabelen worden vastgelegd in een property-bestand
Afbeelding 4: Omgevingsvariabelen worden vastgelegd in een property-bestand

Testen

Testen is vaak een ondergeschoven kindje binnen een project. Door tijdsdruk en de waan van de dag worden testperiodes ingekort of kortweg overgeslagen. Testen is echter een van de belangrijkste fases binnen een project. Op dat moment wordt namelijk gevalideerd of de applicatie(s) (code) voldoet aan de eisen en wensen van de gebruiker. De code mag geen bugs, ongewenst gedrag etc. bevatten.

Binnen Continuous Integration test je zo vaak en zo vroeg mogelijk. Het is namelijk een standaard onderdeel van de (dagelijkse) build-cyclus. Een belangrijke voorwaarde hierbij is dat het testwerk zoveel mogelijk geautomatiseerd wordt. Dit betekent dat ontwikkelaars en testers hun testen moeten automatiseren. Denk hierbij bijvoorbeeld aan unittests en integratie tests. Daarnaast is het van belang dat het testen direct begint. Elk stukje code dat wordt opgeleverd en mee gaat in de dagelijkse build-cyclus moet namelijk getest worden.

Doordat er bij elk stukje nieuwe of gewijzigde functionaliteit een testcase gemaakt moet worden, bouw je stukje bij beetje een steeds groter wordende testportfolio op. Aangezien de testcases geautomatiseerd zijn, kunnen ze mee worden genomen in de build-cyclus. Zo wordt tijdens elke build-cyclus getoetst of de code nog voldoet aan de eerder, in de testcases, vastgestelde functionele wensen en eisen. Er wordt op deze manier gevalideerd dat de nieuwe code geen reeds gerealiseerde functionaliteit stuk maakt. Met andere woorden er wordt een regressie opgebouwd en (meer)dagelijks uitgevoerd.

Er zijn verschillende tools voor het testen van de webservices, OSB proxies, BPEL processen en ADF code binnen een Oracle Fusion Middleware omgeving. In dit Whitebook worden de testsuite van de SOA/BPM Suite zelf en jMeter uitgelicht.

TestSuite

Binnen de SOA/BPM Suite kan je bij een composite één of meerdere testsuites definiëren. Hierbij is het mogelijk om testberichten in te schieten en berichten tussen de verschillende componenten of partnerlinks te valideren (asserten). Daarnaast kan men de response berichten van externe webservices mocken of deze webservices daadwerkelijk aanroepen. Zo is het dus mogelijk om de BPEL processen te testen (een vorm van unit testing) en ook de integratie met de externe webservices.

De testsuites worden gestart met de eerder genoemde ANT scripts die door Oracle zijn aangeleverd.

Testsuites kunnen met ANT gestart worden
Afbeelding 5: Testsuites kunnen met ANT gestart worden

jMeter

JMeter is een opensource testtool waarin je met een GUI testcases kunt ontwikkelen en deze daarna met een script kunt starten. Zo is het mogelijk om jMeter te starten vanaf de buildserver. jMeter is een hulpmiddel voor unittests van webapplicaties waaronder ook webservices van bijvoorbeeld een OSB-proxy. Dit maakt jMeter een goede kandidaat om OSB proxies te testen.

Per applicatie, webservice, component etc. moeten er testcases worden ontwikkeld die valideren of de code goed werkt en voldoet aan de functionele eisen. In principe mag code pas toegevoegd worden aan de repository als deze automatisch getest kan worden. De testcases worden in een repository opgeslagen zodat iedereen er altijd bij kan. Zo kan ook de Buildserver er bij en kunnen de testcases tijdens elke build-cyclus worden uitgevoerd.

Naast het testen van de functionaliteit van de code, is het ook mogelijk om de code te controleren op bijvoorbeeld naamconventies, manier van commentariëren, testdichtheid etc.. Daarvoor kan ook Sonar worden ingezet. Sonar is een verzameling van tools die is gericht op code-analyse waarmee ontwikkelstandaarden, code-standaarden etc. worden bewaakt in de build-cyclus.

Build-cyclus

De configuratie van een build-cyclus begint met het aanmaken van een Job binnen de Hudson buildserver. In een job worden de verschillende stappen van een build proces vastgelegd.

Allereerst moet er een connectie worden gemaakt met de repository. Hudson heeft integratie-mogelijkheden met svn. Het opgeven van de locatie van de svn folder en een username en password is voldoende. Het is mogelijk om bij het starten van een build-cyclus te kijken naar de repository. Zodra men code toevoegt (commit) in svn, kan Hudson een build-cyclus starten. Het doorlopen van een build-cyclus kan echter lang duren en veel resources van de testomgeving vergen. Als dit het geval is, is het verstandig om de build-cyclus 's nachts te starten (nightly builds). Op dat moment werkt er niemand op de testomgeving en heeft niemand er last van als de testomgeving tijdelijk niet beschikbaar is.

Omdat de build op de hudson server zelf gebeurt, doet deze eerst een checkout van de code naar een Hudson repository. Vanuit deze repository worden vervolgens de verschillende projecten gecompileerd en uiteindelijk gedeployed. Dit wordt gedaan met het eerder genoemde en in het voorbeeld getoonde ANT-script. Doordat Hudson altijd eerst een checkout van de code doet, wordt hiermee gegarandeerd dat de laatste versie van de projecten mee worden genomen. Daarmee wordt ook de regel dat code pas bestaat als deze in de repository staat geborgd.

Hudson repository met daarin de verschillende componenten en een property-bestand
Afbeelding 6: Hudson repository met daarin de verschillende componenten en een property-bestand

Zodra de code is gecompileerd en gedeployed door het ANT script wordt de status van de deployment geïnterpreteerd door Husdon. Dit betekent dat indien een compile of deploy niet goed is gegaan de build als “broken” wordt beschouwd. Binnen CI betekent dit in principe dat iedereen alles moet laten vallen en de build moet gaan fiksen. In praktijk zal dit betekenen dat de verantwoordelijke voor de ingecheckte code (de programmeur) zijn gedeelte moet herzien en opnieuw moet committen. Zodra de build-cyclus weer succesvol wordt doorlopen kan hij verder gaan met zijn werkzaamheden.

Nu de nieuwe implementatie op de server staat, kan er ook getest worden. Het is mogelijk om een groot scala aan test-tools te koppelen aan de buildserver zodat deze automatisch gestart worden. In het voorbeeld is gekozen voor de testsuite van de Oracle FMW stack en jMeter. Beide kunnen met behulp van een ANT script worden gestart. De resultaten van de test worden vervolgens net als bij het deployen geïnterpreteerd door Hudson.

Voor jMeter is het noodzakelijk om een plugin te installeren. Deze plugin zorgt ervoor dat Hudson de testresultaten kan interpreteren. De output van de test wordt geplaatst in de Hudson repository, vervolgens kan de plugin het resultaat bekijken. jMeter kan vervolgens met behulp van een ANT Task gestart worden.

ANT wordt gebruikt om jMeter tests te starten
Afbeelding 7: ANT wordt gebruikt om jMeter tests te starten

Als de tests ook succesvol zijn afgerond. is de taak van Hudson afgelopen en is de build-cyclus succesvol doorlopen. Als een test niet goed is gegaan, wordt de build als "broken" beschouwd. Dit betekent dat de verantwoordelijke ervoor moet zorgen dat de build weer gemaakt wordt. Om ervoor te zorgen dat de signalering van een "broken build" tijdig gebeurt, is het mogelijk om met behulp van allerlei kanalen een bericht te sturen. Dit kan bijvoorbeeld een e-mail zijn maar ook een sms. Het bericht kan informatie bevatten met betrekking tot het probleem, zodat er snel aan een oplossing gewerkt kan worden.

Een overzicht van het aantal fouten per build-cyclus
Afbeelding 8: Een overzicht van het aantal fouten per build-cyclus

Conclusie

Continuous integration voorkomt niet dat er fouten worden gemaakt. Het zorgt ervoor dat fouten sneller worden gevonden en daardoor eenvoudiger kunnen worden hersteld. Dit wordt gedaan vanuit de filosofie: “hoe sneller een fout wordt geconstateerd hoe makkelijker het is om de fout op te lossen”.

Tijdens een ontwikkelfase kan het noodzakelijk zijn, zeker als het aantal build-cyclussen groot is, om de testen zoveel mogelijk te automatiseren. Zodra een ontwikkelaar of de tester een stuk code of functionaliteit heeft getest, wordt de betreffende test samen met de ontwikkelde code opgenomen in de build-cyclus. Hierdoor hoeft een tester in principe niet meer te kijken of eerder gerealiseerde functionaliteit(en) nog naar behoren werkt. Dit wordt namelijk iedere build-cyclus automatisch gedaan. Tester en ontwikkelaar kunnen zich richten op andere zaken binnen het project, zoals bijvoorbeeld het ontwikkelen van nieuwe functionaliteiten.

Het toevoegen van functionaliteit en wijzigingen van bestaande code kan er voor zorgen dat externe componenten, die een afhankelijkheid hebben met het gewijzigde component, niet meer correct functioneren. Zonder een goede regressietest is de kans groot dat deze fouten niet snel naar boven komen. Met CI wordt een steeds groeiende regressietest opgebouwd. Hierdoor is de kans groot dat dergelijke fouten eerder boven water komen. De impact van de gewijzigde code is snel bekend en dat maakt het aanpassen van de code een stuk gemakkelijker en minder “gevaarlijk”.

Als de code dagelijks wordt samengevoegd en getest is het mogelijk om met een relatief grote groep ontwikkelaars aan dezelfde code te werken. Door automatische tests aan de code toe te voegen wordt elke dag gecontroleerd of de code van ontwikkelaars elkaar niet in de weg is gaan zitten.

Met de bovengenoemde voordelen van CI komt steeds een belangrijk aspect van CI terug. Dat is namelijk feedback. Door de snelle feedback die CI geeft is het mogelijk "potentieel" grote problemen snel te signaleren. Testers werken na een build-cyclus direct met de laatste versie van de software en kunnen zeer snel feedback geven over gerealiseerde functionaliteit. Dit zal uiteindelijk resulteren in ontwikkelaars en testers die samen aan een zo goed mogelijk product werken.

Dit Whitebook beschrijft een minimale opzet van Continuous Integration en is bedoeld als een introductie in de wereld van CI. Naarmate de organisatie en de omgeving complexer worden zal een CI omgeving meegroeien in complexiteit. Zo kan CI bijvoorbeeld een grote organisatie helpen bij het borgen van ontwikkelstandaarden welke een complexe omgeving vereist. Dit alles maakt CI een zeer goede methode om de kwaliteit van applicaties te vergroten en te borgen.

Referenties

Waardering:
 

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.