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.

Fault Injenction: Einfach automatisiert



Das könnte Sie auch interessieren

MSC Technologies stellt zur embedded world 2018 (2-238) das Smarc-2.0-Modul MSC SM2S-IMX8M vor, das den aktuellen 64Bit Prozessor i.MX8M ARM Cortex-A53 von NXP integriert. Die leistungsfähige Baugruppe zeichnet sich durch einen geringen Energieverbrauch von 3 bis 6W bei einer hohen Rechen- und Grafikleistung aus.

Anzeige

Adlink präsentiert auf der embedded world 2018 (1-540) Technologien für die Fabrik der Zukunft. Im Fokus stehen fünf Lösungsplattformen, die Künstliche Intelligenz (KI) und Echtzeit zur Datenverarbeitung (RTOS) und Kommunikation (DDS) unterstützen.

Anzeige

Mit einem 3-D-Drucker können beliebige dreidimensionale Gegenstände erzeugt werden. Forscherinnen und Forschern des KIT ist es nun im Rahmen eines DFG-Projektes erstmals gelungen, mit einem handelsüblichen 3-D-Drucker das Metall Wolfram zu drucken, das wegen seines hohen Schmelzpunktes von 3.400°C beispielsweise bei Turbinenschaufeln von Düsentriebwerken Verwendung findet.

Anzeige

Eine hocheffiziente Speicherlösung für Überwachungsanwendungen, bei denen es nicht nur auf eine schnelle und zuverlässige Datensicherung, sondern auch auf eine hohe Videoqualität ankommt, stellt SE Spezial-Electronic auf der embedded world 2018 (3A-435) vor. Innodisks neue InnoREC 3MV2-P-Serie bietet eine effektive Datensicherheitsfunktion für verschiedene Videoaufzeichnungssysteme. Zudem gewährleistet die aufeinander abgestimmte Hard-, Soft- und Firmware eine hohe Systemzuverlässigkeit und eine hohe Bildqualität.

Die Validation Toolchain von b-plus bietet für die Aufnahme, Analyse und Verarbeitung vieler Sensoreingänge (z.B.

Der neue 10.1“ RISC basierte Panel PC IOBA-10F von ICP Deutschland ist für den Wandeinbau konzipiert und bietet vielseitige analoge und digitale Eingänge für IoT Sensorik von Grove.‣ weiterlesen

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige