Test long running processes
As long as the application under test is expected to terminate by itself,
it is fine to use .execute().assertSuccess() as we did in several examples above.
On the other hand, when testing some long running process, such as application server or a docker container, you typically want to
-
Run the command starting the service
-
Await it being up and running
-
Perform some assertions
-
Shut down the service
Here is a commented snippet suitable for such situations:
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
import org.cliassured.await.Await;
import org.cliassured.await.Await.LineAwait;
...
// Define an Await that will wait for first line on stdout matching the given regular expression
final LineAwait<Integer> awaitPort = Await
.lineMatching("listening on port: (\\d+)")
.map(Integer::parseInt); // transform the string matching the (\\d+) group to int
try (CommandProcess proc = CliAssured.command(/* Your command for starting the server comes here ... */)
.then()
.stdout()
.await(awaitPort)
.log()
.stderr()
.log()
.start()) {
// Wait at most for 10 seconds for the port message on stdout
int port = awaitPort.await(Duration.ofSeconds(10));
// Now the server has started - we can perform some tests requiring the port
RestAssured.get("http://localhost:" + port)
.then()
.statusCode(200);
} // proc gets auto-closed here
The default auto-close behavior of CommandProcess can be characterized as follows:
-
java.lang.Process.destroy()is called on the main process -
On Java 9+, any descendant processes returned by
process.toHandle().descendants()are also closed usingjava.lang.ProcessHandle.destroy() -
On Java 8, only the main process is destroyed
Use the following methods to customize the auto-closing behavior of
org.cliassured.CommandProcess:
-
CliAssured.command(…).autoCloseWithoutDescendants()to avoid closing descendant processes -
CliAssured.command(…).autoCloseForcibly()to close the main and descendant processes usingjava.lang.Process.destroyForcibly()andjava.lang.ProcessHandle.destroyForcibly()respectively -
CliAssured.command(…).autoCloseTimeout(Duration)to wait at most for the specifiedDurationafterdestroy()ordestroyForcibly()was called on main process and possibly on its descendant processes until the main process reports its state as terminated.