-
Stand der Technik
-
Die
vorliegenden Erfindung betrifft ein Verfahren und ein Werkzeug zum Überprüfen eines
Software-Produkts nach Anspruch 1 und 10.
-
Eine
derartige Prüfung
wird in Zukunft wichtig, da zB im Kontext der Autosar-Initiative
in der Zusammenarbeit zwischen Zulieferern und Herstellern Software-Referenzarchitekturen
einzuhalten sind und die Einhaltung nachzuweisen sein wird.
-
Im
Automotive-Bereich gibt es mehrere Initiativen, die Formalismen
entwickeln, um Architekturschnittstellen implementierungsunabhängig zu
beschreiben. Die prominenteste dieser Initiativen ist das Autosar-Projekt
(AUTomotive Open Software Architecture, www.autosar.org),
in dem Beschreibungsmechanismen für Schnittstellen bereitgestellt
werden, die eine frühe
virtuelle Software-Integration ermöglichen sollen. Ein weiteres
Beispiel ist die AADL (Architecture Analysis & Design Language) der SAE (Society
of Automobile Engineers International: AADL, Document Number: AS5506,
SAE Standard, Nov 2004). Diese Architekturspezifikationssprache
wurde für
die Beschreibung von Automotive Systemarchitekturen mit besonderem
Fokus auf Performanz-Aspekten entwickelt. Den bekannten Architekturspezifikationssprachen
ist gemeinsam, dass sie ihren Schwerpunkt auf der Architekturebene
haben. Die Abbildung auf die Code-Ebene bzw der Abgleich zwischen
Architekturbeschreibung und Umsetzung wird offen gelassen.
-
Es
existieren auch unterschiedliche Arten von Tools, die zB C-Code
analysieren und Querbezüge
im C-Code aufdecken können.
Dazu gehören
Quellcode-Browser, wie zB der in Microsoft Visual Studio enthaltene Class-Browser,
welche die statischen Aufruf- und Nutzungsbeziehungen im Code analysieren
und anhand solcher Beziehungen durch den Code navigieren können. Darüber hinaus
existieren C-Parser und statische Analyse-Programme wie Imagix 4D© (Imagix
Corp.) oder QA-C© (QA-Systems), welche die Aufruf- und Nutzungsbeziehungen
im Code parsen und analysieren, und diese automatisch visualisieren
können,
zB als Graph oder UML-Diagramm.
-
Diesen
Tools fehlt allerdings die Fähigkeit,
die im Quelltext gefundenen Strukturen mit einer vorgegebenen Soll-Architektur
abzugleichen.
-
Die
deutsche Offenlegungsschrift
DE 101 44 050 offenbart ein Verfahren und
ein Werkzeug zum Überprüfen von
Software für
Steuereinheiten, bei dem aus einem identischen Simulationsmodell
für eine
Experimentalsteuereinheit und eine Seriensteuereinheit ein Softwarecode
generiert wird, und Ausgangsgrößen beider
Einheiten gegeneinander verifiziert werden.
-
Die
deutsche Offenlegungsschrift
DE 100 62 545 offenbart ein Verfahren zum Überprüfen eines
Netzwerkes und ein Netzwerk hierzu. Dabei wird eine aktuelle Netztopologie
mit einer dauerhaft abgespeicherten Referenz-Netztopologie verglichen,
wobei eine Änderung
der Anzahl und/oder Art der an das Netzwerk angeschlossenen Geräte, der
Topologie und/oder der Netzknoten erkannt werden kann.
-
Beide
Verfahren setzen jedoch einen automatischen Übersetzungsschritt zwischen
einem Modell und dem daraus resultierenden Code voraus. Modell und
Code sind damit äquivalent,
womit deren Übereinstimmung
lediglich eingeschränkt
auf rein funktionaler Ebene geprüft
werden kann. Ist der Code jedoch nicht äquivalent zur Architektur,
sondern folgt ihren strukturellen Vorgaben auf einer abstrakten
Ebene, auf der ganz allgemein wünschenswerte
Eigenschaften eines Produkts schon vor der eigentlichen Erstellung
des Codes festgelegt werden, ist eine entsprechende Überprüfung ausgeschlossen.
-
Offenbarung der Erfindung
-
Es
ist Aufgabe der vorliegenden Erfindung, ein Verfahren zum Überprüfen eines
Software-Produkts zur Verfügung
zu stellen, das eine Aussage darüber
zulässt,
ob eine gegebene Umsetzung des Produkts tatsächlich die von einer Spezifikation
geforderte Struktur und geforderten Eigenschaften aufweist, das
zudem einfach strukturiert, leicht realisierbar sowie kostengünstig ist.
Es ist auch Aufgabe der vorliegenden Erfindung, ein entsprechendes
Werkzeug bereit zu stellen.
-
Diese
Aufgabe wird durch ein Verfahren gelöst, mit einer Software-Architekturspezifikation,
die zentrale strukturelle Entscheidungen für das Produkt oder die Produktfamilie
festlegt, und einer Software-Referenzarchitektur, die darüber hinaus
Eigenschaften festlegt, die alle Produkte oder Produktfamilien einer
Organisation aufweisen müssen,
umfassend die Schritte: Überprüfen der
Konsistenz zwischen der Architekturspezifikation und der Referenzarchitektur; Überprüfen der
Konsistenz sowohl zwischen der Struktur des Produktcodes und der
Referenzarchitektur, als auch zwischen der Struktur des Codes und
der Architekturspezifikation, und Erstellen eines Konformitätsberichts
zum Dokumentieren von Architekturverletzungen.
-
Ein
wesentlicher Punkt des Verfahrens besteht in der Fähigkeit,
die im Quelltext gefundenen Strukturen mit einer vorgegebenen Soll-Architektur
abzugleichen und somit automatisiert zu verifizieren, dass eine Software
die Soll-Architektur
einhält.
-
Dem
erfindungsgemäßen Verfahren
liegt dabei die Idee zugrunde, dass eine Software-Architektur in den
zentralen Entscheidungen besteht, die getroffen wurden, um das Erreichen
von Qualitätseigenschaften bei
einem Software-Produkt
bzw einer Software-Produktlinie sicherzustellen. Das heißt, dass
die Architektur eine Vorgabe, also ein bewusst festgelegter Sollzustand
ist. In diese Sinne soll im Folgenden der Begriff Software-Architekturspezifikation
verwendet werden, der eine Produktarchitektur definiert. Diese Architektursicht wird
zB auch im Rational Unified Process verwendet (Kruchten:
The Rational Unified Process. Auch zitiert in Booch, Rumbaugh, and
Jacobson: The Unified Modeling Language User Guide, Addison-Wesley,
1999). Da eine solche Architekturspezifikation ein Sollzustand
ist, von dem die tatsächliche
Struktur des Produkts abweichen kann, wird ein Soll-Ist-Vergleich
zwischen geforderten und tatsächlichen
Produkteigenschaften im Hinblick auf die Architektur benötigt. Die
vorliegende Erfindung stellt für
diesen Vergleich ein weitgehend automatisierbares Prüfverfahren
vor.
-
Bevorzugte
Weiterbildungen des erfindungsgemäßen Verfahrens sind in den
Unteransprüchen
2 bis 9 angegeben.
-
Danach
ist es in einer vorteilhaften Ausführungsform vorgesehen, dass
das Verfahren eine Software-Referenzarchitektur (RA) nutzt, die
Eigenschaften festlegt, welche alle Produkte oder Produktfamilien
einer Organisation aufweisen müssen,
und das die weiteren Schritte umfasst: Überprüfen der Konsistenz zwischen der
Architekturspezifikation und der Referenzarchitektur, und Überprüfen der
Konsistenz zwischen der Struktur des Produktcodes und der Referenzarchitektur.
-
Ein
Spezialfall einer Architekturspezifikation ist die Software-Referenzarchitektur.
Hierbei handelt es sich um eine Architekturspezifikation, die bestimmte
Teile einer Architektur vorgibt, die von mehreren Produkten einheitlich
umgesetzt werden sollen. Die Einführung einer Referenzarchitektur
ist eine wichtige Voraussetzung, um eine geplante Wiederverwendung
der Software zu ermöglichen.
Typischerweise gibt eine Referenzarchitektur ein Strukturierungsprinzip
vor, wie zB die Schichtenbildung im Kommunikationsbereich oder bei Datenbanken,
oder die Komponentenbildung im Bereich der Benutzerschnittstellen.
Außerdem
werden typischerweise Kommunikationsmuster zwischen den Architekturelementen
festgelegt. Eine Referenzarchitektur kann zB das Ziel der einfachen
Wartbarkeit von Produkten bei Änderung
von Software-Anforderungen, der einfachen Wartbarkeit von Produkten
bei Änderung
der Hardware-Umgebung, der schnellen Integrierbarkeit von Fremdsoftware,
der schnellen Integrierbarkeit von wieder verwendbaren Software-Blocks, der vorhersagbaren Performanz,
und/oder der Erreichung der Performanz unter wettbewerbstauglichen
Ressourcenanforderungen verfolgen.
-
Die Überprüfung eines
Software-Produkts ist insbesondere in zwei Einsatzszenarien von
Vorteil. Einerseits bei der internen Absicherung einer Software,
wobei sich dann, wenn die Software ihre Soll-Architektur einhält, Kostenvorteile
realisieren lassen, zB durch bessere Wartbarkeit und Verständlichkeit.
Andererseits bei der Integration mit Fremdsoftware, wobei es möglich wird,
bei Zulieferungen unterschiedlicher Softwareteile sicherzustellen,
dass jeder Teil seine Architekturschnittstellen einhält, was
den Integrationsaufwand senkt und Fehlerquellen durch Ausschluss
unspezifizierter Interaktionen zwischen den Software-Teilen reduziert.
-
Der
praktische Einsatz des Verfahrens wird dadurch gewährleistet,
dass keine Veränderungen
im Quelltext vorgenommen werden müssen. Es muss lediglich die
Referenzarchitektur und die Architekturspezifikation in einer für das Verfahren
verständlichen
Form aufgeschrieben werden.
-
Dabei
ist es bevorzugt, dass zunächst
die Konsistenz der Software-Architekturspezifikation selbst überprüft wird.
Dadurch werden Fehlerquellen in der Spezifikation ausgeschlossen,
die Grundlage für
die konkrete Implementierung des späteren Produkts ist.
-
Eine
besonders einfache und durchgängige Überprüfung des
Software-Produkts ergibt sich dadurch, dass die Software-Referenzarchitektur
ein Strukturierungsprinzip für
das Produkt vorgibt, dass die Bildung von Modulen zum Abstrahieren
von Zuständigkeiten
zulässt,
zB für
Mikrocontroller, Sensoren, Aktoren usw.
-
Zur
Definition von Interaktionen ist es dabei von Vorteil, wenn das
Strukturierungsprinzip die Definition von Abhängigkeiten zwischen den Modulen
zulässt,
diese Abhängigkeiten
zusätzlich
hierarchische Beziehungen zwischen den Modulen definieren können, und
diese Beziehungen wiederum wenigstens die Beziehungen 'part-of', 'uses' und 'allowed-to-use' umfassen.
-
In
vorteilhafter Weise werden ergänzende
Reviews zum Überprüfen des
Software-Produkts durchgeführt.
Im Rahmen eines Gesamtprüfkonzepts
kann zB durch derartige Ergänzung
einer automatischen Prüfung zuverlässig die
Einhaltung einer Architekturspezifikation überprüft werden.
-
Das
Verfahren soll bevorzugt zur Überprüfung der
Software von Steuergeräten
von Fahrzeugen angewandt werden.
-
Die
eingangs genannte Aufgabe wird auch durch ein Werkzeug zum Überprüfen eines
Software-Produkts gelöst,
das zum automatischen Durchführen
des erfindungsgemäßen Verfahrens
ausgebildet ist, wobei die Software-Referenzarchitektur in wenigstens
einem selbstständig
lauffähigen
Prüfmodul
hinterlegt ist, der zum Einlesen und Verarbeiten der Struktur des
Produktcodes und von dessen Architekturspezifikation ausgeführt werden
kann.
-
Ein
wesentlicher Punkt des erfindungsgemäßen Werkzeugs besteht in der
Automation des Verfahrens, dass den Entwickler entlastet. Wie bereits
vorstehend beschrieben, muss lediglich die Referenzarchitektur und
die Architekturspezifikation in einer für das Verfahren verständlichen
Form aufgeschrieben werden.
-
Bevorzugte
Weiterbildungen des erfindungsgemäßen Werkzeugs sind in den Unteransprüchen 11
bis 13 angegeben.
-
Danach
ist es in einer vorteilhaften Ausführungsform vorgesehen, dass
die Software-Referenzarchitektur einschließlich des Verfahrens zur Architekturprüfung in
wenigstens einem Code-Analyse-Tool (zB einem Python-Analyse-Skript) und die Software-Architekturspezifikation
in wenigstens einer Spezifikationsdatei (zB einer XML-Datei), sowie
die Struktur des Codes in wenigstens einer Analysedatei (zB einer
QA-C©-Datei)
festgelegt ist. Damit stehen grundsätzlich alle am Markt bereits
erhältlichen
und zur werkzeugseitigen Umsetzung des Verfahrens geeigneten Tools
und Sprachen zur Verfügung,
so dass dies keiner eigenständigen
Entwicklung mehr bedarf. Um Änderungen
der Referenzarchitektur leicht zu integrieren, können insbesondere Definitionen
aus dem Python-Skript in ein eigenständiges Modul ausgelagert werden.
-
Der
Entwicklungsprozess eines Software-Produkts wird bevorzugt dadurch
unterstützt,
indem wenigstens eine Version der Software-Referenzarchitektur gespeichert
wird, und die Software-Architekturspezifikation eine Angabe darüber enthält, gegen
welche Version der Referenzarchitektur eine Überprüfung durchgeführt werden
soll. Damit lassen sich in besonders einfacher Weise Weiterentwicklungen,
Anpassungen, Optimierungen usw eines Produkts auf Konsistenz mit
der Spezifikation überprüfen.
-
In
bevorzugter Weise enthält
der Konformitätsbericht
Angaben darüber,
ob eine 'allowed-to-use'-Beziehung verletzt
ist, dh ob auf eine Variable oder Funktion entgegen den Regeln der
Referenzarchitektur zugegriffen wird. Damit werden strukturelle
Inkonsistenzen zwischen dem Software-Produkt und der Spezifikation
ausgeschlossen, die besonders schwer zu berichtigen sind. Außerdem kann
somit, insbesondere bei zugelieferten Anteilen des Produkts festgestellt
werden, ob diese tatsächlich
die mittels 'allowed-to-use' festgelegten Einschränkungen
einhalten. Dies ist zB für
die Anwendung mit Autosar von zentraler Bedeutung.
-
Kurze Beschreibung der Zeichnungen
-
Das
erfindungsgemäße Verfahren
und das Werkzeug werden im folgenden anhand eines Ausführungsbeispiels
näher erläutert. Gleiche
oder gleichwirkende Teile sind mit gleichen Bezugszeichen versehen. Es
zeigen:
-
1 Stufen
der erfindungsgemäßen Ableitung
einer Architektur;
-
2 Abhängigkeiten
von Modulen der 1 mit 'allowed-to-use'-Beziehung;
-
3 Abhängigkeiten
von Modulen der 1 mit 'uses'-Beziehung;
-
4 zwei
Architekturverletzungen von Beziehungen der 3;
-
5 eine
werkzeugseitige Umsetzung des erfindungsgemäßen Verfahrens, und
-
6 Abhängigkeiten
von Modulen mit 'publishes'- und 'uses'-Beziehungen.
-
Ausführungsformen der Erfindung
-
Im
Folgenden wird ein Ausführungsbeispiel
beschrieben, das mit Hilfe eines Tools zur statischen Codeanalyse
und eines Python-Scripts prüft,
ob die vorgegebene Software-Referenzarchitektur
mit ihren Kommunikationsbeziehungen von dem Produkt eingehalten
wird. Das Konzept sieht vor, dass eine Software-Architekturspezifikation
mit Hilfe einer XML-Datei
dokumentiert wird. Der erste Schritt der Überprüfung besteht darin, die Konsistenz
der Software-Architekturspezifikation
mit der Software-Referenzarchitektur zu prüfen. Im zweiten Schritt wird
der vorliegende Code sowohl gegen die Software-Referenzarchitektur
als auch gegen die Software-Architekturspezifikation geprüft. Die
gefundenen Architekturverletzungen werden in einem Konformitätsbericht
dokumentiert.
-
Die 1 zeigt
Stufen der erfindungsgemäßen Ableitung
einer Architektur. Diese Stufen bestehen aus einer Referenzarchitektur
RA (Reference Architecture), einer Produktarchitektur PA (Product
Architecture), und einer Umsetzung I (Implementation) der Architekturen
RA und PA in ein Software-Produkt. Die Referenz-Architektur RA gibt
unternehmensweite Entscheidungen über alle Produkte, die Produktarchitektur
PA Entscheidungen über
Eigenschaften einer Plattform und die Umsetzung I die Realisierung
eines Produkts in C-Code wieder. Die einzelnen Stufen sind in Modulen
gegliedert, wobei in einzelnen Schichten L1...Ln (Layer) bestimmte
Zuständigkeiten
abstrahiert sind. Es gibt zB Layer Ln, die Eigenschaften eines verwendeten
Mikrocontrollers oder verwendeter Sensoren und Aktoren kapseln und
somit vor der Software verstecken. Die Layer L1...Ln bestehen wiederum
aus Blocks, die eine Granularität
der Architektur darstellen, auf der eine Wiederverwendung stattfindet.
Zur geplanten Wiederverwendung gedachte Blocks werden als Building
Blocks SBB (Standard Building Blocks) bezeichnet. Jeder Block wird
durch eine Menge von Quell-Dateien (Source-Files) implementiert.
Die Produktarchitektur weist dabei produktspezifische Blocks PSB
(Product Specific Block), die Umsetzung I entsprechend umgesetzte
Blocks IB (Implemented Blocks) aus.
-
Um
die Änderung
der Software zu erleichtern, werden hier nur bestimmte definierte
Abhängigkeiten zwischen
den Lagern L1... Ln zugelassen, dh ein Lager Ln darf nur eine definierte
Menge anderer Lager L1...Ln benutzen. Diese erlaubten Benutzungen
zwischen Lagern L1...Ln werden in der 'allowed-to-use'-Beziehung
definiert. Die Blocks eines Lagers Ln dürfen sich untereinander uneingeschränkt benutzen.
Ein Block darf aus anderen Lagern Ln nur die explizit exportierten
Symbole der Lager L1...Ln nutzen. Die Kommunikation zwischen den
Blocks und den Lagern L1...Ln erfolgt über Public Symbols. Diese können globale
Variablen, Funktionen oder auch Makros sein.
-
Das
im Folgenden vorzustellende Prüfkonzept
stellt eine Methodik und ein Werkzeug vor, welche die Einhaltung
von Architekturspezifikationen durch in C implementierte Software
weitgehend automatisch prüfen. Darüber hinaus
wird ein Gesamtprüfkonzept
vorgestellt, in dem die automatische Prüfung so durch Reviews ergänzt wird,
dass zuverlässig
die Einhaltung einer Architekturspezifikation überprüft werden kann.
-
Durch
das vorgestellte Werkzeug wird auf Basis der Referenzarchitektur,
einer vom Entwickler dokumentierten Produktarchitektur und einer
Umsetzung dieser Produktarchitektur in Code geprüft, ob Konsistenz besteht zwischen
der Referenzarchitektur, die unternehmensweite Entscheidungen über alle
Produkte der Organisation widerspiegelt, der geplanten Plattform
oder Produktarchitektur, welche die vom Architekten/Entwickler gewünschte Struktur
des Produkts ausdrückt,
und der realen Struktur des Quell-Codes.
-
Das
Prüfkonzept
ermittelt die Konsistenz zwischen Referenzarchitektur, Produktarchitektur
und Implementierung. Es wird hier eine semantische Konsistenzprüfung dieser
drei Ebenen mit einem Prüfkonzept
vorgestellt, das aus zwei Elementen besteht. Zum einen aus einer
automatischen Prüfung
und zum anderen aus Reviewfragen. Damit wird insgesamt sicher gestellt,
dass die Software nicht nur die Syntax der Referenzarchitektur einhält (vorwiegend
durch die automatische Prüfung überprüft), sondern
auch den Ideen und Absichten folgt, die hinter der Referenzarchitektur
stecken (vorwiegend durch Prüffragen
abgedeckt).
-
Das
beschriebene Verfahren geht von einer Modulsicht der Architektur
aus. Bei dieser Architektursicht besteht die Architektur aus hierarchisch
aufgebauten Architektur-Elementen.
Zwischen diesen Architektur-Elementen werden folgende Beziehungen
betrachtet, die Gegenstand der Überprüfung durch
das Verfahren und das Werkzeug sein sollen.
-
'part-of': Ein Element ist
in einem anderen enthalten. In der hier verwendeten Referenzarchitektur
gibt es zB eine zweistufige 'part-of'-Beziehung, bei der
Layer L Blocks, und Blocks wiederum Quelldateien enthalten.
-
'publishes': Beziehung, die
zwischen einem Symbol S und einem Element A besteht, wenn A dieses Symbol
S anderen Elementen zur Benutzung zur Verfügung stellt. Das Publizieren
eines Symbols ist Voraussetzung für dessen Verwendung mittels 'uses' von anderen Elementen
wie zB Layer oder Block aus.
-
'uses': Ein Element A ist
von einem Element B abhängig,
wenn die Änderung
von B potentiell eine Änderung
von A zur Folge hat. Beispielsweise hängt eine C-Quelldatei A von
der C-Quelldatei
B ab, weil sie deren Header-Datei einliest. Eine 'uses'-Beziehung kann im
Sinne der hier gewählten
Referenzarchitektur auf zwei Arten vorliegen. Zum einen kann ein
Block A einen Block B aus demselben Layer L benutzen, dh eine C-Quelldatei,
die A implementiert, benutzt Symbole, die von B in der Regel in
einer Header-Datei publiziert werden. Zum anderen kann ein Block
A ein Symbol aus einem anderen Layer L benutzen, das der Layer L
ebenfalls in der Regel über
eine Header-Datei publiziert. A darf aber nicht direkt von einem
bestimmten Block in dem Layer L abhängen – dies würde der Kapselungseigenschaft
des Lagers L widersprechen.
-
'allowed-to-use': Beziehung zwischen
zwei Elementen der Referenzarchitektur RA. Wenn zwischen zwei Elementen
in der Referenzarchitektur RA eine 'allowed-to-use'-Beziehung besteht, so darf zwischen
den entsprechenden Elementen der Produktarchitektur PA eine 'uses'-Beziehung bestehen.
Für die
hier benutzte Referenzarchitektur RA heißt dies zum einen, dass dann,
wenn zwischen zwei Lagern L1 und L2 eine 'allowed-to-use'-Beziehung besteht, eine 'uses'-Beziehung zwischen
den Blocks des Lagers L1 und dem Layer L2 bestehen darf. Das heißt, eine 'uses'-Beziehung für alle Blocks
B, so dass B 'part-of' L1 gilt, und B 'uses' L2 eine erlaubte
Benutzungsbeziehung ist. Zum anderen gilt implizit in der Software-Referenzarchitektur,
dass Blocks innerhalb eines Lagers Ln sich gegenseitig benutzen
dürfen.
-
Die
Referenzarchitektur RA definiert nun eine Menge von Architektur-Elementen
und schränkt
auf diesen die 'uses'-Beziehung durch Angabe einer 'allowed-to-use'-Beziehung ein.
-
Die 2 zeigt
Abhängigkeiten
von Modulen (Lagern, Blocks) der 1 mit 'allowed-to-use'-Beziehung. In diesem
Beispiel, was im Folgenden durchgängig verwendet werden wird,
definiert die Referenzarchitektur RA die drei Layer L1, L2 und L3.
Die 'allowed-to-use'-Beziehung (jeweils
durch breite schwarze Pfeile verdeutlicht) legt nun zwei erlaubte Benutzungsbeziehungen
zwischen Lagern Ln fest, nämlich
L1 darf L2 verwenden, und L2 darf L3 verwenden.
-
Die
Produktarchitektur PA bezieht sich nun auf die Referenzarchitektur
RA, in dem sie per 'part-of'-Beziehung festlegt,
in welchen Architektur-Elementen der Referenzarchitektur RA die
im Produkt definierten Architekturelemente liegen, nämlich Block
B1a 'part-of' Lager L1, B1b 'part-of' L1, B2a 'part-of' L2, B2b 'part-of' L2 und B3 'part-of' L3.
-
Die 3 zeigt
Abhängigkeiten
von Modulen (Lagern, Blocks) der 1 mit 'uses'-Beziehung. Anhand
dieser Figur wird das Zusammenspiel der automatischen Prüfung und
der Prüfung
durch Review beispielhaft beschrieben. Es sind dabei die tatsächlichen
Nutzungsbeziehungen in der Produktarchitektur PA wiedergegeben.
Die 'uses'-Beziehungen zwischen
den Blocks sind gestrichelt wiedergegeben, und als Block B1a 'uses' Lager L2, B1b 'uses' L2, B2b 'uses' L1, B1a 'uses' L3, B2a 'uses' L3 und B2b 'uses' L3 zu lesen. Der Block
B1a benutzt ein Symbol wie zB eine Funktion oder eine Variable,
das von Block B2a definiert und von Lager L2 publiziert wird (jeweils
durch schwarzen Punkt und durchgezogene Linie verdeutlicht). Da
der Lager L1 den Lager L2 darf, dürfen auch die im Lager L1 enthaltenen
Blocks B1a, B1b den Lager L2 nutzen (wie in Figur jeweils durch
breite schwarze Pfeile angegeben). Somit ist diese 'uses'-Beziehung korrekt
im Sinne der Referenzarchitektur RA.
-
Die 4 zeigt
zwei Architekturverletzungen von Beziehungen der 3,
also Verletzungen der Referenzarchitektur RA durch die gegebene
Produktarchitektur PA. Die beiden Verletzungen sollen nun durch eine
automatische Architekturverifikation nachgewiesen werden.
-
Block
B1a 'uses' Lager L3: Benutzt
Block B1a ein von Lager L3 (Block B3) angebotenes Symbol, zB durch
einen Funktionsaufruf oder Referenzierung einer globalen Variablen,
so ist die Referenzarchitektur RA verletzt, da es keine 'allowed-to-use'-Beziehung zwischen
Layer L1 und L3 gibt. Diese Architekturverletzung lässt sich
rein syntaktisch durch die erfindungsgemäß vorgestellte automatische
Architekturprüfung
feststellen. Block B1a kann jedoch auch die Architektur verletzen,
ohne syntaktisch Block B3 zu benutzen, indem dieser Annahmen trifft,
die gewisse Code-Teile oder bestimmte Algorithmen in Block B3 voraussetzen,
die aber nicht in der Spezifikation von Block B3 beschrieben sind.
Zum Beispiel könnte
der Programmierer von Block B1a wissen, dass Block B3 ein Signal
bereits entprellt, obwohl dies in der Spezifikation nicht steht.
Besteht eine solche implizite Abhängigkeit, lässt sich Block B3 nicht ohne
Seiteneffekte austauschen. Diese Art der Verletzung der Referenzarchitektur
RA lässt
sich nicht durch eine automatische Überprüfung entdecken, dazu ist vielmehr
ein Review durch einen Menschen notwendig.
-
Block
B2b 'uses' Layer L1: In diesem
Fall liegt der Fehler in der unerlaubten Richtung der Benutzung. Block
B2b benutzt ein von Layer L1 (Block B1b) angebotenes Symbol. Zwar
darf Layer L1 den Layer L2 benutzen, aber nicht umgekehrt. Eine
Nutzung des Lagers L1 durch den Layer L2 widerspricht also der Referenzarchitektur
RA. Wird die Benutzung des von Layer L1 angebotenen Symbols durch
Block B2b in der Produktarchitektur dokumentiert, so ist die Verletzung
der Referenzarchitektur durch die Produktarchitektur automatisch
feststellbar. Erfolgt dagegen die Nutzung nur im Code, so ist es
schwieriger, die Verletzung der Architektur abzulesen, da die Richtung
der Abhängigkeit
im Code nicht ohne Weiteres ersichtlich ist. Als Beispiel kann ein Scheduler
dienen, der eine Applikationsfunktion aufruft. Im Code ist die Aufrufrichtung
vom Scheduler zur Applikation. Die Abhängigkeit ist aber umgekehrt,
da die Applikation den Scheduler braucht, während der Scheduler auch ohne
diese spezifische Applikationsfunktion funktioniert. Aus diesen Beispielen
folgt, dass nicht alle Verletzungen der Referenzarchitektur RA automatisch
festgestellt werden können.
Das erfindungsgemäße automatische
Prüfverfahren
verfolgt hier einen konservativen Ansatz. Es kann nicht alle Architekturverletzungen detektieren,
aber alle vom Programm angezeigten Verletzungen stellen tatsächliche
Verletzungen der Architektur dar.
-
Die 5 zeigt
eine werkzeugseitige Umsetzung des erfindungsgemäßen Verfahrens. Die automatische
Architekturprüfung
erfolgt durch ein Python-Skript CM (Check Modul), das sich aus drei
Quellen bedient. Zum einen der Spezifikation der Referenzarchitektur
RA als Python-Modul, zum anderen der Spezifikation der Produktarchitektur
PA als XML-Datei, und schließlich
der Beschreibung der Code-Struktur auf Basis von Ergebnis-Dateien
QR (QA-C© Results)
mit darin festgehaltenen Abhängigkeiten
D, die aus der Analyse der Umsetzung I durch ein Code-Analyse-Tool,
hier QA-C© rühren. Diese
drei Quellen werden miteinander verglichen, wobei Inkonsistenzen
zwischen den drei Darstellungsebenen als Fehler EM (Error Messages)
in Form eines Konformitätsberichts
CR (Conformance Report) ausgegeben werden.
-
Im
Folgenden wird auf jede der drei Quellen RA, PA und QR sowie auf
das Ergebnis genauer eingegangen.
-
Die
Spezifikation der Referenzarchitektur RA besteht aus der maschinenlesbaren
Definition der 'allowed-to-use'-Beziehungen. Diese Definition wurde
hier aus dem Python-Skript
in ein eigenes Python-Modul ausgelagert, um Änderungen der Referenzarchitektur
leicht integrieren zu können.
Außerdem
lassen sich in dem Python-Modul mehrere Versionen der Referenzarchitektur
RA abspeichern – die
Spezifikation der Produktarchitektur PA enthält die Angabe, gegen welche
Version der Referenzarchitektur RA geprüft werden soll.
-
Als
Beispiel für
die Definition einer Referenzarchitektur dient die 'allowed-to-use'-Beziehung der
2, die
hier tabellarisch zusammengestellt ist.
Lager | allowed-to-use |
Lager
1 | Lager
1, Lager 2 |
Lager
2 | Lager
2, Lager 3 |
Lager
3 | Lager
3 |
-
Dabei
darf Lager L1 die Blocks im eigenen Lager und den Lager L2 und Lager
L3 benutzen. Lager L2 darf nur die Blocks im eigenen Lager und Lager
L3 benutzen. Lager L3 darf nur auf die Blocks im eigenen Lager zugreifen.
Gibt es querschnittliche Funktionen in der Referenzarchitektur RA,
bei denen es dem Scheduler zB erlaubt ist, auf sämtliche Blocks zuzugreifen,
so wird für
die Ausnahme ein eigener Lager definiert, der auf alle anderen Lager
L1...Ln zugreifen darf.
-
Die
Produktarchitektur PA wird in einer XML-Datei definiert. Mit Hilfe
einer DTD (Document Type Declaration) wird überprüft, ob die Angaben vollständig und
vom richtigen Typ sind. Folgende tabellarisch aufgeführte Konstrukte
stehen zu Verfügung.
Element | Attribut | Bedeutung |
ArchitectureElement | Name,
Container,
AEType,
RAVersion | Ein
Architekturelement (Lager oder Block). Das Attribut Name gibt den
Namen an. Container gibt zu einem Block an, welcher Lager den Block
enthält,
bei einem Lager steht hier der Wert 'root',
der aussagt, das Lager auf der obersten Ebene der Architektur angesiedelt
sind. AEType gibt an, ob es sich um einen Lager oder einen Block
handelt. RAVersion enthält
die verwendete Version der Referenzarchitektur. |
Publishes | SymbolName,
SymbolType | Definiert
ein Symbol, das von einem Architekturelement publiziert wird. SymbolName
gibt den Namen des Symbols an, SymbolType gibt an, ob es sich um eine
Variable, eine Funktion, oder ein Makro handelt. |
Uses | SymbolName
SymbolType | Gibt
an, dass ein Block ein Symbol verwendet. SymbolName gibt den Namen
des Symbols an, SymbolType gibt an, ob es sich um eine Variable,
eine Funktion, oder ein Makro handelt. |
-
Die 6 zeigt
schließlich
Abhängigkeiten
von Modulen (Lagern, Blocks) mit 'publishes'-(jeweils durch schwarzen Punkt und
durchgezogene Linie angegeben) und 'uses'-Beziehungen (jeweils
durch gestrichelte Linie verdeutlicht). Die 'allowed-to-use'-Beziehungen sind analog den 1 bis 4 angemerkt.
Als Beispiel wird ein Satz von Definitionen angegeben, die zu der
hier gezeigten Produktarchitektur PA passen. Zum einen wird das
Symbol x vom Block B3 bereitgestellt. Der Lager L3 publiziert das
Symbol zur Benutzung durch andere Lager Ln gemäß der 'allowed-to-use'-Beziehung.
Weiterhin wird das Symbol y vom Block B2a bereitgestellt und vom
Lager L2 publiziert, und das Symbol z wird von Block B1a bereitgestellt
und Lager intern von Block B1b verwendet.
-
Die
zugehörige
Spezifikation in XML stellt sich damit wie folgt dar.
-
-
-
Das
statische Code-Analyse-Tool QA-C© erzeugt
nach der Überprüfung des
Codes für
jede C-Datei einige Ergebnisdateien QR, von denen Callpack-Dateien
(.call) und Cross-Reference-Dateien
(.xrefl) ausgewertet werden. Erstere enthalten die Definitionen
von Variablen und Funktionen, die extern gelinkt werden, die zweiten
Aufrufe von externen Funktionen und Deklarationen von externen Variablen.
-
Bei
jedem Aufruf des Python-Skripts wird ein Konformitätsbericht
CR in Form einer Datei erzeugt, der die Ergebnisse der Architekturprüfung enthält. Falls
die Überprüfung ergibt,
dass der C-Code nicht konform zur Referenzarchitektur RA ist, so
soll dieser Konformitätsbericht
CR dem Entwickler eine Hilfestellung sein, warum die Angaben in
der XML-Datei und der C-Code nicht übereinstimmen. Dazu wird zunächst die
XML-Datei selbst auf Konsistenz geprüft und anschließend mit
den C-Dateien verglichen. Der Konformitätsbericht enthält im ersten
Teil eine Zusammenfassung, welche Variablen und Funktionen in den
vorhandenen C-Dateien definiert und benutzt werden. Dabei wird das
Verzeichnis in dem sich das Python-Script befindet und alle Unterverzeichnisse
davon nach C-Dateien durchsucht. Der zweite Teil besteht aus Analyse-Ergebnissen
und enthält zB
folgende Informationen. Ein Fehler wird ausgegeben, falls die XML-Datei
in sich selbst nicht konsistent ist, zB wenn exportierte Variablen/Funktionen
nicht wieder in der XML-Datei
benutzt werden. Ein Fehler wird auch ausgegeben, falls in der XML-Datei
Variablen/Funktionen mehrmals exportiert werden. Weiterhin wird
ein Fehler ausgegeben, falls die Benutzungsbeziehungen in der XML-Datei
nicht den Regeln der Referenzarchitektur entsprechen. Ein Fehler
wird zudem ausgegeben, falls die Angaben über die C-Dateien in der XML-Datei mit den C-Dateien
in den Verzeichnissen nicht überein
stimmen. Dies kann der Fall sein, wenn Dateien in den Verzeichnissen
existieren, die in der XML-Datei nicht vorkommen oder umgekehrt.
Zusätzlich
wird ein Fehler ausgegeben, falls eine Variable und/oder Funktion
nur in der XML-Datei, jedoch nicht in den C-Dateien existiert. Auch
wird ein Fehler ausgegeben, falls ein Variable und/oder Funktion
nur im C-Code, jedoch nicht in der XML-Datei benutzt wird. Schließlich wird
ein Fehler ausgegeben, falls im C-Code eine 'allowed-to-use'-Beziehung verletzt wird, dh falls auf
eine Variable und/oder Funktion zugegriffen wird und dieser Zugriff
den Regeln der Referenzarchitektur widerspricht.
-
Das
Skript in der Skriptsprache Python liest die XML-Datei ein und legt 'Dictionaries' an, in denen sämtliche
Beziehungen der Produkt-Architektur gespeichert sind. In einem ersten
Verarbeitungsschritt werden dabei Inkonsistenzen aufgedeckt, zB
wenn Variablen definiert werden, die aber innerhalb der XML-Datei
nicht wieder verwendet werden. Im zweiten Schritt wird geprüft, ob die
Referenzarchitektur eingehalten wurde, dh ob alle 'allowed-to-use'-Beziehungen eingehalten
wurden. Dazu wertet das Skript die .call und .xref Dateien aus,
die von QA-C© erzeugt
werden. Mit Hilfe dieser Dateien können wiederum 'Dictionaries' aufgebaut werden,
die dann sämtliche
Beziehungen im C-Code enthalten. Damit kann die Produktarchitektur
PA mit der Referenzarchitektur RA verglichen werden. Der zusätzliche
Aufwand, der entsteht, um eine Architekturprüfung durchführen zu können, besteht lediglich in
der Formulierung der Produktarchitektur PA in einer XML-Datei, die dann
vom Skript ausgewertet werden kann.
-
Ein
entsprechendes Skript RACheck.py wird einfach durch Doppelklicken
im Explorer gestartet. Nach Beendigung des Skriptes existiert im
gleichen Verzeichnis eine Datei RA_check.txt, welche die Ergebnisse
der Architekturüberprüfung enthält. In einer
Datei ra_verification.xml ist die Produktarchitektur PA definiert – die dazu
passende DTD ist ra_verification.dtd.
-
Möglicherweise
können
nicht alle Verletzungen der Referenzarchitektur automatisch gefunden
werden. Insbesondere werden Verletzungen durch implizite Annahmen
und/oder Wissen aus anderen Lagern nicht automatisch entdeckt. Darum
wird den Entwicklern ein Katalog von Regeln und Prüffragen
an die Hand gegeben, mit dessen Hilfe sie oder ein Prüfteam die
Einhaltung der Referenzarchitektur prüfen können, insbesondere die Ideen
und Absichten, die hinter der Referenzarchitektur stecken. Die Regeln
bestehen dabei aus den drei Teilen Begründung für die Regel, Beispiel und Prüffragen.
Die Regeln können
weiterhin vier Kategorien zugeordnet werden, die sich als Fragen
formulieren lassen können.
Befindet sich der Block und/oder die Funktionalität im richtigen
Lager, zB muss der Block, der einen Sensor abstrahiert, im Sensor
und/oder Aktor-Lager sein? Wird die 'allowed-to-use'-Beziehung eingehalten, dh werden nur
die erlaubten Blocks benutzt? Sind die Blocks nach außen hin
abgeschottet (information hiding), dh werden keine Annahmen über das
Verhalten anderer Blocks gemacht? Werden die Codierrichtlinien eingehalten?
-
Insgesamt
ergibt sich damit ein in sich geschlossenes Verfahren zur durchgängigen und
zuverlässigen Konsistenzprüfung eines
Softwareprodukts. Das Verfahren ist leicht umsetzbar, da es von
dem Entwickler und/oder Prüfteam
lediglich die Dokumentation der Produktarchitektur erfordert. Zudem
kann das Verfahren insoweit automatisiert werden, als lediglich
implizites Wissen bzw Annahmen der Entwickler nicht oder nicht notwendigerweise
erfasst wird. Das Verfahren ist daher äußerst effizient, zuverlässig und
gleichzeitig kostengünstig
realisierbar.