Adding upstream version 1.2.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 11:55:09 +01:00
parent 77504588ab
commit 6fd6eb426a
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
154 changed files with 7346 additions and 5000 deletions

View file

@ -21,7 +21,7 @@ def build_test_id(val: dict[str, Any]) -> str:
def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Generate ANTA testts unit tests dynamically during test collection.
"""Generate ANTA tests unit tests dynamically during test collection.
It will parametrize test cases based on the `DATA` data structure defined in `tests.units.anta_tests` modules.
See `tests/units/anta_tests/README.md` for more information on how to use it.

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@ from typing import Any
import pytest
from pydantic import ValidationError
from anta.tests.routing.generic import VerifyRoutingProtocolModel, VerifyRoutingTableEntry, VerifyRoutingTableSize
from anta.tests.routing.generic import VerifyIPv4RouteType, VerifyRoutingProtocolModel, VerifyRoutingTableEntry, VerifyRoutingTableSize
from tests.units.anta_tests import test
DATA: list[dict[str, Any]] = [
@ -304,6 +304,50 @@ DATA: list[dict[str, Any]] = [
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"], "collect": "all"},
"expected": {"result": "failure", "messages": ["The following route(s) are missing from the routing table of VRF default: ['10.1.0.2']"]},
},
{
"name": "success-valid-route-type",
"test": VerifyIPv4RouteType,
"eos_data": [
{
"vrfs": {
"default": {"routes": {"10.10.0.1/32": {"routeType": "eBGP"}, "10.100.0.12/31": {"routeType": "connected"}}},
"MGMT": {"routes": {"10.100.1.5/32": {"routeType": "iBGP"}}},
}
}
],
"inputs": {
"routes_entries": [
{"vrf": "default", "prefix": "10.10.0.1/32", "route_type": "eBGP"},
{"vrf": "default", "prefix": "10.100.0.12/31", "route_type": "connected"},
{"vrf": "MGMT", "prefix": "10.100.1.5/32", "route_type": "iBGP"},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-route-not-found",
"test": VerifyIPv4RouteType,
"eos_data": [{"vrfs": {"default": {"routes": {}}}}],
"inputs": {"routes_entries": [{"vrf": "default", "prefix": "10.10.0.1/32", "route_type": "eBGP"}]},
"expected": {"result": "failure", "messages": ["Prefix: 10.10.0.1/32 VRF: default - Route not found"]},
},
{
"name": "failure-invalid-route-type",
"test": VerifyIPv4RouteType,
"eos_data": [{"vrfs": {"default": {"routes": {"10.10.0.1/32": {"routeType": "eBGP"}}}}}],
"inputs": {"routes_entries": [{"vrf": "default", "prefix": "10.10.0.1/32", "route_type": "iBGP"}]},
"expected": {
"result": "failure",
"messages": ["Prefix: 10.10.0.1/32 VRF: default - Incorrect route type - Expected: iBGP Actual: eBGP"],
},
},
{
"name": "failure-vrf-not-configured",
"test": VerifyIPv4RouteType,
"eos_data": [{"vrfs": {}}],
"inputs": {"routes_entries": [{"vrf": "default", "prefix": "10.10.0.1/32", "route_type": "eBGP"}]},
"expected": {"result": "failure", "messages": ["Prefix: 10.10.0.1/32 VRF: default - VRF not configured"]},
},
]

View file

@ -361,48 +361,63 @@ DATA: list[dict[str, Any]] = [
"avts": {
"DEFAULT-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
"multihop:1": {
"flags": {"directPath": False, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
"multihop:3": {
"flags": {"directPath": False, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
}
}
}
}
}
},
{
"vrfs": {
},
},
"data": {
"avts": {
"DATA-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:8": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.1",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.1",
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.2",
"destination": "10.101.255.1",
},
"multihop:1": {
"flags": {"directPath": False, "valid": True, "active": True},
"nexthopAddr": "10.101.255.2",
"destination": "10.101.255.1",
},
"multihop:3": {
"flags": {"directPath": False, "valid": True, "active": True},
"nexthopAddr": "10.101.255.2",
"destination": "10.101.255.1",
},
}
}
},
}
}
}
},
{
"vrfs": {
"data": {
"avts": {
"DATA-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:8": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
}
}
}
}
},
}
},
],
@ -420,22 +435,6 @@ DATA: list[dict[str, Any]] = [
"test": VerifyAVTSpecificPath,
"eos_data": [
{"vrfs": {}},
{
"vrfs": {
"data": {
"avts": {
"DATA-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
}
}
}
}
}
},
],
"inputs": {
"avt_paths": [
@ -445,11 +444,11 @@ DATA: list[dict[str, Any]] = [
},
"expected": {
"result": "failure",
"messages": ["AVT configuration for peer '10.101.255.2' under topology 'MGMT-AVT-POLICY-DEFAULT' in VRF 'default' is not found."],
"messages": ["AVT MGMT-AVT-POLICY-DEFAULT VRF: default (Destination: 10.101.255.2, Next-hop: 10.101.255.1) - No AVT path configured"],
},
},
{
"name": "failure-no-path-with-correct-next-hop",
"name": "failure-path_type_check_true",
"test": VerifyAVTSpecificPath,
"eos_data": [
{
@ -458,30 +457,38 @@ DATA: list[dict[str, Any]] = [
"avts": {
"DEFAULT-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
}
}
}
}
}
},
{
"vrfs": {
},
},
"data": {
"avts": {
"DATA-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.3",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.3",
},
}
}
},
}
}
},
}
},
],
@ -500,10 +507,72 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"No 'multihop' path found with next-hop address '10.101.255.11' for AVT peer '10.101.255.2' under "
"topology 'DEFAULT-AVT-POLICY-CONTROL-PLANE' in VRF 'default'.",
"No 'direct' path found with next-hop address '10.101.255.21' for AVT peer '10.101.255.1' under "
"topology 'DATA-AVT-POLICY-CONTROL-PLANE' in VRF 'data'.",
"AVT DEFAULT-AVT-POLICY-CONTROL-PLANE VRF: default (Destination: 10.101.255.2, Next-hop: 10.101.255.11) Path Type: multihop - Path not found",
"AVT DATA-AVT-POLICY-CONTROL-PLANE VRF: data (Destination: 10.101.255.1, Next-hop: 10.101.255.21) Path Type: direct - Path not found",
],
},
},
{
"name": "failure-path_type_check_false",
"test": VerifyAVTSpecificPath,
"eos_data": [
{
"vrfs": {
"default": {
"avts": {
"DEFAULT-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
}
}
},
},
"data": {
"avts": {
"DATA-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.3",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.3",
},
}
},
}
},
}
},
],
"inputs": {
"avt_paths": [
{
"avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE",
"vrf": "default",
"destination": "10.101.255.2",
"next_hop": "10.101.255.11",
},
{"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.21"},
]
},
"expected": {
"result": "failure",
"messages": [
"AVT DEFAULT-AVT-POLICY-CONTROL-PLANE VRF: default (Destination: 10.101.255.2, Next-hop: 10.101.255.11) - Path not found",
"AVT DATA-AVT-POLICY-CONTROL-PLANE VRF: data (Destination: 10.101.255.1, Next-hop: 10.101.255.21) - Path not found",
],
},
},
@ -517,30 +586,48 @@ DATA: list[dict[str, Any]] = [
"avts": {
"DEFAULT-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:1": {"flags": {"directPath": True, "valid": False, "active": False}, "nexthopAddr": "10.101.255.1"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": False}, "nexthopAddr": "10.101.255.1"},
"multihop:3": {
"flags": {"directPath": False, "valid": False, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.2",
},
}
}
}
}
}
},
{
"vrfs": {
},
},
"data": {
"avts": {
"DATA-AVT-POLICY-CONTROL-PLANE": {
"avtPaths": {
"direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
"direct:9": {"flags": {"directPath": True, "valid": False, "active": True}, "nexthopAddr": "10.101.255.1"},
"multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
"direct:10": {
"flags": {"directPath": True, "valid": False, "active": True},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.1",
},
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": False},
"nexthopAddr": "10.101.255.1",
"destination": "10.101.255.1",
},
"direct:8": {
"flags": {"directPath": True, "valid": False, "active": False},
"nexthopAddr": "10.101.255.2",
"destination": "10.101.255.1",
},
"multihop:1": {
"flags": {"directPath": False, "valid": True, "active": True},
"nexthopAddr": "10.101.255.2",
"destination": "10.101.255.1",
},
"multihop:3": {
"flags": {"directPath": False, "valid": True, "active": True},
"nexthopAddr": "10.101.255.2",
"destination": "10.101.255.1",
},
}
}
},
}
}
},
}
},
],
@ -559,8 +646,12 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"AVT path 'multihop:3' for topology 'DEFAULT-AVT-POLICY-CONTROL-PLANE' in VRF 'default' is inactive.",
"AVT path 'direct:9' for topology 'DATA-AVT-POLICY-CONTROL-PLANE' in VRF 'data' is invalid.",
"AVT DEFAULT-AVT-POLICY-CONTROL-PLANE VRF: default (Destination: 10.101.255.2, Next-hop: 10.101.255.1) - "
"Incorrect path multihop:3 - Valid: False, Active: True",
"AVT DATA-AVT-POLICY-CONTROL-PLANE VRF: data (Destination: 10.101.255.1, Next-hop: 10.101.255.1) - "
"Incorrect path direct:10 - Valid: False, Active: True",
"AVT DATA-AVT-POLICY-CONTROL-PLANE VRF: data (Destination: 10.101.255.1, Next-hop: 10.101.255.1) - "
"Incorrect path direct:9 - Valid: True, Active: False",
],
},
},

View file

@ -107,8 +107,8 @@ DATA: list[dict[str, Any]] = [
"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'}}"
"Peer: 192.0.255.7 VRF: CS - Not found",
"Peer: 192.0.255.70 VRF: MGMT - Not found",
],
},
},
@ -160,9 +160,11 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"Following BFD peers are not configured or timers are not correct:\n"
"{'192.0.255.7': {'default': {'tx_interval': 1300, 'rx_interval': 1200, 'multiplier': 4}}, "
"'192.0.255.70': {'MGMT': {'tx_interval': 120, 'rx_interval': 120, 'multiplier': 5}}}"
"Peer: 192.0.255.7 VRF: default - Incorrect Transmit interval - Expected: 1200 Actual: 1300",
"Peer: 192.0.255.7 VRF: default - Incorrect Multiplier - Expected: 3 Actual: 4",
"Peer: 192.0.255.70 VRF: MGMT - Incorrect Transmit interval - Expected: 1200 Actual: 120",
"Peer: 192.0.255.70 VRF: MGMT - Incorrect Receive interval - Expected: 1200 Actual: 120",
"Peer: 192.0.255.70 VRF: MGMT - Incorrect Multiplier - Expected: 3 Actual: 5",
],
},
},
@ -239,8 +241,8 @@ DATA: list[dict[str, Any]] = [
"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'}}"
"Peer: 192.0.255.7 VRF: CS - Not found",
"Peer: 192.0.255.70 VRF: MGMT - Not found",
],
},
},
@ -255,7 +257,7 @@ DATA: list[dict[str, Any]] = [
"192.0.255.7": {
"peerStats": {
"": {
"status": "Down",
"status": "down",
"remoteDisc": 108328132,
}
}
@ -267,7 +269,7 @@ DATA: list[dict[str, Any]] = [
"192.0.255.70": {
"peerStats": {
"": {
"status": "Down",
"status": "down",
"remoteDisc": 0,
}
}
@ -281,9 +283,8 @@ DATA: list[dict[str, Any]] = [
"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}}}"
"Peer: 192.0.255.7 VRF: default - Session not properly established - State: down Remote Discriminator: 108328132",
"Peer: 192.0.255.70 VRF: MGMT - Session not properly established - State: down Remote Discriminator: 0",
],
},
},
@ -414,7 +415,8 @@ DATA: list[dict[str, Any]] = [
"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."
"Peer: 192.0.255.7 VRF: default - Session not properly established - State: down Remote Discriminator: 0",
"Peer: 192.0.255.71 VRF: MGMT - Session not properly established - State: down Remote Discriminator: 0",
],
},
},
@ -458,7 +460,10 @@ DATA: list[dict[str, Any]] = [
"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."],
"messages": [
"Peer: 192.0.255.7 VRF: default - Session not properly established - State: up Remote Discriminator: 0",
"Peer: 192.0.255.71 VRF: default - Session not properly established - State: up Remote Discriminator: 0",
],
},
},
{
@ -512,8 +517,9 @@ DATA: list[dict[str, Any]] = [
"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."
"Peer: 192.0.255.7 VRF: default - Session failure detected within the expected uptime threshold (3 hours ago)",
"Peer: 192.0.255.71 VRF: default - Session failure detected within the expected uptime threshold (3 hours ago)",
"Peer: 192.0.255.17 VRF: default - Session failure detected within the expected uptime threshold (3 hours ago)",
],
},
},
@ -609,15 +615,14 @@ DATA: list[dict[str, Any]] = [
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "default", "protocols": ["isis"]},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "protocols": ["isis"]},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "protocols": ["isis", "ospf"]},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BFD peers are not configured or have non-registered protocol(s):\n"
"{'192.0.255.7': {'default': ['isis']}, "
"'192.0.255.70': {'MGMT': ['isis']}}"
"Peer: 192.0.255.7 VRF: default - `isis` routing protocol(s) not configured",
"Peer: 192.0.255.70 VRF: MGMT - `isis` `ospf` routing protocol(s) not configured",
],
},
},
@ -641,8 +646,8 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"The following BFD peers are not configured or have non-registered protocol(s):\n"
"{'192.0.255.7': {'default': 'Not Configured'}, '192.0.255.70': {'MGMT': 'Not Configured'}}"
"Peer: 192.0.255.7 VRF: default - Not found",
"Peer: 192.0.255.70 VRF: MGMT - Not found",
],
},
},

View file

@ -153,7 +153,7 @@ DATA: list[dict[str, Any]] = [
],
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('10.0.0.5', '10.0.0.11')]"]},
"expected": {"result": "failure", "messages": ["Host 10.0.0.11 (src: 10.0.0.5, vrf: default, size: 100B, repeat: 2) - Unreachable"]},
},
{
"name": "failure-interface",
@ -187,7 +187,7 @@ DATA: list[dict[str, Any]] = [
],
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('Management0', '10.0.0.11')]"]},
"expected": {"result": "failure", "messages": ["Host 10.0.0.11 (src: Management0, vrf: default, size: 100B, repeat: 2) - Unreachable"]},
},
{
"name": "failure-size",
@ -209,17 +209,11 @@ DATA: list[dict[str, Any]] = [
],
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('Management0', '10.0.0.1')]"]},
"expected": {"result": "failure", "messages": ["Host 10.0.0.1 (src: Management0, vrf: default, size: 1501B, repeat: 5, df-bit: enabled) - Unreachable"]},
},
{
"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": {
@ -256,16 +250,17 @@ DATA: list[dict[str, Any]] = [
},
},
],
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
],
},
"expected": {"result": "success"},
},
{
"name": "success-multiple-neighbors",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
],
},
"eos_data": [
{
"lldpNeighbors": {
@ -298,17 +293,16 @@ DATA: list[dict[str, Any]] = [
},
},
],
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
],
},
"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": {
@ -330,17 +324,17 @@ DATA: list[dict[str, Any]] = [
},
},
],
"expected": {"result": "failure", "messages": ["Port(s) not configured:\n 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"},
],
},
"expected": {"result": "failure", "messages": ["Port Ethernet2 (Neighbor: DC1-SPINE2, Neighbor Port: Ethernet1) - Port not found"]},
},
{
"name": "failure-no-neighbor",
"test": VerifyLLDPNeighbors,
"eos_data": [
{
"lldpNeighbors": {
@ -363,17 +357,17 @@ DATA: list[dict[str, Any]] = [
},
},
],
"expected": {"result": "failure", "messages": ["No LLDP neighbor(s) on port(s):\n 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"},
],
},
"expected": {"result": "failure", "messages": ["Port Ethernet2 (Neighbor: DC1-SPINE2, Neighbor Port: Ethernet1) - No LLDP neighbors"]},
},
{
"name": "failure-wrong-neighbor",
"test": VerifyLLDPNeighbors,
"eos_data": [
{
"lldpNeighbors": {
@ -410,11 +404,42 @@ DATA: list[dict[str, Any]] = [
},
},
],
"expected": {"result": "failure", "messages": ["Wrong LLDP neighbor(s) on port(s):\n Ethernet2\n DC1-SPINE2_Ethernet2"]},
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
],
},
"expected": {
"result": "failure",
"messages": ["Port Ethernet2 (Neighbor: DC1-SPINE2, Neighbor Port: Ethernet1) - Wrong LLDP neighbors: DC1-SPINE2/Ethernet2"],
},
},
{
"name": "failure-multiple",
"test": VerifyLLDPNeighbors,
"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": []},
},
},
],
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
@ -422,45 +447,18 @@ DATA: list[dict[str, Any]] = [
{"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": [
"Wrong LLDP neighbor(s) on port(s):\n Ethernet1\n DC1-SPINE1_Ethernet2\n"
"No LLDP neighbor(s) on port(s):\n Ethernet2\n"
"Port(s) not configured:\n Ethernet3"
"Port Ethernet1 (Neighbor: DC1-SPINE1, Neighbor Port: Ethernet1) - Wrong LLDP neighbors: DC1-SPINE1/Ethernet2",
"Port Ethernet2 (Neighbor: DC1-SPINE2, Neighbor Port: Ethernet1) - No LLDP neighbors",
"Port Ethernet3 (Neighbor: DC1-SPINE3, Neighbor Port: Ethernet1) - Port not found",
],
},
},
{
"name": "failure-multiple-neighbors",
"test": VerifyLLDPNeighbors,
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE3", "neighbor_port": "Ethernet1"},
],
},
"eos_data": [
{
"lldpNeighbors": {
@ -493,6 +491,14 @@ DATA: list[dict[str, Any]] = [
},
},
],
"expected": {"result": "failure", "messages": ["Wrong LLDP neighbor(s) on port(s):\n Ethernet1\n DC1-SPINE1_Ethernet1\n DC1-SPINE2_Ethernet1"]},
"inputs": {
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE3", "neighbor_port": "Ethernet1"},
],
},
"expected": {
"result": "failure",
"messages": ["Port Ethernet1 (Neighbor: DC1-SPINE3, Neighbor Port: Ethernet1) - Wrong LLDP neighbors: DC1-SPINE1/Ethernet1, DC1-SPINE2/Ethernet1"],
},
},
]

View file

@ -0,0 +1,525 @@
# 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.cvx."""
from __future__ import annotations
from typing import Any
from anta.tests.cvx import VerifyActiveCVXConnections, VerifyCVXClusterStatus, VerifyManagementCVX, VerifyMcsClientMounts, VerifyMcsServerMounts
from tests.units.anta_tests import test
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyMcsClientMounts,
"eos_data": [{"mountStates": [{"path": "mcs/v1/toSwitch/28-99-3a-8f-93-7b", "type": "Mcs::DeviceConfigV1", "state": "mountStateMountComplete"}]}],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "success-haclient",
"test": VerifyMcsClientMounts,
"eos_data": [
{
"mountStates": [
{"path": "mcs/v1/apiCfgRedState", "type": "Mcs::ApiConfigRedundancyState", "state": "mountStateMountComplete"},
{"path": "mcs/v1/toSwitch/00-1c-73-74-c0-8b", "type": "Mcs::DeviceConfigV1", "state": "mountStateMountComplete"},
]
},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "success-partial-non-mcs",
"test": VerifyMcsClientMounts,
"eos_data": [
{
"mountStates": [
{"path": "blah/blah/blah", "type": "blah::blah", "state": "mountStatePreservedUnmounted"},
{"path": "mcs/v1/toSwitch/00-1c-73-74-c0-8b", "type": "Mcs::DeviceConfigV1", "state": "mountStateMountComplete"},
]
},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure-nomounts",
"test": VerifyMcsClientMounts,
"eos_data": [
{"mountStates": []},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["MCS Client mount states are not present"]},
},
{
"name": "failure-mountStatePreservedUnmounted",
"test": VerifyMcsClientMounts,
"eos_data": [{"mountStates": [{"path": "mcs/v1/toSwitch/28-99-3a-8f-93-7b", "type": "Mcs::DeviceConfigV1", "state": "mountStatePreservedUnmounted"}]}],
"inputs": None,
"expected": {"result": "failure", "messages": ["MCS Client mount states are not valid: mountStatePreservedUnmounted"]},
},
{
"name": "failure-partial-haclient",
"test": VerifyMcsClientMounts,
"eos_data": [
{
"mountStates": [
{"path": "mcs/v1/apiCfgRedState", "type": "Mcs::ApiConfigRedundancyState", "state": "mountStateMountComplete"},
{"path": "mcs/v1/toSwitch/00-1c-73-74-c0-8b", "type": "Mcs::DeviceConfigV1", "state": "mountStatePreservedUnmounted"},
]
},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["MCS Client mount states are not valid: mountStatePreservedUnmounted"]},
},
{
"name": "failure-full-haclient",
"test": VerifyMcsClientMounts,
"eos_data": [
{
"mountStates": [
{"path": "blah/blah/blah", "type": "blah::blahState", "state": "mountStatePreservedUnmounted"},
{"path": "mcs/v1/toSwitch/00-1c-73-74-c0-8b", "type": "Mcs::DeviceConfigV1", "state": "mountStatePreservedUnmounted"},
]
},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["MCS Client mount states are not valid: mountStatePreservedUnmounted"]},
},
{
"name": "failure-non-mcs-client",
"test": VerifyMcsClientMounts,
"eos_data": [
{"mountStates": [{"path": "blah/blah/blah", "type": "blah::blahState", "state": "mountStatePreservedUnmounted"}]},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["MCS Client mount states are not present"]},
},
{
"name": "failure-partial-mcs-client",
"test": VerifyMcsClientMounts,
"eos_data": [
{
"mountStates": [
{"path": "blah/blah/blah", "type": "blah::blahState", "state": "mountStatePreservedUnmounted"},
{"path": "blah/blah/blah", "type": "Mcs::DeviceConfigV1", "state": "mountStatePreservedUnmounted"},
]
},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["MCS Client mount states are not valid: mountStatePreservedUnmounted"]},
},
{
"name": "success-enabled",
"test": VerifyManagementCVX,
"eos_data": [
{
"clusterStatus": {
"enabled": True,
}
}
],
"inputs": {"enabled": True},
"expected": {"result": "success"},
},
{
"name": "success-disabled",
"test": VerifyManagementCVX,
"eos_data": [
{
"clusterStatus": {
"enabled": False,
}
}
],
"inputs": {"enabled": False},
"expected": {"result": "success"},
},
{
"name": "failure - no enabled state",
"test": VerifyManagementCVX,
"eos_data": [{"clusterStatus": {}}],
"inputs": {"enabled": False},
"expected": {"result": "failure", "messages": ["Management CVX status is not valid: None"]},
},
{
"name": "failure - no clusterStatus",
"test": VerifyManagementCVX,
"eos_data": [{}],
"inputs": {"enabled": False},
"expected": {"result": "failure", "messages": ["Management CVX status is not valid: None"]},
},
{
"name": "success",
"test": VerifyMcsServerMounts,
"eos_data": [
{
"connections": [
{
"hostname": "media-leaf-1",
"mounts": [
{
"service": "Mcs",
"mountStates": [
{
"pathStates": [
{"path": "mcs/v1/apiCfgRedStatus", "type": "Mcs::ApiConfigRedundancyStatus", "state": "mountStateMountComplete"},
{"path": "mcs/v1/activeflows", "type": "Mcs::ActiveFlows", "state": "mountStateMountComplete"},
{"path": "mcs/switch/status", "type": "Mcs::Client::Status", "state": "mountStateMountComplete"},
]
}
],
}
],
}
]
}
],
"inputs": {"connections_count": 1},
"expected": {"result": "success"},
},
{
"name": "failure-no-mounts",
"test": VerifyMcsServerMounts,
"eos_data": [{"connections": [{"hostname": "media-leaf-1", "mounts": []}]}],
"inputs": {"connections_count": 1},
"expected": {
"result": "failure",
"messages": ["No mount status for media-leaf-1", "Incorrect CVX successful connections count. Expected: 1, Actual : 0"],
},
},
{
"name": "failure-unexpected-number-paths",
"test": VerifyMcsServerMounts,
"eos_data": [
{
"connections": [
{
"hostname": "media-leaf-1",
"mounts": [
{
"service": "Mcs",
"mountStates": [
{
"pathStates": [
{"path": "mcs/v1/apiCfgRedStatus", "type": "Mcs::ApiStatus", "state": "mountStateMountComplete"},
{"path": "mcs/v1/activeflows", "type": "Mcs::ActiveFlows", "state": "mountStateMountComplete"},
]
}
],
}
],
}
]
}
],
"inputs": {"connections_count": 1},
"expected": {
"result": "failure",
"messages": [
"Incorrect number of mount path states for media-leaf-1 - Expected: 3, Actual: 2",
"Unexpected MCS path type for media-leaf-1: 'Mcs::ApiStatus'.",
],
},
},
{
"name": "failure-unexpected-path-type",
"test": VerifyMcsServerMounts,
"eos_data": [
{
"connections": [
{
"hostname": "media-leaf-1",
"mounts": [
{
"service": "Mcs",
"mountStates": [
{
"pathStates": [
{"path": "mcs/v1/apiCfgRedStatus", "type": "Mcs::ApiStatus", "state": "mountStateMountComplete"},
{"path": "mcs/v1/activeflows", "type": "Mcs::ActiveFlows", "state": "mountStateMountComplete"},
{"path": "mcs/switch/status", "type": "Mcs::Client::Status", "state": "mountStateMountComplete"},
]
}
],
}
],
}
]
}
],
"inputs": {"connections_count": 1},
"expected": {"result": "failure", "messages": ["Unexpected MCS path type for media-leaf-1: 'Mcs::ApiStatus'"]},
},
{
"name": "failure-invalid-mount-state",
"test": VerifyMcsServerMounts,
"eos_data": [
{
"connections": [
{
"hostname": "media-leaf-1",
"mounts": [
{
"service": "Mcs",
"mountStates": [
{
"pathStates": [
{"path": "mcs/v1/apiCfgRedStatus", "type": "Mcs::ApiConfigRedundancyStatus", "state": "mountStateMountFailed"},
{"path": "mcs/v1/activeflows", "type": "Mcs::ActiveFlows", "state": "mountStateMountComplete"},
{"path": "mcs/switch/status", "type": "Mcs::Client::Status", "state": "mountStateMountComplete"},
]
}
],
}
],
}
]
}
],
"inputs": {"connections_count": 1},
"expected": {
"result": "failure",
"messages": ["MCS server mount state for path 'Mcs::ApiConfigRedundancyStatus' is not valid is for media-leaf-1: 'mountStateMountFailed'"],
},
},
{
"name": "failure-no-mcs-mount",
"test": VerifyMcsServerMounts,
"eos_data": [
{
"connections": [
{
"hostname": "media-leaf-1",
"mounts": [
{
"service": "blah-blah",
"mountStates": [{"pathStates": [{"path": "blah-blah-path", "type": "blah-blah-type", "state": "blah-blah-state"}]}],
}
],
}
]
}
],
"inputs": {"connections_count": 1},
"expected": {"result": "failure", "messages": ["MCS mount state not detected", "Incorrect CVX successful connections count. Expected: 1, Actual : 0"]},
},
{
"name": "failure-connections",
"test": VerifyMcsServerMounts,
"eos_data": [{}],
"inputs": {"connections_count": 1},
"expected": {"result": "failure", "messages": ["CVX connections are not available."]},
},
{
"name": "success",
"test": VerifyActiveCVXConnections,
"eos_data": [
{
"connections": [
{
"switchId": "fc:bd:67:c3:16:55",
"hostname": "lyv563",
"oobConnectionActive": True,
},
{
"switchId": "00:1c:73:3c:e3:9e",
"hostname": "tg264",
"oobConnectionActive": True,
},
]
}
],
"inputs": {"connections_count": 2},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyActiveCVXConnections,
"eos_data": [
{
"connections": [
{
"switchId": "fc:bd:67:c3:16:55",
"hostname": "lyv563",
"oobConnectionActive": False,
},
{
"switchId": "00:1c:73:3c:e3:9e",
"hostname": "tg264",
"oobConnectionActive": True,
},
]
}
],
"inputs": {"connections_count": 2},
"expected": {"result": "failure", "messages": ["CVX active connections count. Expected: 2, Actual : 1"]},
},
{
"name": "failure-no-connections",
"test": VerifyActiveCVXConnections,
"eos_data": [{}],
"inputs": {"connections_count": 2},
"expected": {"result": "failure", "messages": ["CVX connections are not available"]},
},
{
"name": "success-all",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": True,
"clusterMode": True,
"clusterStatus": {
"role": "Master",
"peerStatus": {
"cvx-red-2": {"peerName": "cvx-red-2", "registrationState": "Registration complete"},
"cvx-red-3": {"peerName": "cvx-red-3", "registrationState": "Registration complete"},
},
},
}
],
"inputs": {
"role": "Master",
"peer_status": [
{"peer_name": "cvx-red-2", "registrationState": "Registration complete"},
{"peer_name": "cvx-red-3", "registrationState": "Registration complete"},
],
},
"expected": {"result": "success"},
},
{
"name": "failure-invalid-role",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": True,
"clusterMode": True,
"clusterStatus": {
"role": "Standby",
"peerStatus": {
"cvx-red-2": {"peerName": "cvx-red-2", "registrationState": "Registration complete"},
"cvx-red-3": {"peerName": "cvx-red-3", "registrationState": "Registration complete"},
},
},
}
],
"inputs": {
"role": "Master",
"peer_status": [
{"peer_name": "cvx-red-2", "registrationState": "Registration complete"},
{"peer_name": "cvx-red-3", "registrationState": "Registration complete"},
],
},
"expected": {"result": "failure", "messages": ["CVX Role is not valid: Standby"]},
},
{
"name": "failure-cvx-enabled",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": False,
"clusterMode": True,
"clusterStatus": {
"role": "Master",
"peerStatus": {},
},
}
],
"inputs": {
"role": "Master",
"peer_status": [],
},
"expected": {"result": "failure", "messages": ["CVX Server status is not enabled"]},
},
{
"name": "failure-cluster-enabled",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": True,
"clusterMode": False,
"clusterStatus": {},
}
],
"inputs": {
"role": "Master",
"peer_status": [],
},
"expected": {"result": "failure", "messages": ["CVX Server is not a cluster"]},
},
{
"name": "failure-missing-peers",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": True,
"clusterMode": True,
"clusterStatus": {
"role": "Master",
"peerStatus": {
"cvx-red-2": {"peerName": "cvx-red-2", "registrationState": "Registration complete"},
},
},
}
],
"inputs": {
"role": "Master",
"peer_status": [
{"peer_name": "cvx-red-2", "registrationState": "Registration complete"},
{"peer_name": "cvx-red-3", "registrationState": "Registration complete"},
],
},
"expected": {"result": "failure", "messages": ["Unexpected number of peers 1 vs 2", "cvx-red-3 is not present"]},
},
{
"name": "failure-invalid-peers",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": True,
"clusterMode": True,
"clusterStatus": {
"role": "Master",
"peerStatus": {},
},
}
],
"inputs": {
"role": "Master",
"peer_status": [
{"peer_name": "cvx-red-2", "registrationState": "Registration complete"},
{"peer_name": "cvx-red-3", "registrationState": "Registration complete"},
],
},
"expected": {"result": "failure", "messages": ["Unexpected number of peers 0 vs 2", "cvx-red-2 is not present", "cvx-red-3 is not present"]},
},
{
"name": "failure-registration-error",
"test": VerifyCVXClusterStatus,
"eos_data": [
{
"enabled": True,
"clusterMode": True,
"clusterStatus": {
"role": "Master",
"peerStatus": {
"cvx-red-2": {"peerName": "cvx-red-2", "registrationState": "Registration error"},
"cvx-red-3": {"peerName": "cvx-red-3", "registrationState": "Registration complete"},
},
},
}
],
"inputs": {
"role": "Master",
"peer_status": [
{"peer_name": "cvx-red-2", "registrationState": "Registration complete"},
{"peer_name": "cvx-red-3", "registrationState": "Registration complete"},
],
},
"expected": {"result": "failure", "messages": ["cvx-red-2 registration state is not complete: Registration error"]},
},
]

