Skip to content

ANTA catalog for connectivity tests

Tests

Module related to various connectivity tests.

VerifyLLDPNeighbors

Verifies the connection status of the specified LLDP (Link Layer Discovery Protocol) neighbors.

This test performs the following checks for each specified LLDP neighbor:

  1. Confirming matching ports on both local and neighboring devices.
  2. Ensuring compatibility of device names and interface identifiers.
  3. Verifying neighbor configurations match expected values per interface; extra neighbors are ignored.
Expected Results
  • Success: The test will pass if all the provided LLDP neighbors are present and correctly connected to the specified port and device.
  • Failure: The test will fail if any of the following conditions are met:
    • The provided LLDP neighbor is not found in the LLDP table.
    • The system name or port of the LLDP neighbor does not match the expected information.
Examples
anta.tests.connectivity:
  - VerifyLLDPNeighbors:
      neighbors:
        - port: Ethernet1
          neighbor_device: DC1-SPINE1
          neighbor_port: Ethernet1
        - port: Ethernet2
          neighbor_device: DC1-SPINE2
          neighbor_port: Ethernet1

Inputs

Name Type Description Default
neighbors list[LLDPNeighbor]
List of LLDP neighbors.
-
Neighbor type[Neighbor]
To maintain backward compatibility.
Neighbor
Source code in anta/tests/connectivity.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
class VerifyLLDPNeighbors(AntaTest):
    """Verifies the connection status of the specified LLDP (Link Layer Discovery Protocol) neighbors.

    This test performs the following checks for each specified LLDP neighbor:

      1. Confirming matching ports on both local and neighboring devices.
      2. Ensuring compatibility of device names and interface identifiers.
      3. Verifying neighbor configurations match expected values per interface; extra neighbors are ignored.

    Expected Results
    ----------------
    * Success: The test will pass if all the provided LLDP neighbors are present and correctly connected to the specified port and device.
    * Failure: The test will fail if any of the following conditions are met:
        - The provided LLDP neighbor is not found in the LLDP table.
        - The system name or port of the LLDP neighbor does not match the expected information.

    Examples
    --------
    ```yaml
    anta.tests.connectivity:
      - VerifyLLDPNeighbors:
          neighbors:
            - port: Ethernet1
              neighbor_device: DC1-SPINE1
              neighbor_port: Ethernet1
            - port: Ethernet2
              neighbor_device: DC1-SPINE2
              neighbor_port: Ethernet1
    ```
    """

    categories: ClassVar[list[str]] = ["connectivity"]
    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show lldp neighbors detail", revision=1)]

    class Input(AntaTest.Input):
        """Input model for the VerifyLLDPNeighbors test."""

        neighbors: list[LLDPNeighbor]
        """List of LLDP neighbors."""
        Neighbor: ClassVar[type[Neighbor]] = Neighbor
        """To maintain backward compatibility."""

    @AntaTest.anta_test
    def test(self) -> None:
        """Main test function for VerifyLLDPNeighbors."""
        self.result.is_success()

        output = self.instance_commands[0].json_output["lldpNeighbors"]
        for neighbor in self.inputs.neighbors:
            if neighbor.port not in output:
                self.result.is_failure(f"{neighbor} - Port not found")
                continue

            if len(lldp_neighbor_info := output[neighbor.port]["lldpNeighborInfo"]) == 0:
                self.result.is_failure(f"{neighbor} - No LLDP neighbors")
                continue

            # Check if the system name and neighbor port matches
            match_found = any(
                info["systemName"] == neighbor.neighbor_device and info["neighborInterfaceInfo"]["interfaceId_v2"] == neighbor.neighbor_port
                for info in lldp_neighbor_info
            )
            if not match_found:
                failure_msg = [f"{info['systemName']}/{info['neighborInterfaceInfo']['interfaceId_v2']}" for info in lldp_neighbor_info]
                self.result.is_failure(f"{neighbor} - Wrong LLDP neighbors: {', '.join(failure_msg)}")

VerifyReachability

Test network reachability to one or many destination IP(s).

Expected Results
  • Success: The test will pass if all destination IP(s) are reachable.
  • Failure: The test will fail if one or many destination IP(s) are unreachable.
Examples
anta.tests.connectivity:
  - VerifyReachability:
      hosts:
        - source: Management0
          destination: 1.1.1.1
          vrf: MGMT
          df_bit: True
          size: 100
          reachable: true
        - source: Management0
          destination: 8.8.8.8
          vrf: MGMT
          df_bit: True
          size: 100
        - source: fd12:3456:789a:1::1
          destination: fd12:3456:789a:1::2
          vrf: default
          df_bit: True
          size: 100
          reachable: false

Inputs

Name Type Description Default
hosts list[Host]
List of host to ping.
-
Host type[Host]
To maintain backward compatibility.
Host
Source code in anta/tests/connectivity.py
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
class VerifyReachability(AntaTest):
    """Test network reachability to one or many destination IP(s).

    Expected Results
    ----------------
    * Success: The test will pass if all destination IP(s) are reachable.
    * Failure: The test will fail if one or many destination IP(s) are unreachable.

    Examples
    --------
    ```yaml
    anta.tests.connectivity:
      - VerifyReachability:
          hosts:
            - source: Management0
              destination: 1.1.1.1
              vrf: MGMT
              df_bit: True
              size: 100
              reachable: true
            - source: Management0
              destination: 8.8.8.8
              vrf: MGMT
              df_bit: True
              size: 100
            - source: fd12:3456:789a:1::1
              destination: fd12:3456:789a:1::2
              vrf: default
              df_bit: True
              size: 100
              reachable: false
    ```
    """

    categories: ClassVar[list[str]] = ["connectivity"]
    # Template uses '{size}{df_bit}' without space since df_bit includes leading space when enabled
    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
        AntaTemplate(template="ping vrf {vrf} {destination} source {source} size {size}{df_bit} repeat {repeat}", revision=1)
    ]

    class Input(AntaTest.Input):
        """Input model for the VerifyReachability test."""

        hosts: list[Host]
        """List of host to ping."""
        Host: ClassVar[type[Host]] = Host
        """To maintain backward compatibility."""

        @field_validator("hosts")
        @classmethod
        def validate_hosts(cls, hosts: list[T]) -> list[T]:
            """Validate the 'destination' and 'source' IP address family in each host."""
            for host in hosts:
                if not isinstance(host.source, str) and host.destination.version != host.source.version:
                    msg = f"{host} IP address family for destination does not match source"
                    raise ValueError(msg)
            return hosts

    def render(self, template: AntaTemplate) -> list[AntaCommand]:
        """Render the template for each host in the input list."""
        return [
            template.render(
                destination=host.destination, source=host.source, vrf=host.vrf, repeat=host.repeat, size=host.size, df_bit=" df-bit" if host.df_bit else ""
            )
            for host in self.inputs.hosts
        ]

    @AntaTest.anta_test
    def test(self) -> None:
        """Main test function for VerifyReachability."""
        self.result.is_success()

        for command, host in zip(self.instance_commands, self.inputs.hosts):
            # Verifies the network is reachable
            if host.reachable and f"{host.repeat} received" not in command.json_output["messages"][0]:
                self.result.is_failure(f"{host} - Unreachable")

            # Verifies the network is unreachable.
            if not host.reachable and f"{host.repeat} received" in command.json_output["messages"][0]:
                self.result.is_failure(f"{host} - Destination is expected to be unreachable but found reachable")

Input models

Module containing input models for connectivity tests.

Host

Model for a remote host to ping.

Name Type Description Default
destination IPv4Address | IPv6Address
Destination address to ping.
-
source IPv4Address | IPv6Address | Interface
Source address IP or egress interface to use.
-
vrf str
VRF context.
'default'
repeat int
Number of ping repetition.
2
size int
Specify datagram size.
100
df_bit bool
Enable do not fragment bit in IP header.
False
reachable bool
Indicates whether the destination should be reachable.
True
Source code in anta/input_models/connectivity.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Host(BaseModel):
    """Model for a remote host to ping."""

    model_config = ConfigDict(extra="forbid")
    destination: IPv4Address | IPv6Address
    """Destination address to ping."""
    source: IPv4Address | IPv6Address | Interface
    """Source address IP or egress interface to use."""
    vrf: str = "default"
    """VRF context."""
    repeat: int = 2
    """Number of ping repetition."""
    size: int = 100
    """Specify datagram size."""
    df_bit: bool = False
    """Enable do not fragment bit in IP header."""
    reachable: bool = True
    """Indicates whether the destination should be reachable."""

    def __str__(self) -> str:
        """Return a human-readable string representation of the Host for reporting.

        Examples
        --------
        Host: 10.1.1.1 Source: 10.2.2.2 VRF: mgmt

        """
        return f"Host: {self.destination} Source: {self.source} VRF: {self.vrf}"

LLDPNeighbor

LLDP (Link Layer Discovery Protocol) model representing the port details and neighbor information.

Name Type Description Default
port Interface
The LLDP port for the local device.
-
neighbor_device str
The system name of the LLDP neighbor device.
-
neighbor_port Interface
The LLDP port on the neighboring device.
-
Source code in anta/input_models/connectivity.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class LLDPNeighbor(BaseModel):
    """LLDP (Link Layer Discovery Protocol) model representing the port details and neighbor information."""

    model_config = ConfigDict(extra="forbid")
    port: Interface
    """The LLDP port for the local device."""
    neighbor_device: str
    """The system name of the LLDP neighbor device."""
    neighbor_port: Interface
    """The LLDP port on the neighboring device."""

    def __str__(self) -> str:
        """Return a human-readable string representation of the LLDPNeighbor for reporting.

        Examples
        --------
        Port: Ethernet1 Neighbor: DC1-SPINE2 Neighbor Port: Ethernet2

        """
        return f"Port: {self.port} Neighbor: {self.neighbor_device} Neighbor Port: {self.neighbor_port}"

Neighbor

Alias for the LLDPNeighbor model to maintain backward compatibility.

When initialized, it will emit a deprecation warning and call the LLDPNeighbor model.

TODO: Remove this class in ANTA v2.0.0.

__init__

__init__(**data: Any) -> None
Source code in anta/input_models/connectivity.py
77
78
79
80
81
82
83
84
def __init__(self, **data: Any) -> None:  # noqa: ANN401
    """Initialize the LLDPNeighbor class, emitting a depreciation warning."""
    warn(
        message="Neighbor model is deprecated and will be removed in ANTA v2.0.0. Use the LLDPNeighbor model instead.",
        category=DeprecationWarning,
        stacklevel=2,
    )
    super().__init__(**data)
Source code in anta/input_models/connectivity.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class Neighbor(LLDPNeighbor):  # pragma: no cover
    """Alias for the LLDPNeighbor model to maintain backward compatibility.

    When initialized, it will emit a deprecation warning and call the LLDPNeighbor model.

    TODO: Remove this class in ANTA v2.0.0.
    """

    def __init__(self, **data: Any) -> None:  # noqa: ANN401
        """Initialize the LLDPNeighbor class, emitting a depreciation warning."""
        warn(
            message="Neighbor model is deprecated and will be removed in ANTA v2.0.0. Use the LLDPNeighbor model instead.",
            category=DeprecationWarning,
            stacklevel=2,
        )
        super().__init__(**data)