Daemon API

Um QF-Test im Daemon-Modus von einer weiteren QF-Test Instanz oder einem anderen Werkzeug zur Durchführung von QF-Test basierten Tests einzusetzen müssen folgende relativ einfache Schritte implementiert werden:

Hinweis Wen Sie eine auf dem Daemon API basierende Anwendung schreiben, müssen Sie sich über Sicherheitsthemen Gedanken machen und Sicherheit entweder deaktivieren, oder einige RMI-spezifische Properties setzen. Näheres hierzu finden Sie in Abschnitt 53.3.

  • Nutzen Sie den DaemonLocator, um damit Zugriff auf einen Daemon zu erhalten.
  • Holen Sie sich entweder den gemeinsamen TestRunDaemon oder weisen Sie den Daemon an, einen TestRunDaemon zu erzeugen. Über diesen TestRunDaemon können Sie globale Variablen und das Wurzelverzeichnis der Testsuiten für die kommenden Testläufe definieren.
  • Holen Sie sich entweder den gemeinsamen DaemonRunContext des TestRunDaemon oder lassen Sie diesen eine oder mehrere Instanzen von DaemonRunContext erzeugen. Ein DaemonRunContext repräsentiert den Ausführungs-Kontext für einen funktionalen Test oder Lasttest. Jeder DaemonRunContext ist eigenständig, mit Ausnahme von Gruppen die mittels TestRunDaemon.createContexts(int threads) erstellt wurden. Diese bilden einen gemeinsamen Kontext für Lasttests, analog zum Start von QF-Test mit dem Kommandozeilenargument -threads <Anzahl>. Jeder DaemonRunContext belegt eine QF-Test Entwickler- oder Runtime Lizenz für die Dauer seines Bestehens.
  • Nun können Sie den DaemonRunContext anweisen, Tests in Ihrem Namen durchzuführen, wahlweise ganze Testsuiten oder spezifische 'Testfallsatz' oder 'Testfall' Knoten. Mit richtig implementierten 'Abhängigkeiten' können Sie im Daemon-Modus einzelne 'Testfälle' in beliebiger Reihenfolge ausführen, ohne sich um die nötigen Vorbereitungs- und Aufräumarbeiten kümmern zu müssen.
  • Der DaemonRunContext bietet auch Methoden zur Abfrage des aktuellen Status eines Tests oder zum Warten auf sein Ende an.
  • Schließlich können Sie noch das Protokoll des Testlauf vom Daemon abholen. Im Moment können Sie dieses lediglich in eine Datei speichern. Später planen wir das API weiter zu öffnen, um zum Beispiel Protokolle von verschiedenen Testläufen aus potenziell verschiedenen Daemons in einem Protokoll zusammenzufassen.

Beim Übergang von einem 'Testfall' zum nächsten kann die korrekte Abarbeitung der Abhängigkeiten - inklusive das Aufösen der nicht mehr benötigten Abhängigkeiten auf dem Stapel - nur dann funktionieren, wenn immer der selbe DaemonRunContext verwendet wird. Dies erreichen Sie am einfachsten durch Verwendung der gemeinsamen TestRunDaemon und DaemonRunContext Objekte. Das Erzeugen von eigenen Objekten macht nur in Spezialfällen Sinn.

Die folgenden Abschnitte enthalten eine komplette Referenz der gesamten Daemon API. Erläuterungen und Beispiele zu deren Verwendung finden Sie in Abschnitt 23.2.

Der DaemonLocator

Über die Singleton Klasse de.qfs.apps.qftest.daemon.DaemonLocator kann auf Daemon Instanzen zugegriffen werden.

 
 
static DaemonLocator instance()
Es gibt immer nur ein einziges DaemonLocator Objekt und diese Methode ist der einzige Weg, Zugriff auf diese Singleton Instanz zu erlangen.
RückgabewertDie DaemonLocator Singleton Instanz.
 
Daemon locateDaemon(String host, int port)
Liefert einen Daemon für einen spezifischen Host und Port.
Parameter
host Der Ziel-Host, Name oder IP-Adresse als String.
port Der Ziel-Port.
RückgabewertDer Daemon oder null falls kein Daemon gefunden wurde.
 
Daemon[] locateDaemons(long timeout)
Alle bekannten Daemons lokalisieren.
Parameter
timeout Die Zeit in Millisekunden, um auf Reaktionen von Daemons zu warten.
RückgabewertDie bekannten Daemons.
 
void setKeystore(String keystoreFile)
Legt den Keystore fest, welcher für die Sicherung der Daemon-Kommunikation verwendet werden soll.
Parameter
keystoreFile Der Pfad zur Datei, welche den Keystore zur Verschlüsselung der Daemon-Kommunikation enthält.
 
void setKeystorePassword(String password)
Legt das Passwort für den Keystore fest, der mit setKeystore gesetzt wurde.
Parameter
password Das Passwort.
 
void setTruststore(String truststoreFile)
Legt den Truststore fest, welcher für die Sicherung der Daemon-Kommunikation verwendet werden soll. Wenn dieser nicht gesetzt ist dann wird der Keystore verwendet, der mit setKeystore gesetzt wurde.
Parameter
truststoreFile Der Pfad zur Datei, welche den Truststore zur Verschlüsselung der Daemon-Kommunikation enthält.
 
void setTruststorePassword(String password)
Legt das Passwort für den Truststore fest, der mit setTruststore gesetzt wurde.
Parameter
password Das Passwort.
 
 

Der Daemon

Das de.qfs.apps.qftest.daemon.Daemon Interface bietet einen Rahmen für verschiedene Arten von QF-Test Daemons. Aktuell ist nur der TestRunDaemon verfügbar, weitere Klassen wie ein SUTClientStarterDaemon sind bereits in Planung und weitere werden eventuell folgen.

 
 
void cleanup()
Räumt alle TestRunDaemons dieses Daemons und beendet dann alle Clients. Auf ein eventuelles Auflösen von Abhängigkeiten wird maximal 30 Sekunden gewartet.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void cleanup(long timeout)
Räumt alle TestRunDaemons dieses Daemons und beendet dann alle Clients.
Parameter
timeout Die maximale Wartezeit in Millisekunden für ein eventuelles Aufräumen von Abhängigkeiten.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
TestRunDaemon createTestRunDaemon()
Erzeugt einen TestRunDaemon.
Rückgabewert Ein TestRunDaemon.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
String getHost()
Liefert den Host des Daemons.
RückgabewertDer Host des Daemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
String getIp()
Liefert die IP-Adresse des Daemons.
Rückgabewert Die IP-Adresse des Daemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
int getPort()
Liefert den Port des Daemons.
Rückgabewert Der Port des Daemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
TestRunDaemon getSharedTestRunDaemon()
Liefert den gemeinsamen TestRunDaemon.
Rückgabewert Der gemeinsame TestRunDaemon.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
TestRunDaemon[] getTestRunDaemons()
Liefert alle von diesem Daemon erzeugten TestRunDaemons, die noch aktiv sind.
Rückgabewert Die aktiven TestRunDaemons, die von diesem Daemon erzeugt wurden, exklusive dem gemeinsamen TestRunDaemon.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void killClients()
Beendet alle Clients, die zur VM des Daemons gehören.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void ping()
Prüft, ob der Daemon noch lebt.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void terminate(int exitCode)
Beendet den Daemon-Prozess durch den Aufruf von System.exit.
Parameter
exitCode Der Exit-Code für den Daemon.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 

Der TestRunDaemon

Der de.qfs.apps.qftest.daemon.TestRunDaemon ist der Einstiegspunkt für die Ausführung von Tests. Er stellt die Umgebung für Testläufe bereit und erstellt DaemonRunContext Objekte welche die eigentliche Durchführung übernehmen.

Verschiedenes

 
 
Daemon getDaemon()
Liefert den Daemon zu dem der TestRunDaemon gehört.
Rückgabewert Der Daemon des TestRunDaemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 

Bearbeiten globaler Variablen

Der TestRunDaemon hält einen eigenen Satz globaler Variablen vor, die zur Initilaisierung der globalen Variablen beim Erzeugen eines neuen DaemonRunContext dienen. Die folgenden Methoden haben keinen Einfluss auf bereits laufende DaemonRunContext Instanzen.

 
 
void clearGlobals()
Löscht alle globalen Variablen.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
String getGlobal(String name)
Liefert den Wert einer globalen Variable.
Parameter
name Der Name der globalen Variable.
Rückgabewert Der Wert der globalen Variable oder null wenn undefiniert.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
Properties getGlobals()
Liefert die Werte aller globalen Variablen.
Rückgabewert Die Werte aller globalen Variablen.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void setGlobal(String name, String value)
Setzt den Wert einer globalen Variable.
Parameter
name Der Name der globalen Variable.
value Der Wert der globalen Variable.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 

Testausführung

 
 
void cleanup()
Räumt alle DaemonRunContexte dieses TestRunDaemons auf und gibts sie frei. Auf ein eventuelles Auflösen von Abhängigkeiten wird maximal 30 Sekunden gewartet.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void cleanup(long timeout)
Räumt alle DaemonRunContexte dieses TestRunDaemons auf und gibts sie frei.
Parameter
timeout Die maximale Wartezeit in Millisekunden für ein eventuelles Aufräumen von Abhängigkeiten.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
DaemonRunContext createContext()
Erzeugt einen einzelnen Daemon Runcontext. Hierfür wird eine Lizenz benötigt und belegt.
Rückgabewert Der Runcontext oder null wenn keine Lizenz belegt werden konnte.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
DaemonRunContext[] createContexts(int threads)
Erzeugt Daemon Runcontext Objekte für mehrere Threads. Es wird eine Lizenz je Thread benötigt und belegt.
Parameter
threads Die Zahl der Threads für den Runcontext.
Rückgabewert Die Runcontext Objekte oder null wenn nicht genug Lizenzen belegt werden konnten.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
DaemonRunContext[] getContexts()
Liefert alle von diesem TestRunDaemon erzeugten DaemonRunContexte, die noch aktiv sind und nicht freigegeben wurden.
Rückgabewert Die aktiven DaemonRunContexte, die von diesem TestRunDaemon erzeugt wurden, exklusive dem gemeinsamen DaemonRunContext.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
DaemonRunContext getSharedContext()
Liefert den gemeinsamen DaemonRunContext. Falls dieser neu erstellt werden muss, wird eine neue Lizenz benötigt und belegt.
Rückgabewert Der gemeinsame RunContext oder null wenn keine Lizenz belegt werden konnte.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void setRootDirectory(String directory)
Setzt das Testsuite-Wurzelverzeichnis für neu erzeugte Daemon Runcontexte.
Parameter
directory Das neue Wurzelverzeichnis.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 

Identifikation

 
 
String getIdentifier()
Liefert den Namen zur Identifikation des TestRunDaemons. Wurde kein Name explizit via setIdentifier gesetzt, wird ein Name aus dem Namen des Daemons, zu dem der TestRunDaemon gehört, sowie einem Zähler gebildet.
Rückgabewert Der Name des TestRunDaemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void setIdentifier(String identifier)
Setzt einen Namen zur Identifikation des TestRunDaemons. Dies kann nützlich sein um einen TestRunDaemon zu identifizieren, der via Daemon.getTestRunDaemons() ermittelt wurde.
Parameter
identifier Der zu setzende Name.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 

Der DaemonRunContext

Das de.qfs.apps.qftest.daemon.DaemonRunContext Interface dient der eigentlichen Testdurchführung.

Folgende Laufzustände sind definiert:

StatusWertBeschreibung
STATE_INVALID-1Ungültig nach der Freigabe - kann nicht reaktiviert werden.
STATE_IDLE0Kein Lauf geplant.
STATE_SCHEDULED1Lauf geplant aber nicht gestartet.
STATE_RUNNING2Laufend.
STATE_PAUSED3Laufend aber pausiert.
STATE_FINISHED4Lauf beendet, Resultat und Protokoll verfügbar.
Tabelle 53.1:  Der Laufzustand

6.0+ Die folgenden Ergebnis-Werte für die Methode getResult() sind die gleichen wie überall in QF-Test:

ErgebnisWertBeschreibung
RESULT_OK0Lauf OK, keine Warnungen, Fehler oder Exceptions.
RESULT_WARNING1Lauf weitgehend OK, einige Warnungen aber keine Fehler oder Exceptions.
RESULT_ERROR2Lauf mit Fehlern aber ohne Exceptions.
RESULT_EXCEPTION3Lauf mit Exception fehlgeschlagen.
Tabelle 53.2:  Die Ergebnis-Werte
 
 
void addTestRunListener(DaemonTestRunListener listener, boolean synchronous, long timeout)
Registriert einen DaemonTestRunListener beim DaemonRunContext.
Parameter
listenerDer zu registrierende Listener.
synchronous Legt fest, ob der Listener synchron benachrichtigt werden soll. In diesem Fall wird der Testlauf blockiert, bis der Listener den Event verarbeitet hat.
timeout Wartezeit in Millisekunden für Aufrufe des Listeners. Falls der Listener nicht innerhalb dieser Zeitspanne antwortet, wird er automatisch deregistriert, um weitere Probleme zu vermeiden. Im Fall eines synchronen Listeners läuft dann auch der Test weiter. Ein Wert von 0 bedeutet kein Timeout, was nicht ungefährlich ist, aber nützlich sein kann.
 
boolean callProcedure(String procedure, Properties bindings=None)
Führt eine Prozedur in diesem Runcontext aus.
Parameter
procedure Die Prozedur, die ausgeführt werden soll, in der Form Suite#Procedure, wobei Procedure der vollständige Name einer 'Prozedur' sein muss.
bindings Ein optionaler Satz von Variablendefinitionen. Diese binden stärker als die globalen Variablen und als alle Definitionen auf dem sekundären Stapel.
Rückgabewert True falls der Prozeduraufruf gestartet wurde, false wenn die Suite oder die Prozedur nicht gefunden werden konnten.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Falls im gegenwärtigen Status kein Test gestartet werden kann, der Status also weder STATE_IDLE noch STATE_FINISHED ist.
 
void clearGlobals()
Löscht die globalen Variablen des DaemonRunContext.
Exceptions
RemoteException If something RMI specific goes wrong.
 
void clearTestRunListeners()
Entfernt alle DaemonTestRunListener vom DaemonRunContext.
 
String getGlobal(String name)
Liefert den Wert einer globalen Variable im DaemonRunContext.
Parameter
nameDer Name der Variable.
Rückgabewert Der Wert der Variable oder null falls nicht definiert.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
Properties getGlobals()
Liefert alle globalen Variablen im DaemonRunContext.
Rückgabewert Die globalen Variablen.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
String getIdentifier()
Liefert den Namen zur Identifikation des DaemonRunContexts. Wurde kein Name explizit via setIdentifier gesetzt, wird ein Name aus dem Namen des TestRunDaemons, zu dem der DaemonRunContext gehört, sowie einem Zähler gebildet.
Rückgabewert Der Name des DaemonRunContexts.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
String getLastTest()
Liefert den Namen der aktuell oder zuletzt von diesem DaemonRunContext ausgeführt wird oder wurde.
Rückgabewert Der Name des aktuellen bzw. zuletzt ausgeführten Tests.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
int getNumThreads()
Liefert die Zahl der Threads in der Gruppe zu der der DaemonRunContext gehört.
Rückgabewert Die Zahl der Threads der Gruppe des DaemonRunContext.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
Properties getProperties(String group)
Liefert alle Properties einer Property oder Ressource Gruppe im DaemonRunContext.
Parameter
nameDer Name der Property oder Ressource Gruppe.
Rückgabewert Die Properties oder null falls die Gruppe nicht existiert.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
String getProperty(String group, String name)
Liefert den Wert einer Property oder Ressource im DaemonRunContext.
Parameter
nameDer Name der Property oder Ressource Gruppe.
nameDer Name der Property.
Rückgabewert Der Wert der Property oder null falls nicht definiert.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
int getResult()
Liefert das Resultat des Testlaufs.
Rückgabewert Das Ergebnis des Testlaufs, einer der Werte RESULT_OK, RESULT_WARNING, RESULT_ERROR oder RESULT_EXCEPTION.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Wenn der Laufzustand ungleich STATE_FINISHED ist.
 
byte[] getRunLog()
Liefert das Protokoll des Testlaufs.
Rückgabewert Das Protokoll in Form eines byte array.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Wenn der Laufzustand ungleich STATE_FINISHED ist.
 
