Mit Continuous Integration/Deployment

Kurze Testzyklen realisieren

3. Mai 2022, 6:30 Uhr | Von Dr. Richard Kölbl
Agile Development
© Elnur_adobestock.com

Software nach dem Entwickeln zu testen ist essenziell, aber nicht immer trivial. Um eine schnelle Markteinführung zu realisieren, sind Tests möglichst effizient durchzuführen und alle Fehler umfänglich zu bereinigen. Wie mit innovativen Test-Tools kurze Testzyklen gelingen können, zeigt Mixed Mode.

Das automatisierte Deployment von Embedded Software mit anschließendem Test auf einer Zielhardware ist nicht trivial. Gleichwohl machen es agile Arbeitsweisen, Rationalisierung und Kostenreduktion sowie das allgemein steigende Bedürfnis nach intensiv getesteter Software nötig, Continuous Integration und Deployment (CI/CD) im Embedded-Bereich anzuwenden: Testen Entwickler Software in kurzen Zyklen, sinkt der Aufwand bei der Fehlersuche erheblich, da Fehler schneller zugrundeliegenden Änderungen zuzuordnen sind. Gerade Steuergeräte im medizinischen Bereich, in Nutzfahrzeugen oder Batteriesteuersysteme unterliegen streng einzuhaltenden Qualitätsvorschriften. Sie sind nahezu ausschließlich mit entwicklungsbegleitenden, automatisierten Tests einzuhalten, ohne den Aufwand zu sehr in die Höhe zu treiben und einen entsprechenden Return on Investment zu gewährleisten. Um die Vorgehensweise in die Praxis umzusetzen, müssen Entwickler auf Hardware- und Software-Ebene verschiedene Herausforderungen angehen.

Anbieter zum Thema

zu Matchmaker+

Simulieren der Hardware

Das erste Problem stellt oft die Hardware selbst dar. Oft ist in der Praxis die zu testende Umgebung der Komponente (Device under Test, DuT) lediglich eingeschränkt verfügbar – wenn sie überhaupt ohne Weiteres zugänglich ist. Schon das DuT selbst, beispielsweise die Steuerung der Bremsanlage einer Straßenbahn, als Testhardware zu bekommen ist logistisch gesehen herausfordernd. Ebenso die limitierte Anzahl von Prototypen oder die schwierige Kontrollier- und Beobachtbarkeit. So ist es nicht möglich, die Umgebung selbst, also die Straßenbahn, in welche die zu entwickelnde Komponente nachher eingebaut wird, in einem Ingenieurbüro zu platzieren. Aus dem Grund emulieren Entwickler solche Umgebungen, um zumindest die funktionalen Tests an der Programmlogik auf der neuen Komponente ausführen zu können. Hierbei spiegelt das Emulieren dem DuT vor, es befinde sich in seiner normalen Umgebung, also beispielsweise der Straßenbahn. Nichtfunktionale Tests, die das Echtzeitverhalten oder interne Timings prüfen, sind natürlich in der realen Umgebung auszuführen. Es liegt jedoch auf der Hand, dass es ein entscheidender Vorteil ist, wenn zuvor anhand kurzzyklischer Tests in emulierten Umgebungen die Applikation auf dem DuT einen hohen Reifegrad erreicht hat. So lässt sich die Time to Market entscheidend reduzieren.

MM-HILF
Bild 1: Schematische Darstellung des »MM-HILF« (links) mit angeschlossenem Device under Test. Im MM-HILF sind die beiden Hauptkomponenten Test Runner und Test Server zu sehen.
© David Kausche | Mixed Mode

Ist die Emulation flankiert von einem Update Framework, einem Update Server sowie einem Build Server, so ergibt sich ein automatisiertes CI/CD-System zur kontinuierlichen Testdurchführung an einem Embedded-System. Eine praxisbewährte Anwendung eines solchen Systems bietet Mixed Mode – mit der Kombination des eigens entwickelten Hardware-in-the-Loop Frameworks »MM-HILF« mit dem firmeneigenen Linux Update Framework LIUF. MM-HILF ist ein Embedded Linux Framework auf Basis von Python, das die Rolle der Umgebung des DuT einnimmt. Je nach Use Case emuliert es die relevanten Aktoren, Sensoren sowie diversen Schnittstellen, sozusagen die testrelevanten Anteile der Straßenbahn, um beim Beispiel zu bleiben. Das MM-HILF läuft z. B. auf einem Raspberry Pi, verfügt standardmäßig über die gängigen Schnittstellen und ist ohne großen Aufwand individuell erweiterbar. Hierdurch ist die zentrale Forderung nach Kontrollier- und Beobachtbarkeit gegeben, die Unternehmen an Softwaretests stellen. Außerdem ist das Testsystem skalierbar und so an die jeweiligen Bedürfnisse des DuT anpassbar. Somit gibt es keine Engpässe mehr bei der Verfügbarkeit der Hardware.

Auf dem MM-HILF laufen als die zwei zentralen Komponenten ein Test Server und ein Test Runner, beide Python-basiert (Bild 1). Der Test Server, beispielsweise von Xilinx, NXP Semiconductors oder STMicroelectronics, emuliert die Umgebung für das DuT und steuert es, während auf dem Test Runner die Testausführung selbst abläuft. Hierbei ist das DuT selbst über die jeweilig relevanten Schnittstellen an das MM-HILF angeschlossen.

Deployment von Binaries

Auf Software- oder Binary-Ebene gibt es weitere Schwierigkeiten zu lösen. Zum einen sind Deployments von falschen Binaries zu verhindern, beispielsweise an falsche Speicheradressen oder in den falschen Speicher. Hierfür gibt es Unified-Modelling-Language(UML)-basierte Deployment-Diagramme, die dokumentieren, welche binären Artefakte für welche Speicherbereiche bestimmt sind. Zum anderen ändern sich im Laufe des Entwickelns die Binaries, die zu updaten sind. Sind es zu Beginn des Entwickelns die tieferliegenden Anteile wie Kernel oder First Stage Bootloader, ist es später bevorzugt die Applikation selbst, die im Zuge des fortschreitenden Entwickelns zu deployen und testen ist. Geschickte Systempartitionierung sowie das Verwenden eines Root File System neben einem Application File System reduzieren den Umfang der jeweils abzulegenden Firmware-Daten. Diese können je nach System bei vollem Umfang mehrere GB umfassen. Weiterhin sind alle möglichen Fehlerszenarien bei einem Deployment zu berücksichtigen. Um lediglich zwei zu nennen: Fehler während des Deployments, beispielsweise aufgrund Netz- oder Stromausfall, oder ein inkonsistentes System nach einem Deployment aufgrund fehlerhafter Firmware. Für Fehler dieser Art müssen Entwickler Recovery- beziehungsweise bootbare Rescue-Systeme oder sonstige Fallback-Szenarien vorhalten.

LIUF
Bild 2: Schematische Darstellung der Ausführung eines Deployments mit dem »LIUF« in einem verteilten Entwicklungsnetz.
© Heinrich Schönberger | Mixed Mode

Um Probleme solcher Art in den Griff zu bekommen, können Entwickler das MM-HILF mit dem von Mixed Mode entwickelten Linux Update Framework LIUF kombinieren. Es wurde für die Client-Seite Linux-basierter, verteilter IoT-Systeme entwickelt und setzt daran an, Laufzeitinstanzen eines Update-Systems auf dem aktuellen Stand der Technik »As a Commodity« zu erzeugen. Außerdem minimiert es die Risiken, die aufgrund sich ändernder Anforderungen im Bereich des Software Deployment entstehen, und richtet den Fokus der Entwicklungstätigkeit weg von Boilerplate hin zu fachlicher Domänenlogik. Das Framework ist seit 2020 verfügbar und wird von mehreren industriellen Nutzern eingesetzt. Es bietet eine in Python 3 entwickelte Plugin-Architektur und folgt dem objektorientierten Entwicklungsansatz. Zudem bildet es alle fachlichen Aspekte über Schnittstellen und Basisklassen ab, die der User entsprechend seinen Bedürfnissen zum Erweitern und Spezialisieren implementieren kann. In der Praxis hat sich gezeigt, dass das System über seine entwicklerfreundliche Struktur der Abstraktionshierarchie gut anwendbar ist.

Eine Besonderheit des Systems besteht darin, dass Entwickler mit hinreichend komplex definierten Update-Mechaniken ebenfalls Plugins »On the Fly« aus den Update-Paketen extrahieren, laden und ausführen können. So können technische Details des Update-Vorgangs in verschiedenen Szenarien vor dem Zugriff eines potenziellen Angreifers verborgen bleiben. Das LIUF ist prinzipiell bereits mit vielen Freiheitsgraden konfiguriert und über die Plugin-Struktur ergänzbar (Bild 2). Es enthält somit von vorneherein eine Reihe von Standardmodulen. Für Prototypen oder Anforderungen eingeschränkter Spezifität können Entwickler so gängige Use Cases aus dem Stand umsetzen. Beispiel: Das LIUF bietet eine Paketaktualisierung über »apt« und »dpkg« und stellt eine sichere Kommunikation mit der »Hawkbit Management API1« bereit. Verschlüsselte und signierte Images können zum Update auf Block Devices (u. a. SD, eMMC, SSD, HDD) transferiert und ausgerollt werden. Eine besondere Synergie ergibt sich aus der Kombination von Erweiterung und Konfiguration des LIUF mit der aktuellen Spezifikation von »The Update Framework« 2 (TUF), das ebenso in anderen gängigen Update-Systemen zum Einsatz kommt. Hierdurch erweitert sich der technische Rahmen des LIUF um die Rollen- und Delegationskalküle von TUF, um ein Beispiel zu nennen.

Ein typischer CI/CD-Zyklus

Der Ablauf eines CI/CD-Zyklus läuft standardmäßig wie folgt ab: Nach der Entwicklung eines Software-Inkrements legt das CI-System, getriggert durch den Build Server (z. B. Azure DevOps oder AWS in einer Cloud), den Firmware-Blob sowie den HILF-Blob ab. Ersterer umfasst die neue Version der Firmware auf dem DuT, die zu testen ist. So beinhaltet der HILF-Blob die aktuelle Version des Test-Frameworks, angepasste beziehungsweise neugeschriebene Testfälle und Testplan. Das Deployment selbst steuert das LIUF, das die Konsistenz sowie das Absichern der Updates gewährleistet. Für den Fall eines inkonsistenten Zustands des DuT oder eines Übertragungsproblems, das bei verteilten Arbeitsgruppen durchaus vorkommen kann, gewährleistet das LIUF den Rollback in einen definierten Vorzustand. Ausführen, Steuern und Auswerten der Tests selbst obliegen Test Runner und Test Server auf dem MM-HILF, wobei LIUF und MM-HILF auf den jeweiligen Anwendungsfall über Pythonskripte zugeschnitten sind. Anschließend werden die Testergebnisse dem Build Server, also der obersten steuernden Applikation, zurückgespielt, wo sie visualisiert und archiviert werden.

Dr. Richard Kölbl
Dr. Richard Kölbl von Mixed Mode.
© Mixed Mode

Selbstredend ist es auf die Weise möglich, eine verteilte Entwicklungsstruktur umzusetzen, die mittlerweile mit zunehmendem Homeoffice gegeben ist. Zudem stellt das LIUF Security-Applikationen bereit, die Updates über das Netz absichern. Je nachdem, welches System zum Einsatz kommt, ist schließlich ebenfalls der jeweilige Projektstatus mit den Testergebnissen zu verknüpfen. Beispielsweise bietet Azure DevOps diese Funktion, das die agile Produktentwicklung (z. B. Scrum) vom Verwalten der Product Backlogs, der Testfälle und -pläne, die Build Pipelines mit ihren Triggern und Visualisieren aller Build- und Testergebnisse unterstützt. Kombiniert man die Komponenten, ergibt sich eine praxisbewährte, erweiterbare und vor allem kostengünstige Applikation, um gewissermaßen die Bremsensteuerung einer Straßenbahn neben sich auf dem Entwicklerschreibtisch zu testen.


Das könnte Sie auch interessieren

Verwandte Artikel

Mixed Mode GmbH

TWO Embedded Computing 22