Adding upstream version 0.15.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 11:39:42 +01:00
parent 6721599912
commit a1777afd4b
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
103 changed files with 79620 additions and 742 deletions

View file

@ -30,6 +30,7 @@ DATA: list[dict[str, Any]] = [
"name": "success",
"test": VerifyBGPPeerCount,
"eos_data": [
# Need to order the output as the commands would be sorted after template rendering.
{
"vrfs": {
"default": {
@ -120,9 +121,10 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"address_families": [
# evpn first to make sure that the correct mapping output to input is kept.
{"afi": "evpn", "num_peers": 2},
{"afi": "ipv4", "safi": "unicast", "vrf": "default", "num_peers": 2},
{"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT", "num_peers": 1},
{"afi": "evpn", "num_peers": 2},
{"afi": "link-state", "num_peers": 2},
{"afi": "path-selection", "num_peers": 2},
]
@ -652,9 +654,10 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"address_families": [
# Path selection first to make sure input to output mapping is correct.
{"afi": "path-selection"},
{"afi": "ipv4", "safi": "unicast", "vrf": "default"},
{"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT"},
{"afi": "path-selection"},
{"afi": "link-state"},
]
},
@ -1081,6 +1084,8 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"address_families": [
# Path selection first to make sure input to output mapping is correct.
{"afi": "path-selection", "peers": ["10.1.255.20", "10.1.255.22"]},
{
"afi": "ipv4",
"safi": "unicast",
@ -1093,7 +1098,6 @@ DATA: list[dict[str, Any]] = [
"vrf": "MGMT",
"peers": ["10.1.255.10", "10.1.255.12"],
},
{"afi": "path-selection", "peers": ["10.1.255.20", "10.1.255.22"]},
{"afi": "link-state", "peers": ["10.1.255.30", "10.1.255.32"]},
]
},

View file

@ -0,0 +1,570 @@
# 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.isis import VerifyISISInterfaceMode, VerifyISISNeighborCount, VerifyISISNeighborState
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success only default vrf",
"test": VerifyISISNeighborState,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"neighbors": {
"0168.0000.0111": {
"adjacencies": [
{
"hostname": "s1-p01",
"circuitId": "83",
"interfaceName": "Ethernet1",
"state": "up",
"lastHelloTime": 1713688408,
"routerIdV4": "1.0.0.111",
}
]
},
"0168.0000.0112": {
"adjacencies": [
{
"hostname": "s1-p02",
"circuitId": "87",
"interfaceName": "Ethernet2",
"state": "up",
"lastHelloTime": 1713688405,
"routerIdV4": "1.0.0.112",
}
]
},
}
}
}
}
}
},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "success different vrfs",
"test": VerifyISISNeighborState,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"neighbors": {
"0168.0000.0111": {
"adjacencies": [
{
"hostname": "s1-p01",
"circuitId": "83",
"interfaceName": "Ethernet1",
"state": "up",
"lastHelloTime": 1713688408,
"routerIdV4": "1.0.0.111",
}
]
},
},
},
},
"customer": {
"isisInstances": {
"CORE-ISIS": {
"neighbors": {
"0168.0000.0112": {
"adjacencies": [
{
"hostname": "s1-p02",
"circuitId": "87",
"interfaceName": "Ethernet2",
"state": "up",
"lastHelloTime": 1713688405,
"routerIdV4": "1.0.0.112",
}
]
}
}
}
}
},
}
}
},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyISISNeighborState,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"neighbors": {
"0168.0000.0111": {
"adjacencies": [
{
"hostname": "s1-p01",
"circuitId": "83",
"interfaceName": "Ethernet1",
"state": "down",
"lastHelloTime": 1713688408,
"routerIdV4": "1.0.0.111",
}
]
},
"0168.0000.0112": {
"adjacencies": [
{
"hostname": "s1-p02",
"circuitId": "87",
"interfaceName": "Ethernet2",
"state": "up",
"lastHelloTime": 1713688405,
"routerIdV4": "1.0.0.112",
}
]
},
}
}
}
}
}
},
],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["Some neighbors are not in the correct state (UP): [{'vrf': 'default', 'instance': 'CORE-ISIS', 'neighbor': 's1-p01', 'state': 'down'}]."],
},
},
{
"name": "success only default vrf",
"test": VerifyISISNeighborCount,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"interfaces": {
"Loopback0": {
"enabled": True,
"intfLevels": {
"2": {
"ipv4Metric": 10,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"areaProxyBoundary": False,
},
"Ethernet1": {
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 1,
"linkId": "84",
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "link",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
"Ethernet2": {
"enabled": True,
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 1,
"linkId": "88",
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "link",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
}
}
}
}
}
},
],
"inputs": {
"interfaces": [
{"name": "Ethernet1", "level": 2, "count": 1},
{"name": "Ethernet2", "level": 2, "count": 1},
]
},
"expected": {"result": "success"},
},
{
"name": "success VerifyISISInterfaceMode only default vrf",
"test": VerifyISISInterfaceMode,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"interfaces": {
"Loopback0": {
"enabled": True,
"index": 2,
"snpa": "0:0:0:0:0:0",
"mtu": 65532,
"interfaceAddressFamily": "ipv4",
"interfaceType": "loopback",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"areaProxyBoundary": False,
},
"Ethernet1": {
"enabled": True,
"index": 132,
"snpa": "P2P",
"interfaceType": "point-to-point",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 1,
"linkId": "84",
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "link",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
"Ethernet2": {
"enabled": True,
"interfaceType": "broadcast",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 0,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
}
}
}
}
}
}
],
"inputs": {
"interfaces": [
{"name": "Loopback0", "mode": "passive"},
{"name": "Ethernet2", "mode": "passive"},
{"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
]
},
"expected": {"result": "success"},
},
{
"name": "failure VerifyISISInterfaceMode default vrf with interface not running passive mode",
"test": VerifyISISInterfaceMode,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"interfaces": {
"Loopback0": {
"enabled": True,
"index": 2,
"snpa": "0:0:0:0:0:0",
"mtu": 65532,
"interfaceAddressFamily": "ipv4",
"interfaceType": "loopback",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"areaProxyBoundary": False,
},
"Ethernet1": {
"enabled": True,
"index": 132,
"snpa": "P2P",
"interfaceType": "point-to-point",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 1,
"linkId": "84",
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "link",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
"Ethernet2": {
"enabled": True,
"interfaceType": "point-to-point",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 0,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
}
}
}
}
}
}
],
"inputs": {
"interfaces": [
{"name": "Loopback0", "mode": "passive"},
{"name": "Ethernet2", "mode": "passive"},
{"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
]
},
"expected": {
"result": "failure",
"messages": ["Interface Ethernet2 in VRF default is not running in passive mode"],
},
},
{
"name": "failure VerifyISISInterfaceMode default vrf with interface not running point-point mode",
"test": VerifyISISInterfaceMode,
"eos_data": [
{
"vrfs": {
"default": {
"isisInstances": {
"CORE-ISIS": {
"interfaces": {
"Loopback0": {
"enabled": True,
"index": 2,
"snpa": "0:0:0:0:0:0",
"mtu": 65532,
"interfaceAddressFamily": "ipv4",
"interfaceType": "loopback",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"areaProxyBoundary": False,
},
"Ethernet1": {
"enabled": True,
"index": 132,
"snpa": "P2P",
"interfaceType": "broadcast",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 1,
"linkId": "84",
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "link",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
"Ethernet2": {
"enabled": True,
"interfaceType": "broadcast",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 0,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
}
}
}
}
}
}
],
"inputs": {
"interfaces": [
{"name": "Loopback0", "mode": "passive"},
{"name": "Ethernet2", "mode": "passive"},
{"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
]
},
"expected": {
"result": "failure",
"messages": ["Interface Ethernet1 in VRF default is not running in point-to-point reporting broadcast"],
},
},
{
"name": "failure VerifyISISInterfaceMode default vrf with interface not running correct VRF mode",
"test": VerifyISISInterfaceMode,
"eos_data": [
{
"vrfs": {
"fake_vrf": {
"isisInstances": {
"CORE-ISIS": {
"interfaces": {
"Loopback0": {
"enabled": True,
"index": 2,
"snpa": "0:0:0:0:0:0",
"mtu": 65532,
"interfaceAddressFamily": "ipv4",
"interfaceType": "loopback",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"areaProxyBoundary": False,
},
"Ethernet1": {
"enabled": True,
"index": 132,
"snpa": "P2P",
"interfaceType": "point-to-point",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 1,
"linkId": "84",
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": False,
"v4Protection": "link",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
"Ethernet2": {
"enabled": True,
"interfaceType": "broadcast",
"intfLevels": {
"2": {
"ipv4Metric": 10,
"numAdjacencies": 0,
"sharedSecretProfile": "",
"isisAdjacencies": [],
"passive": True,
"v4Protection": "disabled",
"v6Protection": "disabled",
}
},
"interfaceSpeed": 1000,
"areaProxyBoundary": False,
},
}
}
}
}
}
}
],
"inputs": {
"interfaces": [
{"name": "Loopback0", "mode": "passive"},
{"name": "Ethernet2", "mode": "passive"},
{"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
]
},
"expected": {
"result": "failure",
"messages": [
"Interface Loopback0 not found in VRF default",
"Interface Ethernet2 not found in VRF default",
"Interface Ethernet1 not found in VRF default",
],
},
},
]

View file

@ -271,6 +271,18 @@ DATA: list[dict[str, Any]] = [
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "success"},
},
{
"name": "success-skipping-exec",
"test": VerifyAuthzMethods,
"eos_data": [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group tacacs+", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group tacacs+", "local"]}},
},
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands"]},
"expected": {"result": "success"},
},
{
"name": "failure-commands",
"test": VerifyAuthzMethods,

View file

@ -0,0 +1,581 @@
# 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.avt.py."""
from __future__ import annotations
from typing import Any
from anta.tests.avt import VerifyAVTPathHealth, VerifyAVTRole, VerifyAVTSpecificPath
from tests.lib.anta import test # noqa: F401; pylint: disable=unused-import
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyAVTPathHealth,
"eos_data": [
{
"vrfs": {
"data": {
"avts": {
"DATA-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
}
}
},
"guest": {
"avts": {
"GUEST-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
}
}
},
"default": {
"avts": {
"CONTROL-PLANE-PROFILE": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
},
"DEFAULT-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
},
}
},
}
}
],
"inputs": {},
"expected": {"result": "success"},
},
{
"name": "failure-avt-not-configured",
"test": VerifyAVTPathHealth,
"eos_data": [{"vrfs": {}}],
"inputs": {},
"expected": {
"result": "failure",
"messages": ["Adaptive virtual topology paths are not configured."],
},
},
{
"name": "failure-not-active-path",
"test": VerifyAVTPathHealth,
"eos_data": [
{
"vrfs": {
"data": {
"avts": {
"DATA-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
}
}
},
"guest": {
"avts": {
"GUEST-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": False},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
}
}
},
"default": {
"avts": {
"CONTROL-PLANE-PROFILE": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": False},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
},
"DEFAULT-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": False},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
},
}
},
}
}
],
"inputs": {},
"expected": {
"result": "failure",
"messages": [
"AVT path direct:10 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is not active.",
"AVT path direct:1 for profile CONTROL-PLANE-PROFILE in VRF default is not active.",
"AVT path direct:10 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is not active.",
],
},
},
{
"name": "failure-invalid-path",
"test": VerifyAVTPathHealth,
"eos_data": [
{
"vrfs": {
"data": {
"avts": {
"DATA-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": False, "active": True},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
}
}
},
"guest": {
"avts": {
"GUEST-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": False, "active": True},
},
}
}
}
},
"default": {
"avts": {
"CONTROL-PLANE-PROFILE": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": False, "active": True},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
},
"DEFAULT-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": False, "active": True},
},
}
},
}
},
}
}
],
"inputs": {},
"expected": {
"result": "failure",
"messages": [
"AVT path direct:10 for profile DATA-AVT-POLICY-DEFAULT in VRF data is invalid.",
"AVT path direct:8 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is invalid.",
"AVT path direct:10 for profile CONTROL-PLANE-PROFILE in VRF default is invalid.",
"AVT path direct:8 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is invalid.",
],
},
},
{
"name": "failure-not-active-and-invalid",
"test": VerifyAVTPathHealth,
"eos_data": [
{
"vrfs": {
"data": {
"avts": {
"DATA-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": False, "active": False},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": False},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
}
}
},
"guest": {
"avts": {
"GUEST-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": False, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": False, "active": False},
},
}
}
}
},
"default": {
"avts": {
"CONTROL-PLANE-PROFILE": {
"avtPaths": {
"direct:9": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:10": {
"flags": {"directPath": True, "valid": False, "active": False},
},
"direct:1": {
"flags": {"directPath": True, "valid": True, "active": True},
},
"direct:8": {
"flags": {"directPath": True, "valid": True, "active": True},
},
}
},
"DEFAULT-AVT-POLICY-DEFAULT": {
"avtPaths": {
"direct:10": {
"flags": {"directPath": True, "valid": True, "active": False},
},
"direct:8": {
"flags": {"directPath": True, "valid": False, "active": False},
},
}
},
}
},
}
}
],
"inputs": {},
"expected": {
"result": "failure",
"messages": [
"AVT path direct:10 for profile DATA-AVT-POLICY-DEFAULT in VRF data is invalid and not active.",
"AVT path direct:1 for profile DATA-AVT-POLICY-DEFAULT in VRF data is not active.",
"AVT path direct:10 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is invalid.",
"AVT path direct:8 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is invalid and not active.",
"AVT path direct:10 for profile CONTROL-PLANE-PROFILE in VRF default is invalid and not active.",
"AVT path direct:10 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is not active.",
"AVT path direct:8 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is invalid and not active.",
],
},
},
{
"name": "success",
"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"},
"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"},
}
}
}
}
}
},
{
"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"},
}
}
}
}
}
},
{
"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"},
}
}
}
}
}
},
],
"inputs": {
"avt_paths": [
{"avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE", "destination": "10.101.255.2", "next_hop": "10.101.255.1", "path_type": "multihop"},
{"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.2", "path_type": "direct"},
{"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.2"},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-no-peer",
"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": [
{"avt_name": "MGMT-AVT-POLICY-DEFAULT", "vrf": "default", "destination": "10.101.255.2", "next_hop": "10.101.255.1", "path_type": "multihop"},
{"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.2", "path_type": "multihop"},
]
},
"expected": {
"result": "failure",
"messages": ["AVT configuration for peer '10.101.255.2' under topology 'MGMT-AVT-POLICY-DEFAULT' in VRF 'default' is not found."],
},
},
{
"name": "failure-no-path-with-correct-next-hop",
"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.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"},
}
}
}
}
}
},
{
"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": [
{
"avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE",
"vrf": "default",
"destination": "10.101.255.2",
"next_hop": "10.101.255.11",
"path_type": "multihop",
},
{"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.21", "path_type": "direct"},
]
},
"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'.",
],
},
},
{
"name": "failure-incorrect-path",
"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.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"},
}
}
}
}
}
},
{
"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"},
}
}
}
}
}
},
],
"inputs": {
"avt_paths": [
{
"avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE",
"vrf": "default",
"destination": "10.101.255.2",
"next_hop": "10.101.255.1",
"path_type": "multihop",
},
{"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.1", "path_type": "direct"},
]
},
"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.",
],
},
},
{
"name": "success",
"test": VerifyAVTRole,
"eos_data": [{"role": "edge"}],
"inputs": {"role": "edge"},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-role",
"test": VerifyAVTRole,
"eos_data": [{"role": "transit"}],
"inputs": {"role": "edge"},
"expected": {"result": "failure", "messages": ["Expected AVT role as `edge`, but found `transit` instead."]},
},
]

View file

@ -7,7 +7,7 @@ from __future__ import annotations
from typing import Any
from anta.tests.configuration import VerifyRunningConfigDiffs, VerifyZeroTouch
from anta.tests.configuration import VerifyRunningConfigDiffs, VerifyRunningConfigLines, VerifyZeroTouch
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
@ -32,5 +32,42 @@ DATA: list[dict[str, Any]] = [
"inputs": None,
"expected": {"result": "success"},
},
{"name": "failure", "test": VerifyRunningConfigDiffs, "eos_data": ["blah blah"], "inputs": None, "expected": {"result": "failure", "messages": ["blah blah"]}},
{
"name": "failure",
"test": VerifyRunningConfigDiffs,
"eos_data": ["blah blah"],
"inputs": None,
"expected": {"result": "failure", "messages": ["blah blah"]},
},
{
"name": "success",
"test": VerifyRunningConfigLines,
"eos_data": ["blah blah"],
"inputs": {"regex_patterns": ["blah"]},
"expected": {"result": "success"},
},
{
"name": "success",
"test": VerifyRunningConfigLines,
"eos_data": ["enable password something\nsome other line"],
"inputs": {"regex_patterns": ["^enable password .*$", "^.*other line$"]},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyRunningConfigLines,
"eos_data": ["enable password something\nsome other line"],
"inputs": {"regex_patterns": ["bla", "bleh"]},
"expected": {"result": "failure", "messages": ["Following patterns were not found: 'bla','bleh'"]},
},
{
"name": "failure-invalid-regex",
"test": VerifyRunningConfigLines,
"eos_data": ["enable password something\nsome other line"],
"inputs": {"regex_patterns": ["["]},
"expected": {
"result": "error",
"messages": ["1 validation error for Input\nregex_patterns.0\n Value error, Invalid regex: unterminated character set at position 0"],
},
},
]

