tests/utils.py: Shorten run_playbook for smaller traceback with assert

Most of the content has been moved to the new function _run_playbook to
reduce the traceback output in the case of a test failure.
This commit is contained in:
Thomas Woerner
2024-08-01 12:04:22 +02:00
parent 8515c9a48b
commit 02ba890eb4

View File

@@ -148,30 +148,6 @@ def write_logs(result, test_name):
log_file.write(result.stderr.decode("utf-8")) log_file.write(result.stderr.decode("utf-8"))
def _run_playbook(playbook):
"""
Create a inventory using a temporary file and run ansible using it.
The logs of the run will be placed in `tests/logs/`.
"""
with tempfile.NamedTemporaryFile() as inventory_file:
inventory_file.write(get_inventory_content())
inventory_file.flush()
cmd_options = ["-i", inventory_file.name]
verbose = os.environ.get("IPA_VERBOSITY", None)
if verbose is not None:
cmd_options.append(verbose)
cmd = ["ansible-playbook"] + cmd_options + [playbook]
# pylint: disable=subprocess-run-check
process = subprocess.run(
cmd, cwd=SCRIPT_DIR, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
test_name = get_test_name_from_playbook_path(playbook)
write_logs(process, test_name)
return process
def _truncate(lines, charcount, minlines=0): def _truncate(lines, charcount, minlines=0):
output = "" output = ""
line_count = 1 line_count = 1
@@ -188,12 +164,11 @@ def _truncate(lines, charcount, minlines=0):
return output return output
def run_playbook(playbook, allow_failures=False): def _run_playbook(playbook):
""" """
Run an Ansible playbook and assert the return code. Create a inventory using a temporary file and run ansible using it.
Call ansible (using _run_playbook function) and assert the result of The logs of the run will be placed in `tests/logs/`.
the execution.
In case of failure the tail of the error message will be displayed In case of failure the tail of the error message will be displayed
as an assertion message. as an assertion message.
@@ -201,43 +176,65 @@ def run_playbook(playbook, allow_failures=False):
The full log of the execution will be available in the directory The full log of the execution will be available in the directory
`tests/logs/`. `tests/logs/`.
""" """
result = _run_playbook(playbook) with tempfile.NamedTemporaryFile() as inventory_file:
inventory_file.write(get_inventory_content())
inventory_file.flush()
cmd_options = ["-i", inventory_file.name]
verbose = os.environ.get("IPA_VERBOSITY", None)
if verbose is not None:
cmd_options.append(verbose)
cmd = ["ansible-playbook"] + cmd_options + [playbook]
process = subprocess.run(
cmd, cwd=SCRIPT_DIR, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, check=False
)
test_name = get_test_name_from_playbook_path(playbook)
write_logs(process, test_name)
if allow_failures: msg = ""
return result if process.returncode != 0:
status_code_msg = "ansible-playbook return code: {0}".format(
process.returncode
)
status_code_msg = "ansible-playbook return code: {0}".format( _stdout = process.stdout.decode("utf8")
result.returncode _stderr = process.stderr.decode("utf8")
) # Truncate stdout and stderr in the way that it hopefully
_stdout = result.stdout.decode("utf8") # shows all important information. At least 15 lines of stdout
_stderr = result.stderr.decode("utf8") # (Ansible tasks) and remaining from stderr to fill up to
# Truncate stdout and stderr in the way that it hopefully # maxlen size.
# shows all important information. At least 15 lines of stdout maxlen = 2000
# (Ansible tasks) and remaining from stderr to fill up to factor = maxlen / (len(_stdout) + len(_stderr))
# maxlen size. stdout = _truncate(_stdout.splitlines(),
maxlen = 2000 int(factor * len(_stdout)),
factor = maxlen / (len(_stdout) + len(_stderr)) minlines=15)
stdout = _truncate(_stdout.splitlines(), stderr = _truncate(_stderr.splitlines(), maxlen - len(stdout))
int(factor * len(_stdout)),
minlines=15)
stderr = _truncate(_stderr.splitlines(), maxlen - len(stdout))
assert_msg = "\n".join( msg = "\n".join(
[ [
"", "",
"-" * 30 + " Captured stdout " + "-" * 30, "-" * 30 + " Captured stdout " + "-" * 30,
stdout, stdout,
"-" * 30 + " Captured stderr " + "-" * 30, "-" * 30 + " Captured stderr " + "-" * 30,
stderr, stderr
"-" * 30 + " Playbook Return Code " + "-" * 30, ]
status_code_msg, )
] msg += "-" * 30 + " Playbook Return Code " + "-" * 30 + "\n"
) msg += status_code_msg
# Need to get the last bytes of msg otherwise Azure return process, msg
# will cut it out.
assert result.returncode == 0, assert_msg[-2500:]
def run_playbook(playbook, allow_failures=False):
"""
Run an Ansible playbook and assert the return code.
Call ansible (using _run_playbook function) and assert the result of
the execution.
"""
result, assert_msg = _run_playbook(playbook)
if not allow_failures:
assert result.returncode == 0, assert_msg
return result return result