Handbuch

45.2
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 45.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 18.2.

45.2.1
Der DaemonLocator

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

 
 
public 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.
 
public 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.
 
public 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.
 
 
45.2.2
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.

 
 
public void ping()
Prüft, ob der Daemon noch lebt.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public String getHost()
Liefert den Host des Daemons.
RückgabewertDer Host des Daemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public String getIp()
Liefert die IP-Adresse des Daemons.
Rückgabewert Die IP-Adresse des Daemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public int getPort()
Liefert den Port des Daemons.
Rückgabewert Der Port des Daemons.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public TestRunDaemon getSharedTestRunDaemon()
Liefert den gemeinsamen TestRunDaemon.
Rückgabewert Der gemeinsame TestRunDaemon.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public TestRunDaemon createTestRunDaemon()
Erzeugt einen TestRunDaemon.
Rückgabewert Ein TestRunDaemon.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public 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.
 
public 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.
 
public void killClients()
Beendet alle Clients, die zur VM des Daemons gehören.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
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.
 
 
45.2.3
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.

45.2.3.1
Verschiedenes
 
 
public 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.
 
 
45.2.3.2
Bearbeiten globaler Variablen
 
 
public 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.
 
public 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.
 
public Properties getGlobals()
Liefert die Werte aller globalen Variablen.
Rückgabewert Die Werte aller globalen Variablen.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public void clearGlobals()
Löscht alle globalen Variablen.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
 
45.2.3.3
Testausführung
 
 
public 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.
 
public 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.
 
public 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.
 
public 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.
 
public 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.
 
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.
 
 
45.2.3.4
Identifikation
 
 
public 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.
 
public 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.
 
 
45.2.4
Der DaemonRunContext

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

Folgende Laufzustände sind definiert:

Status Wert Beschreibung
STATE_INVALID -1 Ungültig nach der Freigabe - kann nicht reaktiviert werden.
STATE_IDLE 0 Kein Lauf geplant.
STATE_SCHEDULED 1 Lauf geplant aber nicht gestartet.
STATE_RUNNING 2 Laufend.
STATE_PAUSED 3 Laufend aber pausiert.
STATE_FINISHED 4 Lauf beendet, Resultat und Protokoll verfügbar.
Tabelle 45.1:  Der Laufzustand
 
 
public 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.
 
public 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.
 
public int getThreadNum()
Liefert den Thread-Index des DaemonRunContext.
Parameter
Rückgabewert Der Thread-Index des DaemonRunContext.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public int getRunState()
Liefert den aktuellen Laufzustand des Runcontext. Möglich sind die Werte STATE_IDLE, STATE_SCHEDULED, STATE_RUNNING, STATE_PAUSED, STATE_FINISHED.
Rückgabewert Der aktuelle Laufzustand des Runcontext.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public 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.
 
public 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.
 
public 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.
 
public 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.
 
public 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.
 
public void stopRun()
Hält den Testlauf an.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Wenn kein Testlauf angestoßen war.
 
public int getResult()
Liefert das Resultat des Testlaufs.
Rückgabewert 0, 1, 2, 3 für OK, warning, error, exception.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
IllegalStateException Wenn der Laufzustand ungleich STATE_FINISHED ist.
 
public 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.
 
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.
 
public 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.
 
public 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.
 
public 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.
 
public 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.
 
public Properties getGlobals()
Liefert alle globalen Variablen im DaemonRunContext.
Rückgabewert Die globalen Variablen.
Exceptions
RemoteException Wenn etwas RMI-Spezifisches schief geht.
 
public 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.
 
public 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.
 
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.
 
void removeTestRunListener(DaemonTestRunListener listener)
Entfernt einen DaemonTestRunListener vom DaemonRunContext.
Parameter
listenerDer zu entfernende Listener.
 
void clearTestRunListeners()
Entfernt alle DaemonTestRunListener vom DaemonRunContext.
 
 
3.1+45.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 44.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.