Testbare Jenkins Shared Pipelines

Ist dein Pipeline Code getestet? Fliegen die Exceptions immer erst zur Laufzeit, weil ein Groovy Syntax Fehler vorliegt? Verziehen deine Kollegen voller Abscheu das Gesicht, wenn du “Pipeline Code” sagst? Say no more!

Comsysto Reply
Nov 20, 2018 · 4 min read

Von Bernhard, Software Engineer @comsysto

Einleitung

Wir nutzen Jenkins in mehreren Projekten und haben uns eine Shared Jenkins Pipeline aufgebaut. Bisher konnten wir unseren Pipeline Code nie wirklich lokal testen, es hat immer erst im eigentlichen Jenkins Job geknallt. Diesen Umstand wollten wir schleunigst ändern und haben uns damit beschäftigt, wie man testbaren Pipeline Code produzieren kann. Dieser BlogPost gibt dabei die Grundzüge unseres Ansatzes wieder.

Image for post
Image for post
Who wrote the Pipeline Code? Why do we see the error on Mars?

UnitTests für Pipeline Code

Wir wollten folgendes erreichen:

  • Jenkins Befehle mocken (sh, withCredentials, echo …)
  • Ein Helper ruft keine anderen Helper auf (Separation of Concerns)
  • Jeder Helper hat einen UnitTest
  • Ein UnitTest mocked Jenkins und prüft (assert) die vom Helper produzierten shell-calls.

Unser Shared Pipeline Setup sieht dabei wie folgt aus:

Image for post
Image for post
‍Struktur der Shared Pipeline

Demo: Shared Pipeline mit GitHelper

Wir wollen zur Demonstration einen simplen GitHelper programmieren, der uns die Arbeit mit GIT erleichtert.

Das ganze Demo-Projekt seht ihr auf GitHub:

Wir binden die Demo Shared Pipeline in Jenkins als Globale Pipeline Library ein. Globale Pipelines laufen außerhalb der Sandbox und ermöglichen so einiges mehr an Funktionen als ge-sandboxte Pipelines.

Wir wollen unsere Library später unter der ID “comsysto” abrufen können und konfigurieren sie wie folgt:

Image for post
Image for post
Jenkins Verwalten — System Konfigurieren
Image for post
Image for post
Konfiguriere Globale Pipeline Library

Somit können wir unsere Library wie folgt in einem Jenkinsfile eines Pipeline-Jobs nutzen:

Credentials in Jenkins einrichten

Wir wollen mit unserem GitHelper und mithilfe von GitHub Personal Access Tokens private GitHub Repositories clonen können. Dafür legen wir uns ein UsernameAndPassword Credential mit dem Token als Passwort an.

Image for post
Image for post
Zugangsdaten
Image for post
Image for post
Zugangsdaten hinzufügen
Image for post
Image for post
Zugangsdaten mit Personal Access Token anlegen

Wir haben später in der Pipeline Zugriff auf die Zugangsdaten über die ID github-credentials-1. Credentials können wie folgt genutzt werden, was aber der GitHelper für uns übernehmen wird:

Einen Pipeline Job einrichten

Wir richten einen Pipeline Job ein, um unsere Pipeline zu testen. Als Randnotiz sei gesagt, dass wir neben den UnitTests auch für jeden Helper einen eigenen Integration-Test-Pipeline-Job haben.

Image for post
Image for post
Neuer Job — Typ Pipeline Job

Wir tragen folgenden Pipeline Code ein:

Dieser nutzt unsere globale comsysto-Library und den GitHelper. Man sieht, dass wir die credentials anhand der ID übergeben sowie Repository-Owner und Repository-name. Es wird also das private Repository https://github.com/comsysto/test-jenkins-private-repository gecloned.

Lässt man den Job laufen, sieht das Ergebnis so aus:

Image for post
Image for post
‍Erfolgreicher Job Run mit Shared Pipeline

GitHelper und cloneGitHubRepository()

Unser GitHelper sieht wie folgt aus:

Der Dazugehörige Unit Test instanziiert den GitHelper sowie einen Jenkins Mock welcher alle Jenkins API Calls mocked.

Der Jenkins Mock ist dabei recht simpel aufgebaut. Aktuell mockt er nur env, sh() und withCredentials().

Die Unit Tests können wir wie folgt ausführen:

groovy -cp src/ src/com/comsysto/pipeline/test/GitHelperTest.groovy

Natürlich muss die Groovy SDK installiert sein. Wenn man alles richtig gemacht hat, laufen alle Tests sauber durch. Das @Grab() sorgt ggf. für eine etwas längere Wartezeit, da erst das JAR heruntergeladen werden muss.

Image for post
Image for post
‍Erfolgreicher Unit Test Run eines Helpers

Fazit

Wir können unsere Jenkins Library lokal testen. Und wissen daher früh, wenn etwas nicht funktioniert. Durch weitere Integration Test Pipeline Jobs pro Helper kann man die Testabdeckung noch weiter erhöhen. Wir sind mit unserem Ansatz sehr zufrieden und werden immer weiter daran feilen.


Originally published at comsystoreply.de.

comsystoreply

Innovation through insight.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store