diff --git a/nixos/doc/manual/development/writing-nixos-tests.section.md b/nixos/doc/manual/development/writing-nixos-tests.section.md
index a9ffffe2277c..e5ee1cb01ff1 100644
--- a/nixos/doc/manual/development/writing-nixos-tests.section.md
+++ b/nixos/doc/manual/development/writing-nixos-tests.section.md
@@ -159,34 +159,42 @@ The following methods are available on machine objects:
`execute`
: Execute a shell command, returning a list `(status, stdout)`.
+
+ Commands are run with `set -euo pipefail` set:
+
+ - If several commands are separated by `;` and one fails, the
+ command as a whole will fail.
+
+ - For pipelines, the last non-zero exit status will be returned
+ (if there is one; otherwise zero will be returned).
+
+ - Dereferencing unset variables fails the command.
+
+ - It will wait for stdout to be closed.
+
If the command detaches, it must close stdout, as `execute` will wait
for this to consume all output reliably. This can be achieved by
redirecting stdout to stderr `>&2`, to `/dev/console`, `/dev/null` or
a file. Examples of detaching commands are `sleep 365d &`, where the
shell forks a new process that can write to stdout and `xclip -i`, where
the `xclip` command itself forks without closing stdout.
+
Takes an optional parameter `check_return` that defaults to `True`.
Setting this parameter to `False` will not check for the return code
and return -1 instead. This can be used for commands that shut down
the VM and would therefore break the pipe that would be used for
retrieving the return code.
+ A timeout for the command can be specified (in seconds) using the optional
+ `timeout` parameter, e.g., `execute(cmd, timeout=10)` or
+ `execute(cmd, timeout=None)`. The default is 900 seconds.
+
`succeed`
: Execute a shell command, raising an exception if the exit status is
- not zero, otherwise returning the standard output. Commands are run
- with `set -euo pipefail` set:
-
- - If several commands are separated by `;` and one fails, the
- command as a whole will fail.
-
- - For pipelines, the last non-zero exit status will be returned
- (if there is one, zero will be returned otherwise).
-
- - Dereferencing unset variables fail the command.
-
- - It will wait for stdout to be closed. See `execute` for the
- implications.
+ not zero, otherwise returning the standard output. Similar to `execute`,
+ except that the timeout is `None` by default. See `execute` for details on
+ command execution.
`fail`
@@ -196,10 +204,13 @@ The following methods are available on machine objects:
`wait_until_succeeds`
: Repeat a shell command with 1-second intervals until it succeeds.
+ Has a default timeout of 900 seconds which can be modified, e.g.
+ `wait_until_succeeds(cmd, timeout=10)`. See `execute` for details on
+ command execution.
`wait_until_fails`
-: Repeat a shell command with 1-second intervals until it fails.
+: Like `wait_until_succeeds`, but repeating the command until it fails.
`wait_for_unit`
diff --git a/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml b/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
index b194d58e5beb..7ce3e4cb2906 100644
--- a/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
+++ b/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
@@ -274,35 +274,9 @@ start_all()
Execute a shell command, returning a list
- (status, stdout). If the command
- detaches, it must close stdout, as
- execute will wait for this to consume all
- output reliably. This can be achieved by redirecting stdout
- to stderr >&2, to
- /dev/console,
- /dev/null or a file. Examples of
- detaching commands are sleep 365d &,
- where the shell forks a new process that can write to stdout
- and xclip -i, where the
- xclip command itself forks without
- closing stdout. Takes an optional parameter
- check_return that defaults to
- True. Setting this parameter to
- False will not check for the return code
- and return -1 instead. This can be used for commands that
- shut down the VM and would therefore break the pipe that
- would be used for retrieving the return code.
+ (status, stdout).
-
-
-
-
- succeed
-
-
- Execute a shell command, raising an exception if the exit
- status is not zero, otherwise returning the standard output.
Commands are run with set -euo pipefail
set:
@@ -317,22 +291,63 @@ start_all()
For pipelines, the last non-zero exit status will be
- returned (if there is one, zero will be returned
- otherwise).
+ returned (if there is one; otherwise zero will be
+ returned).
- Dereferencing unset variables fail the command.
+ Dereferencing unset variables fails the command.
- It will wait for stdout to be closed. See
- execute for the implications.
+ It will wait for stdout to be closed.
+
+ If the command detaches, it must close stdout, as
+ execute will wait for this to consume all
+ output reliably. This can be achieved by redirecting stdout
+ to stderr >&2, to
+ /dev/console,
+ /dev/null or a file. Examples of
+ detaching commands are sleep 365d &,
+ where the shell forks a new process that can write to stdout
+ and xclip -i, where the
+ xclip command itself forks without
+ closing stdout.
+
+
+ Takes an optional parameter check_return
+ that defaults to True. Setting this
+ parameter to False will not check for the
+ return code and return -1 instead. This can be used for
+ commands that shut down the VM and would therefore break the
+ pipe that would be used for retrieving the return code.
+
+
+ A timeout for the command can be specified (in seconds)
+ using the optional timeout parameter,
+ e.g., execute(cmd, timeout=10) or
+ execute(cmd, timeout=None). The default
+ is 900 seconds.
+
+
+
+
+
+ succeed
+
+
+
+ Execute a shell command, raising an exception if the exit
+ status is not zero, otherwise returning the standard output.
+ Similar to execute, except that the
+ timeout is None by default. See
+ execute for details on command execution.
+
@@ -353,7 +368,10 @@ start_all()
Repeat a shell command with 1-second intervals until it
- succeeds.
+ succeeds. Has a default timeout of 900 seconds which can be
+ modified, e.g.
+ wait_until_succeeds(cmd, timeout=10). See
+ execute for details on command execution.
@@ -363,8 +381,8 @@ start_all()
- Repeat a shell command with 1-second intervals until it
- fails.
+ Like wait_until_succeeds, but repeating
+ the command until it fails.
diff --git a/nixos/lib/test-driver/test_driver/machine.py b/nixos/lib/test-driver/test_driver/machine.py
index f3e615fe5bf9..035e3ffe8973 100644
--- a/nixos/lib/test-driver/test_driver/machine.py
+++ b/nixos/lib/test-driver/test_driver/machine.py
@@ -526,10 +526,17 @@ class Machine:
self.run_callbacks()
self.connect()
- if timeout is not None:
- command = "timeout {} sh -c {}".format(timeout, shlex.quote(command))
+ # Always run command with shell opts
+ command = f"set -euo pipefail; {command}"
+
+ timeout_str = ""
+ if timeout is not None:
+ timeout_str = f"timeout {timeout}"
+
+ out_command = (
+ f"{timeout_str} sh -c {shlex.quote(command)} | (base64 --wrap 0; echo)\n"
+ )
- out_command = f"( set -euo pipefail; {command} ) | (base64 --wrap 0; echo)\n"
assert self.shell
self.shell.send(out_command.encode())