View file

@ -1108,7 +1108,7 @@ DATA: list[dict[str, Any]] = [
"inputs": {"interfaces": [{"name": "Ethernet2", "status": "up"}, {"name": "Ethernet8", "status": "up"}, {"name": "Ethernet3", "status": "up"}]},
"expected": {
"result": "failure",
"messages": ["The following interface(s) are not configured: ['Ethernet8']"],
"messages": ["Ethernet8 - Not configured"],
},
},
{
@ -1126,7 +1126,7 @@ DATA: list[dict[str, Any]] = [
"inputs": {"interfaces": [{"name": "Ethernet2", "status": "up"}, {"name": "Ethernet8", "status": "up"}, {"name": "Ethernet3", "status": "up"}]},
"expected": {
"result": "failure",
"messages": ["The following interface(s) are not in the expected state: ['Ethernet8 is down/down'"],
"messages": ["Ethernet8 - Expected: up/up, Actual: down/down"],
},
},
{
@ -1150,7 +1150,7 @@ DATA: list[dict[str, Any]] = [
},
"expected": {
"result": "failure",
"messages": ["The following interface(s) are not in the expected state: ['Ethernet8 is up/down'"],
"messages": ["Ethernet8 - Expected: up/up, Actual: up/down"],
},
},
{
@ -1166,7 +1166,7 @@ DATA: list[dict[str, Any]] = [
"inputs": {"interfaces": [{"name": "PortChannel100", "status": "up"}]},
"expected": {
"result": "failure",
"messages": ["The following interface(s) are not in the expected state: ['Port-Channel100 is down/lowerLayerDown'"],
"messages": ["Port-Channel100 - Expected: up/up, Actual: down/lowerLayerDown"],
},
},
{
@ -1190,7 +1190,38 @@ DATA: list[dict[str, Any]] = [
},
"expected": {
"result": "failure",
"messages": ["The following interface(s) are not in the expected state: ['Ethernet2 is up/unknown'"],
"messages": [
"Ethernet2 - Expected: up/down, Actual: up/unknown",
"Ethernet8 - Expected: up/up, Actual: up/down",
],
},
},
{
"name": "failure-interface-status-down",
"test": VerifyInterfacesStatus,
"eos_data": [
{
"interfaceDescriptions": {
"Ethernet8": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "down"},
"Ethernet2": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "unknown"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
}
}
],
"inputs": {
"interfaces": [
{"name": "Ethernet2", "status": "down"},
{"name": "Ethernet8", "status": "down"},
{"name": "Ethernet3", "status": "down"},
]
},
"expected": {
"result": "failure",
"messages": [
"Ethernet2 - Expected: down, Actual: up",
"Ethernet8 - Expected: down, Actual: up",
"Ethernet3 - Expected: down, Actual: up",
],
},
},
{
@ -1938,8 +1969,8 @@ DATA: list[dict[str, Any]] = [
"interfaces": {
"Ethernet2": {
"interfaceAddress": {
"primaryIp": {"address": "172.30.11.0", "maskLen": 31},
"secondaryIpsOrderedList": [{"address": "10.10.10.0", "maskLen": 31}, {"address": "10.10.10.10", "maskLen": 31}],
"primaryIp": {"address": "172.30.11.1", "maskLen": 31},
"secondaryIpsOrderedList": [{"address": "10.10.10.1", "maskLen": 31}, {"address": "10.10.10.10", "maskLen": 31}],
}
}
}
@ -1957,7 +1988,7 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"interfaces": [
{"name": "Ethernet2", "primary_ip": "172.30.11.0/31", "secondary_ips": ["10.10.10.0/31", "10.10.10.10/31"]},
{"name": "Ethernet2", "primary_ip": "172.30.11.1/31", "secondary_ips": ["10.10.10.1/31", "10.10.10.10/31"]},
{"name": "Ethernet12", "primary_ip": "172.30.11.10/31", "secondary_ips": ["10.10.10.10/31", "10.10.10.20/31"]},
]
},
@ -2479,6 +2510,43 @@ DATA: list[dict[str, Any]] = [
"inputs": {"interfaces": [{"name": "Ethernet5", "portchannel": "Port-Channel5"}]},
"expected": {"result": "success"},
},
{
"name": "success-short-timeout",
"test": VerifyLACPInterfacesStatus,
"eos_data": [
{
"portChannels": {
"Port-Channel5": {
"interfaces": {
"Ethernet5": {
"actorPortStatus": "bundled",
"partnerPortState": {
"activity": True,
"timeout": True,
"aggregation": True,
"synchronization": True,
"collecting": True,
"distributing": True,
},
"actorPortState": {
"activity": True,
"timeout": True,
"aggregation": True,
"synchronization": True,
"collecting": True,
"distributing": True,
},
}
}
}
},
"interface": "Ethernet5",
"orphanPorts": {},
}
],
"inputs": {"interfaces": [{"name": "Ethernet5", "portchannel": "Port-Channel5", "lacp_rate_fast": True}]},
"expected": {"result": "success"},
},
{
"name": "failure-not-bundled",
"test": VerifyLACPInterfacesStatus,
@ -2500,7 +2568,7 @@ DATA: list[dict[str, Any]] = [
"inputs": {"interfaces": [{"name": "Ethernet5", "portchannel": "Po5"}]},
"expected": {
"result": "failure",
"messages": ["For Interface Ethernet5:\nExpected `bundled` as the local port status, but found `No Aggregate` instead.\n"],
"messages": ["Interface: Ethernet5 Port-Channel: Port-Channel5 - Not bundled - Port Status: No Aggregate"],
},
},
{
@ -2514,7 +2582,7 @@ DATA: list[dict[str, Any]] = [
"inputs": {"interfaces": [{"name": "Ethernet5", "portchannel": "Po 5"}]},
"expected": {
"result": "failure",
"messages": ["Interface 'Ethernet5' is not configured to be a member of LACP 'Port-Channel5'."],
"messages": ["Interface: Ethernet5 Port-Channel: Port-Channel5 - Not configured"],
},
},
{
@ -2555,13 +2623,55 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"For Interface Ethernet5:\n"
"Actor port details:\nExpected `True` as the activity, but found `False` instead."
"\nExpected `True` as the aggregation, but found `False` instead."
"\nExpected `True` as the synchronization, but found `False` instead."
"\nPartner port details:\nExpected `True` as the activity, but found `False` instead.\n"
"Expected `True` as the aggregation, but found `False` instead.\n"
"Expected `True` as the synchronization, but found `False` instead.\n"
"Interface: Ethernet5 Port-Channel: Port-Channel5 - Actor port details mismatch - Activity: False, Aggregation: False, "
"Synchronization: False, Collecting: True, Distributing: True, Timeout: False",
"Interface: Ethernet5 Port-Channel: Port-Channel5 - Partner port details mismatch - Activity: False, Aggregation: False, "
"Synchronization: False, Collecting: True, Distributing: True, Timeout: False",
],
},
},
{
"name": "failure-short-timeout",
"test": VerifyLACPInterfacesStatus,
"eos_data": [
{
"portChannels": {
"Port-Channel5": {
"interfaces": {
"Ethernet5": {
"actorPortStatus": "bundled",
"partnerPortState": {
"activity": True,
"timeout": False,
"aggregation": True,
"synchronization": True,
"collecting": True,
"distributing": True,
},
"actorPortState": {
"activity": True,
"timeout": False,
"aggregation": True,
"synchronization": True,
"collecting": True,
"distributing": True,
},
}
}
}
},
"interface": "Ethernet5",
"orphanPorts": {},
}
],
"inputs": {"interfaces": [{"name": "Ethernet5", "portchannel": "port-channel 5", "lacp_rate_fast": True}]},
"expected": {
"result": "failure",
"messages": [
"Interface: Ethernet5 Port-Channel: Port-Channel5 - Actor port details mismatch - Activity: True, Aggregation: True, "
"Synchronization: True, Collecting: True, Distributing: True, Timeout: False",
"Interface: Ethernet5 Port-Channel: Port-Channel5 - Partner port details mismatch - Activity: True, Aggregation: True, "
"Synchronization: True, Collecting: True, Distributing: True, Timeout: False",
],
},
},

View file

@ -1079,7 +1079,7 @@ DATA: list[dict[str, Any]] = [
},
]
},
"expected": {"result": "failure", "messages": ["No IPv4 security connection configured for peer `10.255.0.1`."]},
"expected": {"result": "failure", "messages": ["Peer: 10.255.0.1 VRF: default - Not configured"]},
},
{
"name": "failure-not-established",
@ -1127,14 +1127,10 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"Expected state of IPv4 security connection `source:172.18.3.2 destination:172.18.2.2 vrf:default` for peer `10.255.0.1` is `Established` "
"but found `Idle` instead.",
"Expected state of IPv4 security connection `source:100.64.2.2 destination:100.64.1.2 vrf:default` for peer `10.255.0.1` is `Established` "
"but found `Idle` instead.",
"Expected state of IPv4 security connection `source:100.64.2.2 destination:100.64.1.2 vrf:MGMT` for peer `10.255.0.2` is `Established` "
"but found `Idle` instead.",
"Expected state of IPv4 security connection `source:172.18.2.2 destination:172.18.1.2 vrf:MGMT` for peer `10.255.0.2` is `Established` "
"but found `Idle` instead.",
"Peer: 10.255.0.1 VRF: default Source: 172.18.3.2 Destination: 172.18.2.2 - Connection down - Expected: Established, Actual: Idle",
"Peer: 10.255.0.1 VRF: default Source: 100.64.2.2 Destination: 100.64.1.2 - Connection down - Expected: Established, Actual: Idle",
"Peer: 10.255.0.2 VRF: MGMT Source: 100.64.2.2 Destination: 100.64.1.2 - Connection down - Expected: Established, Actual: Idle",
"Peer: 10.255.0.2 VRF: MGMT Source: 172.18.2.2 Destination: 172.18.1.2 - Connection down - Expected: Established, Actual: Idle",
],
},
},
@ -1194,12 +1190,10 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"Expected state of IPv4 security connection `source:172.18.3.2 destination:172.18.2.2 vrf:default` for peer `10.255.0.1` is `Established` "
"but found `Idle` instead.",
"Expected state of IPv4 security connection `source:100.64.3.2 destination:100.64.2.2 vrf:default` for peer `10.255.0.1` is `Established` "
"but found `Idle` instead.",
"IPv4 security connection `source:100.64.4.2 destination:100.64.1.2 vrf:default` for peer `10.255.0.2` is not found.",
"IPv4 security connection `source:172.18.4.2 destination:172.18.1.2 vrf:default` for peer `10.255.0.2` is not found.",
"Peer: 10.255.0.1 VRF: default Source: 172.18.3.2 Destination: 172.18.2.2 - Connection down - Expected: Established, Actual: Idle",
"Peer: 10.255.0.1 VRF: default Source: 100.64.3.2 Destination: 100.64.2.2 - Connection down - Expected: Established, Actual: Idle",
"Peer: 10.255.0.2 VRF: default Source: 100.64.4.2 Destination: 100.64.1.2 - Connection not found.",
"Peer: 10.255.0.2 VRF: default Source: 172.18.4.2 Destination: 172.18.1.2 - Connection not found.",
],
},
},