View file

@ -21,7 +21,7 @@ DATA: list[dict[str, Any]] = [
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}, {"name": "NotAboot", "version": "Aboot-veos-8.0.0-3255441"}],
},
},
],
@ -128,6 +128,26 @@ DATA: list[dict[str, Any]] = [
"messages": ["device is not impacted by FN044"],
},
},
{
"name": "failure-no-aboot-component",
"test": VerifyFieldNotice44Resolution,
"eos_data": [
{
"imageFormatVersion": "1.0",
"uptime": 1109144.35,
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
"components": [{"name": "NotAboot", "version": "Aboot-veos-4.0.1-3255441"}],
},
},
],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["Aboot component not found"],
},
},
{
"name": "success-JPE",
"test": VerifyFieldNotice72Resolution,

View file

@ -1,7 +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.
"""Test inputs for anta.tests.hardware."""
"""Test inputs for anta.tests.interfaces."""
# pylint: disable=C0302
from __future__ import annotations
@ -14,6 +14,7 @@ from anta.tests.interfaces import (
VerifyInterfaceErrDisabled,
VerifyInterfaceErrors,
VerifyInterfaceIPv4,
VerifyInterfacesSpeed,
VerifyInterfacesStatus,
VerifyInterfaceUtilization,
VerifyIPProxyARP,
@ -1354,6 +1355,14 @@ DATA: list[dict[str, Any]] = [
"lineProtocolStatus": "up",
"mtu": 65535,
},
# Checking not loopbacks are skipped
"Ethernet666": {
"name": "Ethernet666",
"interfaceStatus": "connected",
"interfaceAddress": {"ipAddr": {"maskLen": 32, "address": "6.6.6.6"}},
"ipv4Routable240": False,
"lineProtocolStatus": "up",
},
},
},
],
@ -1733,7 +1742,7 @@ DATA: list[dict[str, Any]] = [
},
},
],
"inputs": {"mtu": 9214},
"inputs": {"mtu": 9214, "ignored_interfaces": ["Loopback", "Port-Channel", "Management", "Vxlan"], "specific_mtu": [{"Ethernet10": 9214}]},
"expected": {"result": "success"},
},
{
@ -2157,4 +2166,279 @@ DATA: list[dict[str, Any]] = [
"inputs": {"mac_address": "00:1c:73:00:dc:01"},
"expected": {"result": "failure", "messages": ["IP virtual router MAC address `00:1c:73:00:dc:01` is not configured."]},
},
{
"name": "success",
"test": VerifyInterfacesSpeed,
"eos_data": [
{
"interfaces": {
"Ethernet1": {
"bandwidth": 1000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 2,
},
"Ethernet1/1/2": {
"bandwidth": 1000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 2,
},
"Ethernet3": {
"bandwidth": 100000000000,
"autoNegotiate": "success",
"duplex": "duplexFull",
"lanes": 8,
},
"Ethernet4": {
"bandwidth": 2500000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 8,
},
}
}
],
"inputs": {
"interfaces": [
{"name": "Ethernet1", "auto": False, "speed": 1},
{"name": "Ethernet1", "auto": False, "speed": 1, "lanes": 2},
{"name": "Ethernet1/1/2", "auto": False, "speed": 1},
{"name": "Ethernet3", "auto": True, "speed": 100},
{"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
{"name": "Ethernet3", "auto": True, "speed": 100},
{"name": "Ethernet4", "auto": False, "speed": 2.5},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-speed",
"test": VerifyInterfacesSpeed,
"eos_data": [
{
"interfaces": {
"Ethernet1": {
"bandwidth": 100000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 2,
},
"Ethernet1/1/1": {
"bandwidth": 100000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 2,
},
"Ethernet3": {
"bandwidth": 10000000000,
"autoNegotiate": "success",
"duplex": "duplexFull",
"lanes": 8,
},
"Ethernet4": {
"bandwidth": 25000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 8,
},
}
}
],
"inputs": {
"interfaces": [
{"name": "Ethernet1", "auto": False, "speed": 1},
{"name": "Ethernet1/1/1", "auto": False, "speed": 1},
{"name": "Ethernet3", "auto": True, "speed": 100},
{"name": "Ethernet4", "auto": False, "speed": 2.5},
]
},
"expected": {
"result": "failure",
"messages": [
"For interface Ethernet1:\nExpected `1Gbps` as the speed, but found `100Gbps` instead.",
"For interface Ethernet1/1/1:\nExpected `1Gbps` as the speed, but found `100Gbps` instead.",
"For interface Ethernet3:\nExpected `100Gbps` as the speed, but found `10Gbps` instead.",
"For interface Ethernet4:\nExpected `2.5Gbps` as the speed, but found `25Gbps` instead.",
],
},
},
{
"name": "failure-incorrect-mode",
"test": VerifyInterfacesSpeed,
"eos_data": [
{
"interfaces": {
"Ethernet1": {
"bandwidth": 1000000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 2,
},
"Ethernet1/2/2": {
"bandwidth": 1000000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 2,
},
"Ethernet3": {
"bandwidth": 100000000000,
"autoNegotiate": "success",
"duplex": "duplexHalf",
"lanes": 8,
},
"Ethernet4": {
"bandwidth": 2500000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 8,
},
}
}
],
"inputs": {
"interfaces": [
{"name": "Ethernet1", "auto": False, "speed": 1},
{"name": "Ethernet1/2/2", "auto": False, "speed": 1},
{"name": "Ethernet3", "auto": True, "speed": 100},
{"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
{"name": "Ethernet4", "auto": False, "speed": 2.5},
]
},
"expected": {
"result": "failure",
"messages": [
"For interface Ethernet1:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
"For interface Ethernet1/2/2:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
"For interface Ethernet3:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
"For interface Ethernet3:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
"For interface Ethernet4:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
],
},
},
{
"name": "failure-incorrect-lane",
"test": VerifyInterfacesSpeed,
"eos_data": [
{
"interfaces": {
"Ethernet1": {
"bandwidth": 1000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 4,
},
"Ethernet2": {
"bandwidth": 10000000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 4,
},
"Ethernet3": {
"bandwidth": 100000000000,
"autoNegotiate": "success",
"duplex": "duplexFull",
"lanes": 4,
},
"Ethernet4": {
"bandwidth": 2500000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 6,
},
"Ethernet4/1/1": {
"bandwidth": 2500000000,
"autoNegotiate": "unknown",
"duplex": "duplexFull",
"lanes": 6,
},
}
}
],
"inputs": {
"interfaces": [
{"name": "Ethernet1", "auto": False, "speed": 1, "lanes": 2},
{"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
{"name": "Ethernet4", "auto": False, "speed": 2.5, "lanes": 4},
{"name": "Ethernet4/1/1", "auto": False, "speed": 2.5, "lanes": 4},
]
},
"expected": {
"result": "failure",
"messages": [
"For interface Ethernet1:\nExpected `2` as the lanes, but found `4` instead.",
"For interface Ethernet3:\nExpected `8` as the lanes, but found `4` instead.",
"For interface Ethernet4:\nExpected `4` as the lanes, but found `6` instead.",
"For interface Ethernet4/1/1:\nExpected `4` as the lanes, but found `6` instead.",
],
},
},
{
"name": "failure-all-type",
"test": VerifyInterfacesSpeed,
"eos_data": [
{
"interfaces": {
"Ethernet1": {
"bandwidth": 10000000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 4,
},
"Ethernet2/1/2": {
"bandwidth": 1000000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 2,
},
"Ethernet3": {
"bandwidth": 10000000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 6,
},
"Ethernet4": {
"bandwidth": 25000000000,
"autoNegotiate": "unknown",
"duplex": "duplexHalf",
"lanes": 4,
},
}
}
],
"inputs": {
"interfaces": [
{"name": "Ethernet1", "auto": False, "speed": 1},
{"name": "Ethernet1", "auto": False, "speed": 1, "lanes": 2},
{"name": "Ethernet2/1/2", "auto": False, "speed": 10},
{"name": "Ethernet3", "auto": True, "speed": 1},
{"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
{"name": "Ethernet3", "auto": True, "speed": 100},
{"name": "Ethernet4", "auto": False, "speed": 2.5},
]
},
"expected": {
"result": "failure",
"messages": [
"For interface Ethernet1:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
"Expected `1Gbps` as the speed, but found `10Gbps` instead.",
"For interface Ethernet1:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
"Expected `1Gbps` as the speed, but found `10Gbps` instead.\n"
"Expected `2` as the lanes, but found `4` instead.",
"For interface Ethernet2/1/2:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
"Expected `10Gbps` as the speed, but found `1Gbps` instead.",
"For interface Ethernet3:\nExpected `success` as the auto negotiation, but found `unknown` instead.\n"
"Expected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
"For interface Ethernet3:\nExpected `success` as the auto negotiation, but found `unknown` instead.\n"
"Expected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
"Expected `100Gbps` as the speed, but found `10Gbps` instead.\n"
"Expected `8` as the lanes, but found `6` instead.",
"For interface Ethernet3:\nExpected `success` as the auto negotiation, but found `unknown` instead.\n"
"Expected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
"Expected `100Gbps` as the speed, but found `10Gbps` instead.",
"For interface Ethernet4:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
"Expected `2.5Gbps` as the speed, but found `25Gbps` instead.",
],
},
},
]

View file

@ -206,7 +206,9 @@ DATA: list[dict[str, Any]] = [
"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",
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingTimestamp validation\n"
"2023-05-10T15:42:44.680813-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Other log\n",
],
"inputs": None,
"expected": {"result": "success"},
@ -222,6 +224,16 @@ DATA: list[dict[str, Any]] = [
"inputs": None,
"expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
},
{
"name": "failure-no-matching-log",
"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): BLAH\n",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
},
{
"name": "success",
"test": VerifyLoggingAccounting,

View file

@ -0,0 +1,327 @@
# 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.path_selection.py."""
from __future__ import annotations
from typing import Any
from anta.tests.path_selection import VerifyPathsHealth, VerifySpecificPath
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
"test": VerifyPathsHealth,
"eos_data": [
{
"dpsPeers": {
"10.255.0.1": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path3": {"state": "routeResolved", "dpsSessions": {"0": {"active": True}}},
},
},
"mpls": {
"dpsPaths": {
"path4": {"state": "ipsecEstablished", "dpsSessions": {"0": {"active": True}}},
},
},
},
},
"10.255.0.2": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path1": {"state": "ipsecEstablished", "dpsSessions": {"0": {"active": True}}},
},
},
"mpls": {
"dpsPaths": {
"path2": {"state": "routeResolved", "dpsSessions": {"0": {"active": True}}},
},
},
},
},
}
},
],
"inputs": {},
"expected": {"result": "success"},
},
{
"name": "failure-no-peer",
"test": VerifyPathsHealth,
"eos_data": [
{"dpsPeers": {}},
],
"inputs": {},
"expected": {"result": "failure", "messages": ["No path configured for router path-selection."]},
},
{
"name": "failure-not-established",
"test": VerifyPathsHealth,
"eos_data": [
{
"dpsPeers": {
"10.255.0.1": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path3": {"state": "ipsecPending", "dpsSessions": {"0": {"active": False}}},
},
},
"mpls": {
"dpsPaths": {
"path4": {"state": "ipsecPending", "dpsSessions": {"0": {"active": False}}},
},
},
},
},
"10.255.0.2": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path1": {"state": "ipsecEstablished", "dpsSessions": {"0": {"active": True}}},
},
},
"mpls": {
"dpsPaths": {
"path2": {"state": "ipsecPending", "dpsSessions": {"0": {"active": False}}},
},
},
},
},
}
},
],
"inputs": {},
"expected": {
"result": "failure",
"messages": [
"Path state for peer 10.255.0.1 in path-group internet is `ipsecPending`.",
"Path state for peer 10.255.0.1 in path-group mpls is `ipsecPending`.",
"Path state for peer 10.255.0.2 in path-group mpls is `ipsecPending`.",
],
},
},
{
"name": "failure-inactive",
"test": VerifyPathsHealth,
"eos_data": [
{
"dpsPeers": {
"10.255.0.1": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path3": {"state": "routeResolved", "dpsSessions": {"0": {"active": False}}},
},
},
"mpls": {
"dpsPaths": {
"path4": {"state": "routeResolved", "dpsSessions": {"0": {"active": False}}},
},
},
},
},
"10.255.0.2": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path1": {"state": "routeResolved", "dpsSessions": {"0": {"active": True}}},
},
},
"mpls": {
"dpsPaths": {
"path2": {"state": "routeResolved", "dpsSessions": {"0": {"active": False}}},
},
},
},
},
}
},
],
"inputs": {},
"expected": {
"result": "failure",
"messages": [
"Telemetry state for peer 10.255.0.1 in path-group internet is `inactive`.",
"Telemetry state for peer 10.255.0.1 in path-group mpls is `inactive`.",
"Telemetry state for peer 10.255.0.2 in path-group mpls is `inactive`.",
],
},
},
{
"name": "success",
"test": VerifySpecificPath,
"eos_data": [
{
"dpsPeers": {
"10.255.0.1": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path3": {
"state": "ipsecEstablished",
"source": "172.18.13.2",
"destination": "172.18.15.2",
"dpsSessions": {"0": {"active": True}},
}
}
}
}
}
}
},
{
"dpsPeers": {
"10.255.0.2": {
"dpsGroups": {
"mpls": {
"dpsPaths": {
"path2": {
"state": "ipsecEstablished",
"source": "172.18.3.2",
"destination": "172.18.5.2",
"dpsSessions": {"0": {"active": True}},
}
}
}
}
}
}
},
],
"inputs": {
"paths": [
{"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
{"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-no-peer",
"test": VerifySpecificPath,
"eos_data": [
{"dpsPeers": {}},
{"dpsPeers": {}},
],
"inputs": {
"paths": [
{"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
{"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
]
},
"expected": {
"result": "failure",
"messages": [
"Path `peer: 10.255.0.1 source: 172.18.3.2 destination: 172.18.5.2` is not configured for path-group `internet`.",
"Path `peer: 10.255.0.2 source: 172.18.13.2 destination: 172.18.15.2` is not configured for path-group `mpls`.",
],
},
},
{
"name": "failure-not-established",
"test": VerifySpecificPath,
"eos_data": [
{
"dpsPeers": {
"10.255.0.1": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path3": {"state": "ipsecPending", "source": "172.18.3.2", "destination": "172.18.5.2", "dpsSessions": {"0": {"active": True}}}
}
}
}
}
}
},
{
"dpsPeers": {
"10.255.0.2": {
"dpsGroups": {
"mpls": {
"dpsPaths": {
"path4": {
"state": "ipsecPending",
"source": "172.18.13.2",
"destination": "172.18.15.2",
"dpsSessions": {"0": {"active": False}},
}
}
}
}
}
}
},
],
"inputs": {
"paths": [
{"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
{"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
]
},
"expected": {
"result": "failure",
"messages": [
"Path state for `peer: 10.255.0.1 source: 172.18.3.2 destination: 172.18.5.2` in path-group internet is `ipsecPending`.",
"Path state for `peer: 10.255.0.2 source: 172.18.13.2 destination: 172.18.15.2` in path-group mpls is `ipsecPending`.",
],
},
},
{
"name": "failure-inactive",
"test": VerifySpecificPath,
"eos_data": [
{
"dpsPeers": {
"10.255.0.1": {
"dpsGroups": {
"internet": {
"dpsPaths": {
"path3": {"state": "routeResolved", "source": "172.18.3.2", "destination": "172.18.5.2", "dpsSessions": {"0": {"active": False}}}
}
}
}
}
}
},
{
"dpsPeers": {
"10.255.0.2": {
"dpsGroups": {
"mpls": {
"dpsPaths": {
"path4": {
"state": "routeResolved",
"source": "172.18.13.2",
"destination": "172.18.15.2",
"dpsSessions": {"0": {"active": False}},
}
}
}
}
}
}
},
],
"inputs": {
"paths": [
{"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
{"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
]
},
"expected": {
"result": "failure",
"messages": [
"Telemetry state for path `peer: 10.255.0.1 source: 172.18.3.2 destination: 172.18.5.2` in path-group internet is `inactive`.",
"Telemetry state for path `peer: 10.255.0.2 source: 172.18.13.2 destination: 172.18.15.2` in path-group mpls is `inactive`.",
],
},
},
]

View file

@ -42,11 +42,11 @@ DATA: list[dict[str, Any]] = [
"expected": {"result": "failure", "messages": ["The device is not configured as a PTP Boundary Clock: 'ptpDisabled'"]},
},
{
"name": "error",
"name": "skipped",
"test": VerifyPtpModeStatus,
"eos_data": [{"ptpIntfSummaries": {}}],
"inputs": None,
"expected": {"result": "error", "messages": ["'ptpMode' variable is not present in the command output"]},
"expected": {"result": "skipped", "messages": ["PTP is not configured"]},
},
{
"name": "success",
@ -104,11 +104,11 @@ DATA: list[dict[str, Any]] = [
},
},
{
"name": "error",
"name": "skipped",
"test": VerifyPtpGMStatus,
"eos_data": [{"ptpIntfSummaries": {}}],
"inputs": {"gmid": "0xec:46:70:ff:fe:00:ff:a8"},
"expected": {"result": "error", "messages": ["'ptpClockSummary' variable is not present in the command output"]},
"expected": {"result": "skipped", "messages": ["PTP is not configured"]},
},
{
"name": "success",
@ -161,14 +161,14 @@ DATA: list[dict[str, Any]] = [
"expected": {"result": "failure", "messages": ["The device lock is more than 60s old: 157s"]},
},
{
"name": "error",
"name": "skipped",
"test": VerifyPtpLockStatus,
"eos_data": [{"ptpIntfSummaries": {}}],
"inputs": None,
"expected": {
"result": "error",
"result": "skipped",
"messages": [
"'ptpClockSummary' variable is not present in the command output",
"PTP is not configured",
],
},
},

View file

@ -34,7 +34,14 @@ DATA: list[dict[str, Any]] = [
"expected": {"result": "success"},
},
{
"name": "failure",
"name": "error-missing-ssh-status",
"test": VerifySSHStatus,
"eos_data": ["SSH per host connection limit is 20\nFIPS status: disabled\n\n"],
"inputs": None,
"expected": {"result": "error", "messages": ["Could not find SSH status in returned output."]},
},
{
"name": "failure-ssh-disabled",
"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,
@ -573,6 +580,40 @@ DATA: list[dict[str, Any]] = [
],
},
},
{
"name": "error-wrong-input-rsa",
"test": VerifyAPISSLCertificate,
"eos_data": [],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_ROOT_CA.crt",
"expiry_threshold": 30,
"common_name": "Arista Networks Internal IT Root Cert Authority",
"encryption_algorithm": "RSA",
"key_size": 256,
},
]
},
"expected": {"result": "error", "messages": ["Allowed sizes are (2048, 3072, 4096)."]},
},
{
"name": "error-wrong-input-ecdsa",
"test": VerifyAPISSLCertificate,
"eos_data": [],
"inputs": {
"certificates": [
{
"certificate_name": "ARISTA_SIGNING_CA.crt",
"expiry_threshold": 30,
"common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
"encryption_algorithm": "ECDSA",
"key_size": 2048,
},
]
},
"expected": {"result": "error", "messages": ["Allowed sizes are (256, 384, 512)."]},
},
{
"name": "success",
"test": VerifyBannerLogin,

View file

@ -127,10 +127,12 @@ DATA: list[dict[str, Any]] = [
"name": "success",
"test": VerifyErrdisableRecovery,
"eos_data": [
# Adding empty line on purpose to verify they are skipped
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Enabled 300
bpduguard Enabled 300
arp-inspection Enabled 30
"""

View file

@ -79,6 +79,7 @@ DATA: list[dict[str, Any]] = [
"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']"]},
},
# TODO: add a test with a real extension?
{
"name": "success-no-extensions",
"test": VerifyEOSExtensions,
@ -89,6 +90,16 @@ DATA: list[dict[str, Any]] = [
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "success-empty-extension",
"test": VerifyEOSExtensions,
"eos_data": [
{"extensions": {}, "extensionStoredDir": "flash:", "warnings": ["No extensions are available"]},
{"extensions": [""]},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyEOSExtensions,