Anzeige

Einfach automatisiert

Die Fehlerinjektion ist eine bewährte Methode, um insbesondere die Software von
sicherheitskritischen Anwendungen dokumentierten Tests zu unterziehen. Für eine nachweisliche 100-prozentige Anweisungsüberdeckung lassen sich jetzt im Test-Tool Tessy mithilfe der Fault-Injection-Funktion Fehlersituationen vollkommen ohne Quellcodeänderung automatisiert testen.

 (Bild: Senior Software Quality Consultant)

(Bild: Senior Software Quality Consultant)

In der Softwareentwicklung Safety-relevanter Anwendungen kommt es in der Code-Erstellung auf Programmiertechniken wie Diversität, Defensivität, Selbsttests und ständige Überprüfungen an. Für den Entwickler bedeutet das eine besondere Herausforderung hinsichtlich der Einhaltung der einschlägigen Normen, wie ISO26262, EN/IEC61508, EN50128 oder IEC62304. Denn die Konformität muss durch dokumentierte Test, wie z.B. eine 100-prozentige Anweisungsüberdeckung (Statement Coverage), nachgewiesen werden. Ob die Funktionalität der Software den Anforderungen entspricht, lässt sich in der Regel ganz einfach mit etablierten Testwerkzeugen nachweisen. Allerdings kann hier die Anweisungsüberdeckung nicht immer vollständig erfüllt werden. Das liegt u.a. daran, dass im Funktionstest nicht alle denkbaren Fehler auftreten und deshalb die Sicherheitsvorkehrungen in der Software nicht vollständig abgearbeitet werden können. Für eine 100-prozentige Statement Coverage muss der Testingenieur daher Fehlersituationen aktiv erzeugen.

Statement Coverage vollständig erfüllen

In einem System- oder HiL (Hardware in the Loop)-Test lassen sich Fehlersituationen relativ einfach herbeiführen, denn es können äußere Interfaces durch Stimulation des Testsystems gesteuert und dadurch Fehlersituationen reproduzierbar getestet werden. Auf diese Weise lässt sich die Anweisungsüberdeckung erhöhen, aber oft noch nicht zu 100 Prozent erfüllen. Das liegt daran, dass die internen Sicherheitsvorkehrungen in der Software, wie z.B. die Diversität, hier nicht beeinflusst werden können. Eine weitere Schwierigkeit stellt die Messung der Statement Coverage dar. Bei der hier eingesetzten Technik wird der Quellcode instrumentiert, was Einfluss auf das dynamische Verhalten des Systems haben kann. In der Praxis wird die Anweisungsüberdeckung hauptsächlich während des Unit Test ermittelt. Auf diese Weise lassen sich beim Test einzelner Funktionen auch die internen Sicherheitsvorkehrungen in der Software testen.

Durch Anwenden von normgerechten Messmethoden wird bereits ein hohes Maß an Testqualität und damit eine hohe Statement Coverage der getesteten Funktion erreicht. Bei hoch-sicherheitskritischem Code lässt sich damit aber immer noch keine 100-prozentige Anweisungsüberdeckung erzielen. Denn Sicherheitsfunktionen wie Diversität und Anwendung von defensiven Programmiertechniken können nur durch Herbeiführen einer entsprechenden Fehlersituation vollständig getestet werden. Ferner wird bei schweren Fehlersituationen der sichere Zustand des Systems nur dadurch erreicht, dass das Programm in eine Endlosschleife läuft und darauf wartet, dass ein Watchdog anschlägt und das System in einen sicheren Modus überführt. Wird der Test auf dem Mikrocontroller ausgeführt, kann die Hardware nicht so einfach in jeden beliebigen Fehlerzustand versetzt werden, denn die Register der Peripherieeinheiten können nur entsprechend ihrer Hardware-Implementierung eingestellt werden. Folglich lassen sich auch in der Software nicht alle Fehlerzustände herstellen. Beim Einsatz eines Simulators wird je nach Leistungsumfang die Peripherie ebenso simuliert und es ergibt sich dieselbe Schwierigkeit wie beim Mikrocontroller-Test. Die Simulation der Peripherie kann zwar zumeist konfiguriert oder abgestellt werden, allerdings geht dann das Verhalten der Hardware verloren. So wird z.B. nach einem Schreibbefehl an die Peripherie ein Registerbit durch die Hardware gesetzt. Ohne Simulation liegen die Register der Peripherie in einem RAM-Speicher und verhalten sich nur noch wie eine Variable.

Fault Injection ohne Quellcodeänderung

Abhilfe schaffen an dieser Stelle Techniken wie die Fehlerinjektion (Fault Injection): Dazu werden im Quellcode, z.B. mithilfe von Makros, Fehler in die Anwendung eingeschleust, um ihr Verhalten in diesem Fall zu testen. In der Entwicklung wird die Fault Injection mit Sicht auf das System und die Systemanforderungen durchgeführt und ohne Berücksichtigung der inneren Sicherheitsvorkehrungen der Software. Eine unvollständige Anweisungsüberdeckung tritt damit erst bei der Entwicklung der Unit Tests auf. Diesen Mangel kann der Testingenieur erkennen und dann entsprechend die notwendigen Fehlerinjektionen implementieren. Die manuelle Fault Injection, z.B. mit Makros, hat den entscheidenden Nachteil, dass sie von Hand durchgeführt und verwaltet wird – und anschließend im produktiven Quellcode verbleibt. Das stellt beim Test von hoch-sicherheitskritischen Anwendungen ein Problem dar, denn in einem normgerechten Entwicklungsprozess sollte eine Quellcodeveränderung wieder alle Instanzen durchlaufen. Das bedeutet, die Änderungen für die Fault Injection werden freigegeben, in das Versionskontrollsystem übertragen und durchlaufen einen Codereview. Dieser Umweg bedeutet einen häufig unerwünschten zusätzlichen Zeit- und Kostenaufwand. Aus diesem Grund kommt die Analyse der Anweisungsüberdeckung bei professionellen Unit-Test-Werkzeugen ohne Quellcodeänderung aus. Dabei wird die Rate der Anweisungsüberdeckung ebenfalls mithilfe des Quellcodes gemessen, aber die Implementierung ist dynamisch für die Testdurchführung und verbleibt nicht dauerhaft im produktiven Quellcode. Durch das Abschalten der Messung der Anweisungsüberdeckung ist darüber hinaus bei einem erneuten Testlauf durch das gleiche Ergebnis beider Testdurchführungen gewährleistet, dass diese Instrumentierung keinen Einfluss auf den Ablauf der Funktion nimmt.

Fault Injection: Ein Beispiel

Beleuchten wir eine oft genutzte Funktionalität eines sehr einfachen Handlers einer Zustandsmaschine. Hierbei verhindern Sicherheitsmaßnahmen, dass der default-Pfad eines switch-Statements erreicht werden kann. Nur mit einer Fault Injection, die z.B. einen undefinierten Zustand einstellt, ist es möglich, diesen default-Pfad zu erreichen. Im Systemtest ist eine derartige Fehlerinjektion nicht möglich, da keine Software-Fault-Injections mehr vorhanden sind. Im HiL-Test werden zumeist Fault Injections für spezifizierte Fehlersituationen eingesetzt, die in den seltensten Fällen derartige oder alle default-Pfade abdecken. Nur während Unit-Test-Phase können Fehlerinjektionen sinnvoll für die Abdeckungsanalyse eingesetzt werden, was zudem eine sehr gute Ausgangsbasis für folgende Testphasen wie Integrations-, HiL- und Systemtest ist. Betrachten wir das Beispiel genauer: Das einhüllende if-Statement in Zeile 7 fasst alle vorherigen Sicherheitsabfragen über den gültigen Zustand der Zustandsmaschine zusammen. Ist der Zustand undefiniert, erfolgt bereits nach dieser Sicherheitsabfrage der Aufruf des Error Handlers und die Funktion wird beendet. Durch solche oder ähnliche vorherige Überprüfungen des Zustandes können nicht alle default-Pfade in der Software erreicht werden, so wie im vorliegenden Beispiel in Zeile 20 der default-Pfad des switch-Statements nicht erreicht werden kann.

 

Eine Fehlerinjektion, gesteuert über ein Define FAULTINJECTION für den C-Präprozessor, kann z.B. ab Zeile 9 des obigen Beispiels wie folgt aussehen:

 

Wird das Define FAULTINJECTION gesetzt, so kann auch diese Fehlersituation getestet und die Anweisungsüberdeckung zu 100 Prozent erfüllt werden. Die zusätzliche Testvariable tstFaultInjection steuert, ob die Fehlersituation für einen Testfall eintritt oder nicht, und wird gleichzeitig als Wert für den undefinierten Zustand genutzt. Bei der Erzeugung des binären Codes für das Endprodukt ist das Define FAULTINJECTION nicht gesetzt und die Fault Injection sollte nicht vorhanden sein. Da nicht immer alle Fault Injections aktiv sein können, werden diese für das System weiter unterteilt und über verschiedene Defines und Testvariablen gesteuert. Je nach Umfang des Systems steigt die Anzahl der Fault Injections, was wiederum eine entsprechende Verwaltung notwendig macht.

Das könnte Sie auch interessieren

Mit kompakten Lösungen für das Internet der Dinge verbindet ICPDAS die Feldebene mit der IT-Ebene. Dazu bietet der IIoT Communication Server UA-5231 viele Technologien in einem Gerät. Neben den Datenerfassungs- und Steuerungsfunktionen, verfügt er über einen integrierten OPC-UA-Server und MQTT-Broker.

Anzeige

Kontron stellt den neuen Embedded Server Zinc Cube SKD vor. Der Embedded Server basiert auf Intel Xeon D-2100 Prozessoren (12C 75W/8C 65W/4C 60W) mit vier bis zwölf CPU-Kernen, seine acht DIMM-Sockel unterstützen bis zu 256GB ECC Speicher. Zudem ist der Server mit acht 2,5"-SATA-SSD/HDD-Wechsellaufwerken sowie einem internen M.2-2280-Laufwerk ausgestattet, jeweils mit möglichen RAID-Funktionalitäten. Die Schnittstellen umfassen zwei USB3.0-Anschlüsse an der Frontseite sowie an der Rückseite zwei USB3.0- und zwei USB2.0-Anschlüsse. Für einen hohen Datendurchsatz sorgen die vier 10GBit SFP+ LAN-Ethernet-Schnittstellen. Systemerweiterungen können über einen PCIe x16 (Double Wide) und zwei PCIe x8 Erweiterungssteckplätze vorgenommen werden. Zertifiziert ist er für Windows 10, Windows Server und Linux Server. Dank des ‚Rugged Designs‘ bietet der Server eine hohe Widerstandfähigkeit gegenüber Schock und Vibrationen.

Um im Embedded-Umfeld erfolgreich agil zu entwickeln, müssen neben den Scrum-Grundlagen die Besonderheiten des komplexen Zusammenspiels von Hard- und Software von der Planung bis zum Test berücksichtigt werden. ScrumBedded verspricht hier als maßgeschneiderte Lösung Erfolg.

Das UrsaLeo UL-NXP1S2R2-Kit von RS Components enthält ein Silicon Labs Thunderboard 2-Sensormodul, das für die Verbindung mit der Plattform von UrsaLeo in der Google Cloud vorbereitet ist. Der bereits vorregistrierter Zugriff hilft Entwicklern, schnell produktive Fortschritte zu machen.

Die neue Version der Wago Cloud geht voraussichtlich im ersten Quartal 2019 an den Start. Neben den etablierten Funktionen wie Controllerstatusverwaltung und Dashboards stehen das moderne, übersichtliche Design in Appstruktur sowie weitere Funktionen wie Fernzugang im Fokus.

Sigfox stellte auf der Sigfox Connect die vernetzte Bubble vor, mit der man weltweit Assets lokalisieren kann. Bubbles sind kleine, innerhalb weniger Sekunden überall installierbare Transmitter zum Tracking von Sigfox-Devices, deren Sendeleistung die Lokalisierungsreichweite definiert.

Anzeige
Anzeige
Anzeige