Skip to content

Commit

Permalink
Add functionality to hide stacktraces and handle component output (#9)
Browse files Browse the repository at this point in the history
* Add functionality to hide stacktraces.

* Fix styling

* Update styling for new black

* Update CHANGELOG

* Update CHANGELOG
  • Loading branch information
DriesSchaumont authored Jun 6, 2023
1 parent f4341ba commit 92e0767
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 6 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
Changelog
*********

0.3.0 (6/06/2023)
=================
* `run_component`: when the component fails, stack traces from helper functions are no longer shown.

* `run_component`: component output captured from stderr and stdout is added to pytest output.

0.2.1 (3/02/2023)
=================

Bug fixes
---------
* `run_component` now outputs captured stdout and stderr from the component run.
* `run_component` now returns captured stdout and stderr from the component run.

0.2.0 (5/12/2022)
==================
Expand Down
44 changes: 40 additions & 4 deletions tests/unittests/fixtures/test_run_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,10 @@ def test_loading_run_component(run_component):
def test_run_component_executes_subprocess(
request, pytester, makepyfile_and_add_meta, config_fixture, expected
):
executable = pytester.makefile("", foo="This is a dummy executable!")
executable.chmod(executable.stat().st_mode | stat.S_IEXEC)

makepyfile_and_add_meta(
f"""
import subprocess
from pathlib import Path, PosixPath
from pathlib import Path
def test_loading_run_component(mocker, run_component):
mocked_check_output = mocker.patch('viashpy._run.check_output',
Expand Down Expand Up @@ -116,3 +113,42 @@ def test_loading_run_component(mocker, run_component):
]
)
assert result.ret != 0


def test_run_component_fails_logging(
pytester, makepyfile_and_add_meta, dummy_config_with_info
):
executable = pytester.makefile(
"",
foo="#!/bin/sh\npython -c 'import sys; raise RuntimeError(\"This script should fail\")'",
)
executable.chmod(executable.stat().st_mode | stat.S_IEXEC)

makepyfile_and_add_meta(
"""
import subprocess
from pathlib import Path, PosixPath
def test_loading_run_component(mocker, run_component):
mocked_path = mocker.patch('viashpy.testing.Path.is_file', return_value=True)
stdout = run_component(["bar"])
""",
dummy_config_with_info,
executable,
)
result = pytester.runpytest()
# Check if output from component is shown on error
result.stdout.fnmatch_lines(
[
"*FAILED test_run_component_fails_logging.py::test_loading_run_component*",
]
)
result.stdout.fnmatch_lines(
[
"*This script should fail*",
]
)
# Check if stack traces are hidden
result.stdout.no_fnmatch_line("*def wrapper*")
result.stdout.no_fnmatch_line("*def run_component*")
assert result.ret == 1
26 changes: 25 additions & 1 deletion viashpy/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from ._run import run_build_component, viash_run
from .config import read_viash_config
from pathlib import Path
from functools import wraps
from subprocess import CalledProcessError

logger = logging.Logger(__name__)

Expand Down Expand Up @@ -79,7 +81,7 @@ def viash_source_config(viash_source_config_path):


@pytest.fixture
def run_component(executable, viash_source_config_path, viash_executable):
def run_component(caplog, executable, viash_source_config_path, viash_executable):
"""
Returns a function that allows the user to run a viash component.
The function will use 'viash run' to execute the component or run
Expand All @@ -94,8 +96,29 @@ def run_component(executable, viash_source_config_path, viash_executable):
tests using 'viash test'), the build component executable will be used
instead.
"""
__tracebackhide__ = True

def run_and_handle_errors(function_to_run):
@wraps(function_to_run)
def wrapper(*args, **kwargs):
try:
return function_to_run(*args, **kwargs)
except CalledProcessError as e:
with caplog.at_level(logging.DEBUG):
logger = logging.getLogger()
logger.info(
f"Captured component output was:\n{e.stdout.decode('utf-8')}"
)
pytest.fail(
f"The component exited with exitcode {e.returncode}.",
pytrace=False,
)

return wrapper

if viash_source_config_path.is_file():

@run_and_handle_errors
def wrapper(args_as_list):
return viash_run(
viash_source_config_path, args_as_list, viash_location=viash_executable
Expand All @@ -108,6 +131,7 @@ def wrapper(args_as_list):
"Assuming test script is run from 'viash test' or 'viash_test'."
)

@run_and_handle_errors
def wrapper(args_as_list):
return run_build_component(executable, args_as_list)

Expand Down

0 comments on commit 92e0767

Please sign in to comment.