int getRunState()
Liefert den aktuellen Laufzustand des Runcontext.
Rückgabewert Der aktuelle Laufzustand des Runcontext, einer von STATE_IDLE, STATE_SCHEDULED, STATE_RUNNING, STATE_PAUSED oder STATE_FINISHED.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
TestRunDaemon getTestRunDaemon()
Liefert den TestRunDaemon zu dem der DaemonRunContext gehört.
Rückgabewert Der TestRunDaemon des DaemonRunContext.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
int getThreadNum()
Liefert den Thread-Index des DaemonRunContext.
Parameter
Rückgabewert Der Thread-Index des DaemonRunContext.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void release()
Gibt den DaemonRunContext frei und auch die Lizenz, die dieser belegt hatte. Wenn ein Test läuft, wird dieser angehalten.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Wenn kein DaemonRunContext angelegt war.
 
void removeTestRunListener(DaemonTestRunListener listener)
Entfernt einen DaemonTestRunListener vom DaemonRunContext.
Parameter
listenerDer zu entfernende Listener.
 
void rollbackDependencies()
Löst die Abhängigkeiten dieses DaemonRunContext auf.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Falls im gegenwärtigen Status kein Test gestartet werden kann, der Status also weder STATE_IDLE noch STATE_FINISHED ist.
 
boolean runTest(String test, Properties bindings=None)
Startet einen Test in diesem Runcontext.
Parameter
test Der Test, der ausgeführt werden soll, in der Form Suite#Test, wobei #Test optional ist und Test der vollständige Name eines Testfallsatzes oder Testfalls oder ein "." sein kann. Letzteres ist äquivalent zur Angabe von Suite alleine und bewirkt das Ausführen der ganzen Testsuite.

Beispiele:
MySuite   Führt die ganze Testsuite MySuite aus.
MySuite#.   Führt die ganze Testsuite MySuite aus.
MySuite#MyTestSet   Führt den Testfallsatz MyTestSet in der Testsuite MySuite aus.
MySuite#MyTestSet.MyTestCase   Führt den Testfall MyTestCase aus, der sich im Testfallsatz MyTestSet in der Testsuite MySuite befindet.
bindings Ein optionaler Satz von Variablendefinitionen. Diese binden stärker als die globalen Variablen und als alle Definitionen auf dem sekundären Stapel.
Rückgabewert True falls der Test gestartet wurde, false wenn die Suite oder der Test nicht gefunden werden konnten.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Falls im gegenwärtigen Status kein Test gestartet werden kann, der Status also weder STATE_IDLE noch STATE_FINISHED ist.
 
void setIdentifier(String identifier)
Setzt einen Namen zur Identifikation des DaemonRunContexts. Dies kann nützlich sein, um einen DaemonRunContext zu identifizieren, der via TestRunDaemon.getContexts() ermittelt wurde.
Parameter
identifier Der zu setzende Name.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void setGlobals(Properties globals)
Setzt die globalen Variablen des DaemonRunContext.
Parameter
globals Die zu setzende globalen Variablen.
Exceptions
RemoteException If something RMI specific goes wrong.
 
void setRootDirectory(String directory)
Setzt das Testsuite-Wurzelverzeichnis für den nächsten Testlauf.
Parameter
directory Das neue Wurzelverzeichnis.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
void stopRun()
Hält den Testlauf an.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Wenn kein Testlauf angestoßen war.
 
boolean waitForRunState(int state, long timeout)
Wartet bis der Runcontext einen vorgegebenen Zustand erreicht.
Parameter
state Der Zustand auf den gewartet werden soll.
timeout Maximale Wartezeit im Millisekunden.
Rückgabewert True falls der Zustand erreicht wurde, false wenn die Wartezeit verstrichen ist und der Zustand bis dahin nicht erreicht wurde.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 

3.1+53.2.5
Der DaemonTestRunListener

Das Interface de.qfs.apps.qftest.daemon.DaemonTestRunListener ist identisch zum Interface de.qfs.apps.qftest.extensions.qftest.TestRunListener, welches in Abschnitt 52.7 beschrieben wird, außer dass seine Methoden eine RemoteException bei RMI Problemen werfen können. Wenn Sie dieses Interface implementieren, müssen Sie von der Klasse java.rmi.server.UnicastRemoteObject ableiten.

Sie können den Listener beim DaemonRunContext mittels seiner Methode addTestRunListener registrieren, die im vorhergehenden Abschnitt beschrieben wurde.