Invoke the command and await its termination
You can start the command process and await its termination in one step using CommandSpec.execute()
or you can use CommandSpec.start() and CommandProcess.awatTermination() if you need more control.
CommandSpec.execute()
0.0.1
execute() starts the command process and blocks until it terminates.
It is a shorthand for start().awaitTermination().
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
import org.cliassured.CommandResult;
// execute() starts the process, waits for it to terminate
// and returns a CommandResult
CommandResult result = CliAssured
.command("echo", "Hello World!")
.then()
.stdout()
.hasLines("Hello World!")
.execute();
// Check that all assertions passed
result.assertSuccess();
CommandSpec.start() and CommandProcess.awaitTermination()
0.0.1
Use start() when you need a reference to the running CommandProcess before it terminates — for example, to interact
with the process, read its PID, or await a specific output line.
Call awaitTermination() on the returned CommandProcess to block until it exits.
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
import org.cliassured.CommandResult;
// start() returns a running CommandProcess without blocking
CommandProcess proc = CliAssured
.command("echo", "Hello World!")
.then()
.stdout()
.hasLines("Hello World!")
.start();
// awaitTermination() blocks until the process exits
CommandResult result = proc.awaitTermination();
result.assertSuccess();
CommandProcess implements AutoCloseable, so you can use it in a try-with-resources block.
When the block exits, close() kills the process and waits for its termination.
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
import org.cliassured.CommandResult;
// CommandProcess is AutoCloseable — close() kills the process
try (CommandProcess proc = CliAssured
.command("echo", "Hello World!")
.then()
.stdout()
.hasLines("Hello World!")
.start()) {
// Interact with the running process here if needed
proc.awaitTermination()
.assertSuccess();
}
Timeouts
0.0.1
Use execute(Duration) or execute(long) to set a maximum time to wait for the process to terminate.
If the process does not terminate within the given timeout, it is killed.
import java.time.Duration;
import org.cliassured.CliAssured;
CliAssured
.command("echo", "Hello World!")
.then()
.stdout()
.hasLinesContaining("Hello")
// Wait at most 10 seconds for the process to terminate
.execute(Duration.ofSeconds(10))
.assertSuccess();
You can also specify the timeout in milliseconds:
import java.time.Duration;
import org.cliassured.CliAssured;
CliAssured
.command("echo", "Hello World!")
.then()
.stdout()
.hasLinesContaining("Hello")
// Wait at most 10000 milliseconds
.execute(10_000)
.assertSuccess();
Use assertTimeout() on the CommandResult to verify that a process was killed due to a timeout:
import java.time.Duration;
import org.cliassured.CliAssured;
CliAssured
// A command that would run for 60 seconds
.command("sleep", "60")
.then()
.stdout()
.isEmpty()
// Wait at most 100 ms
.execute(Duration.ofMillis(100))
// Assert that the process timed out
.assertTimeout();
Killing the command midflight
0.0.1
Use kill(boolean forcibly, boolean withDescendants) to terminate a running process before it exits on its own.
When forcibly is false, the process receives a graceful signal (SIGTERM on Linux/macOS); when true, it is killed
immediately (SIGKILL). The withDescendants flag controls whether child processes are also killed.
import java.time.Duration;
import java.util.stream.LongStream;
import org.assertj.core.api.Assertions;
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
// Start a long-running process
CommandProcess proc = CliAssured
.command("sleep", "60")
.then()
// SIGTERM yields exit code 143, SIGKILL yields 137
.exitCodeIsAnyOf(143, 137)
.start();
// Kill the process gracefully (SIGTERM), without killing descendants
proc.kill(false, false);
// Await termination after the kill signal
proc.awaitTermination()
.assertSuccess();
To kill both the process and all its descendants forcibly:
import java.time.Duration;
import java.util.stream.LongStream;
import org.assertj.core.api.Assertions;
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
CommandProcess proc = CliAssured
.command("sleep", "60")
.then()
.exitCodeIsAnyOf(137)
.start();
// Kill the process forcibly (SIGKILL) including all descendant processes
proc.kill(true, true);
proc.awaitTermination()
.assertSuccess();
Access the PID of the command process
0.0.1
Use pid() to obtain the operating system process ID of the running command. This requires Java 9 or newer.
import java.time.Duration;
import java.util.stream.LongStream;
import org.assertj.core.api.Assertions;
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
try (CommandProcess proc = CliAssured
.command("sleep", "5")
.then()
.exitCodeIsAnyOf(143, 137)
.start()) {
// Get the OS process ID
long pid = proc.pid();
Assertions.assertThat(pid).isPositive();
}
Child and descendant processes
0.0.1
Use children() to get a LongStream of PIDs of direct child processes, or descendants() to include all direct and
indirect child processes. Both methods require Java 9 or newer.
import java.time.Duration;
import java.util.stream.LongStream;
import org.assertj.core.api.Assertions;
import org.cliassured.CliAssured;
import org.cliassured.CommandProcess;
// Start a shell that spawns a child process
try (CommandProcess proc = CliAssured
.command("bash", "-c", "sleep 30 & wait")
// Allow time for the process to terminate after closing
.autoCloseTimeout(Duration.ofSeconds(5))
.then()
.exitCodeIsAnyOf(0, 143, 137)
.start()) {
// Wait briefly for the child process to spawn
try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
// children() returns PIDs of direct child processes
LongStream children = proc.children();
Assertions.assertThat(children.toArray()).isNotEmpty();
// descendants() returns PIDs of all direct and indirect child processes
LongStream descendants = proc.descendants();
Assertions.assertThat(descendants.toArray()).isNotEmpty();
}