Adding upstream version 1.4.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-15 09:34:27 +02:00
parent dc7df702ea
commit 7996c81031
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
166 changed files with 13787 additions and 11959 deletions

View file

@ -123,7 +123,7 @@ def click_runner(capsys: pytest.CaptureFixture[str], anta_env: dict[str, str]) -
# Patch asynceapi methods used by AsyncEOSDevice. See tests/units/test_device.py
with (
patch("asynceapi.device.Device.check_connection", return_value=True),
patch("asynceapi.device.Device.check_api_endpoint", return_value=True),
patch("asynceapi.device.Device.cli", side_effect=cli),
patch("asyncssh.connect"),
patch(

View file

@ -368,7 +368,7 @@ def test_from_ansible_overwrite(
None,
True,
False,
"`anta get tests --module <module>` does not support relative imports",
"`--module <module>` option does not support relative imports",
ExitCode.USAGE_ERROR,
id="Use relative module name",
),
@ -454,3 +454,185 @@ def test_get_tests_local_module(click_runner: CliRunner) -> None:
if cwd != local_module_parent_path:
assert "injecting CWD in PYTHONPATH and retrying..." in result.output
assert "No test found in 'local_module'" in result.output
@pytest.mark.parametrize(
("module", "test_name", "catalog", "expected_output", "expected_exit_code"),
[
pytest.param(
None,
None,
None,
"VerifyAcctConsoleMethods",
ExitCode.OK,
id="Get all commands",
),
pytest.param(
"anta.tests.aaa",
None,
None,
"VerifyAcctConsoleMethods",
ExitCode.OK,
id="Get commands, filter on module",
),
pytest.param(
None,
"VerifyNTPAssociations",
None,
"VerifyNTPAssociations",
ExitCode.OK,
id="Get commands, filter on exact test name",
),
pytest.param(
None,
"VerifyNTP",
None,
"anta.tests.system",
ExitCode.OK,
id="Get commands, filter on included test name",
),
pytest.param(
"unknown_module",
None,
None,
"Module `unknown_module` was not found!",
ExitCode.USAGE_ERROR,
id="Get commands wrong module",
),
pytest.param(
"unknown_module.unknown",
None,
None,
"Module `unknown_module.unknown` was not found!",
ExitCode.USAGE_ERROR,
id="Get commands wrong submodule",
),
pytest.param(
".unknown_module",
None,
None,
"`--module <module>` option does not support relative imports",
ExitCode.USAGE_ERROR,
id="Use relative module name",
),
pytest.param(
None,
"VerifySomething",
None,
"No test 'VerifySomething' found in 'anta.tests'",
ExitCode.OK,
id="Get commands wrong test name",
),
pytest.param(
"anta.tests.aaa",
"VerifyNTP",
None,
"No test 'VerifyNTP' found in 'anta.tests.aaa'",
ExitCode.OK,
id="Get commands test exists but not in module",
),
pytest.param(
None,
None,
DATA_DIR / "test_catalog.yml",
"VerifyEOSVersion",
ExitCode.OK,
id="Get all commands from catalog",
),
pytest.param(
"anta.tests.aaa",
None,
DATA_DIR / "test_catalog.yml",
"No test found in 'anta.tests.aaa' for catalog '", # partial match as no test from aaa in the catalog
ExitCode.OK,
id="Get all commands from module in catalog",
),
pytest.param(
None,
None,
DATA_DIR / "non_existing_catalog.yml",
"Invalid value for '--catalog'",
ExitCode.USAGE_ERROR,
id="Catalog does not exist",
),
# TODO: catalog format JSON
],
)
def test_get_commands(
click_runner: CliRunner, module: str | None, test_name: str | None, catalog: str | None, expected_output: str, expected_exit_code: str
) -> None:
"""Test `anta get commands`."""
cli_args = [
"get",
"commands",
]
if module is not None:
cli_args.extend(["--module", module])
if test_name is not None:
cli_args.extend(["--test", test_name])
if catalog is not None:
cli_args.extend(["--catalog", catalog])
# Make sure to disable any ANTA_CATALOG env that could be set and pollute the test
result = click_runner.invoke(anta, cli_args, env={"ANTA_CATALOG": None})
assert result.exit_code == expected_exit_code
assert expected_output in result.output
@pytest.mark.parametrize(
("module", "test_name", "catalog", "expected_count"),
[
pytest.param(
"anta.tests.aaa",
None,
None,
4,
id="Get unique commands, filter on module",
),
pytest.param(
None,
"VerifyNTPAssociations",
None,
1,
id="Get unique commands, filter on exact test name",
),
pytest.param(
None,
"VerifyNTP",
None,
2,
id="Get unique commands, filter on included test name",
),
pytest.param(
None,
None,
DATA_DIR / "test_catalog.yml",
1,
id="Get all unique commands from catalog",
),
],
)
def test_get_commands_unique(click_runner: CliRunner, module: str | None, test_name: str | None, catalog: str | None, expected_count: int) -> None:
"""Test `anta get commands`."""
cli_args = [
"get",
"commands",
]
if module is not None:
cli_args.extend(["--module", module])
if test_name is not None:
cli_args.extend(["--test", test_name])
if catalog is not None:
cli_args.extend(["--catalog", catalog])
cli_args.extend(["--unique"])
# Make sure to disable any ANTA_CATALOG env that could be set and pollute the test
result = click_runner.invoke(anta, cli_args, env={"ANTA_CATALOG": None})
assert expected_count == len(result.output.splitlines())

View file

@ -13,7 +13,7 @@ from unittest.mock import MagicMock, patch
import pytest
import requests
from anta.cli.get.utils import create_inventory_from_ansible, create_inventory_from_cvp, extract_examples, find_tests_examples, get_cv_token, print_test
from anta.cli.get.utils import create_inventory_from_ansible, create_inventory_from_cvp, extract_examples, find_tests_in_module, get_cv_token, print_test
from anta.inventory import AntaInventory
from anta.models import AntaCommand, AntaTemplate, AntaTest
@ -219,14 +219,14 @@ class TypoExampleTest(AntaTest):
self.result.is_success()
def test_find_tests_examples() -> None:
def test_find_tests_in_module() -> None:
"""Test find_tests_examples.
Only testing the failure scenarii not tested through test_commands.
TODO: expand
"""
with pytest.raises(ValueError, match="Error when importing"):
find_tests_examples("blah", "UnusedTestName")
find_tests_in_module("blah", "UnusedTestName")
def test_print_test() -> None:

View file

@ -178,7 +178,7 @@ def test_anta_nrfu_md_report(click_runner: CliRunner, tmp_path: Path) -> None:
def test_anta_nrfu_md_report_failure(click_runner: CliRunner, tmp_path: Path) -> None:
"""Test anta nrfu md-report failure."""
md_output = tmp_path / "test.md"
with patch("anta.reporter.md_reporter.MDReportGenerator.generate", side_effect=OSError()):
with patch("anta.reporter.md_reporter.MDReportGenerator.generate_sections", side_effect=OSError()):
result = click_runner.invoke(anta, ["nrfu", "md-report", "--md-output", str(md_output)])
assert result.exit_code == ExitCode.USAGE_ERROR
@ -206,5 +206,17 @@ def test_anta_nrfu_md_report_with_hide(click_runner: CliRunner, tmp_path: Path)
total_tests = int(match.group(1))
total_tests_success = int(match.group(2))
assert total_tests == 0
assert total_tests_success == 0
assert total_tests == 3
assert total_tests_success == 3
# Collecting the rows inside the Test Results section
row_count = 0
lines = content.splitlines()
idx = lines.index("## Test Results")
for line in lines[idx + 1 :]:
if line.startswith("|") and "---" not in line:
row_count += 1
# Reducing the row count by 1, as above conditions counts the TABLE_HEADING
assert (row_count - 1) == 0

View file

@ -6,35 +6,21 @@
from __future__ import annotations
import sys
from importlib import reload
from typing import TYPE_CHECKING, Any
from typing import Any
from unittest.mock import patch
import pytest
import anta.cli
if TYPE_CHECKING:
from types import ModuleType
builtins_import = __import__
# Tried to achieve this with mock
# http://materials-scientist.com/blog/2021/02/11/mocking-failing-module-import-python/
def import_mock(name: str, *args: Any) -> ModuleType: # noqa: ANN401
"""Mock."""
if name == "click":
msg = "No module named 'click'"
raise ModuleNotFoundError(msg)
return builtins_import(name, *args)
def test_cli_error_missing(capsys: pytest.CaptureFixture[Any]) -> None:
# https://github.com/python/cpython/issues/88852
@pytest.mark.skipif(sys.version_info <= (3, 11), reason="Unreliable behavior patching sys.modules before 3.11")
def test_cli_error_missing_click(capsys: pytest.CaptureFixture[Any]) -> None:
"""Test ANTA errors out when anta[cli] was not installed."""
with patch.dict(sys.modules) as sys_modules, patch("builtins.__import__", import_mock):
del sys_modules["anta.cli._main"]
reload(anta.cli)
with patch.dict(sys.modules, {"click": None}) as sys_modules:
for k in list(sys_modules.keys()):
if k.startswith("anta."):
del sys_modules[k]
import anta.cli
with pytest.raises(SystemExit) as e_info:
anta.cli.cli()
@ -53,3 +39,18 @@ def test_cli_error_missing(capsys: pytest.CaptureFixture[Any]) -> None:
assert "Make sure you've installed everything with: pip install 'anta[cli]'" in captured.out
assert "The caught exception was:" in captured.out
assert e_info.value.code == 1
# https://github.com/python/cpython/issues/88852
@pytest.mark.skipif(sys.version_info <= (3, 11), reason="Unreliable behavior patching sys.modules before 3.11")
def test_cli_error_missing_other() -> None:
"""Test ANTA errors out when anta[cli] was not installed."""
with patch.dict(sys.modules, {"httpx": None}) as sys_modules:
# Need to clean up from previous runs a path that will trigger reimporting httpx
for k in list(sys_modules.keys()):
if k.startswith("anta."):
del sys_modules[k]
import anta.cli
with pytest.raises(ImportError, match="httpx"):
anta.cli.cli()