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
comsystoreply
4 min readNov 20, 2018

--

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.

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:

‍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:

Jenkins Verwalten — System Konfigurieren
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.

Zugangsdaten
Zugangsdaten hinzufügen
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.

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:

‍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.

‍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.

--

--