Blocking Calls
It is possible to run a command using a blocking call, meaning the code will
block until the command is finished and its result is returned. The result is
instance of ProcessResult and gives you access to
return code, standard output and standard error output.
from pytest_mh import MultihostHost
from pytest_mh.conn import ProcessResult
class ExampleRole(MultihostHost[ExampleDomain]):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
def say_hello(self) -> ProcessResult:
"""
Run a single line script code.
"""
return self.host.conn.run("echo 'Hello World'")
def say_hello_argv(self) -> ProcessResult:
"""
Execute command by passing list of arguments.
"""
return self.host.conn.exec(["echo", "Hello World"])
def say_script(self) -> ProcessResult:
"""
Execute a multiline script code.
"""
return self.host.conn.run(
"""
set -ex
echo 'Hello World'
"""
)
def say_hello_cat(self) -> ProcessResult:
"""
You can also pass input data.
"""
return self.host.conn.run("cat", input="Hello World")
@pytest.mark.topology(...)
def test_hello(example: ExampleRole) -> None:
result = example.say_hello()
assert result.stdout == "Hello World"
result = example.say_hello_argv()
assert result.stdout == "Hello World"
result = example.say_hello_script()
assert result.stdout == "Hello World"
result = example.say_hello_cat()
assert result.stdout == "Hello World"
If the command returns a non-zero return code, it is automatically considered a
failure and ProcessError is raised. If you don’t want
to raise the error or if you want to raise it on different condition, you can
overwrite the behaviour with raise_on_error argument.
result = self.host.conn.run("echo 'Hello World'", raise_on_error=False)
if result.rc not in (0, 1):
# Raise ProcessError if rc was not 0 or 1
result.throw()
Note
Each command execution is logged in the pytest-mh logger. This can often pollute the logs with a lot of commands whose output result is only really important if it fails. Therefore, you can change the log level to add a log record only if the command yields a non-zero return code.
self.host.conn.run(
"echo 'Hello World'",
log_level=ProcessLogLevel.Error
)
See ProcessLogLevel for all available log levels.