Merging upstream version 1.3.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
5b922100c9
commit
8a6a3342fc
337 changed files with 16571 additions and 4891 deletions
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models module."""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Test for anta.input_models.routing submodule."""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.routing.bgp.py."""
|
||||
|
@ -6,24 +6,29 @@
|
|||
# pylint: disable=C0302
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.input_models.routing.bgp import BgpAddressFamily, BgpPeer
|
||||
from anta.input_models.routing.bgp import AddressFamilyConfig, BgpAddressFamily, BgpPeer, BgpRoute, RedistributedRouteConfig
|
||||
from anta.tests.routing.bgp import (
|
||||
VerifyBGPExchangedRoutes,
|
||||
VerifyBGPNlriAcceptance,
|
||||
VerifyBGPPeerCount,
|
||||
VerifyBGPPeerGroup,
|
||||
VerifyBGPPeerMPCaps,
|
||||
VerifyBGPPeerRouteLimit,
|
||||
VerifyBGPPeerTtlMultiHops,
|
||||
VerifyBGPRouteECMP,
|
||||
VerifyBgpRouteMaps,
|
||||
VerifyBGPRoutePaths,
|
||||
VerifyBGPSpecificPeers,
|
||||
VerifyBGPTimers,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.custom_types import Afi, Safi
|
||||
from anta.custom_types import Afi, RedistributedAfiSafi, RedistributedProtocol, Safi
|
||||
|
||||
|
||||
class TestBgpAddressFamily:
|
||||
|
@ -116,6 +121,7 @@ class TestVerifyBGPExchangedRoutesInput:
|
|||
[{"peer_address": "172.30.255.5", "vrf": "default", "advertised_routes": ["192.0.254.5/32"], "received_routes": ["192.0.255.4/32"]}],
|
||||
id="valid_both_received_advertised",
|
||||
),
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "advertised_routes": ["192.0.254.5/32"]}], id="valid_advertised_routes"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
|
@ -126,8 +132,6 @@ class TestVerifyBGPExchangedRoutesInput:
|
|||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default"}], id="invalid"),
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "advertised_routes": ["192.0.254.5/32"]}], id="invalid_received_route"),
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "received_routes": ["192.0.254.5/32"]}], id="invalid_advertised_route"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
|
@ -236,3 +240,271 @@ class TestVerifyBGPPeerRouteLimitInput:
|
|||
"""Test VerifyBGPPeerRouteLimit.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBGPPeerRouteLimit.Input(bgp_peers=bgp_peers)
|
||||
|
||||
|
||||
class TestVerifyBGPPeerGroupInput:
|
||||
"""Test anta.tests.routing.bgp.VerifyBGPPeerGroup.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "peer_group": "IPv4-UNDERLAY-PEERS"}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
"""Test VerifyBGPPeerGroup.Input valid inputs."""
|
||||
VerifyBGPPeerGroup.Input(bgp_peers=bgp_peers)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
"""Test VerifyBGPPeerGroup.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBGPPeerGroup.Input(bgp_peers=bgp_peers)
|
||||
|
||||
|
||||
class TestVerifyBGPNlriAcceptanceInput:
|
||||
"""Test anta.tests.routing.bgp.VerifyBGPNlriAcceptance.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "capabilities": ["ipv4Unicast"]}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
"""Test VerifyBGPNlriAcceptance.Input valid inputs."""
|
||||
VerifyBGPNlriAcceptance.Input(bgp_peers=bgp_peers)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
"""Test VerifyBGPNlriAcceptance.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBGPNlriAcceptance.Input(bgp_peers=bgp_peers)
|
||||
|
||||
|
||||
class TestVerifyBGPRouteECMPInput:
|
||||
"""Test anta.tests.routing.bgp.VerifyBGPRouteECMP.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_routes"),
|
||||
[
|
||||
pytest.param([{"prefix": "10.100.0.128/31", "vrf": "default", "ecmp_count": 2}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bgp_routes: list[BgpRoute]) -> None:
|
||||
"""Test VerifyBGPRouteECMP.Input valid inputs."""
|
||||
VerifyBGPRouteECMP.Input(route_entries=bgp_routes)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_routes"),
|
||||
[
|
||||
pytest.param([{"prefix": "10.100.0.128/31", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bgp_routes: list[BgpRoute]) -> None:
|
||||
"""Test VerifyBGPRouteECMP.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBGPRouteECMP.Input(route_entries=bgp_routes)
|
||||
|
||||
|
||||
class TestVerifyBGPRoutePathsInput:
|
||||
"""Test anta.tests.routing.bgp.VerifyBGPRoutePaths.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("route_entries"),
|
||||
[
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"prefix": "10.100.0.128/31",
|
||||
"vrf": "default",
|
||||
"paths": [{"nexthop": "10.100.0.10", "origin": "Igp"}, {"nexthop": "10.100.4.5", "origin": "Incomplete"}],
|
||||
}
|
||||
],
|
||||
id="valid",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_valid(self, route_entries: list[BgpRoute]) -> None:
|
||||
"""Test VerifyBGPRoutePaths.Input valid inputs."""
|
||||
VerifyBGPRoutePaths.Input(route_entries=route_entries)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("route_entries"),
|
||||
[
|
||||
pytest.param([{"prefix": "10.100.0.128/31", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, route_entries: list[BgpRoute]) -> None:
|
||||
"""Test VerifyBGPRoutePaths.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBGPRoutePaths.Input(route_entries=route_entries)
|
||||
|
||||
|
||||
class TestVerifyBGPRedistributedRoute:
|
||||
"""Test anta.input_models.routing.bgp.RedistributedRouteConfig."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("proto", "include_leaked"),
|
||||
[
|
||||
pytest.param("Connected", True, id="proto-valid"),
|
||||
pytest.param("Static", False, id="proto-valid-leaked-false"),
|
||||
pytest.param("User", False, id="proto-User"),
|
||||
],
|
||||
)
|
||||
def test_validate_inputs(self, proto: RedistributedProtocol, include_leaked: bool) -> None:
|
||||
"""Test RedistributedRouteConfig valid inputs."""
|
||||
RedistributedRouteConfig(proto=proto, include_leaked=include_leaked)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("proto", "include_leaked"),
|
||||
[
|
||||
pytest.param("Dynamic", True, id="proto-valid"),
|
||||
pytest.param("User", True, id="proto-valid-leaked-false"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, proto: RedistributedProtocol, include_leaked: bool) -> None:
|
||||
"""Test RedistributedRouteConfig invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
RedistributedRouteConfig(proto=proto, include_leaked=include_leaked)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("proto", "include_leaked", "route_map", "expected"),
|
||||
[
|
||||
pytest.param("Connected", True, "RM-CONN-2-BGP", "Proto: Connected, Include Leaked: True, Route Map: RM-CONN-2-BGP", id="check-all-params"),
|
||||
pytest.param("Static", False, None, "Proto: Static", id="check-proto-include_leaked-false"),
|
||||
pytest.param("User", False, "RM-CONN-2-BGP", "Proto: EOS SDK, Route Map: RM-CONN-2-BGP", id="check-proto-route_map"),
|
||||
pytest.param("Dynamic", False, None, "Proto: Dynamic", id="check-proto-only"),
|
||||
],
|
||||
)
|
||||
def test_valid_str(self, proto: RedistributedProtocol, include_leaked: bool, route_map: str | None, expected: str) -> None:
|
||||
"""Test RedistributedRouteConfig __str__."""
|
||||
assert str(RedistributedRouteConfig(proto=proto, include_leaked=include_leaked, route_map=route_map)) == expected
|
||||
|
||||
|
||||
class TestVerifyBGPAddressFamilyConfig:
|
||||
"""Test anta.input_models.routing.bgp.AddressFamilyConfig."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("afi_safi", "redistributed_routes"),
|
||||
[
|
||||
pytest.param("ipv4Unicast", [{"proto": "OSPFv3 External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="afisafi-ipv4-unicast"),
|
||||
pytest.param("ipv6 Multicast", [{"proto": "OSPF Internal", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="afisafi-ipv6-multicast"),
|
||||
pytest.param("ipv4-Multicast", [{"proto": "IS-IS", "include_leaked": False, "route_map": "RM-CONN-2-BGP"}], id="afisafi-ipv4-multicast"),
|
||||
pytest.param("ipv6_Unicast", [{"proto": "AttachedHost", "route_map": "RM-CONN-2-BGP"}], id="afisafi-ipv6-unicast"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, afi_safi: RedistributedAfiSafi, redistributed_routes: list[Any]) -> None:
|
||||
"""Test AddressFamilyConfig valid inputs."""
|
||||
AddressFamilyConfig(afi_safi=afi_safi, redistributed_routes=redistributed_routes)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("afi_safi", "redistributed_routes"),
|
||||
[
|
||||
pytest.param("evpn", [{"proto": "OSPFv3 Nssa-External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="invalid-address-family"),
|
||||
pytest.param("ipv6 sr-te", [{"proto": "RIP", "route_map": "RM-CONN-2-BGP"}], id="ipv6-invalid-address-family"),
|
||||
pytest.param("iipv6_Unicast", [{"proto": "Bgp", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="ipv6-unicast-invalid-address-family"),
|
||||
pytest.param("ipv6_Unicastt", [{"proto": "Static", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="ipv6-unicast-invalid-address-family"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, afi_safi: RedistributedAfiSafi, redistributed_routes: list[Any]) -> None:
|
||||
"""Test AddressFamilyConfig invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
AddressFamilyConfig(afi_safi=afi_safi, redistributed_routes=redistributed_routes)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("afi_safi", "redistributed_routes"),
|
||||
[
|
||||
pytest.param("ipv4Unicast", [{"proto": "OSPF External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-ospf-external"),
|
||||
pytest.param("ipv4 Unicast", [{"proto": "OSPF Internal", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-ospf-internal"),
|
||||
pytest.param("ipv4-Unicast", [{"proto": "OSPF Nssa-External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-ospf-nssa-external"),
|
||||
pytest.param("ipv4_Unicast", [{"proto": "OSPFv3 External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-ospfv3-external"),
|
||||
pytest.param("Ipv4Unicast", [{"proto": "OSPFv3 Internal", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-ospfv3-internal"),
|
||||
pytest.param(
|
||||
"ipv4Unicast", [{"proto": "OSPFv3 Nssa-External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-ospfv3-nssa-external"
|
||||
),
|
||||
pytest.param("ipv4unicast", [{"proto": "AttachedHost", "include_leaked": False, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-attached-host"),
|
||||
pytest.param("IPv4UNiCast", [{"proto": "RIP", "include_leaked": False, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-rip"),
|
||||
pytest.param("IPv4UnicasT", [{"proto": "Bgp", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4u-proto-bgp"),
|
||||
pytest.param("ipv6_Multicast", [{"proto": "Static", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v6m-proto-static"),
|
||||
pytest.param("ipv6 Multicast", [{"proto": "OSPF Internal", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v6m-proto-ospf-internal"),
|
||||
pytest.param("ipv6-Multicast", [{"proto": "Connected", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v6m-proto-connected"),
|
||||
pytest.param("ipv4-Multicast", [{"proto": "IS-IS", "include_leaked": False, "route_map": "RM-CONN-2-BGP"}], id="v4m-proto-isis"),
|
||||
pytest.param("ipv4Multicast", [{"proto": "Connected", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], id="v4m-proto-connected"),
|
||||
pytest.param("ipv4_Multicast", [{"proto": "AttachedHost", "include_leaked": False, "route_map": "RM-CONN-2-BGP"}], id="v4m-proto-attached-host"),
|
||||
pytest.param("ipv6_Unicast", [{"proto": "AttachedHost", "route_map": "RM-CONN-2-BGP"}], id="v6u-proto-attached-host"),
|
||||
pytest.param("ipv6unicast", [{"proto": "DHCP", "route_map": "RM-CONN-2-BGP"}], id="v6u-proto-dhcp"),
|
||||
pytest.param("ipv6 Unicast", [{"proto": "Dynamic", "include_leaked": False, "route_map": "RM-CONN-2-BGP"}], id="v6u-proto-dynamic"),
|
||||
],
|
||||
)
|
||||
def test_validate_afi_safi_supported_routes(self, afi_safi: RedistributedAfiSafi, redistributed_routes: list[Any]) -> None:
|
||||
"""Test AddressFamilyConfig validate afi-safi supported routes."""
|
||||
AddressFamilyConfig(afi_safi=afi_safi, redistributed_routes=redistributed_routes)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("afi_safi", "redistributed_routes"),
|
||||
[
|
||||
pytest.param("ipv6_Unicast", [{"proto": "RIP", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv6-unicast-rip"),
|
||||
pytest.param("ipv6-Unicast", [{"proto": "OSPF Internal", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv6-unicast-ospf-internal"),
|
||||
pytest.param("ipv4Unicast", [{"proto": "DHCP", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv4-unicast-dhcp"),
|
||||
pytest.param("ipv4-Multicast", [{"proto": "Bgp", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv4-multicast-bgp"),
|
||||
pytest.param("ipv4-Multicast", [{"proto": "RIP", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv4-multicast-rip"),
|
||||
pytest.param("ipv6-Multicast", [{"proto": "Dynamic", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv4-multicast-dynamic"),
|
||||
pytest.param("ipv6-Multicast", [{"proto": "AttachedHost", "route_map": "RM-CONN-2-BGP"}], id="invalid-proto-ipv6-multicast-attached-host"),
|
||||
],
|
||||
)
|
||||
def test_invalid_afi_safi_supported_routes(self, afi_safi: RedistributedAfiSafi, redistributed_routes: list[Any]) -> None:
|
||||
"""Test AddressFamilyConfig invalid afi-safi supported routes."""
|
||||
with pytest.raises(ValidationError):
|
||||
AddressFamilyConfig(afi_safi=afi_safi, redistributed_routes=redistributed_routes)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("afi_safi", "redistributed_routes", "expected"),
|
||||
[
|
||||
pytest.param(
|
||||
"v4u", [{"proto": "OSPFv3 Nssa-External", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], "AFI-SAFI: IPv4 Unicast", id="valid-ipv4-unicast"
|
||||
),
|
||||
pytest.param("v4m", [{"proto": "IS-IS", "route_map": "RM-CONN-2-BGP"}], "AFI-SAFI: IPv4 Multicast", id="valid-ipv4-multicast"),
|
||||
pytest.param("v6u", [{"proto": "Bgp", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], "AFI-SAFI: IPv6 Unicast", id="valid-ipv6-unicast"),
|
||||
pytest.param("v6m", [{"proto": "Static", "include_leaked": True, "route_map": "RM-CONN-2-BGP"}], "AFI-SAFI: IPv6 Multicast", id="valid-ipv6-multicast"),
|
||||
],
|
||||
)
|
||||
def test_valid_str(self, afi_safi: RedistributedAfiSafi, redistributed_routes: list[Any], expected: str) -> None:
|
||||
"""Test AddressFamilyConfig __str__."""
|
||||
assert str(AddressFamilyConfig(afi_safi=afi_safi, redistributed_routes=redistributed_routes)) == expected
|
||||
|
||||
|
||||
class TestVerifyBGPPeerTtlMultiHopsInput:
|
||||
"""Test anta.tests.routing.bgp.VerifyBGPPeerTtlMultiHops.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "ttl": 3, "max_ttl_hops": 3}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
"""Test VerifyBGPPeerTtlMultiHops.Input valid inputs."""
|
||||
VerifyBGPPeerTtlMultiHops.Input(bgp_peers=bgp_peers)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bgp_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "ttl": None, "max_ttl_hops": 3}], id="invalid-ttl-time"),
|
||||
pytest.param([{"peer_address": "172.30.255.6", "vrf": "default", "ttl": 3, "max_ttl_hops": None}], id="invalid-max-ttl-hops"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bgp_peers: list[BgpPeer]) -> None:
|
||||
"""Test VerifyBGPPeerTtlMultiHops.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBGPPeerTtlMultiHops.Input(bgp_peers=bgp_peers)
|
||||
|
|
66
tests/units/input_models/routing/test_generic.py
Normal file
66
tests/units/input_models/routing/test_generic.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.routing.generic.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.tests.routing.generic import VerifyIPv4RouteNextHops, VerifyIPv4RouteType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.input_models.routing.generic import IPv4Routes
|
||||
|
||||
|
||||
class TestVerifyRouteEntryInput:
|
||||
"""Test anta.tests.routing.generic.VerifyIPv4RouteNextHops.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("route_entries"),
|
||||
[
|
||||
pytest.param([{"prefix": "10.10.0.1/32", "vrf": "default", "strict": True, "nexthops": ["10.100.0.8", "10.100.0.10"]}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, route_entries: list[IPv4Routes]) -> None:
|
||||
"""Test VerifyIPv4RouteNextHops.Input valid inputs."""
|
||||
VerifyIPv4RouteNextHops.Input(route_entries=route_entries)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("route_entries"),
|
||||
[
|
||||
pytest.param([{"prefix": "10.10.0.1/32", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, route_entries: list[IPv4Routes]) -> None:
|
||||
"""Test VerifyIPv4RouteNextHops.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyIPv4RouteNextHops.Input(route_entries=route_entries)
|
||||
|
||||
|
||||
class TestVerifyIPv4RouteTypeInput:
|
||||
"""Test anta.tests.routing.bgp.VerifyIPv4RouteType.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("routes_entries"),
|
||||
[
|
||||
pytest.param([{"prefix": "192.168.0.0/24", "vrf": "default", "route_type": "eBGP"}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, routes_entries: list[IPv4Routes]) -> None:
|
||||
"""Test VerifyIPv4RouteType.Input valid inputs."""
|
||||
VerifyIPv4RouteType.Input(routes_entries=routes_entries)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("routes_entries"),
|
||||
[
|
||||
pytest.param([{"prefix": "192.168.0.0/24", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, routes_entries: list[IPv4Routes]) -> None:
|
||||
"""Test VerifyIPv4RouteType.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyIPv4RouteType.Input(routes_entries=routes_entries)
|
101
tests/units/input_models/routing/test_isis.py
Normal file
101
tests/units/input_models/routing/test_isis.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.routing.isis.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.input_models.routing.isis import ISISInstance, TunnelPath
|
||||
from anta.tests.routing.isis import VerifyISISSegmentRoutingAdjacencySegments, VerifyISISSegmentRoutingDataplane
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ipaddress import IPv4Address
|
||||
|
||||
from anta.custom_types import Interface
|
||||
|
||||
|
||||
class TestVerifyISISSegmentRoutingAdjacencySegmentsInput:
|
||||
"""Test anta.tests.routing.isis.VerifyISISSegmentRoutingAdjacencySegments.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("instances"),
|
||||
[
|
||||
pytest.param(
|
||||
[{"name": "CORE-ISIS", "vrf": "default", "segments": [{"interface": "Ethernet2", "address": "10.0.1.3", "sid_origin": "dynamic"}]}], id="valid_vrf"
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_valid(self, instances: list[ISISInstance]) -> None:
|
||||
"""Test VerifyISISSegmentRoutingAdjacencySegments.Input valid inputs."""
|
||||
VerifyISISSegmentRoutingAdjacencySegments.Input(instances=instances)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("instances"),
|
||||
[
|
||||
pytest.param(
|
||||
[{"name": "CORE-ISIS", "vrf": "PROD", "segments": [{"interface": "Ethernet2", "address": "10.0.1.3", "sid_origin": "dynamic"}]}], id="invalid_vrf"
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, instances: list[ISISInstance]) -> None:
|
||||
"""Test VerifyISISSegmentRoutingAdjacencySegments.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyISISSegmentRoutingAdjacencySegments.Input(instances=instances)
|
||||
|
||||
|
||||
class TestVerifyISISSegmentRoutingDataplaneInput:
|
||||
"""Test anta.tests.routing.isis.VerifyISISSegmentRoutingDataplane.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("instances"),
|
||||
[
|
||||
pytest.param([{"name": "CORE-ISIS", "vrf": "default", "dataplane": "MPLS"}], id="valid_vrf"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, instances: list[ISISInstance]) -> None:
|
||||
"""Test VerifyISISSegmentRoutingDataplane.Input valid inputs."""
|
||||
VerifyISISSegmentRoutingDataplane.Input(instances=instances)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("instances"),
|
||||
[
|
||||
pytest.param([{"name": "CORE-ISIS", "vrf": "PROD", "dataplane": "MPLS"}], id="invalid_vrf"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, instances: list[ISISInstance]) -> None:
|
||||
"""Test VerifyISISSegmentRoutingDataplane.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyISISSegmentRoutingDataplane.Input(instances=instances)
|
||||
|
||||
|
||||
class TestTunnelPath:
|
||||
"""Test anta.input_models.routing.isis.TestTunnelPath."""
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("nexthop", "type", "interface", "tunnel_id", "expected"),
|
||||
[
|
||||
pytest.param("1.1.1.1", None, None, None, "Next-hop: 1.1.1.1", id="nexthop"),
|
||||
pytest.param(None, "ip", None, None, "Type: ip", id="type"),
|
||||
pytest.param(None, None, "Et1", None, "Interface: Ethernet1", id="interface"),
|
||||
pytest.param(None, None, None, "TI-LFA", "Tunnel ID: TI-LFA", id="tunnel_id"),
|
||||
pytest.param("1.1.1.1", "ip", "Et1", "TI-LFA", "Next-hop: 1.1.1.1 Type: ip Interface: Ethernet1 Tunnel ID: TI-LFA", id="all"),
|
||||
pytest.param(None, None, None, None, "", id="None"),
|
||||
],
|
||||
)
|
||||
def test_valid__str__(
|
||||
self,
|
||||
nexthop: IPv4Address | None,
|
||||
type: Literal["ip", "tunnel"] | None, # noqa: A002
|
||||
interface: Interface | None,
|
||||
tunnel_id: Literal["TI-LFA", "ti-lfa", "unset"] | None,
|
||||
expected: str,
|
||||
) -> None:
|
||||
"""Test TunnelPath __str__."""
|
||||
assert str(TunnelPath(nexthop=nexthop, type=type, interface=interface, tunnel_id=tunnel_id)) == expected
|
68
tests/units/input_models/test_bfd.py
Normal file
68
tests/units/input_models/test_bfd.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.bfd.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.tests.bfd import VerifyBFDPeersIntervals, VerifyBFDPeersRegProtocols
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.input_models.bfd import BFDPeer
|
||||
|
||||
|
||||
class TestVerifyBFDPeersIntervalsInput:
|
||||
"""Test anta.tests.bfd.VerifyBFDPeersIntervals.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bfd_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "10.0.0.1", "vrf": "default", "tx_interval": 1200, "rx_interval": 1200, "multiplier": 3}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bfd_peers: list[BFDPeer]) -> None:
|
||||
"""Test VerifyBFDPeersIntervals.Input valid inputs."""
|
||||
VerifyBFDPeersIntervals.Input(bfd_peers=bfd_peers)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bfd_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "10.0.0.1", "vrf": "default", "tx_interval": 1200}], id="invalid-tx-interval"),
|
||||
pytest.param([{"peer_address": "10.0.0.1", "vrf": "default", "rx_interval": 1200}], id="invalid-rx-interval"),
|
||||
pytest.param([{"peer_address": "10.0.0.1", "vrf": "default", "tx_interval": 1200, "rx_interval": 1200}], id="invalid-multiplier"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bfd_peers: list[BFDPeer]) -> None:
|
||||
"""Test VerifyBFDPeersIntervals.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBFDPeersIntervals.Input(bfd_peers=bfd_peers)
|
||||
|
||||
|
||||
class TestVerifyBFDPeersRegProtocolsInput:
|
||||
"""Test anta.tests.bfd.VerifyBFDPeersRegProtocols.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bfd_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "10.0.0.1", "vrf": "default", "protocols": ["bgp"]}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, bfd_peers: list[BFDPeer]) -> None:
|
||||
"""Test VerifyBFDPeersRegProtocols.Input valid inputs."""
|
||||
VerifyBFDPeersRegProtocols.Input(bfd_peers=bfd_peers)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("bfd_peers"),
|
||||
[
|
||||
pytest.param([{"peer_address": "10.0.0.1", "vrf": "default"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, bfd_peers: list[BFDPeer]) -> None:
|
||||
"""Test VerifyBFDPeersRegProtocols.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyBFDPeersRegProtocols.Input(bfd_peers=bfd_peers)
|
43
tests/units/input_models/test_connectivity.py
Normal file
43
tests/units/input_models/test_connectivity.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.connectivity.py."""
|
||||
|
||||
# pylint: disable=C0302
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.tests.connectivity import VerifyReachability
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.input_models.connectivity import Host
|
||||
|
||||
|
||||
class TestVerifyReachabilityInput:
|
||||
"""Test anta.tests.connectivity.VerifyReachability.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("hosts"),
|
||||
[
|
||||
pytest.param([{"destination": "fd12:3456:789a:1::2", "source": "fd12:3456:789a:1::1"}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, hosts: list[Host]) -> None:
|
||||
"""Test VerifyReachability.Input valid inputs."""
|
||||
VerifyReachability.Input(hosts=hosts)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("hosts"),
|
||||
[
|
||||
pytest.param([{"destination": "fd12:3456:789a:1::2", "source": "192.168.0.10"}], id="invalid-source"),
|
||||
pytest.param([{"destination": "192.168.0.10", "source": "fd12:3456:789a:1::2"}], id="invalid-destination"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, hosts: list[Host]) -> None:
|
||||
"""Test VerifyReachability.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyReachability.Input(hosts=hosts)
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
||||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.interfaces.py."""
|
||||
|
@ -9,8 +9,10 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.input_models.interfaces import InterfaceState
|
||||
from anta.tests.interfaces import VerifyInterfaceIPv4, VerifyInterfacesSpeed, VerifyInterfacesStatus, VerifyLACPInterfacesStatus
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.custom_types import Interface, PortChannelInterface
|
||||
|
@ -31,3 +33,103 @@ class TestInterfaceState:
|
|||
def test_valid__str__(self, name: Interface, portchannel: PortChannelInterface | None, expected: str) -> None:
|
||||
"""Test InterfaceState __str__."""
|
||||
assert str(InterfaceState(name=name, portchannel=portchannel)) == expected
|
||||
|
||||
|
||||
class TestVerifyInterfacesStatusInput:
|
||||
"""Test anta.tests.interfaces.VerifyInterfacesStatus.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1", "status": "up"}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyInterfacesStatus.Input valid inputs."""
|
||||
VerifyInterfacesStatus.Input(interfaces=interfaces)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyInterfacesStatus.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyInterfacesStatus.Input(interfaces=interfaces)
|
||||
|
||||
|
||||
class TestVerifyLACPInterfacesStatusInput:
|
||||
"""Test anta.tests.interfaces.VerifyLACPInterfacesStatus.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1", "portchannel": "Port-Channel100"}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyLACPInterfacesStatus.Input valid inputs."""
|
||||
VerifyLACPInterfacesStatus.Input(interfaces=interfaces)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1"}], id="invalid"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyLACPInterfacesStatus.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyLACPInterfacesStatus.Input(interfaces=interfaces)
|
||||
|
||||
|
||||
class TestVerifyInterfaceIPv4Input:
|
||||
"""Test anta.tests.interfaces.VerifyInterfaceIPv4.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1", "primary_ip": "172.30.11.1/31"}], id="valid"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyInterfaceIPv4.Input valid inputs."""
|
||||
VerifyInterfaceIPv4.Input(interfaces=interfaces)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1"}], id="invalid-no-primary-ip"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyInterfaceIPv4.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyInterfaceIPv4.Input(interfaces=interfaces)
|
||||
|
||||
|
||||
class TestVerifyInterfacesSpeedInput:
|
||||
"""Test anta.tests.interfaces.VerifyInterfacesSpeed.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1", "speed": 10}], id="valid-speed-is-given"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyInterfacesSpeed.Input valid inputs."""
|
||||
VerifyInterfacesSpeed.Input(interfaces=interfaces)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("interfaces"),
|
||||
[
|
||||
pytest.param([{"name": "Ethernet1"}], id="invalid-speed-is-not-given"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, interfaces: list[InterfaceState]) -> None:
|
||||
"""Test VerifyInterfacesSpeed.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyInterfacesSpeed.Input(interfaces=interfaces)
|
||||
|
|
192
tests/units/input_models/test_snmp.py
Normal file
192
tests/units/input_models/test_snmp.py
Normal file
|
@ -0,0 +1,192 @@
|
|||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.snmp.py."""
|
||||
|
||||
# pylint: disable=C0302
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.input_models.snmp import SnmpGroup
|
||||
from anta.tests.snmp import VerifySnmpNotificationHost, VerifySnmpUser
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.custom_types import SnmpVersion, SnmpVersionV3AuthType
|
||||
from anta.input_models.snmp import SnmpHost, SnmpUser
|
||||
|
||||
|
||||
class TestVerifySnmpUserInput:
|
||||
"""Test anta.tests.snmp.VerifySnmpUser.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("snmp_users"),
|
||||
[
|
||||
pytest.param([{"username": "test", "group_name": "abc", "version": "v1", "auth_type": None, "priv_type": None}], id="valid-v1"),
|
||||
pytest.param([{"username": "test", "group_name": "abc", "version": "v2c", "auth_type": None, "priv_type": None}], id="valid-v2c"),
|
||||
pytest.param([{"username": "test", "group_name": "abc", "version": "v3", "auth_type": "SHA", "priv_type": "AES-128"}], id="valid-v3"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, snmp_users: list[SnmpUser]) -> None:
|
||||
"""Test VerifySnmpUser.Input valid inputs."""
|
||||
VerifySnmpUser.Input(snmp_users=snmp_users)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("snmp_users"),
|
||||
[
|
||||
pytest.param([{"username": "test", "group_name": "abc", "version": "v3", "auth_type": None, "priv_type": None}], id="invalid-v3"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, snmp_users: list[SnmpUser]) -> None:
|
||||
"""Test VerifySnmpUser.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifySnmpUser.Input(snmp_users=snmp_users)
|
||||
|
||||
|
||||
class TestSnmpHost:
|
||||
"""Test anta.input_models.snmp.SnmpHost."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("notification_hosts"),
|
||||
[
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": "v1",
|
||||
"udp_port": 162,
|
||||
"community_string": "public",
|
||||
"user": None,
|
||||
}
|
||||
],
|
||||
id="valid-v1",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": "v2c",
|
||||
"udp_port": 162,
|
||||
"community_string": "public",
|
||||
"user": None,
|
||||
}
|
||||
],
|
||||
id="valid-v2c",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": "v3",
|
||||
"udp_port": 162,
|
||||
"community_string": None,
|
||||
"user": "public",
|
||||
}
|
||||
],
|
||||
id="valid-v3",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_valid(self, notification_hosts: list[SnmpHost]) -> None:
|
||||
"""Test VerifySnmpNotificationHost.Input valid inputs."""
|
||||
VerifySnmpNotificationHost.Input(notification_hosts=notification_hosts)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("notification_hosts"),
|
||||
[
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": None,
|
||||
"udp_port": 162,
|
||||
"community_string": None,
|
||||
"user": None,
|
||||
}
|
||||
],
|
||||
id="invalid-version",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": "v1",
|
||||
"udp_port": 162,
|
||||
"community_string": None,
|
||||
"user": None,
|
||||
}
|
||||
],
|
||||
id="invalid-community-string-version-v1",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": "v2c",
|
||||
"udp_port": 162,
|
||||
"community_string": None,
|
||||
"user": None,
|
||||
}
|
||||
],
|
||||
id="invalid-community-string-version-v2c",
|
||||
),
|
||||
pytest.param(
|
||||
[
|
||||
{
|
||||
"hostname": "192.168.1.100",
|
||||
"vrf": "test",
|
||||
"notification_type": "trap",
|
||||
"version": "v3",
|
||||
"udp_port": 162,
|
||||
"community_string": None,
|
||||
"user": None,
|
||||
}
|
||||
],
|
||||
id="invalid-user-version-v3",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, notification_hosts: list[SnmpHost]) -> None:
|
||||
"""Test VerifySnmpNotificationHost.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifySnmpNotificationHost.Input(notification_hosts=notification_hosts)
|
||||
|
||||
|
||||
class TestSnmpGroupInput:
|
||||
"""Test anta.input_models.snmp.SnmpGroup."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("group_name", "version", "read_view", "write_view", "notify_view", "authentication"),
|
||||
[
|
||||
pytest.param("group1", "v3", "", "write_1", None, "auth", id="snmp-auth"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, group_name: str, read_view: str, version: SnmpVersion, write_view: str, notify_view: str, authentication: SnmpVersionV3AuthType) -> None:
|
||||
"""Test SnmpGroup valid inputs."""
|
||||
SnmpGroup(group_name=group_name, version=version, read_view=read_view, write_view=write_view, notify_view=notify_view, authentication=authentication)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("group_name", "version", "read_view", "write_view", "notify_view", "authentication"),
|
||||
[
|
||||
pytest.param("group1", "v3", "", "write_1", None, None, id="snmp-invalid-auth"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, group_name: str, read_view: str, version: SnmpVersion, write_view: str, notify_view: str, authentication: SnmpVersionV3AuthType) -> None:
|
||||
"""Test SnmpGroup invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
SnmpGroup(group_name=group_name, version=version, read_view=read_view, write_view=write_view, notify_view=notify_view, authentication=authentication)
|
48
tests/units/input_models/test_system.py
Normal file
48
tests/units/input_models/test_system.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
# Copyright (c) 2023-2025 Arista Networks, Inc.
|
||||
# Use of this source code is governed by the Apache License 2.0
|
||||
# that can be found in the LICENSE file.
|
||||
"""Tests for anta.input_models.system.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from anta.tests.system import VerifyNTPAssociations
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from anta.input_models.system import NTPPool, NTPServer
|
||||
|
||||
|
||||
class TestVerifyNTPAssociationsInput:
|
||||
"""Test anta.tests.system.VerifyNTPAssociations.Input."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("ntp_servers", "ntp_pool"),
|
||||
[
|
||||
pytest.param([{"server_address": "1.1.1.1", "preferred": True, "stratum": 1}], None, id="valid-ntp-server"),
|
||||
pytest.param(None, {"server_addresses": ["1.1.1.1"], "preferred_stratum_range": [1, 3]}, id="valid-ntp-pool"),
|
||||
],
|
||||
)
|
||||
def test_valid(self, ntp_servers: list[NTPServer], ntp_pool: NTPPool) -> None:
|
||||
"""Test VerifyNTPAssociations.Input valid inputs."""
|
||||
VerifyNTPAssociations.Input(ntp_servers=ntp_servers, ntp_pool=ntp_pool)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("ntp_servers", "ntp_pool"),
|
||||
[
|
||||
pytest.param(
|
||||
[{"server_address": "1.1.1.1", "preferred": True, "stratum": 1}],
|
||||
{"server_addresses": ["1.1.1.1"], "preferred_stratum_range": [1, 3]},
|
||||
id="invalid-both-server-pool",
|
||||
),
|
||||
pytest.param(None, {"server_addresses": ["1.1.1.1"], "preferred_stratum_range": [1, 3, 6]}, id="invalid-ntp-pool-stratum"),
|
||||
pytest.param(None, None, id="invalid-both-none"),
|
||||
],
|
||||
)
|
||||
def test_invalid(self, ntp_servers: list[NTPServer], ntp_pool: NTPPool) -> None:
|
||||
"""Test VerifyNTPAssociations.Input invalid inputs."""
|
||||
with pytest.raises(ValidationError):
|
||||
VerifyNTPAssociations.Input(ntp_servers=ntp_servers, ntp_pool=ntp_pool)
|
Loading…
Add table
Add a link
Reference in a new issue