Adding upstream version 1.3.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
6fd6eb426a
commit
dc7df702ea
337 changed files with 16571 additions and 4891 deletions
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.result_manager submodule."""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""See https://docs.pytest.org/en/stable/reference/fixtures.html#conftest-py-sharing-fixtures-across-multiple-files."""
|
||||
|
@ -34,12 +34,12 @@ def result_manager_factory(list_result_factory: Callable[[int], list[TestResult]
|
|||
def result_manager() -> ResultManager:
|
||||
"""Return a ResultManager with 30 random tests loaded from a JSON file.
|
||||
|
||||
Devices: DC1-SPINE1, DC1-LEAF1A
|
||||
Devices: s1-spine1
|
||||
|
||||
- Total tests: 30
|
||||
- Success: 7
|
||||
- Skipped: 2
|
||||
- Failure: 19
|
||||
- Success: 4
|
||||
- Skipped: 9
|
||||
- Failure: 15
|
||||
- Error: 2
|
||||
|
||||
See `tests/units/result_manager/test_md_report_results.json` for details.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Test anta.result_manager.__init__.py."""
|
||||
|
@ -20,6 +20,7 @@ if TYPE_CHECKING:
|
|||
from anta.result_manager.models import TestResult
|
||||
|
||||
|
||||
# pylint: disable=too-many-public-methods
|
||||
class TestResultManager:
|
||||
"""Test ResultManager class."""
|
||||
|
||||
|
@ -73,8 +74,8 @@ class TestResultManager:
|
|||
assert test.get("custom_field") is None
|
||||
assert test.get("result") == "success"
|
||||
|
||||
def test_sorted_category_stats(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
|
||||
"""Test ResultManager.sorted_category_stats."""
|
||||
def test_category_stats(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
|
||||
"""Test ResultManager.category_stats."""
|
||||
result_manager = ResultManager()
|
||||
results = list_result_factory(4)
|
||||
|
||||
|
@ -86,13 +87,9 @@ class TestResultManager:
|
|||
|
||||
result_manager.results = results
|
||||
|
||||
# Check the current categories order
|
||||
expected_order = ["ospf", "bgp", "vxlan", "system"]
|
||||
assert list(result_manager.category_stats.keys()) == expected_order
|
||||
|
||||
# Check the sorted categories order
|
||||
# Check that category_stats returns sorted order by default
|
||||
expected_order = ["bgp", "ospf", "system", "vxlan"]
|
||||
assert list(result_manager.sorted_category_stats.keys()) == expected_order
|
||||
assert list(result_manager.category_stats.keys()) == expected_order
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("starting_status", "test_status", "expected_status", "expected_raise"),
|
||||
|
@ -198,12 +195,12 @@ class TestResultManager:
|
|||
"""Test ResultManager.get_results."""
|
||||
# Check for single status
|
||||
success_results = result_manager.get_results(status={AntaTestStatus.SUCCESS})
|
||||
assert len(success_results) == 7
|
||||
assert len(success_results) == 4
|
||||
assert all(r.result == "success" for r in success_results)
|
||||
|
||||
# Check for multiple statuses
|
||||
failure_results = result_manager.get_results(status={AntaTestStatus.FAILURE, AntaTestStatus.ERROR})
|
||||
assert len(failure_results) == 21
|
||||
assert len(failure_results) == 17
|
||||
assert all(r.result in {"failure", "error"} for r in failure_results)
|
||||
|
||||
# Check all results
|
||||
|
@ -215,19 +212,18 @@ class TestResultManager:
|
|||
# Check all results with sort_by result
|
||||
all_results = result_manager.get_results(sort_by=["result"])
|
||||
assert len(all_results) == 30
|
||||
assert [r.result for r in all_results] == ["error"] * 2 + ["failure"] * 19 + ["skipped"] * 2 + ["success"] * 7
|
||||
assert [r.result for r in all_results] == ["error"] * 2 + ["failure"] * 15 + ["skipped"] * 9 + ["success"] * 4
|
||||
|
||||
# Check all results with sort_by device (name)
|
||||
all_results = result_manager.get_results(sort_by=["name"])
|
||||
assert len(all_results) == 30
|
||||
assert all_results[0].name == "DC1-LEAF1A"
|
||||
assert all_results[-1].name == "DC1-SPINE1"
|
||||
assert all_results[0].name == "s1-spine1"
|
||||
|
||||
# Check multiple statuses with sort_by categories
|
||||
success_skipped_results = result_manager.get_results(status={AntaTestStatus.SUCCESS, AntaTestStatus.SKIPPED}, sort_by=["categories"])
|
||||
assert len(success_skipped_results) == 9
|
||||
assert success_skipped_results[0].categories == ["Interfaces"]
|
||||
assert success_skipped_results[-1].categories == ["VXLAN"]
|
||||
assert len(success_skipped_results) == 13
|
||||
assert success_skipped_results[0].categories == ["avt"]
|
||||
assert success_skipped_results[-1].categories == ["vxlan"]
|
||||
|
||||
# Check all results with bad sort_by
|
||||
with pytest.raises(
|
||||
|
@ -244,14 +240,14 @@ class TestResultManager:
|
|||
assert result_manager.get_total_results() == 30
|
||||
|
||||
# Test single status
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS}) == 7
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.FAILURE}) == 19
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS}) == 4
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.FAILURE}) == 15
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.ERROR}) == 2
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SKIPPED}) == 2
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SKIPPED}) == 9
|
||||
|
||||
# Test multiple statuses
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS, AntaTestStatus.FAILURE}) == 26
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS, AntaTestStatus.FAILURE, AntaTestStatus.ERROR}) == 28
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS, AntaTestStatus.FAILURE}) == 19
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS, AntaTestStatus.FAILURE, AntaTestStatus.ERROR}) == 21
|
||||
assert result_manager.get_total_results(status={AntaTestStatus.SUCCESS, AntaTestStatus.FAILURE, AntaTestStatus.ERROR, AntaTestStatus.SKIPPED}) == 30
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -465,7 +461,6 @@ class TestResultManager:
|
|||
with caplog.at_level(logging.INFO):
|
||||
_ = result_manager.category_stats
|
||||
_ = result_manager.test_stats
|
||||
_ = result_manager.sorted_category_stats
|
||||
assert "Computing statistics" not in caplog.text
|
||||
|
||||
# Add another result - should mark stats as unsynced
|
||||
|
@ -480,3 +475,89 @@ class TestResultManager:
|
|||
_ = result_manager.device_stats
|
||||
assert "Computing statistics for all results" in caplog.text
|
||||
assert result_manager._stats_in_sync is True
|
||||
|
||||
def test_sort_by_result(self, test_result_factory: Callable[[], TestResult]) -> None:
|
||||
"""Test sorting by result."""
|
||||
result_manager = ResultManager()
|
||||
test1 = test_result_factory()
|
||||
test1.result = AntaTestStatus.SUCCESS
|
||||
test2 = test_result_factory()
|
||||
test2.result = AntaTestStatus.FAILURE
|
||||
test3 = test_result_factory()
|
||||
test3.result = AntaTestStatus.ERROR
|
||||
|
||||
result_manager.results = [test1, test2, test3]
|
||||
sorted_manager = result_manager.sort(["result"])
|
||||
assert [r.result for r in sorted_manager.results] == ["error", "failure", "success"]
|
||||
|
||||
def test_sort_by_name(self, test_result_factory: Callable[[], TestResult]) -> None:
|
||||
"""Test sorting by name."""
|
||||
result_manager = ResultManager()
|
||||
test1 = test_result_factory()
|
||||
test1.name = "Device3"
|
||||
test2 = test_result_factory()
|
||||
test2.name = "Device1"
|
||||
test3 = test_result_factory()
|
||||
test3.name = "Device2"
|
||||
|
||||
result_manager.results = [test1, test2, test3]
|
||||
sorted_manager = result_manager.sort(["name"])
|
||||
assert [r.name for r in sorted_manager.results] == ["Device1", "Device2", "Device3"]
|
||||
|
||||
def test_sort_by_categories(self, test_result_factory: Callable[[], TestResult]) -> None:
|
||||
"""Test sorting by categories."""
|
||||
result_manager = ResultManager()
|
||||
test1 = test_result_factory()
|
||||
test1.categories = ["VXLAN", "networking"]
|
||||
test2 = test_result_factory()
|
||||
test2.categories = ["BGP", "routing"]
|
||||
test3 = test_result_factory()
|
||||
test3.categories = ["system", "hardware"]
|
||||
|
||||
result_manager.results = [test1, test2, test3]
|
||||
sorted_manager = result_manager.sort(["categories"])
|
||||
results = sorted_manager.results
|
||||
|
||||
assert results[0].categories == ["BGP", "routing"]
|
||||
assert results[1].categories == ["VXLAN", "networking"]
|
||||
assert results[2].categories == ["system", "hardware"]
|
||||
|
||||
def test_sort_multiple_fields(self, test_result_factory: Callable[[], TestResult]) -> None:
|
||||
"""Test sorting by multiple fields."""
|
||||
result_manager = ResultManager()
|
||||
test1 = test_result_factory()
|
||||
test1.result = AntaTestStatus.ERROR
|
||||
test1.test = "Test3"
|
||||
test2 = test_result_factory()
|
||||
test2.result = AntaTestStatus.ERROR
|
||||
test2.test = "Test1"
|
||||
test3 = test_result_factory()
|
||||
test3.result = AntaTestStatus.FAILURE
|
||||
test3.test = "Test2"
|
||||
|
||||
result_manager.results = [test1, test2, test3]
|
||||
sorted_manager = result_manager.sort(["result", "test"])
|
||||
results = sorted_manager.results
|
||||
|
||||
assert results[0].result == "error"
|
||||
assert results[0].test == "Test1"
|
||||
assert results[1].result == "error"
|
||||
assert results[1].test == "Test3"
|
||||
assert results[2].result == "failure"
|
||||
assert results[2].test == "Test2"
|
||||
|
||||
def test_sort_invalid_field(self) -> None:
|
||||
"""Test that sort method raises ValueError for invalid sort_by fields."""
|
||||
result_manager = ResultManager()
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=re.escape(
|
||||
"Invalid sort_by fields: ['bad_field']. Accepted fields are: ['name', 'test', 'categories', 'description', 'result', 'messages', 'custom_field']",
|
||||
),
|
||||
):
|
||||
result_manager.sort(["bad_field"])
|
||||
|
||||
def test_sort_is_chainable(self) -> None:
|
||||
"""Test that the sort method is chainable."""
|
||||
result_manager = ResultManager()
|
||||
assert isinstance(result_manager.sort(["name"]), ResultManager)
|
||||
|
|
|
@ -1,378 +1,389 @@
|
|||
[
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyTacacsSourceIntf",
|
||||
"categories": [
|
||||
"AAA"
|
||||
],
|
||||
"description": "Verifies TACACS source-interface for a specified VRF.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Source-interface Management0 is not configured in VRF default"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyLLDPNeighbors",
|
||||
"categories": [
|
||||
"Connectivity"
|
||||
],
|
||||
"description": "Verifies that the provided LLDP neighbors are connected properly.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Wrong LLDP neighbor(s) on port(s):\n Ethernet1\n DC1-LEAF1A_Ethernet1\n Ethernet2\n DC1-LEAF1B_Ethernet1\nPort(s) not configured:\n Ethernet7"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyBGPPeerCount",
|
||||
"categories": [
|
||||
"BGP"
|
||||
],
|
||||
"description": "Verifies the count of BGP peers.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'PROD': 'Not Configured', 'default': 'Expected: 3, Actual: 4'}}, {'afi': 'ipv4', 'safi': 'multicast', 'vrfs': {'DEV': 'Not Configured'}}, {'afi': 'evpn', 'vrfs': {'default': 'Expected: 2, Actual: 4'}}]"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifySTPMode",
|
||||
"categories": [
|
||||
"STP"
|
||||
],
|
||||
"description": "Verifies the configured STP mode for a provided list of VLAN(s).",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"STP mode 'rapidPvst' not configured for the following VLAN(s): [10, 20]"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifySnmpStatus",
|
||||
"categories": [
|
||||
"SNMP"
|
||||
],
|
||||
"description": "Verifies if the SNMP agent is enabled.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"SNMP agent disabled in vrf default"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyRoutingTableEntry",
|
||||
"categories": [
|
||||
"Routing"
|
||||
],
|
||||
"description": "Verifies that the provided routes are present in the routing table of a specified VRF.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"The following route(s) are missing from the routing table of VRF default: ['10.1.0.2']"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyInterfaceUtilization",
|
||||
"categories": [
|
||||
"Interfaces"
|
||||
],
|
||||
"description": "Verifies that the utilization of interfaces is below a certain threshold.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyMlagStatus",
|
||||
"categories": [
|
||||
"MLAG"
|
||||
],
|
||||
"description": "Verifies the health status of the MLAG configuration.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"MLAG is disabled"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyVxlan1Interface",
|
||||
"categories": [
|
||||
"VXLAN"
|
||||
],
|
||||
"description": "Verifies the Vxlan1 interface status.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"Vxlan1 interface is not configured"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyBFDSpecificPeers",
|
||||
"categories": [
|
||||
"BFD"
|
||||
],
|
||||
"description": "Verifies the IPv4 BFD peer's sessions and remote disc in the specified VRF.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Following BFD peers are not configured, status is not up or remote disc is zero:\n{'192.0.255.8': {'default': 'Not Configured'}, '192.0.255.7': {'default': 'Not Configured'}}"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyNTP",
|
||||
"categories": [
|
||||
"System"
|
||||
],
|
||||
"description": "Verifies if NTP is synchronised.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"The device is not synchronized with the configured NTP server(s): 'NTP is disabled.'"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyReachability",
|
||||
"categories": [
|
||||
"Connectivity"
|
||||
],
|
||||
"description": "Test the network reachability to one or many destination IP(s).",
|
||||
"result": "error",
|
||||
"messages": [
|
||||
"ping vrf MGMT 1.1.1.1 source Management1 repeat 2 has failed: No source interface Management1"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyTelnetStatus",
|
||||
"categories": [
|
||||
"Security"
|
||||
],
|
||||
"description": "Verifies if Telnet is disabled in the default VRF.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyEOSVersion",
|
||||
"categories": [
|
||||
"Software"
|
||||
],
|
||||
"description": "Verifies the EOS version of the device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"device is running version \"4.31.1F-34554157.4311F (engineering build)\" not in expected versions: ['4.25.4M', '4.26.1F']"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-SPINE1",
|
||||
"test": "VerifyHostname",
|
||||
"categories": [
|
||||
"Services"
|
||||
],
|
||||
"description": "Verifies the hostname of a device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Expected `s1-spine1` as the hostname, but found `DC1-SPINE1` instead."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyTacacsSourceIntf",
|
||||
"categories": [
|
||||
"AAA"
|
||||
],
|
||||
"description": "Verifies TACACS source-interface for a specified VRF.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Source-interface Management0 is not configured in VRF default"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyLLDPNeighbors",
|
||||
"categories": [
|
||||
"Connectivity"
|
||||
],
|
||||
"description": "Verifies that the provided LLDP neighbors are connected properly.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Wrong LLDP neighbor(s) on port(s):\n Ethernet1\n DC1-SPINE1_Ethernet1\n Ethernet2\n DC1-SPINE2_Ethernet1\nPort(s) not configured:\n Ethernet7"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyBGPPeerCount",
|
||||
"categories": [
|
||||
"BGP"
|
||||
],
|
||||
"description": "Verifies the count of BGP peers.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'PROD': 'Expected: 2, Actual: 1'}}, {'afi': 'ipv4', 'safi': 'multicast', 'vrfs': {'DEV': 'Expected: 3, Actual: 0'}}]"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifySTPMode",
|
||||
"categories": [
|
||||
"STP"
|
||||
],
|
||||
"description": "Verifies the configured STP mode for a provided list of VLAN(s).",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Wrong STP mode configured for the following VLAN(s): [10, 20]"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifySnmpStatus",
|
||||
"categories": [
|
||||
"SNMP"
|
||||
],
|
||||
"description": "Verifies if the SNMP agent is enabled.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"SNMP agent disabled in vrf default"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyRoutingTableEntry",
|
||||
"categories": [
|
||||
"Routing"
|
||||
],
|
||||
"description": "Verifies that the provided routes are present in the routing table of a specified VRF.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyInterfaceUtilization",
|
||||
"categories": [
|
||||
"Interfaces"
|
||||
],
|
||||
"description": "Verifies that the utilization of interfaces is below a certain threshold.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyMlagStatus",
|
||||
"categories": [
|
||||
"MLAG"
|
||||
],
|
||||
"description": "Verifies the health status of the MLAG configuration.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyVxlan1Interface",
|
||||
"categories": [
|
||||
"VXLAN"
|
||||
],
|
||||
"description": "Verifies the Vxlan1 interface status.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyBFDSpecificPeers",
|
||||
"categories": [
|
||||
"BFD"
|
||||
],
|
||||
"description": "Verifies the IPv4 BFD peer's sessions and remote disc in the specified VRF.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Following BFD peers are not configured, status is not up or remote disc is zero:\n{'192.0.255.8': {'default': 'Not Configured'}, '192.0.255.7': {'default': 'Not Configured'}}"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyNTP",
|
||||
"categories": [
|
||||
"System"
|
||||
],
|
||||
"description": "Verifies if NTP is synchronised.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"The device is not synchronized with the configured NTP server(s): 'NTP is disabled.'"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyReachability",
|
||||
"categories": [
|
||||
"Connectivity"
|
||||
],
|
||||
"description": "Test the network reachability to one or many destination IP(s).",
|
||||
"result": "error",
|
||||
"messages": [
|
||||
"ping vrf MGMT 1.1.1.1 source Management1 repeat 2 has failed: No source interface Management1"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyTelnetStatus",
|
||||
"categories": [
|
||||
"Security"
|
||||
],
|
||||
"description": "Verifies if Telnet is disabled in the default VRF.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyEOSVersion",
|
||||
"categories": [
|
||||
"Software"
|
||||
],
|
||||
"description": "Verifies the EOS version of the device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"device is running version \"4.31.1F-34554157.4311F (engineering build)\" not in expected versions: ['4.25.4M', '4.26.1F']"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "DC1-LEAF1A",
|
||||
"test": "VerifyHostname",
|
||||
"categories": [
|
||||
"Services"
|
||||
],
|
||||
"description": "Verifies the hostname of a device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Expected `s1-spine1` as the hostname, but found `DC1-LEAF1A` instead."
|
||||
],
|
||||
"custom_field": null
|
||||
}
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyMlagDualPrimary",
|
||||
"categories": [
|
||||
"mlag"
|
||||
],
|
||||
"description": "Verifies the MLAG dual-primary detection parameters.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Dual-primary detection is disabled"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyHostname",
|
||||
"categories": [
|
||||
"services"
|
||||
],
|
||||
"description": "Verifies the hostname of a device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Incorrect Hostname - Expected: s1-spine1 Actual: leaf1-dc1"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyBGPAdvCommunities",
|
||||
"categories": [
|
||||
"bgp"
|
||||
],
|
||||
"description": "Verifies that advertised communities are standard, extended and large for BGP IPv4 peer(s).",
|
||||
"result": "error",
|
||||
"messages": [
|
||||
"show bgp neighbors vrf all has failed: The command is only supported in the multi-agent routing protocol model., The command is only supported in the multi-agent routing protocol model., The command is only supported in the multi-agent routing protocol model., The command is only supported in the multi-agent routing protocol model."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyStunClient",
|
||||
"categories": [
|
||||
"stun"
|
||||
],
|
||||
"description": "(Deprecated) Verifies the translation for a source address on a STUN client.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Client 172.18.3.2 Port: 4500 - STUN client translation not found."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyBannerLogin",
|
||||
"categories": [
|
||||
"security"
|
||||
],
|
||||
"description": "Verifies the login banner of a device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Expected `# Copyright (c) 2023-2024 Arista Networks, Inc.\n# Use of this source code is governed by the Apache License 2.0\n# that can be found in the LICENSE file.\n` as the login banner, but found `` instead."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyISISNeighborState",
|
||||
"categories": [
|
||||
"isis"
|
||||
],
|
||||
"description": "Verifies the health of IS-IS neighbors.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"IS-IS not configured"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyEOSVersion",
|
||||
"categories": [
|
||||
"software"
|
||||
],
|
||||
"description": "Verifies the EOS version of the device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"EOS version mismatch - Actual: 4.31.0F-33804048.4310F (engineering build) not in Expected: 4.25.4M, 4.26.1F"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyTcamProfile",
|
||||
"categories": [
|
||||
"profiles"
|
||||
],
|
||||
"description": "Verifies the device TCAM profile.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyTcamProfile test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyPathsHealth",
|
||||
"categories": [
|
||||
"path-selection"
|
||||
],
|
||||
"description": "Verifies the path and telemetry state of all paths under router path-selection.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyPathsHealth test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyBannerMotd",
|
||||
"categories": [
|
||||
"security"
|
||||
],
|
||||
"description": "Verifies the motd banner of a device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Expected `# Copyright (c) 2023-2024 Arista Networks, Inc.\n# Use of this source code is governed by the Apache License 2.0\n# that can be found in the LICENSE file.\n` as the motd banner, but found `` instead."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyFieldNotice44Resolution",
|
||||
"categories": [
|
||||
"field notices"
|
||||
],
|
||||
"description": "Verifies that the device is using the correct Aboot version per FN0044.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyFieldNotice44Resolution test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyLoggingHosts",
|
||||
"categories": [
|
||||
"logging"
|
||||
],
|
||||
"description": "Verifies logging hosts (syslog servers) for a specified VRF.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Syslog servers 1.1.1.1, 2.2.2.2 are not configured in VRF default"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyAVTPathHealth",
|
||||
"categories": [
|
||||
"avt"
|
||||
],
|
||||
"description": "Verifies the status of all AVT paths for all VRFs.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyAVTPathHealth test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyTemperature",
|
||||
"categories": [
|
||||
"hardware"
|
||||
],
|
||||
"description": "Verifies if the device temperature is within acceptable limits.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyTemperature test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyNTPAssociations",
|
||||
"categories": [
|
||||
"system"
|
||||
],
|
||||
"description": "Verifies the Network Time Protocol (NTP) associations.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"NTP Server: 1.1.1.1 Preferred: True Stratum: 1 - Not configured",
|
||||
"NTP Server: 2.2.2.2 Preferred: False Stratum: 2 - Not configured",
|
||||
"NTP Server: 3.3.3.3 Preferred: False Stratum: 2 - Not configured"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyDynamicVlanSource",
|
||||
"categories": [
|
||||
"vlan"
|
||||
],
|
||||
"description": "Verifies dynamic VLAN allocation for specified VLAN sources.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Dynamic VLAN source(s) exist but have no VLANs allocated: mlagsync"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyActiveCVXConnections",
|
||||
"categories": [
|
||||
"cvx"
|
||||
],
|
||||
"description": "Verifies the number of active CVX Connections.",
|
||||
"result": "error",
|
||||
"messages": [
|
||||
"show cvx connections brief has failed: Unavailable command (controller not ready) (at token 2: 'connections')"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyIPv4RouteNextHops",
|
||||
"categories": [
|
||||
"routing"
|
||||
],
|
||||
"description": "Verifies the next-hops of the IPv4 prefixes.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyVxlan1ConnSettings",
|
||||
"categories": [
|
||||
"vxlan"
|
||||
],
|
||||
"description": "Verifies the interface vxlan1 source interface and UDP port.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyStunClientTranslation",
|
||||
"categories": [
|
||||
"stun"
|
||||
],
|
||||
"description": "Verifies the translation for a source address on a STUN client.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Client 172.18.3.2 Port: 4500 - STUN client translation not found.",
|
||||
"Client 100.64.3.2 Port: 4500 - STUN client translation not found."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyPtpGMStatus",
|
||||
"categories": [
|
||||
"ptp"
|
||||
],
|
||||
"description": "Verifies that the device is locked to a valid PTP Grandmaster.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyPtpGMStatus test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyRunningConfigDiffs",
|
||||
"categories": [
|
||||
"configuration"
|
||||
],
|
||||
"description": "Verifies there is no difference between the running-config and the startup-config.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyBFDPeersHealth",
|
||||
"categories": [
|
||||
"bfd"
|
||||
],
|
||||
"description": "Verifies the health of IPv4 BFD peers across all VRFs.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"No IPv4 BFD peers are configured for any VRF."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyIPProxyARP",
|
||||
"categories": [
|
||||
"interfaces"
|
||||
],
|
||||
"description": "Verifies if Proxy ARP is enabled.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Interface: Ethernet1 - Proxy-ARP disabled",
|
||||
"Interface: Ethernet2 - Proxy-ARP disabled"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifySnmpContact",
|
||||
"categories": [
|
||||
"snmp"
|
||||
],
|
||||
"description": "Verifies the SNMP contact of a device.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"SNMP contact is not configured."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyLLDPNeighbors",
|
||||
"categories": [
|
||||
"connectivity"
|
||||
],
|
||||
"description": "Verifies the connection status of the specified LLDP (Link Layer Discovery Protocol) neighbors.",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"Port: Ethernet1 Neighbor: DC1-SPINE1 Neighbor Port: Ethernet1 - Wrong LLDP neighbors: spine1-dc1.fun.aristanetworks.com/Ethernet3",
|
||||
"Port: Ethernet2 Neighbor: DC1-SPINE2 Neighbor Port: Ethernet1 - Wrong LLDP neighbors: spine2-dc1.fun.aristanetworks.com/Ethernet3"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyAcctConsoleMethods",
|
||||
"categories": [
|
||||
"aaa"
|
||||
],
|
||||
"description": "Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x).",
|
||||
"result": "failure",
|
||||
"messages": [
|
||||
"AAA console accounting is not configured for commands, exec, system, dot1x"
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyOSPFMaxLSA",
|
||||
"categories": [
|
||||
"ospf"
|
||||
],
|
||||
"description": "Verifies all OSPF instances did not cross the maximum LSA threshold.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"No OSPF instance found."
|
||||
],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifySTPBlockedPorts",
|
||||
"categories": [
|
||||
"stp"
|
||||
],
|
||||
"description": "Verifies there is no STP blocked ports.",
|
||||
"result": "success",
|
||||
"messages": [],
|
||||
"custom_field": null
|
||||
},
|
||||
{
|
||||
"name": "s1-spine1",
|
||||
"test": "VerifyLANZ",
|
||||
"categories": [
|
||||
"lanz"
|
||||
],
|
||||
"description": "Verifies if LANZ is enabled.",
|
||||
"result": "skipped",
|
||||
"messages": [
|
||||
"VerifyLANZ test is not supported on cEOSLab."
|
||||
],
|
||||
"custom_field": null
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""ANTA Result Manager models unit tests."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue