Adding upstream version 0.13.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 11:32:35 +01:00
parent c0ae77e0f6
commit ecf5ca3300
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
272 changed files with 33172 additions and 0 deletions

View file

@ -0,0 +1,7 @@
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
A guide explaining how to write the unit test can be found in the [contribution guide](../../../docs/contribution.md#unit-tests)

View file

@ -0,0 +1,3 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.

View file

@ -0,0 +1,3 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,230 @@
# Copyright (c) 2023-2024 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.tests.routing.generic.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.routing.generic import VerifyRoutingProtocolModel, VerifyRoutingTableEntry, VerifyRoutingTableSize
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyRoutingProtocolModel,
"eos_data": [{"vrfs": {"default": {}}, "protoModelStatus": {"configuredProtoModel": "multi-agent", "operatingProtoModel": "multi-agent"}}],
"inputs": {"model": "multi-agent"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-configured-model",
"test": VerifyRoutingProtocolModel,
"eos_data": [{"vrfs": {"default": {}}, "protoModelStatus": {"configuredProtoModel": "ribd", "operatingProtoModel": "ribd"}}],
"inputs": {"model": "multi-agent"},
"expected": {"result": "failure", "messages": ["routing model is misconfigured: configured: ribd - operating: ribd - expected: multi-agent"]},
},
{
"name": "failure-mismatch-operating-model",
"test": VerifyRoutingProtocolModel,
"eos_data": [{"vrfs": {"default": {}}, "protoModelStatus": {"configuredProtoModel": "multi-agent", "operatingProtoModel": "ribd"}}],
"inputs": {"model": "multi-agent"},
"expected": {"result": "failure", "messages": ["routing model is misconfigured: configured: multi-agent - operating: ribd - expected: multi-agent"]},
},
{
"name": "success",
"test": VerifyRoutingTableSize,
"eos_data": [
{
"vrfs": {
"default": {
# Output truncated
"maskLen": {"8": 2},
"totalRoutes": 123,
}
},
}
],
"inputs": {"minimum": 42, "maximum": 666},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyRoutingTableSize,
"eos_data": [
{
"vrfs": {
"default": {
# Output truncated
"maskLen": {"8": 2},
"totalRoutes": 1000,
}
},
}
],
"inputs": {"minimum": 42, "maximum": 666},
"expected": {"result": "failure", "messages": ["routing-table has 1000 routes and not between min (42) and maximum (666)"]},
},
{
"name": "error-max-smaller-than-min",
"test": VerifyRoutingTableSize,
"eos_data": [{}],
"inputs": {"minimum": 666, "maximum": 42},
"expected": {
"result": "error",
"messages": ["Minimum 666 is greater than maximum 42"],
},
},
{
"name": "success",
"test": VerifyRoutingTableEntry,
"eos_data": [
{
"vrfs": {
"default": {
"routingDisabled": False,
"allRoutesProgrammedHardware": True,
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {
"10.1.0.1/32": {
"hardwareProgrammed": True,
"routeType": "eBGP",
"routeLeaked": False,
"kernelProgrammed": True,
"routeAction": "forward",
"directlyConnected": False,
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.4", "interface": "Ethernet1"}],
}
},
}
}
},
{
"vrfs": {
"default": {
"routingDisabled": False,
"allRoutesProgrammedHardware": True,
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {
"10.1.0.2/32": {
"hardwareProgrammed": True,
"routeType": "eBGP",
"routeLeaked": False,
"kernelProgrammed": True,
"routeAction": "forward",
"directlyConnected": False,
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.6", "interface": "Ethernet2"}],
}
},
}
}
},
],
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"]},
"expected": {"result": "success"},
},
{
"name": "failure-missing-route",
"test": VerifyRoutingTableEntry,
"eos_data": [
{
"vrfs": {
"default": {
"routingDisabled": False,
"allRoutesProgrammedHardware": True,
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {},
}
}
},
{
"vrfs": {
"default": {
"routingDisabled": False,
"allRoutesProgrammedHardware": True,
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {
"10.1.0.2/32": {
"hardwareProgrammed": True,
"routeType": "eBGP",
"routeLeaked": False,
"kernelProgrammed": True,
"routeAction": "forward",
"directlyConnected": False,
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.6", "interface": "Ethernet2"}],
}
},
}
}
},
],
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"]},
"expected": {"result": "failure", "messages": ["The following route(s) are missing from the routing table of VRF default: ['10.1.0.1']"]},
},
{
"name": "failure-wrong-route",
"test": VerifyRoutingTableEntry,
"eos_data": [
{
"vrfs": {
"default": {
"routingDisabled": False,
"allRoutesProgrammedHardware": True,
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {
"10.1.0.1/32": {
"hardwareProgrammed": True,
"routeType": "eBGP",
"routeLeaked": False,
"kernelProgrammed": True,
"routeAction": "forward",
"directlyConnected": False,
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.4", "interface": "Ethernet1"}],
}
},
}
}
},
{
"vrfs": {
"default": {
"routingDisabled": False,
"allRoutesProgrammedHardware": True,
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {
"10.1.0.55/32": {
"hardwareProgrammed": True,
"routeType": "eBGP",
"routeLeaked": False,
"kernelProgrammed": True,
"routeAction": "forward",
"directlyConnected": False,
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.6", "interface": "Ethernet2"}],
}
},
}
}
},
],
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"]},
"expected": {"result": "failure", "messages": ["The following route(s) are missing from the routing table of VRF default: ['10.1.0.2']"]},
},
]

View file

@ -0,0 +1,298 @@
# Copyright (c) 2023-2024 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.tests.routing.ospf.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.routing.ospf import VerifyOSPFNeighborCount, VerifyOSPFNeighborState
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyOSPFNeighborState,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"666": {
"ospfNeighborEntries": [
{
"routerId": "7.7.7.7",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
{
"routerId": "9.9.9.9",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
]
}
}
},
"BLAH": {
"instList": {
"777": {
"ospfNeighborEntries": [
{
"routerId": "8.8.8.8",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
}
]
}
}
},
}
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyOSPFNeighborState,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"666": {
"ospfNeighborEntries": [
{
"routerId": "7.7.7.7",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "2-way",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
{
"routerId": "9.9.9.9",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
]
}
}
},
"BLAH": {
"instList": {
"777": {
"ospfNeighborEntries": [
{
"routerId": "8.8.8.8",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "down",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
}
]
}
}
},
}
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"Some neighbors are not correctly configured: [{'vrf': 'default', 'instance': '666', 'neighbor': '7.7.7.7', 'state': '2-way'},"
" {'vrf': 'BLAH', 'instance': '777', 'neighbor': '8.8.8.8', 'state': 'down'}]."
],
},
},
{
"name": "skipped",
"test": VerifyOSPFNeighborState,
"eos_data": [
{
"vrfs": {},
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["no OSPF neighbor found"]},
},
{
"name": "success",
"test": VerifyOSPFNeighborCount,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"666": {
"ospfNeighborEntries": [
{
"routerId": "7.7.7.7",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
{
"routerId": "9.9.9.9",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
]
}
}
},
"BLAH": {
"instList": {
"777": {
"ospfNeighborEntries": [
{
"routerId": "8.8.8.8",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
}
]
}
}
},
}
}
],
"inputs": {"number": 3},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifyOSPFNeighborCount,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"666": {
"ospfNeighborEntries": [
{
"routerId": "7.7.7.7",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
]
}
}
}
}
}
],
"inputs": {"number": 3},
"expected": {"result": "failure", "messages": ["device has 1 neighbors (expected 3)"]},
},
{
"name": "failure-good-number-wrong-state",
"test": VerifyOSPFNeighborCount,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"666": {
"ospfNeighborEntries": [
{
"routerId": "7.7.7.7",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "2-way",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
{
"routerId": "9.9.9.9",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
]
}
}
},
"BLAH": {
"instList": {
"777": {
"ospfNeighborEntries": [
{
"routerId": "8.8.8.8",
"priority": 1,
"drState": "DR",
"interfaceName": "Ethernet1",
"adjacencyState": "down",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
}
]
}
}
},
}
}
],
"inputs": {"number": 3},
"expected": {
"result": "failure",
"messages": [
"Some neighbors are not correctly configured: [{'vrf': 'default', 'instance': '666', 'neighbor': '7.7.7.7', 'state': '2-way'},"
" {'vrf': 'BLAH', 'instance': '777', 'neighbor': '8.8.8.8', 'state': 'down'}]."
],
},
},
{
"name": "skipped",
"test": VerifyOSPFNeighborCount,
"eos_data": [
{
"vrfs": {},
}
],
"inputs": {"number": 3},
"expected": {"result": "skipped", "messages": ["no OSPF neighbor found"]},
},
]

View file

@ -0,0 +1,516 @@
# Copyright (c) 2023-2024 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.tests.aaa.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.aaa import (
VerifyAcctConsoleMethods,
VerifyAcctDefaultMethods,
VerifyAuthenMethods,
VerifyAuthzMethods,
VerifyTacacsServerGroups,
VerifyTacacsServers,
VerifyTacacsSourceIntf,
)
from tests.lib.anta import test # noqa: F401; pylint: disable=unused-import
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyTacacsSourceIntf,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
}
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-not-configured",
"test": VerifyTacacsSourceIntf,
"eos_data": [
{
"tacacsServers": [],
"groups": {},
"srcIntf": {},
}
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface Management0 is not configured in VRF MGMT"]},
},
{
"name": "failure-wrong-intf",
"test": VerifyTacacsSourceIntf,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management1"},
}
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Wrong source-interface configured in VRF MGMT"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifyTacacsSourceIntf,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"PROD": "Management0"},
}
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface Management0 is not configured in VRF MGMT"]},
},
{
"name": "success",
"test": VerifyTacacsServers,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
}
],
"inputs": {"servers": ["10.22.10.91"], "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-no-servers",
"test": VerifyTacacsServers,
"eos_data": [
{
"tacacsServers": [],
"groups": {},
"srcIntf": {},
}
],
"inputs": {"servers": ["10.22.10.91"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["No TACACS servers are configured"]},
},
{
"name": "failure-not-configured",
"test": VerifyTacacsServers,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
}
],
"inputs": {"servers": ["10.22.10.91", "10.22.10.92"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["TACACS servers ['10.22.10.92'] are not configured in VRF MGMT"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifyTacacsServers,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "PROD"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
}
],
"inputs": {"servers": ["10.22.10.91"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["TACACS servers ['10.22.10.91'] are not configured in VRF MGMT"]},
},
{
"name": "success",
"test": VerifyTacacsServerGroups,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
}
],
"inputs": {"groups": ["GROUP1"]},
"expected": {"result": "success"},
},
{
"name": "failure-no-server-groups",
"test": VerifyTacacsServerGroups,
"eos_data": [
{
"tacacsServers": [],
"groups": {},
"srcIntf": {},
}
],
"inputs": {"groups": ["GROUP1"]},
"expected": {"result": "failure", "messages": ["No TACACS server group(s) are configured"]},
},
{
"name": "failure-not-configured",
"test": VerifyTacacsServerGroups,
"eos_data": [
{
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
}
],
"groups": {"GROUP2": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
}
],
"inputs": {"groups": ["GROUP1"]},
"expected": {"result": "failure", "messages": ["TACACS server group(s) ['GROUP1'] are not configured"]},
},
{
"name": "success-login-enable",
"test": VerifyAuthenMethods,
"eos_data": [
{
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}, "login": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "success"},
},
{
"name": "success-dot1x",
"test": VerifyAuthenMethods,
"eos_data": [
{
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}, "login": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
}
],
"inputs": {"methods": ["radius"], "types": ["dot1x"]},
"expected": {"result": "success"},
},
{
"name": "failure-no-login-console",
"test": VerifyAuthenMethods,
"eos_data": [
{
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "failure", "messages": ["AAA authentication methods are not configured for login console"]},
},
{
"name": "failure-login-console",
"test": VerifyAuthenMethods,
"eos_data": [
{
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}, "login": {"methods": ["group radius", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "failure", "messages": ["AAA authentication methods ['group tacacs+', 'local'] are not matching for login console"]},
},
{
"name": "failure-login-default",
"test": VerifyAuthenMethods,
"eos_data": [
{
"loginAuthenMethods": {"default": {"methods": ["group radius", "local"]}, "login": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "failure", "messages": ["AAA authentication methods ['group tacacs+', 'local'] are not matching for ['login']"]},
},
{
"name": "success",
"test": VerifyAuthzMethods,
"eos_data": [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group tacacs+", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group tacacs+", "local"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "success"},
},
{
"name": "failure-commands",
"test": VerifyAuthzMethods,
"eos_data": [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group radius", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group tacacs+", "local"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "failure", "messages": ["AAA authorization methods ['group tacacs+', 'local'] are not matching for ['commands']"]},
},
{
"name": "failure-exec",
"test": VerifyAuthzMethods,
"eos_data": [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group tacacs+", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group radius", "local"]}},
}
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "failure", "messages": ["AAA authorization methods ['group tacacs+', 'local'] are not matching for ['exec']"]},
},
{
"name": "success-commands-exec-system",
"test": VerifyAcctDefaultMethods,
"eos_data": [
{
"commandsAcctMethods": {"privilege0-15": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "success"},
},
{
"name": "success-dot1x",
"test": VerifyAcctDefaultMethods,
"eos_data": [
{
"commandsAcctMethods": {"privilege0-15": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultAction": "startStop", "defaultMethods": ["group radius", "logging"], "consoleMethods": []}},
}
],
"inputs": {"methods": ["radius", "logging"], "types": ["dot1x"]},
"expected": {"result": "success"},
},
{
"name": "failure-not-configured",
"test": VerifyAcctDefaultMethods,
"eos_data": [
{
"commandsAcctMethods": {"privilege0-15": {"defaultMethods": [], "consoleMethods": []}},
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA default accounting is not configured for ['commands']"]},
},
{
"name": "failure-not-configured-empty",
"test": VerifyAcctDefaultMethods,
"eos_data": [
{
"systemAcctMethods": {"system": {"defaultMethods": [], "consoleMethods": []}},
"execAcctMethods": {"exec": {"defaultMethods": [], "consoleMethods": []}},
"commandsAcctMethods": {"privilege0-15": {"defaultMethods": [], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA default accounting is not configured for ['system', 'exec', 'commands']"]},
},
{
"name": "failure-not-matching",
"test": VerifyAcctDefaultMethods,
"eos_data": [
{
"commandsAcctMethods": {"privilege0-15": {"defaultAction": "startStop", "defaultMethods": ["group radius", "logging"], "consoleMethods": []}},
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA accounting default methods ['group tacacs+', 'logging'] are not matching for ['commands']"]},
},
{
"name": "success-commands-exec-system",
"test": VerifyAcctConsoleMethods,
"eos_data": [
{
"commandsAcctMethods": {
"privilege0-15": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "success"},
},
{
"name": "success-dot1x",
"test": VerifyAcctConsoleMethods,
"eos_data": [
{
"commandsAcctMethods": {
"privilege0-15": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"dot1xAcctMethods": {
"dot1x": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["dot1x"]},
"expected": {"result": "success"},
},
{
"name": "failure-not-configured",
"test": VerifyAcctConsoleMethods,
"eos_data": [
{
"commandsAcctMethods": {
"privilege0-15": {
"defaultMethods": [],
"consoleMethods": [],
}
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA console accounting is not configured for ['commands']"]},
},
{
"name": "failure-not-configured-empty",
"test": VerifyAcctConsoleMethods,
"eos_data": [
{
"systemAcctMethods": {"system": {"defaultMethods": [], "consoleMethods": []}},
"execAcctMethods": {"exec": {"defaultMethods": [], "consoleMethods": []}},
"commandsAcctMethods": {"privilege0-15": {"defaultMethods": [], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA console accounting is not configured for ['system', 'exec', 'commands']"]},
},
{
"name": "failure-not-matching",
"test": VerifyAcctConsoleMethods,
"eos_data": [
{
"commandsAcctMethods": {
"privilege0-15": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group radius", "logging"],
}
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
}
},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
}
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA accounting console methods ['group tacacs+', 'logging'] are not matching for ['commands']"]},
},
]

View file

@ -0,0 +1,523 @@
# Copyright (c) 2023-2024 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.tests.bfd.py
"""
# pylint: disable=C0302
from __future__ import annotations
from typing import Any
# pylint: disable=C0413
# because of the patch above
from anta.tests.bfd import VerifyBFDPeersHealth, VerifyBFDPeersIntervals, VerifyBFDSpecificPeers # noqa: E402
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyBFDPeersIntervals,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"peerStatsDetail": {
"operTxInterval": 1200000,
"operRxInterval": 1200000,
"detectMult": 3,
}
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.70": {
"peerStats": {
"": {
"peerStatsDetail": {
"operTxInterval": 1200000,
"operRxInterval": 1200000,
"detectMult": 3,
}
}
}
}
}
},
}
}
],
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "default", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-no-peer",
"test": VerifyBFDPeersIntervals,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"peerStatsDetail": {
"operTxInterval": 1200000,
"operRxInterval": 1200000,
"detectMult": 3,
}
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.71": {
"peerStats": {
"": {
"peerStatsDetail": {
"operTxInterval": 1200000,
"operRxInterval": 1200000,
"detectMult": 3,
}
}
}
}
}
},
}
}
],
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "CS", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3},
]
},
"expected": {
"result": "failure",
"messages": [
"Following BFD peers are not configured or timers are not correct:\n"
"{'192.0.255.7': {'CS': 'Not Configured'}, '192.0.255.70': {'MGMT': 'Not Configured'}}"
],
},
},
{
"name": "failure-incorrect-timers",
"test": VerifyBFDPeersIntervals,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"peerStatsDetail": {
"operTxInterval": 1300000,
"operRxInterval": 1200000,
"detectMult": 4,
}
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.70": {
"peerStats": {
"": {
"peerStatsDetail": {
"operTxInterval": 120000,
"operRxInterval": 120000,
"detectMult": 5,
}
}
}
}
}
},
}
}
],
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "default", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3},
]
},
"expected": {
"result": "failure",
"messages": [
"Following BFD peers are not configured or timers are not correct:\n"
"{'192.0.255.7': {'default': {'tx_interval': 1300000, 'rx_interval': 1200000, 'multiplier': 4}}, "
"'192.0.255.70': {'MGMT': {'tx_interval': 120000, 'rx_interval': 120000, 'multiplier': 5}}}"
],
},
},
{
"name": "success",
"test": VerifyBFDSpecificPeers,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 108328132,
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.70": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 108328132,
}
}
}
}
},
}
}
],
"inputs": {"bfd_peers": [{"peer_address": "192.0.255.7", "vrf": "default"}, {"peer_address": "192.0.255.70", "vrf": "MGMT"}]},
"expected": {"result": "success"},
},
{
"name": "failure-no-peer",
"test": VerifyBFDSpecificPeers,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 108328132,
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.71": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 108328132,
}
}
}
}
},
}
}
],
"inputs": {"bfd_peers": [{"peer_address": "192.0.255.7", "vrf": "CS"}, {"peer_address": "192.0.255.70", "vrf": "MGMT"}]},
"expected": {
"result": "failure",
"messages": [
"Following BFD peers are not configured, status is not up or remote disc is zero:\n"
"{'192.0.255.7': {'CS': 'Not Configured'}, '192.0.255.70': {'MGMT': 'Not Configured'}}"
],
},
},
{
"name": "failure-session-down",
"test": VerifyBFDSpecificPeers,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "Down",
"remoteDisc": 108328132,
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.70": {
"peerStats": {
"": {
"status": "Down",
"remoteDisc": 0,
}
}
}
}
},
}
}
],
"inputs": {"bfd_peers": [{"peer_address": "192.0.255.7", "vrf": "default"}, {"peer_address": "192.0.255.70", "vrf": "MGMT"}]},
"expected": {
"result": "failure",
"messages": [
"Following BFD peers are not configured, status is not up or remote disc is zero:\n"
"{'192.0.255.7': {'default': {'status': 'Down', 'remote_disc': 108328132}}, "
"'192.0.255.70': {'MGMT': {'status': 'Down', 'remote_disc': 0}}}"
],
},
},
{
"name": "success",
"test": VerifyBFDPeersHealth,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 3940685114,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
},
"ipv6Neighbors": {},
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.71": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 3940685114,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
},
"ipv6Neighbors": {},
},
}
},
{
"utcTime": 1703667348.111288,
},
],
"inputs": {"down_threshold": 2},
"expected": {"result": "success"},
},
{
"name": "failure-no-peer",
"test": VerifyBFDPeersHealth,
"eos_data": [
{
"vrfs": {
"MGMT": {
"ipv6Neighbors": {},
"ipv4Neighbors": {},
},
"default": {
"ipv6Neighbors": {},
"ipv4Neighbors": {},
},
}
},
{
"utcTime": 1703658481.8778424,
},
],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["No IPv4 BFD peers are configured for any VRF."],
},
},
{
"name": "failure-session-down",
"test": VerifyBFDPeersHealth,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "down",
"remoteDisc": 0,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
"192.0.255.70": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 3940685114,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
},
"ipv6Neighbors": {},
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.71": {
"peerStats": {
"": {
"status": "down",
"remoteDisc": 0,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
},
"ipv6Neighbors": {},
},
}
},
{
"utcTime": 1703658481.8778424,
},
],
"inputs": {},
"expected": {
"result": "failure",
"messages": [
"Following BFD peers are not up:\n192.0.255.7 is down in default VRF with remote disc 0.\n192.0.255.71 is down in MGMT VRF with remote disc 0."
],
},
},
{
"name": "failure-session-up-disc",
"test": VerifyBFDPeersHealth,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 0,
"lastDown": 1703657258.652725,
"l3intf": "Ethernet2",
}
}
},
"192.0.255.71": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 0,
"lastDown": 1703657258.652725,
"l3intf": "Ethernet2",
}
}
},
},
"ipv6Neighbors": {},
}
}
},
{
"utcTime": 1703658481.8778424,
},
],
"inputs": {},
"expected": {
"result": "failure",
"messages": ["Following BFD peers were down:\n192.0.255.7 in default VRF has remote disc 0.\n192.0.255.71 in default VRF has remote disc 0."],
},
},
{
"name": "failure-last-down",
"test": VerifyBFDPeersHealth,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 3940685114,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
"192.0.255.71": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 3940685114,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
"192.0.255.17": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 3940685114,
"lastDown": 1703657258.652725,
"l3intf": "",
}
}
},
},
"ipv6Neighbors": {},
}
}
},
{
"utcTime": 1703667348.111288,
},
],
"inputs": {"down_threshold": 4},
"expected": {
"result": "failure",
"messages": [
"Following BFD peers were down:\n192.0.255.7 in default VRF was down 3 hours ago.\n"
"192.0.255.71 in default VRF was down 3 hours ago.\n192.0.255.17 in default VRF was down 3 hours ago."
],
},
},
]

View file

@ -0,0 +1,35 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Data for testing anta.tests.configuration"""
from __future__ import annotations
from typing import Any
from anta.tests.configuration import VerifyRunningConfigDiffs, VerifyZeroTouch
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyZeroTouch,
"eos_data": [{"mode": "disabled"}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyZeroTouch,
"eos_data": [{"mode": "enabled"}],
"inputs": None,
"expected": {"result": "failure", "messages": ["ZTP is NOT disabled"]},
},
{
"name": "success",
"test": VerifyRunningConfigDiffs,
"eos_data": [""],
"inputs": None,
"expected": {"result": "success"},
},
{"name": "failure", "test": VerifyRunningConfigDiffs, "eos_data": ["blah blah"], "inputs": None, "expected": {"result": "failure", "messages": ["blah blah"]}},
]

View file

@ -0,0 +1,369 @@
# Copyright (c) 2023-2024 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.tests.connectivity.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.connectivity import VerifyLLDPNeighbors, VerifyReachability
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success-ip",
"test": VerifyReachability,
"inputs": {"hosts": [{"destination": "10.0.0.1", "source": "10.0.0.5"}, {"destination": "10.0.0.2", "source": "10.0.0.5"}]},
"eos_data": [
{
"messages": [
"""PING 10.0.0.1 (10.0.0.1) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.247 ms
80 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.072 ms
--- 10.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
{
"messages": [
"""PING 10.0.0.2 (10.0.0.2) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.247 ms
80 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.072 ms
--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
],
"expected": {"result": "success"},
},
{
"name": "success-interface",
"test": VerifyReachability,
"inputs": {"hosts": [{"destination": "10.0.0.1", "source": "Management0"}, {"destination": "10.0.0.2", "source": "Management0"}]},
"eos_data": [
{
"messages": [
"""PING 10.0.0.1 (10.0.0.1) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.247 ms
80 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.072 ms
--- 10.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
{
"messages": [
"""PING 10.0.0.2 (10.0.0.2) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.247 ms
80 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.072 ms
--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
],
"expected": {"result": "success"},
},
{
"name": "success-repeat",
"test": VerifyReachability,
"inputs": {"hosts": [{"destination": "10.0.0.1", "source": "Management0", "repeat": 1}]},
"eos_data": [
{
"messages": [
"""PING 10.0.0.1 (10.0.0.1) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.247 ms
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
],
"expected": {"result": "success"},
},
{
"name": "failure-ip",
"test": VerifyReachability,
"inputs": {"hosts": [{"destination": "10.0.0.11", "source": "10.0.0.5"}, {"destination": "10.0.0.2", "source": "10.0.0.5"}]},
"eos_data": [
{
"messages": [
"""ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
PING 10.0.0.11 (10.0.0.11) from 10.0.0.5 : 72(100) bytes of data.
--- 10.0.0.11 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 10ms
"""
]
},
{
"messages": [
"""PING 10.0.0.2 (10.0.0.2) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.247 ms
80 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.072 ms
--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('10.0.0.5', '10.0.0.11')]"]},
},
{
"name": "failure-interface",
"test": VerifyReachability,
"inputs": {"hosts": [{"destination": "10.0.0.11", "source": "Management0"}, {"destination": "10.0.0.2", "source": "Management0"}]},
"eos_data": [
{
"messages": [
"""ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
PING 10.0.0.11 (10.0.0.11) from 10.0.0.5 : 72(100) bytes of data.
--- 10.0.0.11 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 10ms
"""
]
},
{
"messages": [
"""PING 10.0.0.2 (10.0.0.2) from 10.0.0.5 : 72(100) bytes of data.
80 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.247 ms
80 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.072 ms
--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
"""
]
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('Management0', '10.0.0.11')]"]},
},
{
"name": "success",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
]
},
"eos_data": [
{
"lldpNeighbors": {
"Ethernet1": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73a0.fc18",
"systemName": "DC1-SPINE1",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet1"',
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
}
]
},
"Ethernet2": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73f7.d138",
"systemName": "DC1-SPINE2",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet1"',
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet2",
},
}
]
},
}
}
],
"expected": {"result": "success"},
},
{
"name": "failure-port-not-configured",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
]
},
"eos_data": [
{
"lldpNeighbors": {
"Ethernet1": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73a0.fc18",
"systemName": "DC1-SPINE1",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet1"',
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
}
]
},
}
}
],
"expected": {"result": "failure", "messages": ["The following port(s) have issues: {'port_not_configured': ['Ethernet2']}"]},
},
{
"name": "failure-no-neighbor",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
]
},
"eos_data": [
{
"lldpNeighbors": {
"Ethernet1": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73a0.fc18",
"systemName": "DC1-SPINE1",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet1"',
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
}
]
},
"Ethernet2": {"lldpNeighborInfo": []},
}
}
],
"expected": {"result": "failure", "messages": ["The following port(s) have issues: {'no_lldp_neighbor': ['Ethernet2']}"]},
},
{
"name": "failure-wrong-neighbor",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
]
},
"eos_data": [
{
"lldpNeighbors": {
"Ethernet1": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73a0.fc18",
"systemName": "DC1-SPINE1",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet1"',
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
}
]
},
"Ethernet2": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73f7.d138",
"systemName": "DC1-SPINE2",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet2"',
"interfaceId_v2": "Ethernet2",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet2",
},
}
]
},
}
}
],
"expected": {"result": "failure", "messages": ["The following port(s) have issues: {'wrong_lldp_neighbor': ['Ethernet2']}"]},
},
{
"name": "failure-multiple",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
{"port": "Ethernet3", "neighbor_device": "DC1-SPINE3", "neighbor_port": "Ethernet1"},
]
},
"eos_data": [
{
"lldpNeighbors": {
"Ethernet1": {
"lldpNeighborInfo": [
{
"chassisIdType": "macAddress",
"chassisId": "001c.73a0.fc18",
"systemName": "DC1-SPINE1",
"neighborInterfaceInfo": {
"interfaceIdType": "interfaceName",
"interfaceId": '"Ethernet2"',
"interfaceId_v2": "Ethernet2",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
}
]
},
"Ethernet2": {"lldpNeighborInfo": []},
}
}
],
"expected": {
"result": "failure",
"messages": [
"The following port(s) have issues: {'wrong_lldp_neighbor': ['Ethernet1'], 'no_lldp_neighbor': ['Ethernet2'], 'port_not_configured': ['Ethernet3']}"
],
},
},
]

View file

@ -0,0 +1,291 @@
# Copyright (c) 2023-2024 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 inputs for anta.tests.field_notices"""
from __future__ import annotations
from typing import Any
from anta.tests.field_notices import VerifyFieldNotice44Resolution, VerifyFieldNotice72Resolution
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
},
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure-4.0",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-4.0.1-3255441"}],
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (4.0.1)"]},
},
{
"name": "failure-4.1",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-4.1.0-3255441"}],
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (4.1.0)"]},
},
{
"name": "failure-6.0",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-6.0.1-3255441"}],
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (6.0.1)"]},
},
{
"name": "failure-6.1",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-6.1.1-3255441"}],
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (6.1.1)"]},
},
{
"name": "skipped-model",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "vEOS-lab",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
},
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["device is not impacted by FN044"]},
},
{
"name": "success-JPE",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3-48YC8",
"serialNumber": "JPE2130000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
}
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
},
{
"name": "success-JAS",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3-48YC8",
"serialNumber": "JAS2040000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
}
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
},
{
"name": "success-K-JPE",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3K-48YC8",
"serialNumber": "JPE2133000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
}
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
},
{
"name": "success-K-JAS",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3K-48YC8",
"serialNumber": "JAS2040000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
}
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
},
{
"name": "skipped-Serial",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3K-48YC8",
"serialNumber": "BAN2040000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Device not exposed"]},
},
{
"name": "skipped-Platform",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7150-52-CL",
"serialNumber": "JAS0040000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Platform is not impacted by FN072"]},
},
{
"name": "skipped-range-JPE",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3-48YC8",
"serialNumber": "JPE2131000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Device not exposed"]},
},
{
"name": "skipped-range-K-JAS",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3K-48YC8",
"serialNumber": "JAS2041000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Device not exposed"]},
},
{
"name": "failed-JPE",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3K-48YC8",
"serialNumber": "JPE2133000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device is exposed to FN72"]},
},
{
"name": "failed-JAS",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3-48YC8",
"serialNumber": "JAS2040000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device is exposed to FN72"]},
},
{
"name": "error",
"test": VerifyFieldNotice72Resolution,
"eos_data": [
{
"modelName": "DCS-7280SR3-48YC8",
"serialNumber": "JAS2040000",
"details": {
"deviations": [],
"components": [{"name": "FixedSystemvrm2", "version": "5"}],
},
}
],
"inputs": None,
"expected": {"result": "error", "messages": ["Error in running test - FixedSystemvrm1 not found"]},
},
]

View file

@ -0,0 +1,47 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Data for testing anta.tests.configuration"""
from __future__ import annotations
from typing import Any
from anta.tests.greent import VerifyGreenT, VerifyGreenTCounters
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyGreenTCounters,
"eos_data": [{"sampleRcvd": 0, "sampleDiscarded": 0, "multiDstSampleRcvd": 0, "grePktSent": 1, "sampleSent": 0}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyGreenTCounters,
"eos_data": [{"sampleRcvd": 0, "sampleDiscarded": 0, "multiDstSampleRcvd": 0, "grePktSent": 0, "sampleSent": 0}],
"inputs": None,
"expected": {"result": "failure"},
},
{
"name": "success",
"test": VerifyGreenT,
"eos_data": [{"sampleRcvd": 0, "sampleDiscarded": 0, "multiDstSampleRcvd": 0, "grePktSent": 1, "sampleSent": 0}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyGreenT,
"eos_data": [
{
"profiles": {
"default": {"interfaces": [], "appliedInterfaces": [], "samplePolicy": "default", "failures": {}, "appliedInterfaces6": [], "failures6": {}},
"testProfile": {"interfaces": [], "appliedInterfaces": [], "samplePolicy": "default", "failures": {}, "appliedInterfaces6": [], "failures6": {}},
}
}
],
"inputs": None,
"expected": {"result": "failure"},
},
]

View file

@ -0,0 +1,918 @@
# Copyright (c) 2023-2024 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 inputs for anta.tests.hardware"""
from __future__ import annotations
from typing import Any
from anta.tests.hardware import (
VerifyAdverseDrops,
VerifyEnvironmentCooling,
VerifyEnvironmentPower,
VerifyEnvironmentSystemCooling,
VerifyTemperature,
VerifyTransceiversManufacturers,
VerifyTransceiversTemperature,
)
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyTransceiversManufacturers,
"eos_data": [
{
"xcvrSlots": {
"1": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501340", "hardwareRev": "21"},
"2": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501337", "hardwareRev": "21"},
}
}
],
"inputs": {"manufacturers": ["Arista Networks"]},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyTransceiversManufacturers,
"eos_data": [
{
"xcvrSlots": {
"1": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501340", "hardwareRev": "21"},
"2": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501337", "hardwareRev": "21"},
}
}
],
"inputs": {"manufacturers": ["Arista"]},
"expected": {"result": "failure", "messages": ["Some transceivers are from unapproved manufacturers: {'1': 'Arista Networks', '2': 'Arista Networks'}"]},
},
{
"name": "success",
"test": VerifyTemperature,
"eos_data": [
{
"powercycleOnOverheat": "False",
"ambientThreshold": 45,
"cardSlots": [],
"shutdownOnOverheat": "True",
"systemStatus": "temperatureOk",
"recoveryModeOnOverheat": "recoveryModeNA",
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyTemperature,
"eos_data": [
{
"powercycleOnOverheat": "False",
"ambientThreshold": 45,
"cardSlots": [],
"shutdownOnOverheat": "True",
"systemStatus": "temperatureKO",
"recoveryModeOnOverheat": "recoveryModeNA",
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device temperature exceeds acceptable limits. Current system status: 'temperatureKO'"]},
},
{
"name": "success",
"test": VerifyTransceiversTemperature,
"eos_data": [
{
"tempSensors": [
{
"maxTemperature": 25.03125,
"maxTemperatureLastChange": 1682509618.2227979,
"hwStatus": "ok",
"alertCount": 0,
"description": "Xcvr54 temp sensor",
"overheatThreshold": 70.0,
"criticalThreshold": 70.0,
"inAlertState": False,
"targetTemperature": 62.0,
"relPos": "54",
"currentTemperature": 24.171875,
"setPointTemperature": 61.8,
"pidDriverCount": 0,
"isPidDriver": False,
"name": "DomTemperatureSensor54",
}
],
"cardSlots": [],
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure-hwStatus",
"test": VerifyTransceiversTemperature,
"eos_data": [
{
"tempSensors": [
{
"maxTemperature": 25.03125,
"maxTemperatureLastChange": 1682509618.2227979,
"hwStatus": "ko",
"alertCount": 0,
"description": "Xcvr54 temp sensor",
"overheatThreshold": 70.0,
"criticalThreshold": 70.0,
"inAlertState": False,
"targetTemperature": 62.0,
"relPos": "54",
"currentTemperature": 24.171875,
"setPointTemperature": 61.8,
"pidDriverCount": 0,
"isPidDriver": False,
"name": "DomTemperatureSensor54",
}
],
"cardSlots": [],
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"The following sensors are operating outside the acceptable temperature range or have raised alerts: "
"{'DomTemperatureSensor54': "
"{'hwStatus': 'ko', 'alertCount': 0}}"
],
},
},
{
"name": "failure-alertCount",
"test": VerifyTransceiversTemperature,
"eos_data": [
{
"tempSensors": [
{
"maxTemperature": 25.03125,
"maxTemperatureLastChange": 1682509618.2227979,
"hwStatus": "ok",
"alertCount": 1,
"description": "Xcvr54 temp sensor",
"overheatThreshold": 70.0,
"criticalThreshold": 70.0,
"inAlertState": False,
"targetTemperature": 62.0,
"relPos": "54",
"currentTemperature": 24.171875,
"setPointTemperature": 61.8,
"pidDriverCount": 0,
"isPidDriver": False,
"name": "DomTemperatureSensor54",
}
],
"cardSlots": [],
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"The following sensors are operating outside the acceptable temperature range or have raised alerts: "
"{'DomTemperatureSensor54': "
"{'hwStatus': 'ok', 'alertCount': 1}}"
],
},
},
{
"name": "success",
"test": VerifyEnvironmentSystemCooling,
"eos_data": [
{
"defaultZones": False,
"numCoolingZones": [],
"coolingMode": "automatic",
"ambientTemperature": 24.5,
"shutdownOnInsufficientFans": True,
"airflowDirection": "frontToBackAirflow",
"overrideFanSpeed": 0,
"powerSupplySlots": [],
"fanTraySlots": [],
"minFanSpeed": 0,
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingOk",
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyEnvironmentSystemCooling,
"eos_data": [
{
"defaultZones": False,
"numCoolingZones": [],
"coolingMode": "automatic",
"ambientTemperature": 24.5,
"shutdownOnInsufficientFans": True,
"airflowDirection": "frontToBackAirflow",
"overrideFanSpeed": 0,
"powerSupplySlots": [],
"fanTraySlots": [],
"minFanSpeed": 0,
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingKo",
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device system cooling is not OK: 'coolingKo'"]},
},
{
"name": "success",
"test": VerifyEnvironmentCooling,
"eos_data": [
{
"defaultZones": False,
"numCoolingZones": [],
"coolingMode": "automatic",
"ambientTemperature": 24.5,
"shutdownOnInsufficientFans": True,
"airflowDirection": "frontToBackAirflow",
"overrideFanSpeed": 0,
"powerSupplySlots": [
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498937.0240965,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499033.0403435,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
}
],
"speed": 30,
"label": "PowerSupply1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498935.9121106,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499092.4665174,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
}
],
"speed": 30,
"label": "PowerSupply2",
},
],
"fanTraySlots": [
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303148,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0139885,
"configuredSpeed": 30,
"actualSpeed": 29,
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
}
],
"speed": 30,
"label": "1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9304729,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498939.9329433,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
}
],
"speed": 30,
"label": "2",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9383528,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140095,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
}
],
"speed": 30,
"label": "3",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303904,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140295,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
}
],
"speed": 30,
"label": "4",
},
],
"minFanSpeed": 0,
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingOk",
}
],
"inputs": {"states": ["ok"]},
"expected": {"result": "success"},
},
{
"name": "success-additional-states",
"test": VerifyEnvironmentCooling,
"eos_data": [
{
"defaultZones": False,
"numCoolingZones": [],
"coolingMode": "automatic",
"ambientTemperature": 24.5,
"shutdownOnInsufficientFans": True,
"airflowDirection": "frontToBackAirflow",
"overrideFanSpeed": 0,
"powerSupplySlots": [
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498937.0240965,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499033.0403435,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
}
],
"speed": 30,
"label": "PowerSupply1",
},
{
"status": "ok",
"fans": [
{
"status": "Not Inserted",
"uptime": 1682498935.9121106,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499092.4665174,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
}
],
"speed": 30,
"label": "PowerSupply2",
},
],
"fanTraySlots": [
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303148,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0139885,
"configuredSpeed": 30,
"actualSpeed": 29,
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
}
],
"speed": 30,
"label": "1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9304729,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498939.9329433,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
}
],
"speed": 30,
"label": "2",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9383528,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140095,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
}
],
"speed": 30,
"label": "3",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303904,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140295,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
}
],
"speed": 30,
"label": "4",
},
],
"minFanSpeed": 0,
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingOk",
}
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "success"},
},
{
"name": "failure-fan-tray",
"test": VerifyEnvironmentCooling,
"eos_data": [
{
"defaultZones": False,
"numCoolingZones": [],
"coolingMode": "automatic",
"ambientTemperature": 24.5,
"shutdownOnInsufficientFans": True,
"airflowDirection": "frontToBackAirflow",
"overrideFanSpeed": 0,
"powerSupplySlots": [
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498937.0240965,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499033.0403435,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
}
],
"speed": 30,
"label": "PowerSupply1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498935.9121106,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499092.4665174,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
}
],
"speed": 30,
"label": "PowerSupply2",
},
],
"fanTraySlots": [
{
"status": "ok",
"fans": [
{
"status": "down",
"uptime": 1682498923.9303148,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0139885,
"configuredSpeed": 30,
"actualSpeed": 29,
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
}
],
"speed": 30,
"label": "1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9304729,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498939.9329433,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
}
],
"speed": 30,
"label": "2",
},
{
"status": "ok",
"fans": [
{
"status": "Not Inserted",
"uptime": 1682498923.9383528,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140095,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
}
],
"speed": 30,
"label": "3",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303904,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140295,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
}
],
"speed": 30,
"label": "4",
},
],
"minFanSpeed": 0,
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "CoolingKo",
}
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "failure", "messages": ["Fan 1/1 on Fan Tray 1 is: 'down'"]},
},
{
"name": "failure-power-supply",
"test": VerifyEnvironmentCooling,
"eos_data": [
{
"defaultZones": False,
"numCoolingZones": [],
"coolingMode": "automatic",
"ambientTemperature": 24.5,
"shutdownOnInsufficientFans": True,
"airflowDirection": "frontToBackAirflow",
"overrideFanSpeed": 0,
"powerSupplySlots": [
{
"status": "ok",
"fans": [
{
"status": "down",
"uptime": 1682498937.0240965,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499033.0403435,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
}
],
"speed": 30,
"label": "PowerSupply1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498935.9121106,
"maxSpeed": 23000,
"lastSpeedStableChangeTime": 1682499092.4665174,
"configuredSpeed": 30,
"actualSpeed": 33,
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
}
],
"speed": 30,
"label": "PowerSupply2",
},
],
"fanTraySlots": [
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303148,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0139885,
"configuredSpeed": 30,
"actualSpeed": 29,
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
}
],
"speed": 30,
"label": "1",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9304729,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498939.9329433,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
}
],
"speed": 30,
"label": "2",
},
{
"status": "ok",
"fans": [
{
"status": "Not Inserted",
"uptime": 1682498923.9383528,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140095,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
}
],
"speed": 30,
"label": "3",
},
{
"status": "ok",
"fans": [
{
"status": "ok",
"uptime": 1682498923.9303904,
"maxSpeed": 17500,
"lastSpeedStableChangeTime": 1682498975.0140295,
"configuredSpeed": 30,
"actualSpeed": 30,
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
}
],
"speed": 30,
"label": "4",
},
],
"minFanSpeed": 0,
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "CoolingKo",
}
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "failure", "messages": ["Fan PowerSupply1/1 on PowerSupply PowerSupply1 is: 'down'"]},
},
{
"name": "success",
"test": VerifyEnvironmentPower,
"eos_data": [
{
"powerSupplies": {
"1": {
"outputPower": 0.0,
"modelName": "PWR-500AC-F",
"capacity": 500.0,
"tempSensors": {
"TempSensorP1/2": {"status": "ok", "temperature": 0.0},
"TempSensorP1/3": {"status": "ok", "temperature": 0.0},
"TempSensorP1/1": {"status": "ok", "temperature": 0.0},
},
"fans": {"FanP1/1": {"status": "ok", "speed": 33}},
"state": "ok",
"inputCurrent": 0.0,
"dominant": False,
"inputVoltage": 0.0,
"outputCurrent": 0.0,
"managed": True,
},
"2": {
"outputPower": 117.375,
"uptime": 1682498935.9121966,
"modelName": "PWR-500AC-F",
"capacity": 500.0,
"tempSensors": {
"TempSensorP2/1": {"status": "ok", "temperature": 39.0},
"TempSensorP2/3": {"status": "ok", "temperature": 43.0},
"TempSensorP2/2": {"status": "ok", "temperature": 31.0},
},
"fans": {"FanP2/1": {"status": "ok", "speed": 33}},
"state": "ok",
"inputCurrent": 0.572265625,
"dominant": False,
"inputVoltage": 232.5,
"outputCurrent": 9.828125,
"managed": True,
},
}
}
],
"inputs": {"states": ["ok"]},
"expected": {"result": "success"},
},
{
"name": "success-additional-states",
"test": VerifyEnvironmentPower,
"eos_data": [
{
"powerSupplies": {
"1": {
"outputPower": 0.0,
"modelName": "PWR-500AC-F",
"capacity": 500.0,
"tempSensors": {
"TempSensorP1/2": {"status": "ok", "temperature": 0.0},
"TempSensorP1/3": {"status": "ok", "temperature": 0.0},
"TempSensorP1/1": {"status": "ok", "temperature": 0.0},
},
"fans": {"FanP1/1": {"status": "ok", "speed": 33}},
"state": "Not Inserted",
"inputCurrent": 0.0,
"dominant": False,
"inputVoltage": 0.0,
"outputCurrent": 0.0,
"managed": True,
},
"2": {
"outputPower": 117.375,
"uptime": 1682498935.9121966,
"modelName": "PWR-500AC-F",
"capacity": 500.0,
"tempSensors": {
"TempSensorP2/1": {"status": "ok", "temperature": 39.0},
"TempSensorP2/3": {"status": "ok", "temperature": 43.0},
"TempSensorP2/2": {"status": "ok", "temperature": 31.0},
},
"fans": {"FanP2/1": {"status": "ok", "speed": 33}},
"state": "ok",
"inputCurrent": 0.572265625,
"dominant": False,
"inputVoltage": 232.5,
"outputCurrent": 9.828125,
"managed": True,
},
}
}
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyEnvironmentPower,
"eos_data": [
{
"powerSupplies": {
"1": {
"outputPower": 0.0,
"modelName": "PWR-500AC-F",
"capacity": 500.0,
"tempSensors": {
"TempSensorP1/2": {"status": "ok", "temperature": 0.0},
"TempSensorP1/3": {"status": "ok", "temperature": 0.0},
"TempSensorP1/1": {"status": "ok", "temperature": 0.0},
},
"fans": {"FanP1/1": {"status": "ok", "speed": 33}},
"state": "powerLoss",
"inputCurrent": 0.0,
"dominant": False,
"inputVoltage": 0.0,
"outputCurrent": 0.0,
"managed": True,
},
"2": {
"outputPower": 117.375,
"uptime": 1682498935.9121966,
"modelName": "PWR-500AC-F",
"capacity": 500.0,
"tempSensors": {
"TempSensorP2/1": {"status": "ok", "temperature": 39.0},
"TempSensorP2/3": {"status": "ok", "temperature": 43.0},
"TempSensorP2/2": {"status": "ok", "temperature": 31.0},
},
"fans": {"FanP2/1": {"status": "ok", "speed": 33}},
"state": "ok",
"inputCurrent": 0.572265625,
"dominant": False,
"inputVoltage": 232.5,
"outputCurrent": 9.828125,
"managed": True,
},
}
}
],
"inputs": {"states": ["ok"]},
"expected": {"result": "failure", "messages": ["The following power supplies status are not in the accepted states list: {'1': {'state': 'powerLoss'}}"]},
},
{
"name": "success",
"test": VerifyAdverseDrops,
"eos_data": [{"totalAdverseDrops": 0}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyAdverseDrops,
"eos_data": [{"totalAdverseDrops": 10}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device totalAdverseDrops counter is: '10'"]},
},
]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,27 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Data for testing anta.tests.configuration"""
from __future__ import annotations
from typing import Any
from anta.tests.lanz import VerifyLANZ
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyLANZ,
"eos_data": [{"lanzEnabled": True}],
"inputs": None,
"expected": {"result": "success", "messages": ["LANZ is enabled"]},
},
{
"name": "failure",
"test": VerifyLANZ,
"eos_data": [{"lanzEnabled": False}],
"inputs": None,
"expected": {"result": "failure", "messages": ["LANZ is not enabled"]},
},
]

View file

@ -0,0 +1,254 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Data for testing anta.tests.logging"""
from __future__ import annotations
from typing import Any
from anta.tests.logging import (
VerifyLoggingAccounting,
VerifyLoggingErrors,
VerifyLoggingHostname,
VerifyLoggingHosts,
VerifyLoggingLogsGeneration,
VerifyLoggingPersistent,
VerifyLoggingSourceIntf,
VerifyLoggingTimestamp,
)
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyLoggingPersistent,
"eos_data": [
"Persistent logging: level debugging\n",
"""Directory of flash:/persist/messages
-rw- 9948 May 10 13:54 messages
33214693376 bytes total (10081136640 bytes free)
""",
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure-disabled",
"test": VerifyLoggingPersistent,
"eos_data": [
"Persistent logging: disabled\n",
"""Directory of flash:/persist/messages
-rw- 0 Apr 13 16:29 messages
33214693376 bytes total (10082168832 bytes free)
""",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Persistent logging is disabled"]},
},
{
"name": "failure-not-saved",
"test": VerifyLoggingPersistent,
"eos_data": [
"Persistent logging: level debugging\n",
"""Directory of flash:/persist/messages
-rw- 0 Apr 13 16:29 messages
33214693376 bytes total (10082168832 bytes free)
""",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["No persistent logs are saved in flash"]},
},
{
"name": "success",
"test": VerifyLoggingSourceIntf,
"eos_data": [
"""Trap logging: level informational
Logging source-interface 'Management0', IP Address 172.20.20.12 in VRF MGMT
Logging to '10.22.10.92' port 514 in VRF MGMT via udp
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
"""
],
"inputs": {"interface": "Management0", "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-intf",
"test": VerifyLoggingSourceIntf,
"eos_data": [
"""Trap logging: level informational
Logging source-interface 'Management1', IP Address 172.20.20.12 in VRF MGMT
Logging to '10.22.10.92' port 514 in VRF MGMT via udp
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
"""
],
"inputs": {"interface": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface 'Management0' is not configured in VRF MGMT"]},
},
{
"name": "failure-vrf",
"test": VerifyLoggingSourceIntf,
"eos_data": [
"""Trap logging: level informational
Logging source-interface 'Management0', IP Address 172.20.20.12 in VRF default
Logging to '10.22.10.92' port 514 in VRF MGMT via udp
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
"""
],
"inputs": {"interface": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface 'Management0' is not configured in VRF MGMT"]},
},
{
"name": "success",
"test": VerifyLoggingHosts,
"eos_data": [
"""Trap logging: level informational
Logging source-interface 'Management0', IP Address 172.20.20.12 in VRF MGMT
Logging to '10.22.10.92' port 514 in VRF MGMT via udp
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
"""
],
"inputs": {"hosts": ["10.22.10.92", "10.22.10.93", "10.22.10.94"], "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-hosts",
"test": VerifyLoggingHosts,
"eos_data": [
"""Trap logging: level informational
Logging source-interface 'Management1', IP Address 172.20.20.12 in VRF MGMT
Logging to '10.22.10.92' port 514 in VRF MGMT via udp
Logging to '10.22.10.103' port 514 in VRF MGMT via tcp
Logging to '10.22.10.104' port 911 in VRF MGMT via udp
"""
],
"inputs": {"hosts": ["10.22.10.92", "10.22.10.93", "10.22.10.94"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Syslog servers ['10.22.10.93', '10.22.10.94'] are not configured in VRF MGMT"]},
},
{
"name": "failure-vrf",
"test": VerifyLoggingHosts,
"eos_data": [
"""Trap logging: level informational
Logging source-interface 'Management0', IP Address 172.20.20.12 in VRF MGMT
Logging to '10.22.10.92' port 514 in VRF MGMT via udp
Logging to '10.22.10.93' port 514 in VRF default via tcp
Logging to '10.22.10.94' port 911 in VRF default via udp
"""
],
"inputs": {"hosts": ["10.22.10.92", "10.22.10.93", "10.22.10.94"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Syslog servers ['10.22.10.93', '10.22.10.94'] are not configured in VRF MGMT"]},
},
{
"name": "success",
"test": VerifyLoggingLogsGeneration,
"eos_data": [
"",
"2023-05-10T13:54:21.463497-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingLogsGeneration validation\n",
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingLogsGeneration,
"eos_data": ["", "Log Buffer:\n"],
"inputs": None,
"expected": {"result": "failure", "messages": ["Logs are not generated"]},
},
{
"name": "success",
"test": VerifyLoggingHostname,
"eos_data": [
{"hostname": "NW-CORE", "fqdn": "NW-CORE.example.org"},
"",
"2023-05-10T15:41:44.701810-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingHostname validation\n",
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingHostname,
"eos_data": [
{"hostname": "NW-CORE", "fqdn": "NW-CORE.example.org"},
"",
"2023-05-10T13:54:21.463497-05:00 NW-CORE ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingLogsHostname validation\n",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Logs are not generated with the device FQDN"]},
},
{
"name": "success",
"test": VerifyLoggingTimestamp,
"eos_data": [
"",
"2023-05-10T15:41:44.680813-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingTimestamp validation\n",
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingTimestamp,
"eos_data": [
"",
"May 10 13:54:22 NE-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingTimestamp validation\n",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
},
{
"name": "success",
"test": VerifyLoggingAccounting,
"eos_data": ["2023 May 10 15:50:31 arista command-api 10.22.1.107 stop service=shell priv-lvl=15 cmd=show aaa accounting logs | tail\n"],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingAccounting,
"eos_data": ["2023 May 10 15:52:26 arista vty14 10.22.1.107 stop service=shell priv-lvl=15 cmd=show bgp summary\n"],
"inputs": None,
"expected": {"result": "failure", "messages": ["AAA accounting logs are not generated"]},
},
{
"name": "success",
"test": VerifyLoggingErrors,
"eos_data": [""],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingErrors,
"eos_data": [
"Aug 2 19:57:42 DC1-LEAF1A Mlag: %FWK-3-SOCKET_CLOSE_REMOTE: Connection to Mlag (pid:27200) at tbt://192.168.0.1:4432/+n closed by peer (EOF)"
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device has reported syslog messages with a severity of ERRORS or higher"]},
},
]

View file

@ -0,0 +1,343 @@
# Copyright (c) 2023-2024 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.tests.mlag.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.mlag import VerifyMlagConfigSanity, VerifyMlagDualPrimary, VerifyMlagInterfaces, VerifyMlagPrimaryPriority, VerifyMlagReloadDelay, VerifyMlagStatus
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyMlagStatus,
"eos_data": [{"state": "active", "negStatus": "connected", "peerLinkStatus": "up", "localIntfStatus": "up"}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "skipped",
"test": VerifyMlagStatus,
"eos_data": [
{
"state": "disabled",
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
},
{
"name": "failure",
"test": VerifyMlagStatus,
"eos_data": [{"state": "active", "negStatus": "connected", "peerLinkStatus": "down", "localIntfStatus": "up"}],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["MLAG status is not OK: {'state': 'active', 'negStatus': 'connected', 'localIntfStatus': 'up', 'peerLinkStatus': 'down'}"],
},
},
{
"name": "success",
"test": VerifyMlagInterfaces,
"eos_data": [
{
"state": "active",
"mlagPorts": {"Disabled": 0, "Configured": 0, "Inactive": 0, "Active-partial": 0, "Active-full": 1},
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "skipped",
"test": VerifyMlagInterfaces,
"eos_data": [
{
"state": "disabled",
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
},
{
"name": "failure-active-partial",
"test": VerifyMlagInterfaces,
"eos_data": [
{
"state": "active",
"mlagPorts": {"Disabled": 0, "Configured": 0, "Inactive": 0, "Active-partial": 1, "Active-full": 1},
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["MLAG status is not OK: {'Disabled': 0, 'Configured': 0, 'Inactive': 0, 'Active-partial': 1, 'Active-full': 1}"],
},
},
{
"name": "failure-inactive",
"test": VerifyMlagInterfaces,
"eos_data": [
{
"state": "active",
"mlagPorts": {"Disabled": 0, "Configured": 0, "Inactive": 1, "Active-partial": 1, "Active-full": 1},
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["MLAG status is not OK: {'Disabled': 0, 'Configured': 0, 'Inactive': 1, 'Active-partial': 1, 'Active-full': 1}"],
},
},
{
"name": "success",
"test": VerifyMlagConfigSanity,
"eos_data": [{"globalConfiguration": {}, "interfaceConfiguration": {}, "mlagActive": True, "mlagConnected": True}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "skipped",
"test": VerifyMlagConfigSanity,
"eos_data": [
{
"mlagActive": False,
}
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
},
{
"name": "error",
"test": VerifyMlagConfigSanity,
"eos_data": [
{
"dummy": False,
}
],
"inputs": None,
"expected": {"result": "error", "messages": ["Incorrect JSON response - 'mlagActive' state was not found"]},
},
{
"name": "failure-global",
"test": VerifyMlagConfigSanity,
"eos_data": [
{
"globalConfiguration": {"mlag": {"globalParameters": {"dual-primary-detection-delay": {"localValue": "0", "peerValue": "200"}}}},
"interfaceConfiguration": {},
"mlagActive": True,
"mlagConnected": True,
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"MLAG config-sanity returned inconsistencies: "
"{'globalConfiguration': {'mlag': {'globalParameters': "
"{'dual-primary-detection-delay': {'localValue': '0', 'peerValue': '200'}}}}, "
"'interfaceConfiguration': {}}"
],
},
},
{
"name": "failure-interface",
"test": VerifyMlagConfigSanity,
"eos_data": [
{
"globalConfiguration": {},
"interfaceConfiguration": {"trunk-native-vlan mlag30": {"interface": {"Port-Channel30": {"localValue": "123", "peerValue": "3700"}}}},
"mlagActive": True,
"mlagConnected": True,
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"MLAG config-sanity returned inconsistencies: "
"{'globalConfiguration': {}, "
"'interfaceConfiguration': {'trunk-native-vlan mlag30': "
"{'interface': {'Port-Channel30': {'localValue': '123', 'peerValue': '3700'}}}}}"
],
},
},
{
"name": "success",
"test": VerifyMlagReloadDelay,
"eos_data": [{"state": "active", "reloadDelay": 300, "reloadDelayNonMlag": 330}],
"inputs": {"reload_delay": 300, "reload_delay_non_mlag": 330},
"expected": {"result": "success"},
},
{
"name": "skipped-disabled",
"test": VerifyMlagReloadDelay,
"eos_data": [
{
"state": "disabled",
}
],
"inputs": {"reload_delay": 300, "reload_delay_non_mlag": 330},
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
},
{
"name": "failure",
"test": VerifyMlagReloadDelay,
"eos_data": [{"state": "active", "reloadDelay": 400, "reloadDelayNonMlag": 430}],
"inputs": {"reload_delay": 300, "reload_delay_non_mlag": 330},
"expected": {"result": "failure", "messages": ["The reload-delay parameters are not configured properly: {'reloadDelay': 400, 'reloadDelayNonMlag': 430}"]},
},
{
"name": "success",
"test": VerifyMlagDualPrimary,
"eos_data": [
{
"state": "active",
"dualPrimaryDetectionState": "configured",
"dualPrimaryPortsErrdisabled": False,
"dualPrimaryMlagRecoveryDelay": 60,
"dualPrimaryNonMlagRecoveryDelay": 0,
"detail": {"dualPrimaryDetectionDelay": 200, "dualPrimaryAction": "none"},
}
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {"result": "success"},
},
{
"name": "skipped-disabled",
"test": VerifyMlagDualPrimary,
"eos_data": [
{
"state": "disabled",
}
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
},
{
"name": "failure-disabled",
"test": VerifyMlagDualPrimary,
"eos_data": [
{
"state": "active",
"dualPrimaryDetectionState": "disabled",
"dualPrimaryPortsErrdisabled": False,
}
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {"result": "failure", "messages": ["Dual-primary detection is disabled"]},
},
{
"name": "failure-wrong-timers",
"test": VerifyMlagDualPrimary,
"eos_data": [
{
"state": "active",
"dualPrimaryDetectionState": "configured",
"dualPrimaryPortsErrdisabled": False,
"dualPrimaryMlagRecoveryDelay": 160,
"dualPrimaryNonMlagRecoveryDelay": 0,
"detail": {"dualPrimaryDetectionDelay": 300, "dualPrimaryAction": "none"},
}
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {
"result": "failure",
"messages": [
(
"The dual-primary parameters are not configured properly: "
"{'detail.dualPrimaryDetectionDelay': 300, "
"'detail.dualPrimaryAction': 'none', "
"'dualPrimaryMlagRecoveryDelay': 160, "
"'dualPrimaryNonMlagRecoveryDelay': 0}"
)
],
},
},
{
"name": "failure-wrong-action",
"test": VerifyMlagDualPrimary,
"eos_data": [
{
"state": "active",
"dualPrimaryDetectionState": "configured",
"dualPrimaryPortsErrdisabled": False,
"dualPrimaryMlagRecoveryDelay": 60,
"dualPrimaryNonMlagRecoveryDelay": 0,
"detail": {"dualPrimaryDetectionDelay": 200, "dualPrimaryAction": "none"},
}
],
"inputs": {"detection_delay": 200, "errdisabled": True, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {
"result": "failure",
"messages": [
(
"The dual-primary parameters are not configured properly: "
"{'detail.dualPrimaryDetectionDelay': 200, "
"'detail.dualPrimaryAction': 'none', "
"'dualPrimaryMlagRecoveryDelay': 60, "
"'dualPrimaryNonMlagRecoveryDelay': 0}"
)
],
},
},
{
"name": "success",
"test": VerifyMlagPrimaryPriority,
"eos_data": [
{
"state": "active",
"detail": {"mlagState": "primary", "primaryPriority": 32767},
}
],
"inputs": {
"primary_priority": 32767,
},
"expected": {"result": "success"},
},
{
"name": "skipped-disabled",
"test": VerifyMlagPrimaryPriority,
"eos_data": [
{
"state": "disabled",
}
],
"inputs": {"primary_priority": 32767},
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
},
{
"name": "failure-not-primary",
"test": VerifyMlagPrimaryPriority,
"eos_data": [
{
"state": "active",
"detail": {"mlagState": "secondary", "primaryPriority": 32767},
}
],
"inputs": {"primary_priority": 32767},
"expected": {
"result": "failure",
"messages": ["The device is not set as MLAG primary."],
},
},
{
"name": "failure-incorrect-priority",
"test": VerifyMlagPrimaryPriority,
"eos_data": [
{
"state": "active",
"detail": {"mlagState": "secondary", "primaryPriority": 32767},
}
],
"inputs": {"primary_priority": 1},
"expected": {
"result": "failure",
"messages": ["The device is not set as MLAG primary.", "The primary priority does not match expected. Expected `1`, but found `32767` instead."],
},
},
]

View file

@ -0,0 +1,175 @@
# Copyright (c) 2023-2024 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 inputs for anta.tests.multicast"""
from __future__ import annotations
from typing import Any
from anta.tests.multicast import VerifyIGMPSnoopingGlobal, VerifyIGMPSnoopingVlans
from tests.lib.anta import test # noqa: F401; pylint: disable=unused-import
DATA: list[dict[str, Any]] = [
{
"name": "success-enabled",
"test": VerifyIGMPSnoopingVlans,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "enabled",
"vlans": {
"1": {
"reportFlooding": "disabled",
"proxyActive": False,
"groupsOverrun": False,
"multicastRouterLearningMode": "pim-dvmrp",
"igmpSnoopingState": "enabled",
"pruningActive": False,
"maxGroups": 65534,
"immediateLeave": "default",
"floodingTraffic": True,
},
"42": {
"reportFlooding": "disabled",
"proxyActive": False,
"groupsOverrun": False,
"multicastRouterLearningMode": "pim-dvmrp",
"igmpSnoopingState": "enabled",
"pruningActive": False,
"maxGroups": 65534,
"immediateLeave": "default",
"floodingTraffic": True,
},
},
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
}
],
"inputs": {"vlans": {1: True, 42: True}},
"expected": {"result": "success"},
},
{
"name": "success-disabled",
"test": VerifyIGMPSnoopingVlans,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "enabled",
"vlans": {
"42": {
"reportFlooding": "disabled",
"proxyActive": False,
"groupsOverrun": False,
"multicastRouterLearningMode": "pim-dvmrp",
"igmpSnoopingState": "disabled",
"pruningActive": False,
"maxGroups": 65534,
"immediateLeave": "default",
"floodingTraffic": True,
}
},
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
}
],
"inputs": {"vlans": {42: False}},
"expected": {"result": "success"},
},
{
"name": "failure-missing-vlan",
"test": VerifyIGMPSnoopingVlans,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "enabled",
"vlans": {
"1": {
"reportFlooding": "disabled",
"proxyActive": False,
"groupsOverrun": False,
"multicastRouterLearningMode": "pim-dvmrp",
"igmpSnoopingState": "enabled",
"pruningActive": False,
"maxGroups": 65534,
"immediateLeave": "default",
"floodingTraffic": True,
},
},
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
}
],
"inputs": {"vlans": {1: False, 42: False}},
"expected": {"result": "failure", "messages": ["IGMP state for vlan 1 is enabled", "Supplied vlan 42 is not present on the device."]},
},
{
"name": "failure-wrong-state",
"test": VerifyIGMPSnoopingVlans,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "enabled",
"vlans": {
"1": {
"reportFlooding": "disabled",
"proxyActive": False,
"groupsOverrun": False,
"multicastRouterLearningMode": "pim-dvmrp",
"igmpSnoopingState": "disabled",
"pruningActive": False,
"maxGroups": 65534,
"immediateLeave": "default",
"floodingTraffic": True,
},
},
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
}
],
"inputs": {"vlans": {1: True}},
"expected": {"result": "failure", "messages": ["IGMP state for vlan 1 is disabled"]},
},
{
"name": "success-enabled",
"test": VerifyIGMPSnoopingGlobal,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "enabled",
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
}
],
"inputs": {"enabled": True},
"expected": {"result": "success"},
},
{
"name": "success-disabled",
"test": VerifyIGMPSnoopingGlobal,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "disabled",
}
],
"inputs": {"enabled": False},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-state",
"test": VerifyIGMPSnoopingGlobal,
"eos_data": [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "disabled",
}
],
"inputs": {"enabled": True},
"expected": {"result": "failure", "messages": ["IGMP state is not valid: disabled"]},
},
]

View file

@ -0,0 +1,47 @@
# Copyright (c) 2023-2024 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.tests.profiles.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.profiles import VerifyTcamProfile, VerifyUnifiedForwardingTableMode
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyUnifiedForwardingTableMode,
"eos_data": [{"uftMode": "2", "urpfEnabled": False, "chipModel": "bcm56870", "l2TableSize": 163840, "l3TableSize": 147456, "lpmTableSize": 32768}],
"inputs": {"mode": 2},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyUnifiedForwardingTableMode,
"eos_data": [{"uftMode": "2", "urpfEnabled": False, "chipModel": "bcm56870", "l2TableSize": 163840, "l3TableSize": 147456, "lpmTableSize": 32768}],
"inputs": {"mode": 3},
"expected": {"result": "failure", "messages": ["Device is not running correct UFT mode (expected: 3 / running: 2)"]},
},
{
"name": "success",
"test": VerifyTcamProfile,
"eos_data": [
{"pmfProfiles": {"FixedSystem": {"config": "test", "configType": "System Profile", "status": "test", "mode": "tcam"}}, "lastProgrammingStatus": {}}
],
"inputs": {"profile": "test"},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyTcamProfile,
"eos_data": [
{"pmfProfiles": {"FixedSystem": {"config": "test", "configType": "System Profile", "status": "default", "mode": "tcam"}}, "lastProgrammingStatus": {}}
],
"inputs": {"profile": "test"},
"expected": {"result": "failure", "messages": ["Incorrect profile running on device: default"]},
},
]

View file

@ -0,0 +1,42 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Data for testing anta.tests.configuration"""
from __future__ import annotations
from typing import Any
from anta.tests.ptp import VerifyPtpStatus
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyPtpStatus,
"eos_data": [
{
"ptpMode": "ptpBoundaryClock",
"ptpProfile": "ptpDefaultProfile",
"ptpClockSummary": {
"clockIdentity": "0xcc:1a:a3:ff:ff:c3:bf:eb",
"gmClockIdentity": "0x00:00:00:00:00:00:00:00",
"numberOfSlavePorts": 0,
"numberOfMasterPorts": 0,
"offsetFromMaster": 0,
"meanPathDelay": 0,
"stepsRemoved": 0,
"skew": 1.0,
},
"ptpIntfSummaries": {},
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyPtpStatus,
"eos_data": [{"ptpIntfSummaries": {}}],
"inputs": None,
"expected": {"result": "failure"},
},
]

View file

@ -0,0 +1,900 @@
# Copyright (c) 2023-2024 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.tests.security.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.security import (
VerifyAPIHttpsSSL,
VerifyAPIHttpStatus,
VerifyAPIIPv4Acl,
VerifyAPIIPv6Acl,
VerifyAPISSLCertificate,
VerifyBannerLogin,
VerifyBannerMotd,
VerifyIPv4ACL,
VerifySSHIPv4Acl,
VerifySSHIPv6Acl,
VerifySSHStatus,
VerifyTelnetStatus,
)
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifySSHStatus,
"eos_data": ["SSHD status for Default VRF is disabled\nSSH connection limit is 50\nSSH per host connection limit is 20\nFIPS status: disabled\n\n"],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifySSHStatus,
"eos_data": ["SSHD status for Default VRF is enabled\nSSH connection limit is 50\nSSH per host connection limit is 20\nFIPS status: disabled\n\n"],
"inputs": None,
"expected": {"result": "failure", "messages": ["SSHD status for Default VRF is enabled"]},
},
{
"name": "success",
"test": VerifySSHIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": [{"type": "Ip4Acl", "name": "ACL_IPV4_SSH", "configuredVrfs": ["MGMT"], "activeVrfs": ["MGMT"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifySSHIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": []}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Expected 1 SSH IPv4 ACL(s) in vrf MGMT but got 0"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifySSHIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": [{"type": "Ip4Acl", "name": "ACL_IPV4_SSH", "configuredVrfs": ["default"], "activeVrfs": ["default"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["SSH IPv4 ACL(s) not configured or active in vrf MGMT: ['ACL_IPV4_SSH']"]},
},
{
"name": "success",
"test": VerifySSHIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": [{"type": "Ip6Acl", "name": "ACL_IPV6_SSH", "configuredVrfs": ["MGMT"], "activeVrfs": ["MGMT"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifySSHIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": []}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Expected 1 SSH IPv6 ACL(s) in vrf MGMT but got 0"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifySSHIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": [{"type": "Ip6Acl", "name": "ACL_IPV6_SSH", "configuredVrfs": ["default"], "activeVrfs": ["default"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["SSH IPv6 ACL(s) not configured or active in vrf MGMT: ['ACL_IPV6_SSH']"]},
},
{
"name": "success",
"test": VerifyTelnetStatus,
"eos_data": [{"serverState": "disabled", "vrfName": "default", "maxTelnetSessions": 20, "maxTelnetSessionsPerHost": 20}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyTelnetStatus,
"eos_data": [{"serverState": "enabled", "vrfName": "default", "maxTelnetSessions": 20, "maxTelnetSessionsPerHost": 20}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Telnet status for Default VRF is enabled"]},
},
{
"name": "success",
"test": VerifyAPIHttpStatus,
"eos_data": [
{
"enabled": True,
"httpServer": {"configured": False, "running": False, "port": 80},
"localHttpServer": {"configured": False, "running": False, "port": 8080},
"httpsServer": {"configured": True, "running": True, "port": 443},
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "API_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyAPIHttpStatus,
"eos_data": [
{
"enabled": True,
"httpServer": {"configured": True, "running": True, "port": 80},
"localHttpServer": {"configured": False, "running": False, "port": 8080},
"httpsServer": {"configured": True, "running": True, "port": 443},
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "API_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["eAPI HTTP server is enabled globally"]},
},
{
"name": "success",
"test": VerifyAPIHttpsSSL,
"eos_data": [
{
"enabled": True,
"httpServer": {"configured": False, "running": False, "port": 80},
"localHttpServer": {"configured": False, "running": False, "port": 8080},
"httpsServer": {"configured": True, "running": True, "port": 443},
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "API_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
}
],
"inputs": {"profile": "API_SSL_Profile"},
"expected": {"result": "success"},
},
{
"name": "failure-not-configured",
"test": VerifyAPIHttpsSSL,
"eos_data": [
{
"enabled": True,
"httpServer": {"configured": True, "running": True, "port": 80},
"localHttpServer": {"configured": False, "running": False, "port": 8080},
"httpsServer": {"configured": True, "running": True, "port": 443},
"unixSocketServer": {"configured": False, "running": False},
"tlsProtocol": ["1.2"],
}
],
"inputs": {"profile": "API_SSL_Profile"},
"expected": {"result": "failure", "messages": ["eAPI HTTPS server SSL profile (API_SSL_Profile) is not configured"]},
},
{
"name": "failure-misconfigured-invalid",
"test": VerifyAPIHttpsSSL,
"eos_data": [
{
"enabled": True,
"httpServer": {"configured": True, "running": True, "port": 80},
"localHttpServer": {"configured": False, "running": False, "port": 8080},
"httpsServer": {"configured": True, "running": True, "port": 443},
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "Wrong_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
}
],
"inputs": {"profile": "API_SSL_Profile"},
"expected": {"result": "failure", "messages": ["eAPI HTTPS server SSL profile (API_SSL_Profile) is misconfigured or invalid"]},
},
{
"name": "success",
"test": VerifyAPIIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": [{"type": "Ip4Acl", "name": "ACL_IPV4_API", "configuredVrfs": ["MGMT"], "activeVrfs": ["MGMT"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifyAPIIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": []}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Expected 1 eAPI IPv4 ACL(s) in vrf MGMT but got 0"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifyAPIIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": [{"type": "Ip4Acl", "name": "ACL_IPV4_API", "configuredVrfs": ["default"], "activeVrfs": ["default"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["eAPI IPv4 ACL(s) not configured or active in vrf MGMT: ['ACL_IPV4_API']"]},
},
{
"name": "success",
"test": VerifyAPIIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": [{"type": "Ip6Acl", "name": "ACL_IPV6_API", "configuredVrfs": ["MGMT"], "activeVrfs": ["MGMT"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifyAPIIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": []}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Expected 1 eAPI IPv6 ACL(s) in vrf MGMT but got 0"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifyAPIIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": [{"type": "Ip6Acl", "name": "ACL_IPV6_API", "configuredVrfs": ["default"], "activeVrfs": ["default"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["eAPI IPv6 ACL(s) not configured or active in vrf MGMT: ['ACL_IPV6_API']"]},
},
{
"name": "success",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_ROOT_CA.crt": {
"subject": {"commonName": "Arista Networks Internal IT Root Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "RSA",
"size": 4096,
},
},
"ARISTA_SIGNING_CA.crt": {
"subject": {"commonName": "AristaIT-ICA ECDSA Issuing Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "ECDSA",
"size": 256,
},
},
}
},
{
"utcTime": 1702288467.6736515,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-certificate-not-configured",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_SIGNING_CA.crt": {
"subject": {"commonName": "AristaIT-ICA ECDSA Issuing Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "ECDSA",
"size": 256,
},
},
}
},
{
"utcTime": 1702288467.6736515,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {
"result": "failure",
"messages": ["SSL certificate 'ARISTA_ROOT_CA.crt', is not configured.\n"],
},
},
{
"name": "failure-certificate-expired",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_ROOT_CA.crt": {
"subject": {"commonName": "Arista Networks Internal IT Root Cert Authority"},
"notAfter": 1702533518,
"publicKey": {
"encryptionAlgorithm": "RSA",
"size": 4096,
},
},
}
},
{
"utcTime": 1702622372.2240553,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {
"result": "failure",
"messages": ["SSL certificate 'ARISTA_SIGNING_CA.crt', is not configured.\n", "SSL certificate `ARISTA_ROOT_CA.crt` is expired.\n"],
},
},
{
"name": "failure-certificate-about-to-expire",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_ROOT_CA.crt": {
"subject": {"commonName": "Arista Networks Internal IT Root Cert Authority"},
"notAfter": 1704782709,
"publicKey": {
"encryptionAlgorithm": "RSA",
"size": 4096,
},
},
"ARISTA_SIGNING_CA.crt": {
"subject": {"commonName": "AristaIT-ICA ECDSA Issuing Cert Authority"},
"notAfter": 1702533518,
"publicKey": {
"encryptionAlgorithm": "ECDSA",
"size": 256,
},
},
}
},
{
"utcTime": 1702622372.2240553,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {
"result": "failure",
"messages": ["SSL certificate `ARISTA_SIGNING_CA.crt` is expired.\n", "SSL certificate `ARISTA_ROOT_CA.crt` is about to expire in 25 days."],
},
},
{
"name": "failure-wrong-subject-name",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_ROOT_CA.crt": {
"subject": {"commonName": "AristaIT-ICA Networks Internal IT Root Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "RSA",
"size": 4096,
},
},
"ARISTA_SIGNING_CA.crt": {
"subject": {"commonName": "Arista ECDSA Issuing Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "ECDSA",
"size": 256,
},
},
}
},
{
"utcTime": 1702288467.6736515,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {
"result": "failure",
"messages": [
"SSL certificate `ARISTA_SIGNING_CA.crt` is not configured properly:\n"
"Expected `AristaIT-ICA ECDSA Issuing Cert Authority` as the subject.commonName, but found "
"`Arista ECDSA Issuing Cert Authority` instead.\n",
"SSL certificate `ARISTA_ROOT_CA.crt` is not configured properly:\n"
"Expected `Arista Networks Internal IT Root Cert Authority` as the subject.commonName, "
"but found `AristaIT-ICA Networks Internal IT Root Cert Authority` instead.\n",
],
},
},
{
"name": "failure-wrong-encryption-type-and-size",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_ROOT_CA.crt": {
"subject": {"commonName": "Arista Networks Internal IT Root Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "ECDSA",
"size": 256,
},
},
"ARISTA_SIGNING_CA.crt": {
"subject": {"commonName": "AristaIT-ICA ECDSA Issuing Cert Authority"},
"notAfter": 2127420899,
"publicKey": {
"encryptionAlgorithm": "RSA",
"size": 4096,
},
},
}
},
{
"utcTime": 1702288467.6736515,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {
"result": "failure",
"messages": [
"SSL certificate `ARISTA_SIGNING_CA.crt` is not configured properly:\n"
"Expected `ECDSA` as the publicKey.encryptionAlgorithm, but found `RSA` instead.\n"
"Expected `256` as the publicKey.size, but found `4096` instead.\n",
"SSL certificate `ARISTA_ROOT_CA.crt` is not configured properly:\n"
"Expected `RSA` as the publicKey.encryptionAlgorithm, but found `ECDSA` instead.\n"
"Expected `4096` as the publicKey.size, but found `256` instead.\n",
],
},
},
{
"name": "failure-missing-actual-output",
"test": VerifyAPISSLCertificate,
"eos_data": [
{
"certificates": {
"ARISTA_ROOT_CA.crt": {
"subject": {"commonName": "Arista Networks Internal IT Root Cert Authority"},
"notAfter": 2127420899,
},
"ARISTA_SIGNING_CA.crt": {
"subject": {"commonName": "AristaIT-ICA ECDSA Issuing Cert Authority"},
"notAfter": 2127420899,
},
}
},
{
"utcTime": 1702288467.6736515,
},
],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 256,
},
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 4096,
},
]
},
"expected": {
"result": "failure",
"messages": [
"SSL certificate `ARISTA_SIGNING_CA.crt` is not configured properly:\n"
"Expected `ECDSA` as the publicKey.encryptionAlgorithm, but it was not found in the actual output.\n"
"Expected `256` as the publicKey.size, but it was not found in the actual output.\n",
"SSL certificate `ARISTA_ROOT_CA.crt` is not configured properly:\n"
"Expected `RSA` as the publicKey.encryptionAlgorithm, but it was not found in the actual output.\n"
"Expected `4096` as the publicKey.size, but it was not found in the actual output.\n",
],
},
},
{
"name": "success",
"test": VerifyBannerLogin,
"eos_data": [
{
"loginBanner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"login_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {"result": "success"},
},
{
"name": "success-multiline",
"test": VerifyBannerLogin,
"eos_data": [
{
"loginBanner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"login_banner": """Copyright (c) 2023-2024 Arista Networks, Inc.
Use of this source code is governed by the Apache License 2.0
that can be found in the LICENSE file."""
},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-login-banner",
"test": VerifyBannerLogin,
"eos_data": [
{
"loginBanner": "Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"login_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {
"result": "failure",
"messages": [
"Expected `Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file.` as the login banner, but found `Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is "
"governed by the Apache License 2.0\nthat can be found in the LICENSE file.` instead."
],
},
},
{
"name": "success",
"test": VerifyBannerMotd,
"eos_data": [
{
"motd": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"motd_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {"result": "success"},
},
{
"name": "success-multiline",
"test": VerifyBannerMotd,
"eos_data": [
{
"motd": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"motd_banner": """Copyright (c) 2023-2024 Arista Networks, Inc.
Use of this source code is governed by the Apache License 2.0
that can be found in the LICENSE file."""
},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-motd-banner",
"test": VerifyBannerMotd,
"eos_data": [
{
"motd": "Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"motd_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {
"result": "failure",
"messages": [
"Expected `Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file.` as the motd banner, but found `Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is "
"governed by the Apache License 2.0\nthat can be found in the LICENSE file.` instead."
],
},
},
{
"name": "success",
"test": VerifyIPv4ACL,
"eos_data": [
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit ip any any tracked", "sequenceNumber": 20},
{"text": "permit udp any any eq bfd ttl eq 255", "sequenceNumber": 30},
],
}
]
},
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit tcp any any range 5900 5910", "sequenceNumber": 20},
],
}
]
},
],
"inputs": {
"ipv4_access_lists": [
{
"name": "default-control-plane-acl",
"entries": [
{"sequence": 10, "action": "permit icmp any any"},
{"sequence": 20, "action": "permit ip any any tracked"},
{"sequence": 30, "action": "permit udp any any eq bfd ttl eq 255"},
],
},
{
"name": "LabTest",
"entries": [{"sequence": 10, "action": "permit icmp any any"}, {"sequence": 20, "action": "permit tcp any any range 5900 5910"}],
},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-acl-not-found",
"test": VerifyIPv4ACL,
"eos_data": [
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit ip any any tracked", "sequenceNumber": 20},
{"text": "permit udp any any eq bfd ttl eq 255", "sequenceNumber": 30},
],
}
]
},
{"aclList": []},
],
"inputs": {
"ipv4_access_lists": [
{
"name": "default-control-plane-acl",
"entries": [
{"sequence": 10, "action": "permit icmp any any"},
{"sequence": 20, "action": "permit ip any any tracked"},
{"sequence": 30, "action": "permit udp any any eq bfd ttl eq 255"},
],
},
{
"name": "LabTest",
"entries": [{"sequence": 10, "action": "permit icmp any any"}, {"sequence": 20, "action": "permit tcp any any range 5900 5910"}],
},
]
},
"expected": {"result": "failure", "messages": ["LabTest: Not found"]},
},
{
"name": "failure-sequence-not-found",
"test": VerifyIPv4ACL,
"eos_data": [
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit ip any any tracked", "sequenceNumber": 20},
{"text": "permit udp any any eq bfd ttl eq 255", "sequenceNumber": 40},
],
}
]
},
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit tcp any any range 5900 5910", "sequenceNumber": 30},
],
}
]
},
],
"inputs": {
"ipv4_access_lists": [
{
"name": "default-control-plane-acl",
"entries": [
{"sequence": 10, "action": "permit icmp any any"},
{"sequence": 20, "action": "permit ip any any tracked"},
{"sequence": 30, "action": "permit udp any any eq bfd ttl eq 255"},
],
},
{
"name": "LabTest",
"entries": [{"sequence": 10, "action": "permit icmp any any"}, {"sequence": 20, "action": "permit tcp any any range 5900 5910"}],
},
]
},
"expected": {
"result": "failure",
"messages": ["default-control-plane-acl:\nSequence number `30` is not found.\n", "LabTest:\nSequence number `20` is not found.\n"],
},
},
{
"name": "failure-action-not-match",
"test": VerifyIPv4ACL,
"eos_data": [
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit ip any any tracked", "sequenceNumber": 20},
{"text": "permit tcp any any range 5900 5910", "sequenceNumber": 30},
],
}
]
},
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit udp any any eq bfd ttl eq 255", "sequenceNumber": 20},
],
}
]
},
],
"inputs": {
"ipv4_access_lists": [
{
"name": "default-control-plane-acl",
"entries": [
{"sequence": 10, "action": "permit icmp any any"},
{"sequence": 20, "action": "permit ip any any tracked"},
{"sequence": 30, "action": "permit udp any any eq bfd ttl eq 255"},
],
},
{
"name": "LabTest",
"entries": [{"sequence": 10, "action": "permit icmp any any"}, {"sequence": 20, "action": "permit tcp any any range 5900 5910"}],
},
]
},
"expected": {
"result": "failure",
"messages": [
"default-control-plane-acl:\n"
"Expected `permit udp any any eq bfd ttl eq 255` as sequence number 30 action but found `permit tcp any any range 5900 5910` instead.\n",
"LabTest:\nExpected `permit tcp any any range 5900 5910` as sequence number 20 action but found `permit udp any any eq bfd ttl eq 255` instead.\n",
],
},
},
{
"name": "failure-all-type",
"test": VerifyIPv4ACL,
"eos_data": [
{
"aclList": [
{
"sequence": [
{"text": "permit icmp any any", "sequenceNumber": 10},
{"text": "permit ip any any tracked", "sequenceNumber": 40},
{"text": "permit tcp any any range 5900 5910", "sequenceNumber": 30},
],
}
]
},
{"aclList": []},
],
"inputs": {
"ipv4_access_lists": [
{
"name": "default-control-plane-acl",
"entries": [
{"sequence": 10, "action": "permit icmp any any"},
{"sequence": 20, "action": "permit ip any any tracked"},
{"sequence": 30, "action": "permit udp any any eq bfd ttl eq 255"},
],
},
{
"name": "LabTest",
"entries": [{"sequence": 10, "action": "permit icmp any any"}, {"sequence": 20, "action": "permit tcp any any range 5900 5910"}],
},
]
},
"expected": {
"result": "failure",
"messages": [
"default-control-plane-acl:\nSequence number `20` is not found.\n"
"Expected `permit udp any any eq bfd ttl eq 255` as sequence number 30 action but found `permit tcp any any range 5900 5910` instead.\n",
"LabTest: Not found",
],
},
},
]

View file

@ -0,0 +1,218 @@
# Copyright (c) 2023-2024 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.tests.services.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.services import VerifyDNSLookup, VerifyDNSServers, VerifyErrdisableRecovery, VerifyHostname
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyHostname,
"eos_data": [{"hostname": "s1-spine1", "fqdn": "s1-spine1.fun.aristanetworks.com"}],
"inputs": {"hostname": "s1-spine1"},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-hostname",
"test": VerifyHostname,
"eos_data": [{"hostname": "s1-spine2", "fqdn": "s1-spine1.fun.aristanetworks.com"}],
"inputs": {"hostname": "s1-spine1"},
"expected": {
"result": "failure",
"messages": ["Expected `s1-spine1` as the hostname, but found `s1-spine2` instead."],
},
},
{
"name": "success",
"test": VerifyDNSLookup,
"eos_data": [
{
"messages": [
"Server:\t\t127.0.0.1\nAddress:\t127.0.0.1#53\n\nNon-authoritative answer:\nName:\tarista.com\nAddress: 151.101.130.132\nName:\tarista.com\n"
"Address: 151.101.2.132\nName:\tarista.com\nAddress: 151.101.194.132\nName:\tarista.com\nAddress: 151.101.66.132\n\n"
]
},
{"messages": ["Server:\t\t127.0.0.1\nAddress:\t127.0.0.1#53\n\nNon-authoritative answer:\nName:\twww.google.com\nAddress: 172.217.12.100\n\n"]},
],
"inputs": {"domain_names": ["arista.com", "www.google.com"]},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyDNSLookup,
"eos_data": [
{"messages": ["Server:\t\t127.0.0.1\nAddress:\t127.0.0.1#53\n\nNon-authoritative answer:\n*** Can't find arista.ca: No answer\n\n"]},
{"messages": ["Server:\t\t127.0.0.1\nAddress:\t127.0.0.1#53\n\nNon-authoritative answer:\nName:\twww.google.com\nAddress: 172.217.12.100\n\n"]},
{"messages": ["Server:\t\t127.0.0.1\nAddress:\t127.0.0.1#53\n\nNon-authoritative answer:\n*** Can't find google.ca: No answer\n\n"]},
],
"inputs": {"domain_names": ["arista.ca", "www.google.com", "google.ca"]},
"expected": {"result": "failure", "messages": ["The following domain(s) are not resolved to an IP address: arista.ca, google.ca"]},
},
{
"name": "success",
"test": VerifyDNSServers,
"eos_data": [
{
"nameServerConfigs": [{"ipAddr": "10.14.0.1", "vrf": "default", "priority": 0}, {"ipAddr": "10.14.0.11", "vrf": "MGMT", "priority": 1}],
}
],
"inputs": {
"dns_servers": [{"server_address": "10.14.0.1", "vrf": "default", "priority": 0}, {"server_address": "10.14.0.11", "vrf": "MGMT", "priority": 1}]
},
"expected": {"result": "success"},
},
{
"name": "failure-dns-missing",
"test": VerifyDNSServers,
"eos_data": [
{
"nameServerConfigs": [{"ipAddr": "10.14.0.1", "vrf": "default", "priority": 0}, {"ipAddr": "10.14.0.11", "vrf": "MGMT", "priority": 1}],
}
],
"inputs": {
"dns_servers": [{"server_address": "10.14.0.10", "vrf": "default", "priority": 0}, {"server_address": "10.14.0.21", "vrf": "MGMT", "priority": 1}]
},
"expected": {
"result": "failure",
"messages": ["DNS server `10.14.0.10` is not configured with any VRF.", "DNS server `10.14.0.21` is not configured with any VRF."],
},
},
{
"name": "failure-no-dns-found",
"test": VerifyDNSServers,
"eos_data": [
{
"nameServerConfigs": [],
}
],
"inputs": {
"dns_servers": [{"server_address": "10.14.0.10", "vrf": "default", "priority": 0}, {"server_address": "10.14.0.21", "vrf": "MGMT", "priority": 1}]
},
"expected": {
"result": "failure",
"messages": ["DNS server `10.14.0.10` is not configured with any VRF.", "DNS server `10.14.0.21` is not configured with any VRF."],
},
},
{
"name": "failure-incorrect-dns-details",
"test": VerifyDNSServers,
"eos_data": [
{
"nameServerConfigs": [{"ipAddr": "10.14.0.1", "vrf": "CS", "priority": 1}, {"ipAddr": "10.14.0.11", "vrf": "MGMT", "priority": 1}],
}
],
"inputs": {
"dns_servers": [
{"server_address": "10.14.0.1", "vrf": "CS", "priority": 0},
{"server_address": "10.14.0.11", "vrf": "default", "priority": 0},
{"server_address": "10.14.0.110", "vrf": "MGMT", "priority": 0},
]
},
"expected": {
"result": "failure",
"messages": [
"For DNS server `10.14.0.1`, the expected priority is `0`, but `1` was found instead.",
"DNS server `10.14.0.11` is not configured with VRF `default`.",
"DNS server `10.14.0.110` is not configured with any VRF.",
],
},
},
{
"name": "success",
"test": VerifyErrdisableRecovery,
"eos_data": [
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Enabled 300
bpduguard Enabled 300
arp-inspection Enabled 30
"""
],
"inputs": {"reasons": [{"reason": "acl", "interval": 300}, {"reason": "bpduguard", "interval": 300}]},
"expected": {"result": "success"},
},
{
"name": "failure-reason-missing",
"test": VerifyErrdisableRecovery,
"eos_data": [
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Enabled 300
bpduguard Enabled 300
arp-inspection Enabled 30
"""
],
"inputs": {"reasons": [{"reason": "acl", "interval": 300}, {"reason": "arp-inspection", "interval": 30}, {"reason": "tapagg", "interval": 30}]},
"expected": {
"result": "failure",
"messages": ["`tapagg`: Not found."],
},
},
{
"name": "failure-reason-disabled",
"test": VerifyErrdisableRecovery,
"eos_data": [
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Disabled 300
bpduguard Enabled 300
arp-inspection Enabled 30
"""
],
"inputs": {"reasons": [{"reason": "acl", "interval": 300}, {"reason": "arp-inspection", "interval": 30}]},
"expected": {
"result": "failure",
"messages": ["`acl`:\nExpected `Enabled` as the status, but found `Disabled` instead."],
},
},
{
"name": "failure-interval-not-ok",
"test": VerifyErrdisableRecovery,
"eos_data": [
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Enabled 300
bpduguard Enabled 300
arp-inspection Enabled 30
"""
],
"inputs": {"reasons": [{"reason": "acl", "interval": 30}, {"reason": "arp-inspection", "interval": 30}]},
"expected": {
"result": "failure",
"messages": ["`acl`:\nExpected `30` as the interval, but found `300` instead."],
},
},
{
"name": "failure-all-type",
"test": VerifyErrdisableRecovery,
"eos_data": [
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Disabled 300
bpduguard Enabled 300
arp-inspection Enabled 30
"""
],
"inputs": {"reasons": [{"reason": "acl", "interval": 30}, {"reason": "arp-inspection", "interval": 300}, {"reason": "tapagg", "interval": 30}]},
"expected": {
"result": "failure",
"messages": [
"`acl`:\nExpected `30` as the interval, but found `300` instead.\nExpected `Enabled` as the status, but found `Disabled` instead.",
"`arp-inspection`:\nExpected `300` as the interval, but found `30` instead.",
"`tapagg`: Not found.",
],
},
},
]

View file

@ -0,0 +1,128 @@
# Copyright (c) 2023-2024 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.tests.snmp.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.snmp import VerifySnmpContact, VerifySnmpIPv4Acl, VerifySnmpIPv6Acl, VerifySnmpLocation, VerifySnmpStatus
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifySnmpStatus,
"eos_data": [{"vrfs": {"snmpVrfs": ["MGMT", "default"]}, "enabled": True}],
"inputs": {"vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-vrf",
"test": VerifySnmpStatus,
"eos_data": [{"vrfs": {"snmpVrfs": ["default"]}, "enabled": True}],
"inputs": {"vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["SNMP agent disabled in vrf MGMT"]},
},
{
"name": "failure-disabled",
"test": VerifySnmpStatus,
"eos_data": [{"vrfs": {"snmpVrfs": ["default"]}, "enabled": False}],
"inputs": {"vrf": "default"},
"expected": {"result": "failure", "messages": ["SNMP agent disabled in vrf default"]},
},
{
"name": "success",
"test": VerifySnmpIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": [{"type": "Ip4Acl", "name": "ACL_IPV4_SNMP", "configuredVrfs": ["MGMT"], "activeVrfs": ["MGMT"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifySnmpIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": []}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Expected 1 SNMP IPv4 ACL(s) in vrf MGMT but got 0"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifySnmpIPv4Acl,
"eos_data": [{"ipAclList": {"aclList": [{"type": "Ip4Acl", "name": "ACL_IPV4_SNMP", "configuredVrfs": ["default"], "activeVrfs": ["default"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["SNMP IPv4 ACL(s) not configured or active in vrf MGMT: ['ACL_IPV4_SNMP']"]},
},
{
"name": "success",
"test": VerifySnmpIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": [{"type": "Ip6Acl", "name": "ACL_IPV6_SNMP", "configuredVrfs": ["MGMT"], "activeVrfs": ["MGMT"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "success"},
},
{
"name": "failure-wrong-number",
"test": VerifySnmpIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": []}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Expected 1 SNMP IPv6 ACL(s) in vrf MGMT but got 0"]},
},
{
"name": "failure-wrong-vrf",
"test": VerifySnmpIPv6Acl,
"eos_data": [{"ipv6AclList": {"aclList": [{"type": "Ip6Acl", "name": "ACL_IPV6_SNMP", "configuredVrfs": ["default"], "activeVrfs": ["default"]}]}}],
"inputs": {"number": 1, "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["SNMP IPv6 ACL(s) not configured or active in vrf MGMT: ['ACL_IPV6_SNMP']"]},
},
{
"name": "success",
"test": VerifySnmpLocation,
"eos_data": [
{
"location": {"location": "New York"},
}
],
"inputs": {"location": "New York"},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-location",
"test": VerifySnmpLocation,
"eos_data": [
{
"location": {"location": "Europe"},
}
],
"inputs": {"location": "New York"},
"expected": {
"result": "failure",
"messages": ["Expected `New York` as the location, but found `Europe` instead."],
},
},
{
"name": "success",
"test": VerifySnmpContact,
"eos_data": [
{
"contact": {"contact": "Jon@example.com"},
}
],
"inputs": {"contact": "Jon@example.com"},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-contact",
"test": VerifySnmpContact,
"eos_data": [
{
"contact": {"contact": "Jon@example.com"},
}
],
"inputs": {"contact": "Bob@example.com"},
"expected": {
"result": "failure",
"messages": ["Expected `Bob@example.com` as the contact, but found `Jon@example.com` instead."],
},
},
]

View file

@ -0,0 +1,101 @@
# Copyright (c) 2023-2024 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 inputs for anta.tests.hardware"""
from __future__ import annotations
from typing import Any
from anta.tests.software import VerifyEOSExtensions, VerifyEOSVersion, VerifyTerminAttrVersion
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyEOSVersion,
"eos_data": [
{
"modelName": "vEOS-lab",
"internalVersion": "4.27.0F-24305004.4270F",
"version": "4.27.0F",
}
],
"inputs": {"versions": ["4.27.0F", "4.28.0F"]},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyEOSVersion,
"eos_data": [
{
"modelName": "vEOS-lab",
"internalVersion": "4.27.0F-24305004.4270F",
"version": "4.27.0F",
}
],
"inputs": {"versions": ["4.27.1F"]},
"expected": {"result": "failure", "messages": ["device is running version \"4.27.0F\" not in expected versions: ['4.27.1F']"]},
},
{
"name": "success",
"test": VerifyTerminAttrVersion,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1107543.52,
"modelName": "vEOS-lab",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
"switchType": "fixedSystem",
"packages": {
"TerminAttr-core": {"release": "1", "version": "v1.17.0"},
},
},
}
],
"inputs": {"versions": ["v1.17.0", "v1.18.1"]},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyTerminAttrVersion,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1107543.52,
"modelName": "vEOS-lab",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
"switchType": "fixedSystem",
"packages": {
"TerminAttr-core": {"release": "1", "version": "v1.17.0"},
},
},
}
],
"inputs": {"versions": ["v1.17.1", "v1.18.1"]},
"expected": {"result": "failure", "messages": ["device is running TerminAttr version v1.17.0 and is not in the allowed list: ['v1.17.1', 'v1.18.1']"]},
},
{
"name": "success-no-extensions",
"test": VerifyEOSExtensions,
"eos_data": [
{"extensions": {}, "extensionStoredDir": "flash:", "warnings": ["No extensions are available"]},
{"extensions": []},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyEOSExtensions,
"eos_data": [
{"extensions": {}, "extensionStoredDir": "flash:", "warnings": ["No extensions are available"]},
{"extensions": ["dummy"]},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Missing EOS extensions: installed [] / configured: ['dummy']"]},
},
]

View file

@ -0,0 +1,328 @@
# Copyright (c) 2023-2024 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.tests.stp.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.stp import VerifySTPBlockedPorts, VerifySTPCounters, VerifySTPForwardingPorts, VerifySTPMode, VerifySTPRootPriority
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifySTPMode,
"eos_data": [
{"spanningTreeVlanInstances": {"10": {"spanningTreeVlanInstance": {"protocol": "rstp"}}}},
{"spanningTreeVlanInstances": {"20": {"spanningTreeVlanInstance": {"protocol": "rstp"}}}},
],
"inputs": {"mode": "rstp", "vlans": [10, 20]},
"expected": {"result": "success"},
},
{
"name": "failure-no-instances",
"test": VerifySTPMode,
"eos_data": [
{"spanningTreeVlanInstances": {}},
{"spanningTreeVlanInstances": {}},
],
"inputs": {"mode": "rstp", "vlans": [10, 20]},
"expected": {"result": "failure", "messages": ["STP mode 'rstp' not configured for the following VLAN(s): [10, 20]"]},
},
{
"name": "failure-wrong-mode",
"test": VerifySTPMode,
"eos_data": [
{"spanningTreeVlanInstances": {"10": {"spanningTreeVlanInstance": {"protocol": "mstp"}}}},
{"spanningTreeVlanInstances": {"20": {"spanningTreeVlanInstance": {"protocol": "mstp"}}}},
],
"inputs": {"mode": "rstp", "vlans": [10, 20]},
"expected": {"result": "failure", "messages": ["Wrong STP mode configured for the following VLAN(s): [10, 20]"]},
},
{
"name": "failure-both",
"test": VerifySTPMode,
"eos_data": [
{"spanningTreeVlanInstances": {}},
{"spanningTreeVlanInstances": {"20": {"spanningTreeVlanInstance": {"protocol": "mstp"}}}},
],
"inputs": {"mode": "rstp", "vlans": [10, 20]},
"expected": {
"result": "failure",
"messages": ["STP mode 'rstp' not configured for the following VLAN(s): [10]", "Wrong STP mode configured for the following VLAN(s): [20]"],
},
},
{
"name": "success",
"test": VerifySTPBlockedPorts,
"eos_data": [{"spanningTreeInstances": {}}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifySTPBlockedPorts,
"eos_data": [{"spanningTreeInstances": {"MST0": {"spanningTreeBlockedPorts": ["Ethernet10"]}, "MST10": {"spanningTreeBlockedPorts": ["Ethernet10"]}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following ports are blocked by STP: {'MST0': ['Ethernet10'], 'MST10': ['Ethernet10']}"]},
},
{
"name": "success",
"test": VerifySTPCounters,
"eos_data": [{"interfaces": {"Ethernet10": {"bpduSent": 99, "bpduReceived": 0, "bpduTaggedError": 0, "bpduOtherError": 0, "bpduRateLimitCount": 0}}}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifySTPCounters,
"eos_data": [
{
"interfaces": {
"Ethernet10": {"bpduSent": 201, "bpduReceived": 0, "bpduTaggedError": 3, "bpduOtherError": 0, "bpduRateLimitCount": 0},
"Ethernet11": {"bpduSent": 99, "bpduReceived": 0, "bpduTaggedError": 0, "bpduOtherError": 6, "bpduRateLimitCount": 0},
}
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following interfaces have STP BPDU packet errors: ['Ethernet10', 'Ethernet11']"]},
},
{
"name": "success",
"test": VerifySTPForwardingPorts,
"eos_data": [
{
"unmappedVlans": [],
"topologies": {"Mst10": {"vlans": [10], "interfaces": {"Ethernet10": {"state": "forwarding"}, "MplsTrunk1": {"state": "forwarding"}}}},
},
{
"unmappedVlans": [],
"topologies": {"Mst20": {"vlans": [20], "interfaces": {"Ethernet10": {"state": "forwarding"}, "MplsTrunk1": {"state": "forwarding"}}}},
},
],
"inputs": {"vlans": [10, 20]},
"expected": {"result": "success"},
},
{
"name": "success-vlan-not-in-topology", # Should it succeed really ? TODO - this output should be impossible
"test": VerifySTPForwardingPorts,
"eos_data": [
{
"unmappedVlans": [],
"topologies": {"Mst10": {"vlans": [10], "interfaces": {"Ethernet10": {"state": "forwarding"}, "MplsTrunk1": {"state": "forwarding"}}}},
},
{
"unmappedVlans": [],
"topologies": {"Mst10": {"vlans": [10], "interfaces": {"Ethernet10": {"state": "forwarding"}, "MplsTrunk1": {"state": "forwarding"}}}},
},
],
"inputs": {"vlans": [10, 20]},
"expected": {"result": "success"},
},
{
"name": "failure-no-instances",
"test": VerifySTPForwardingPorts,
"eos_data": [{"unmappedVlans": [], "topologies": {}}, {"unmappedVlans": [], "topologies": {}}],
"inputs": {"vlans": [10, 20]},
"expected": {"result": "failure", "messages": ["STP instance is not configured for the following VLAN(s): [10, 20]"]},
},
{
"name": "failure",
"test": VerifySTPForwardingPorts,
"eos_data": [
{
"unmappedVlans": [],
"topologies": {"Vl10": {"vlans": [10], "interfaces": {"Ethernet10": {"state": "discarding"}, "MplsTrunk1": {"state": "forwarding"}}}},
},
{
"unmappedVlans": [],
"topologies": {"Vl20": {"vlans": [20], "interfaces": {"Ethernet10": {"state": "discarding"}, "MplsTrunk1": {"state": "forwarding"}}}},
},
],
"inputs": {"vlans": [10, 20]},
"expected": {
"result": "failure",
"messages": ["The following VLAN(s) have interface(s) that are not in a fowarding state: [{'VLAN 10': ['Ethernet10']}, {'VLAN 20': ['Ethernet10']}]"],
},
},
{
"name": "success-specific-instances",
"test": VerifySTPRootPriority,
"eos_data": [
{
"instances": {
"VL10": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 10,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
"VL20": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 20,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
"VL30": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 30,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
}
}
],
"inputs": {"priority": 32768, "instances": [10, 20]},
"expected": {"result": "success"},
},
{
"name": "success-all-instances",
"test": VerifySTPRootPriority,
"eos_data": [
{
"instances": {
"VL10": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 10,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
"VL20": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 20,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
"VL30": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 30,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
}
}
],
"inputs": {"priority": 32768},
"expected": {"result": "success"},
},
{
"name": "success-MST",
"test": VerifySTPRootPriority,
"eos_data": [
{
"instances": {
"MST0": {
"rootBridge": {
"priority": 16384,
"systemIdExtension": 0,
"macAddress": "02:1c:73:8b:93:ac",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
}
}
}
],
"inputs": {"priority": 16384, "instances": [0]},
"expected": {"result": "success"},
},
{
"name": "failure-no-instances",
"test": VerifySTPRootPriority,
"eos_data": [
{
"instances": {
"WRONG0": {
"rootBridge": {
"priority": 16384,
"systemIdExtension": 0,
"macAddress": "02:1c:73:8b:93:ac",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
}
}
}
],
"inputs": {"priority": 32768, "instances": [0]},
"expected": {"result": "failure", "messages": ["Unsupported STP instance type: WRONG0"]},
},
{
"name": "failure-wrong-instance-type",
"test": VerifySTPRootPriority,
"eos_data": [{"instances": {}}],
"inputs": {"priority": 32768, "instances": [10, 20]},
"expected": {"result": "failure", "messages": ["No STP instances configured"]},
},
{
"name": "failure-wrong-priority",
"test": VerifySTPRootPriority,
"eos_data": [
{
"instances": {
"VL10": {
"rootBridge": {
"priority": 32768,
"systemIdExtension": 10,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
"VL20": {
"rootBridge": {
"priority": 8196,
"systemIdExtension": 20,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
"VL30": {
"rootBridge": {
"priority": 8196,
"systemIdExtension": 30,
"macAddress": "00:1c:73:27:95:a2",
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
}
},
}
}
],
"inputs": {"priority": 32768, "instances": [10, 20, 30]},
"expected": {"result": "failure", "messages": ["The following instance(s) have the wrong STP root priority configured: ['VL20', 'VL30']"]},
},
]

View file

@ -0,0 +1,283 @@
# Copyright (c) 2023-2024 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 inputs for anta.tests.system"""
from __future__ import annotations
from typing import Any
from anta.tests.system import (
VerifyAgentLogs,
VerifyCoredump,
VerifyCPUUtilization,
VerifyFileSystemUtilization,
VerifyMemoryUtilization,
VerifyNTP,
VerifyReloadCause,
VerifyUptime,
)
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyUptime,
"eos_data": [{"upTime": 1186689.15, "loadAvg": [0.13, 0.12, 0.09], "users": 1, "currentTime": 1683186659.139859}],
"inputs": {"minimum": 666},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyUptime,
"eos_data": [{"upTime": 665.15, "loadAvg": [0.13, 0.12, 0.09], "users": 1, "currentTime": 1683186659.139859}],
"inputs": {"minimum": 666},
"expected": {"result": "failure", "messages": ["Device uptime is 665.15 seconds"]},
},
{
"name": "success-no-reload",
"test": VerifyReloadCause,
"eos_data": [{"kernelCrashData": [], "resetCauses": [], "full": False}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "success-valid-cause",
"test": VerifyReloadCause,
"eos_data": [
{
"resetCauses": [
{"recommendedAction": "No action necessary.", "description": "Reload requested by the user.", "timestamp": 1683186892.0, "debugInfoIsDir": False}
],
"full": False,
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyReloadCause,
# The failure cause is made up
"eos_data": [
{
"resetCauses": [
{"recommendedAction": "No action necessary.", "description": "Reload after crash.", "timestamp": 1683186892.0, "debugInfoIsDir": False}
],
"full": False,
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Reload cause is: 'Reload after crash.'"]},
},
{
"name": "error",
"test": VerifyReloadCause,
"eos_data": [{}],
"inputs": None,
"expected": {"result": "error", "messages": ["No reload causes available"]},
},
{
"name": "success-without-minidump",
"test": VerifyCoredump,
"eos_data": [{"mode": "compressedDeferred", "coreFiles": []}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "success-with-minidump",
"test": VerifyCoredump,
"eos_data": [{"mode": "compressedDeferred", "coreFiles": ["minidump"]}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure-without-minidump",
"test": VerifyCoredump,
"eos_data": [{"mode": "compressedDeferred", "coreFiles": ["core.2344.1584483862.Mlag.gz", "core.23101.1584483867.Mlag.gz"]}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Core dump(s) have been found: ['core.2344.1584483862.Mlag.gz', 'core.23101.1584483867.Mlag.gz']"]},
},
{
"name": "failure-with-minidump",
"test": VerifyCoredump,
"eos_data": [{"mode": "compressedDeferred", "coreFiles": ["minidump", "core.2344.1584483862.Mlag.gz", "core.23101.1584483867.Mlag.gz"]}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Core dump(s) have been found: ['core.2344.1584483862.Mlag.gz', 'core.23101.1584483867.Mlag.gz']"]},
},
{
"name": "success",
"test": VerifyAgentLogs,
"eos_data": [""],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyAgentLogs,
"eos_data": [
"""===> /var/log/agents/Test-666 Thu May 4 09:57:02 2023 <===
CLI Exception: Exception
CLI Exception: Backtrace
===> /var/log/agents/Aaa-855 Fri Jul 7 15:07:00 2023 <===
===== Output from /usr/bin/Aaa [] (PID=855) started Jul 7 15:06:11.606414 ===
EntityManager::doBackoff waiting for remote sysdb version ....ok
===> /var/log/agents/Acl-830 Fri Jul 7 15:07:00 2023 <===
===== Output from /usr/bin/Acl [] (PID=830) started Jul 7 15:06:10.871700 ===
EntityManager::doBackoff waiting for remote sysdb version ...................ok
"""
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"Device has reported agent crashes:\n"
" * /var/log/agents/Test-666 Thu May 4 09:57:02 2023\n"
" * /var/log/agents/Aaa-855 Fri Jul 7 15:07:00 2023\n"
" * /var/log/agents/Acl-830 Fri Jul 7 15:07:00 2023",
],
},
},
{
"name": "success",
"test": VerifyCPUUtilization,
"eos_data": [
{
"cpuInfo": {"%Cpu(s)": {"idle": 88.2, "stolen": 0.0, "user": 5.9, "swIrq": 0.0, "ioWait": 0.0, "system": 0.0, "hwIrq": 5.9, "nice": 0.0}},
"processes": {
"1": {
"userName": "root",
"status": "S",
"memPct": 0.3,
"niceValue": 0,
"cpuPct": 0.0,
"cpuPctType": "{:.1f}",
"cmd": "systemd",
"residentMem": "5096",
"priority": "20",
"activeTime": 360,
"virtMem": "6644",
"sharedMem": "3996",
}
},
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyCPUUtilization,
"eos_data": [
{
"cpuInfo": {"%Cpu(s)": {"idle": 24.8, "stolen": 0.0, "user": 5.9, "swIrq": 0.0, "ioWait": 0.0, "system": 0.0, "hwIrq": 5.9, "nice": 0.0}},
"processes": {
"1": {
"userName": "root",
"status": "S",
"memPct": 0.3,
"niceValue": 0,
"cpuPct": 0.0,
"cpuPctType": "{:.1f}",
"cmd": "systemd",
"residentMem": "5096",
"priority": "20",
"activeTime": 360,
"virtMem": "6644",
"sharedMem": "3996",
}
},
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device has reported a high CPU utilization: 75.2%"]},
},
{
"name": "success",
"test": VerifyMemoryUtilization,
"eos_data": [
{
"uptime": 1994.67,
"modelName": "vEOS-lab",
"internalVersion": "4.27.3F-26379303.4273F",
"memTotal": 2004568,
"memFree": 879004,
"version": "4.27.3F",
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyMemoryUtilization,
"eos_data": [
{
"uptime": 1994.67,
"modelName": "vEOS-lab",
"internalVersion": "4.27.3F-26379303.4273F",
"memTotal": 2004568,
"memFree": 89004,
"version": "4.27.3F",
}
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device has reported a high memory usage: 95.56%"]},
},
{
"name": "success",
"test": VerifyFileSystemUtilization,
"eos_data": [
"""Filesystem Size Used Avail Use% Mounted on
/dev/sda2 3.9G 988M 2.9G 26% /mnt/flash
none 294M 78M 217M 27% /
none 294M 78M 217M 27% /.overlay
/dev/loop0 461M 461M 0 100% /rootfs-i386
"""
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyFileSystemUtilization,
"eos_data": [
"""Filesystem Size Used Avail Use% Mounted on
/dev/sda2 3.9G 988M 2.9G 84% /mnt/flash
none 294M 78M 217M 27% /
none 294M 78M 217M 84% /.overlay
/dev/loop0 461M 461M 0 100% /rootfs-i386
"""
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"Mount point /dev/sda2 3.9G 988M 2.9G 84% /mnt/flash is higher than 75%: reported 84%",
"Mount point none 294M 78M 217M 84% /.overlay is higher than 75%: reported 84%",
],
},
},
{
"name": "success",
"test": VerifyNTP,
"eos_data": [
"""synchronised
poll interval unknown
"""
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyNTP,
"eos_data": [
"""unsynchronised
poll interval unknown
"""
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The device is not synchronized with the configured NTP server(s): 'unsynchronised'"]},
},
]

View file

@ -0,0 +1,37 @@
# Copyright (c) 2023-2024 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.tests.vlan.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.vlan import VerifyVlanInternalPolicy
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyVlanInternalPolicy,
"eos_data": [{"policy": "ascending", "startVlanId": 1006, "endVlanId": 4094}],
"inputs": {"policy": "ascending", "start_vlan_id": 1006, "end_vlan_id": 4094},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-policy",
"test": VerifyVlanInternalPolicy,
"eos_data": [{"policy": "descending", "startVlanId": 4094, "endVlanId": 1006}],
"inputs": {"policy": "ascending", "start_vlan_id": 1006, "end_vlan_id": 4094},
"expected": {
"result": "failure",
"messages": [
"The VLAN internal allocation policy is not configured properly:\n"
"Expected `ascending` as the policy, but found `descending` instead.\n"
"Expected `1006` as the startVlanId, but found `4094` instead.\n"
"Expected `4094` as the endVlanId, but found `1006` instead."
],
},
},
]

View file

@ -0,0 +1,365 @@
# Copyright (c) 2023-2024 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.tests.vxlan.py
"""
from __future__ import annotations
from typing import Any
from anta.tests.vxlan import VerifyVxlan1ConnSettings, VerifyVxlan1Interface, VerifyVxlanConfigSanity, VerifyVxlanVniBinding, VerifyVxlanVtep
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "up", "interfaceStatus": "up"}}}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "skipped",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Loopback0": {"lineProtocolStatus": "up", "interfaceStatus": "up"}}}],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Vxlan1 interface is not configured"]},
},
{
"name": "failure",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "down", "interfaceStatus": "up"}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Vxlan1 interface is down/up"]},
},
{
"name": "failure",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "up", "interfaceStatus": "down"}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Vxlan1 interface is up/down"]},
},
{
"name": "failure",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "down", "interfaceStatus": "down"}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Vxlan1 interface is down/down"]},
},
{
"name": "success",
"test": VerifyVxlanConfigSanity,
"eos_data": [
{
"categories": {
"localVtep": {
"description": "Local VTEP Configuration Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [
{"name": "Loopback IP Address", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VLAN-VNI Map", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Flood List", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Routing", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VNI VRF ACL", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VRF-VNI Dynamic VLAN", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Decap VRF-VNI Map", "checkPass": True, "hasWarning": False, "detail": ""},
],
},
"remoteVtep": {
"description": "Remote VTEP Configuration Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [{"name": "Remote VTEP", "checkPass": True, "hasWarning": False, "detail": ""}],
},
"pd": {
"description": "Platform Dependent Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [
{"name": "VXLAN Bridging", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VXLAN Routing", "checkPass": True, "hasWarning": False, "detail": "VXLAN Routing not enabled"},
],
},
"cvx": {
"description": "CVX Configuration Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [{"name": "CVX Server", "checkPass": True, "hasWarning": False, "detail": "Not in controller client mode"}],
},
"mlag": {
"description": "MLAG Configuration Check",
"allCheckPass": True,
"detail": "Run 'show mlag config-sanity' to verify MLAG config",
"hasWarning": False,
"items": [
{"name": "Peer VTEP IP", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "MLAG VTEP IP", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Virtual VTEP IP", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Peer VLAN-VNI", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "MLAG Inactive State", "checkPass": True, "hasWarning": False, "detail": ""},
],
},
},
"warnings": [],
}
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyVxlanConfigSanity,
"eos_data": [
{
"categories": {
"localVtep": {
"description": "Local VTEP Configuration Check",
"allCheckPass": False,
"detail": "",
"hasWarning": True,
"items": [
{"name": "Loopback IP Address", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VLAN-VNI Map", "checkPass": False, "hasWarning": False, "detail": "No VLAN-VNI mapping in Vxlan1"},
{"name": "Flood List", "checkPass": False, "hasWarning": True, "detail": "No VXLAN VLANs in Vxlan1"},
{"name": "Routing", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VNI VRF ACL", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VRF-VNI Dynamic VLAN", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Decap VRF-VNI Map", "checkPass": True, "hasWarning": False, "detail": ""},
],
},
"remoteVtep": {
"description": "Remote VTEP Configuration Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [{"name": "Remote VTEP", "checkPass": True, "hasWarning": False, "detail": ""}],
},
"pd": {
"description": "Platform Dependent Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [
{"name": "VXLAN Bridging", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "VXLAN Routing", "checkPass": True, "hasWarning": False, "detail": "VXLAN Routing not enabled"},
],
},
"cvx": {
"description": "CVX Configuration Check",
"allCheckPass": True,
"detail": "",
"hasWarning": False,
"items": [{"name": "CVX Server", "checkPass": True, "hasWarning": False, "detail": "Not in controller client mode"}],
},
"mlag": {
"description": "MLAG Configuration Check",
"allCheckPass": True,
"detail": "Run 'show mlag config-sanity' to verify MLAG config",
"hasWarning": False,
"items": [
{"name": "Peer VTEP IP", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "MLAG VTEP IP", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Virtual VTEP IP", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "Peer VLAN-VNI", "checkPass": True, "hasWarning": False, "detail": ""},
{"name": "MLAG Inactive State", "checkPass": True, "hasWarning": False, "detail": ""},
],
},
},
"warnings": ["Your configuration contains warnings. This does not mean misconfigurations. But you may wish to re-check your configurations."],
}
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"VXLAN config sanity check is not passing: {'localVtep': {'description': 'Local VTEP Configuration Check', "
"'allCheckPass': False, 'detail': '', 'hasWarning': True, 'items': [{'name': 'Loopback IP Address', 'checkPass': True, "
"'hasWarning': False, 'detail': ''}, {'name': 'VLAN-VNI Map', 'checkPass': False, 'hasWarning': False, 'detail': "
"'No VLAN-VNI mapping in Vxlan1'}, {'name': 'Flood List', 'checkPass': False, 'hasWarning': True, 'detail': "
"'No VXLAN VLANs in Vxlan1'}, {'name': 'Routing', 'checkPass': True, 'hasWarning': False, 'detail': ''}, {'name': "
"'VNI VRF ACL', 'checkPass': True, 'hasWarning': False, 'detail': ''}, {'name': 'VRF-VNI Dynamic VLAN', 'checkPass': True, "
"'hasWarning': False, 'detail': ''}, {'name': 'Decap VRF-VNI Map', 'checkPass': True, 'hasWarning': False, 'detail': ''}]}}"
],
},
},
{
"name": "skipped",
"test": VerifyVxlanConfigSanity,
"eos_data": [{"categories": {}}],
"inputs": None,
"expected": {"result": "skipped", "messages": ["VXLAN is not configured"]},
},
{
"name": "success",
"test": VerifyVxlanVniBinding,
"eos_data": [
{
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
"10020": {"vlan": 20, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
}
}
}
],
"inputs": {"bindings": {10020: 20, 500: 1199}},
"expected": {"result": "success"},
},
{
"name": "failure-no-binding",
"test": VerifyVxlanVniBinding,
"eos_data": [
{
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
"10020": {"vlan": 20, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
}
}
}
],
"inputs": {"bindings": {10010: 10, 10020: 20, 500: 1199}},
"expected": {"result": "failure", "messages": ["The following VNI(s) have no binding: ['10010']"]},
},
{
"name": "failure-wrong-binding",
"test": VerifyVxlanVniBinding,
"eos_data": [
{
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
"10020": {"vlan": 30, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
}
}
}
],
"inputs": {"bindings": {10020: 20, 500: 1199}},
"expected": {"result": "failure", "messages": ["The following VNI(s) have the wrong VLAN binding: [{'10020': 30}]"]},
},
{
"name": "failure-no-and-wrong-binding",
"test": VerifyVxlanVniBinding,
"eos_data": [
{
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
"10020": {"vlan": 30, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
}
}
}
],
"inputs": {"bindings": {10010: 10, 10020: 20, 500: 1199}},
"expected": {
"result": "failure",
"messages": ["The following VNI(s) have no binding: ['10010']", "The following VNI(s) have the wrong VLAN binding: [{'10020': 30}]"],
},
},
{
"name": "skipped",
"test": VerifyVxlanVniBinding,
"eos_data": [{"vxlanIntfs": {}}],
"inputs": {"bindings": {10020: 20, 500: 1199}},
"expected": {"result": "skipped", "messages": ["Vxlan1 interface is not configured"]},
},
{
"name": "success",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": ["10.1.1.5", "10.1.1.6"]}}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6"]},
"expected": {"result": "success"},
},
{
"name": "failure-missing-vtep",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": ["10.1.1.5", "10.1.1.6"]}}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6", "10.1.1.7"]},
"expected": {"result": "failure", "messages": ["The following VTEP peer(s) are missing from the Vxlan1 interface: ['10.1.1.7']"]},
},
{
"name": "failure-no-vtep",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": []}}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6"]},
"expected": {"result": "failure", "messages": ["The following VTEP peer(s) are missing from the Vxlan1 interface: ['10.1.1.5', '10.1.1.6']"]},
},
{
"name": "failure-no-input-vtep",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": ["10.1.1.5"]}}}],
"inputs": {"vteps": []},
"expected": {"result": "failure", "messages": ["Unexpected VTEP peer(s) on Vxlan1 interface: ['10.1.1.5']"]},
},
{
"name": "failure-missmatch",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": ["10.1.1.6", "10.1.1.7", "10.1.1.8"]}}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6"]},
"expected": {
"result": "failure",
"messages": [
"The following VTEP peer(s) are missing from the Vxlan1 interface: ['10.1.1.5']",
"Unexpected VTEP peer(s) on Vxlan1 interface: ['10.1.1.7', '10.1.1.8']",
],
},
},
{
"name": "skipped",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6", "10.1.1.7"]},
"expected": {"result": "skipped", "messages": ["Vxlan1 interface is not configured"]},
},
{
"name": "success",
"test": VerifyVxlan1ConnSettings,
"eos_data": [{"interfaces": {"Vxlan1": {"srcIpIntf": "Loopback1", "udpPort": 4789}}}],
"inputs": {"source_interface": "Loopback1", "udp_port": 4789},
"expected": {"result": "success"},
},
{
"name": "skipped",
"test": VerifyVxlan1ConnSettings,
"eos_data": [{"interfaces": {}}],
"inputs": {"source_interface": "Loopback1", "udp_port": 4789},
"expected": {"result": "skipped", "messages": ["Vxlan1 interface is not configured."]},
},
{
"name": "failure-wrong-interface",
"test": VerifyVxlan1ConnSettings,
"eos_data": [{"interfaces": {"Vxlan1": {"srcIpIntf": "Loopback10", "udpPort": 4789}}}],
"inputs": {"source_interface": "lo1", "udp_port": 4789},
"expected": {
"result": "failure",
"messages": ["Source interface is not correct. Expected `Loopback1` as source interface but found `Loopback10` instead."],
},
},
{
"name": "failure-wrong-port",
"test": VerifyVxlan1ConnSettings,
"eos_data": [{"interfaces": {"Vxlan1": {"srcIpIntf": "Loopback10", "udpPort": 4789}}}],
"inputs": {"source_interface": "Lo1", "udp_port": 4780},
"expected": {
"result": "failure",
"messages": [
"Source interface is not correct. Expected `Loopback1` as source interface but found `Loopback10` instead.",
"UDP port is not correct. Expected `4780` as UDP port but found `4789` instead.",
],
},
},
]