Adding upstream version 1.1.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
f13b7abbd8
commit
77504588ab
196 changed files with 10121 additions and 3780 deletions
|
@ -8,14 +8,16 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
import pytest
|
||||
|
||||
from anta.decorators import deprecated_test, skip_on_platforms
|
||||
from anta.models import AntaCommand, AntaTemplate, AntaTest
|
||||
from tests.lib.fixture import DEVICE_HW_MODEL
|
||||
from tests.lib.utils import generate_test_ids
|
||||
from anta.result_manager.models import AntaTestStatus
|
||||
from tests.units.anta_tests.conftest import build_test_id
|
||||
from tests.units.conftest import DEVICE_HW_MODEL
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.device import AntaDevice
|
||||
|
@ -302,6 +304,15 @@ class DeprecatedTestWithNewTest(AntaTest):
|
|||
self.result.is_success()
|
||||
|
||||
|
||||
class FakeTestWithMissingTest(AntaTest):
|
||||
"""ANTA test with missing test() method implementation."""
|
||||
|
||||
name = "FakeTestWithMissingTest"
|
||||
description = "ANTA test with missing test() method implementation"
|
||||
categories: ClassVar[list[str]] = []
|
||||
commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
|
||||
|
||||
|
||||
ANTATEST_DATA: list[dict[str, Any]] = [
|
||||
{
|
||||
"name": "no input",
|
||||
|
@ -507,17 +518,17 @@ ANTATEST_DATA: list[dict[str, Any]] = [
|
|||
},
|
||||
]
|
||||
|
||||
BLACKLIST_COMMANDS_PARAMS = ["reload", "reload --force", "write", "wr mem"]
|
||||
|
||||
|
||||
class TestAntaTest:
|
||||
"""Test for anta.models.AntaTest."""
|
||||
|
||||
def test__init_subclass__name(self) -> None:
|
||||
def test__init_subclass__(self) -> None:
|
||||
"""Test __init_subclass__."""
|
||||
# Pylint detects all the classes in here as unused which is on purpose
|
||||
# pylint: disable=unused-variable
|
||||
with pytest.raises(NotImplementedError) as exec_info:
|
||||
|
||||
class WrongTestNoName(AntaTest):
|
||||
class _WrongTestNoName(AntaTest):
|
||||
"""ANTA test that is missing a name."""
|
||||
|
||||
description = "ANTA test that is missing a name"
|
||||
|
@ -528,11 +539,11 @@ class TestAntaTest:
|
|||
def test(self) -> None:
|
||||
self.result.is_success()
|
||||
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models.WrongTestNoName is missing required class attribute name"
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models._WrongTestNoName is missing required class attribute name"
|
||||
|
||||
with pytest.raises(NotImplementedError) as exec_info:
|
||||
|
||||
class WrongTestNoDescription(AntaTest):
|
||||
class _WrongTestNoDescription(AntaTest):
|
||||
"""ANTA test that is missing a description."""
|
||||
|
||||
name = "WrongTestNoDescription"
|
||||
|
@ -543,11 +554,11 @@ class TestAntaTest:
|
|||
def test(self) -> None:
|
||||
self.result.is_success()
|
||||
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models.WrongTestNoDescription is missing required class attribute description"
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models._WrongTestNoDescription is missing required class attribute description"
|
||||
|
||||
with pytest.raises(NotImplementedError) as exec_info:
|
||||
|
||||
class WrongTestNoCategories(AntaTest):
|
||||
class _WrongTestNoCategories(AntaTest):
|
||||
"""ANTA test that is missing categories."""
|
||||
|
||||
name = "WrongTestNoCategories"
|
||||
|
@ -558,11 +569,11 @@ class TestAntaTest:
|
|||
def test(self) -> None:
|
||||
self.result.is_success()
|
||||
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models.WrongTestNoCategories is missing required class attribute categories"
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models._WrongTestNoCategories is missing required class attribute categories"
|
||||
|
||||
with pytest.raises(NotImplementedError) as exec_info:
|
||||
|
||||
class WrongTestNoCommands(AntaTest):
|
||||
class _WrongTestNoCommands(AntaTest):
|
||||
"""ANTA test that is missing commands."""
|
||||
|
||||
name = "WrongTestNoCommands"
|
||||
|
@ -573,22 +584,34 @@ class TestAntaTest:
|
|||
def test(self) -> None:
|
||||
self.result.is_success()
|
||||
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models.WrongTestNoCommands is missing required class attribute commands"
|
||||
assert exec_info.value.args[0] == "Class tests.units.test_models._WrongTestNoCommands is missing required class attribute commands"
|
||||
|
||||
def test_abc(self) -> None:
|
||||
"""Test that an error is raised if AntaTest is not implemented."""
|
||||
with pytest.raises(TypeError) as exec_info:
|
||||
FakeTestWithMissingTest() # type: ignore[abstract,call-arg]
|
||||
msg = (
|
||||
"Can't instantiate abstract class FakeTestWithMissingTest without an implementation for abstract method 'test'"
|
||||
if sys.version_info >= (3, 12)
|
||||
else "Can't instantiate abstract class FakeTestWithMissingTest with abstract method test"
|
||||
)
|
||||
assert exec_info.value.args[0] == msg
|
||||
|
||||
def _assert_test(self, test: AntaTest, expected: dict[str, Any]) -> None:
|
||||
assert test.result.result == expected["result"]
|
||||
if "messages" in expected:
|
||||
assert len(test.result.messages) == len(expected["messages"])
|
||||
for result_msg, expected_msg in zip(test.result.messages, expected["messages"]): # NOTE: zip(strict=True) has been added in Python 3.10
|
||||
assert expected_msg in result_msg
|
||||
|
||||
@pytest.mark.parametrize("data", ANTATEST_DATA, ids=generate_test_ids(ANTATEST_DATA))
|
||||
@pytest.mark.parametrize("data", ANTATEST_DATA, ids=build_test_id)
|
||||
def test__init__(self, device: AntaDevice, data: dict[str, Any]) -> None:
|
||||
"""Test the AntaTest constructor."""
|
||||
expected = data["expected"]["__init__"]
|
||||
test = data["test"](device, inputs=data["inputs"])
|
||||
self._assert_test(test, expected)
|
||||
|
||||
@pytest.mark.parametrize("data", ANTATEST_DATA, ids=generate_test_ids(ANTATEST_DATA))
|
||||
@pytest.mark.parametrize("data", ANTATEST_DATA, ids=build_test_id)
|
||||
def test_test(self, device: AntaDevice, data: dict[str, Any]) -> None:
|
||||
"""Test the AntaTest.test method."""
|
||||
expected = data["expected"]["test"]
|
||||
|
@ -596,38 +619,42 @@ class TestAntaTest:
|
|||
asyncio.run(test.test())
|
||||
self._assert_test(test, expected)
|
||||
|
||||
@pytest.mark.parametrize("command", BLACKLIST_COMMANDS_PARAMS)
|
||||
def test_blacklist(self, device: AntaDevice, command: str) -> None:
|
||||
"""Test that blacklisted commands are not collected."""
|
||||
|
||||
ANTATEST_BLACKLIST_DATA = ["reload", "reload --force", "write", "wr mem"]
|
||||
class FakeTestWithBlacklist(AntaTest):
|
||||
"""Fake Test for blacklist."""
|
||||
|
||||
name = "FakeTestWithBlacklist"
|
||||
description = "ANTA test that has blacklisted command"
|
||||
categories: ClassVar[list[str]] = []
|
||||
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command=command)]
|
||||
|
||||
@pytest.mark.parametrize("data", ANTATEST_BLACKLIST_DATA)
|
||||
def test_blacklist(device: AntaDevice, data: str) -> None:
|
||||
"""Test for blacklisting function."""
|
||||
@AntaTest.anta_test
|
||||
def test(self) -> None:
|
||||
self.result.is_success()
|
||||
|
||||
class FakeTestWithBlacklist(AntaTest):
|
||||
"""Fake Test for blacklist."""
|
||||
test = FakeTestWithBlacklist(device)
|
||||
asyncio.run(test.test())
|
||||
assert test.result.result == AntaTestStatus.ERROR
|
||||
assert f"<{command}> is blocked for security reason" in test.result.messages
|
||||
assert test.instance_commands[0].collected is False
|
||||
|
||||
name = "FakeTestWithBlacklist"
|
||||
description = "ANTA test that has blacklisted command"
|
||||
categories: ClassVar[list[str]] = []
|
||||
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command=data)]
|
||||
|
||||
@AntaTest.anta_test
|
||||
def test(self) -> None:
|
||||
self.result.is_success()
|
||||
|
||||
test_instance = FakeTestWithBlacklist(device)
|
||||
|
||||
# Run the test() method
|
||||
asyncio.run(test_instance.test())
|
||||
assert test_instance.result.result == "error"
|
||||
def test_result_overwrite(self, device: AntaDevice) -> None:
|
||||
"""Test the AntaTest.Input.ResultOverwrite model."""
|
||||
test = FakeTest(device, inputs={"result_overwrite": {"categories": ["hardware"], "description": "a description", "custom_field": "a custom field"}})
|
||||
asyncio.run(test.test())
|
||||
assert test.result.result == AntaTestStatus.SUCCESS
|
||||
assert "hardware" in test.result.categories
|
||||
assert test.result.description == "a description"
|
||||
assert test.result.custom_field == "a custom field"
|
||||
|
||||
|
||||
class TestAntaComamnd:
|
||||
"""Test for anta.models.AntaCommand."""
|
||||
|
||||
# ruff: noqa: B018
|
||||
# pylint: disable=pointless-statement
|
||||
|
||||
def test_empty_output_access(self) -> None:
|
||||
"""Test for both json and text ofmt."""
|
||||
|
@ -656,16 +683,20 @@ class TestAntaComamnd:
|
|||
text_cmd_2.json_output
|
||||
|
||||
def test_supported(self) -> None:
|
||||
"""Test if the supported property."""
|
||||
"""Test the supported property."""
|
||||
command = AntaCommand(command="show hardware counter drop", errors=["Unavailable command (not supported on this hardware platform) (at token 2: 'counter')"])
|
||||
assert command.supported is False
|
||||
command = AntaCommand(
|
||||
command="show hardware counter drop", output={"totalAdverseDrops": 0, "totalCongestionDrops": 0, "totalPacketProcessorDrops": 0, "dropEvents": {}}
|
||||
)
|
||||
assert command.supported is True
|
||||
command = AntaCommand(command="show hardware counter drop")
|
||||
with pytest.raises(RuntimeError) as exec_info:
|
||||
command.supported
|
||||
assert exec_info.value.args[0] == "Command 'show hardware counter drop' has not been collected and has not returned an error. Call AntaDevice.collect()."
|
||||
|
||||
def test_requires_privileges(self) -> None:
|
||||
"""Test if the requires_privileges property."""
|
||||
"""Test the requires_privileges property."""
|
||||
command = AntaCommand(command="show aaa methods accounting", errors=["Invalid input (privileged mode required)"])
|
||||
assert command.requires_privileges is True
|
||||
command = AntaCommand(
|
||||
|
@ -678,3 +709,7 @@ class TestAntaComamnd:
|
|||
},
|
||||
)
|
||||
assert command.requires_privileges is False
|
||||
command = AntaCommand(command="show aaa methods accounting")
|
||||
with pytest.raises(RuntimeError) as exec_info:
|
||||
command.requires_privileges
|
||||
assert exec_info.value.args[0] == "Command 'show aaa methods accounting' has not been collected and has not returned an error. Call AntaDevice.collect()."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue