Skip to content

Commit

Permalink
pytest: improve logging and reliability
Browse files Browse the repository at this point in the history
- avoid polluting console when not in verbose mode
- stop trying extra step when on fails
  • Loading branch information
ssbarnea committed Mar 1, 2024
1 parent 20d7f7c commit bccaf8a
Show file tree
Hide file tree
Showing 22 changed files with 101 additions and 16 deletions.
1 change: 1 addition & 0 deletions .config/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ templated
templating
testhost
testname
testsfailed
topbar
tracebacks
truecolor
Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ incremental = false

[[tool.mypy.overrides]]
# https://github.com/ansible/ansible-runner/issues/1340
module = [
"ansible_runner"
]
module = ["ansible_runner"]
ignore_missing_imports = true

[tool.pydoclint]
Expand Down Expand Up @@ -111,6 +109,7 @@ ignore = [
good-names = "i,j,k,ex,Run,_,f,fh"
jobs = 0
no-docstring-rgx = "__.*__"
max-args = 6 # default of 5 too low

[tool.pylint.messages_control]
disable = [
Expand Down
1 change: 0 additions & 1 deletion src/ansible_navigator/ui_framework/menu_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def __init__(
:param color_menu_item: The callback for adding color to menu entries
:param ui_config: The current user interface configuration
"""
# pylint: disable=too-many-arguments
self._number_colors = number_colors
self._progress_bar_width = progress_bar_width
self._screen_width = screen_width
Expand Down
32 changes: 31 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
from .defaults import FIXTURES_DIR


# implicit verbosity, updated at runtime
VERBOSITY = 0


def valid_ce() -> str:
"""Return an available container engine.
Expand Down Expand Up @@ -199,7 +203,8 @@ def pull_image(valid_container_engine: str, image_name: str) -> None:
pull_policy="missing",
)
image_puller.assess()
image_puller.prologue_stdout()
if VERBOSITY > 0:
image_puller.prologue_stdout()
if image_puller.assessment.exit_messages:
print(
msg.to_lines(color=False, width=console_width(), with_prefix=True)
Expand Down Expand Up @@ -313,6 +318,14 @@ def pytest_sessionstart(session: pytest.Session) -> None:
if getattr(session.config, "workerinput", None) is not None:
return
container_engine = valid_ce()
# fail fast if engine is not working properly, macos podman machine have
# the habit of getting stuck.
try:
cmd = [container_engine, "info"]
subprocess.check_output(cmd, stderr=subprocess.STDOUT, timeout=6)
except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as exc:
pytest.exit(f"Container engine is broken, fail to run: {' '.join(cmd)}: {exc}")

pull_image(
valid_container_engine=container_engine,
image_name=default_ee_image_name(),
Expand All @@ -331,6 +344,8 @@ def pytest_configure(config: pytest.Config) -> None:
:param config: The pytest config object
"""
global VERBOSITY
VERBOSITY = config.option.verbose
# limit an environment variables that may conflict with tests
allow = ("ANSIBLE_NAVIGATOR_UPDATE_TEST_FIXTURES",)
for k in os.environ:
Expand Down Expand Up @@ -371,3 +386,18 @@ def pytest_unconfigure(config: pytest.Config) -> None:
"""
for key, value in USER_ENVIRONMENT.items():
os.environ[key] = value


@pytest.fixture(scope="function")
def skip_if_already_failed(
request: pytest.FixtureRequest, failed=set()
) -> Generator[None, None, None]:
"""Fixture that stops parametrized tests running on first failure."""
key = request.node.name.split("[")[0]
failed_before = request.session.testsfailed
if key in failed:
pytest.skip(f"previous test {key} failed")
yield
failed_after = request.session.testsfailed
if failed_before != failed_after:
failed.add(key)
6 changes: 5 additions & 1 deletion tests/integration/actions/builder/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ def fixture_tmux_session(
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Run the tests for ``builder``, mode and ``ee`` set in child class.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/actions/collections/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def test(
request: pytest.FixtureRequest,
step: UiTestStep,
tmux_session: TmuxSession,
skip_if_already_failed: None,
) -> None:
"""Run the tests for ``collections``, mode and ``ee`` set in child class.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ def fixture_tmux_session(
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
# pylint: disable=too-many-locals
"""Run the tests for ``config``, mode and ``ee`` set in child class.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/actions/doc/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def test(
comment: str,
testname: str,
expected_in_output: list[str] | None,
skip_if_already_failed: None,
) -> None:
# pylint: disable=too-many-arguments
# pylint: disable=too-many-locals
Expand Down
1 change: 1 addition & 0 deletions tests/integration/actions/doc/test_stdout_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def test(
data: StdoutCliTest,
exec_env: bool,
cmd_in_tty: TCmdInTty,
skip_if_already_failed: None,
) -> None:
"""Test doc using subcommand.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/exec/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ def fixture_tmux_session(
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Test interactive/stdout exec.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/images/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ def fixture_tmux_session(request: pytest.FixtureRequest) -> Generator[TmuxSessio
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Run the tests for images, mode and ``ee`` set in child class.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/inventory/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ def fixture_tmux_session(request: pytest.FixtureRequest) -> Generator[TmuxSessio
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Run the tests for inventory, mode and ``ee`` set in child class.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/lint/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def fixture_tmux_session(request: pytest.FixtureRequest) -> Generator[TmuxSessio
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Run the tests for lint, mode and ``ee`` set in child class.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/run/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ def fixture_tmux_session(request: pytest.FixtureRequest) -> Generator[TmuxSessio
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Run the tests for run, mode and ``ee`` set in child class.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/actions/run_unicode/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def test(
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Run the tests for run, mode and ``ee`` set in child class.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ def fixture_tmux_session(
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
# pylint: disable=too-many-locals
"""Run the tests for ``settings``, mode and ``ee`` set in child class.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/actions/stdout/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def test(
user_input: str,
comment: str,
search_within_response: str,
skip_if_already_failed: None,
) -> None:
# pylint:disable=too-many-arguments
"""Run the tests for stdout, mode and EE set in child class.
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/actions/templar/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ def fixture_tmux_session(request: pytest.FixtureRequest) -> Generator[TmuxSessio
yield tmux_session

def test(
self, request: pytest.FixtureRequest, tmux_session: TmuxSession, step: UiTestStep
self,
request: pytest.FixtureRequest,
tmux_session: TmuxSession,
step: UiTestStep,
skip_if_already_failed: None,
) -> None:
"""Test interactive and ``stdout`` mode ``config``.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/diagnostics/test_from_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def test(
monkeypatch: pytest.MonkeyPatch,
settings_env_var_to_full: tuple[Path, SettingsFileType],
tmp_path: Path,
skip_if_already_failed: None,
) -> None:
"""Test diagnostics generation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def test_posix_message_queue_ee(
:param platform: The system platform to mock
:param generate_config: The configuration generator fixture
"""
# pylint: disable=too-many-arguments
message_queue_msg = (
"Execution environment support while using podman requires a '/dev/mqueue/' directory."
)
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/utils/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,18 @@ def test_now_iso(caplog: pytest.LogCaptureFixture, time_zone: str) -> None:
if time_zone == "bogus":
assert matched["timezone"] == "+00:00"
assert "The time zone 'bogus' could not be found. Using UTC." in caplog.text


@pytest.mark.parametrize(
"data,output",
(
pytest.param({}, {}, id="0"),
pytest.param(None, None, id="1"),
pytest.param([], [], id="2"),
pytest.param("foo", "foo", id="3"),
),
)
def test_unescape_moustaches(data: Any, output: Any) -> None:
"""Tests unescape_moustaches."""
result = functions.unescape_moustaches(data)
assert result == output
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ commands =
# pytest params are kept in pyproject.toml
# if one wants to control parallelism define PYTEST_XDIST_AUTO_NUM_WORKERS
coverage run -m pytest {posargs:-n=auto --dist=loadfile}
sh -c "coverage combine -q .tox/.coverage.* && coverage xml || true && coverage report"
sh -c "coverage combine -q {toxworkdir}/.coverage.* && coverage xml || true && coverage report"
setenv =
COVERAGE_FILE = {env:COVERAGE_FILE:{toxworkdir}/.coverage.{envname}}
COVERAGE_PROCESS_START={toxinidir}/pyproject.toml
Expand Down

0 comments on commit bccaf8a

Please sign in to comment.