View file

@ -59,30 +59,22 @@ DATA: list[dict[str, Any]] = [
"test": VerifyDNSServers,
"eos_data": [
{
"nameServerConfigs": [{"ipAddr": "10.14.0.1", "vrf": "default", "priority": 0}, {"ipAddr": "10.14.0.11", "vrf": "MGMT", "priority": 1}],
"nameServerConfigs": [
{"ipAddr": "10.14.0.1", "vrf": "default", "priority": 0},
{"ipAddr": "10.14.0.11", "vrf": "MGMT", "priority": 1},
{"ipAddr": "fd12:3456:789a::1", "vrf": "default", "priority": 0},
],
}
],
"inputs": {
"dns_servers": [{"server_address": "10.14.0.1", "vrf": "default", "priority": 0}, {"server_address": "10.14.0.11", "vrf": "MGMT", "priority": 1}]
"dns_servers": [
{"server_address": "10.14.0.1", "vrf": "default", "priority": 0},
{"server_address": "10.14.0.11", "vrf": "MGMT", "priority": 1},
{"server_address": "fd12:3456:789a::1", "vrf": "default", "priority": 0},
]
},
"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,
@ -96,7 +88,7 @@ DATA: list[dict[str, Any]] = [
},
"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."],
"messages": ["Server 10.14.0.10 (VRF: default, Priority: 0) - Not configured", "Server 10.14.0.21 (VRF: MGMT, Priority: 1) - Not configured"],
},
},
{
@ -117,9 +109,9 @@ DATA: list[dict[str, Any]] = [
"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.",
"Server 10.14.0.1 (VRF: CS, Priority: 0) - Incorrect priority - Priority: 1",
"Server 10.14.0.11 (VRF: default, Priority: 0) - Not configured",
"Server 10.14.0.110 (VRF: MGMT, Priority: 0) - Not configured",
],
},
},

View file

@ -7,13 +7,13 @@ from __future__ import annotations
from typing import Any
from anta.tests.stun import VerifyStunClient, VerifyStunServer
from anta.tests.stun import VerifyStunClientTranslation, VerifyStunServer
from tests.units.anta_tests import test
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyStunClient,
"test": VerifyStunClientTranslation,
"eos_data": [
{
"bindings": {
@ -60,7 +60,7 @@ DATA: list[dict[str, Any]] = [
},
{
"name": "failure-incorrect-public-ip",
"test": VerifyStunClient,
"test": VerifyStunClientTranslation,
"eos_data": [
{
"bindings": {
@ -88,14 +88,14 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"For STUN source `100.64.3.2:4500`:\nExpected `192.164.3.2` as the public ip, but found `192.64.3.2` instead.",
"For STUN source `172.18.3.2:4500`:\nExpected `192.118.3.2` as the public ip, but found `192.18.3.2` instead.",
"Client 100.64.3.2 Port: 4500 - Incorrect public-facing address - Expected: 192.164.3.2 Actual: 192.64.3.2",
"Client 172.18.3.2 Port: 4500 - Incorrect public-facing address - Expected: 192.118.3.2 Actual: 192.18.3.2",
],
},
},
{
"name": "failure-no-client",
"test": VerifyStunClient,
"test": VerifyStunClientTranslation,
"eos_data": [
{"bindings": {}},
{"bindings": {}},
@ -108,12 +108,12 @@ DATA: list[dict[str, Any]] = [
},
"expected": {
"result": "failure",
"messages": ["STUN client transaction for source `100.64.3.2:4500` is not found.", "STUN client transaction for source `172.18.3.2:4500` is not found."],
"messages": ["Client 100.64.3.2 Port: 4500 - STUN client translation not found.", "Client 172.18.3.2 Port: 4500 - STUN client translation not found."],
},
},
{
"name": "failure-incorrect-public-port",
"test": VerifyStunClient,
"test": VerifyStunClientTranslation,
"eos_data": [
{"bindings": {}},
{
@ -134,16 +134,15 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"STUN client transaction for source `100.64.3.2:4500` is not found.",
"For STUN source `172.18.3.2:4500`:\n"
"Expected `192.118.3.2` as the public ip, but found `192.18.3.2` instead.\n"
"Expected `6006` as the public port, but found `4800` instead.",
"Client 100.64.3.2 Port: 4500 - STUN client translation not found.",
"Client 172.18.3.2 Port: 4500 - Incorrect public-facing address - Expected: 192.118.3.2 Actual: 192.18.3.2",
"Client 172.18.3.2 Port: 4500 - Incorrect public-facing port - Expected: 6006 Actual: 4800",
],
},
},
{
"name": "failure-all-type",
"test": VerifyStunClient,
"test": VerifyStunClientTranslation,
"eos_data": [
{"bindings": {}},
{
@ -164,12 +163,9 @@ DATA: list[dict[str, Any]] = [
"expected": {
"result": "failure",
"messages": [
"STUN client transaction for source `100.64.3.2:4500` is not found.",
"For STUN source `172.18.4.2:4800`:\n"
"Expected `172.18.4.2` as the source ip, but found `172.18.3.2` instead.\n"
"Expected `4800` as the source port, but found `4500` instead.\n"
"Expected `192.118.3.2` as the public ip, but found `192.18.3.2` instead.\n"
"Expected `6006` as the public port, but found `4800` instead.",
"Client 100.64.3.2 Port: 4500 - STUN client translation not found.",
"Client 172.18.4.2 Port: 4800 - Incorrect public-facing address - Expected: 192.118.3.2 Actual: 192.18.3.2",
"Client 172.18.4.2 Port: 4800 - Incorrect public-facing port - Expected: 6006 Actual: 4800",
],
},
},

View file

@ -346,6 +346,39 @@ poll interval unknown
},
"expected": {"result": "success"},
},
{
"name": "success-ip-dns",
"test": VerifyNTPAssociations,
"eos_data": [
{
"peers": {
"1.1.1.1 (1.ntp.networks.com)": {
"condition": "sys.peer",
"peerIpAddr": "1.1.1.1",
"stratumLevel": 1,
},
"2.2.2.2 (2.ntp.networks.com)": {
"condition": "candidate",
"peerIpAddr": "2.2.2.2",
"stratumLevel": 2,
},
"3.3.3.3 (3.ntp.networks.com)": {
"condition": "candidate",
"peerIpAddr": "3.3.3.3",
"stratumLevel": 2,
},
}
}
],
"inputs": {
"ntp_servers": [
{"server_address": "1.1.1.1", "preferred": True, "stratum": 1},
{"server_address": "2.2.2.2", "stratum": 2},
{"server_address": "3.3.3.3", "stratum": 2},
]
},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyNTPAssociations,
@ -380,9 +413,9 @@ poll interval unknown
"expected": {
"result": "failure",
"messages": [
"For NTP peer 1.1.1.1:\nExpected `sys.peer` as the condition, but found `candidate` instead.\nExpected `1` as the stratum, but found `2` instead.\n"
"For NTP peer 2.2.2.2:\nExpected `candidate` as the condition, but found `sys.peer` instead.\n"
"For NTP peer 3.3.3.3:\nExpected `candidate` as the condition, but found `sys.peer` instead.\nExpected `2` as the stratum, but found `3` instead."
"1.1.1.1 (Preferred: True, Stratum: 1) - Bad association - Condition: candidate, Stratum: 2",
"2.2.2.2 (Preferred: False, Stratum: 2) - Bad association - Condition: sys.peer, Stratum: 2",
"3.3.3.3 (Preferred: False, Stratum: 2) - Bad association - Condition: sys.peer, Stratum: 3",
],
},
},
@ -399,7 +432,7 @@ poll interval unknown
},
"expected": {
"result": "failure",
"messages": ["None of NTP peers are not configured."],
"messages": ["No NTP peers configured"],
},
},
{
@ -430,7 +463,7 @@ poll interval unknown
},
"expected": {
"result": "failure",
"messages": ["NTP peer 3.3.3.3 is not configured."],
"messages": ["3.3.3.3 (Preferred: False, Stratum: 1) - Not configured"],
},
},
{
@ -457,8 +490,9 @@ poll interval unknown
"expected": {
"result": "failure",
"messages": [
"For NTP peer 1.1.1.1:\nExpected `sys.peer` as the condition, but found `candidate` instead.\n"
"NTP peer 2.2.2.2 is not configured.\nNTP peer 3.3.3.3 is not configured."
"1.1.1.1 (Preferred: True, Stratum: 1) - Bad association - Condition: candidate, Stratum: 1",
"2.2.2.2 (Preferred: False, Stratum: 1) - Not configured",
"3.3.3.3 (Preferred: False, Stratum: 1) - Not configured",
],
},
},