Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(anta.tests): Nicer result failure messages interface(part-2) test module  #1046

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 40 additions & 57 deletions anta/tests/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,15 +325,12 @@ class VerifyPortChannels(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyPortChannels."""
self.result.is_success()
command_output = self.instance_commands[0].json_output
po_with_inactive_ports: list[dict[str, str]] = []
for portchannel, portchannel_dict in command_output["portChannels"].items():
if len(portchannel_dict["inactivePorts"]) != 0:
po_with_inactive_ports.extend({portchannel: portchannel_dict["inactivePorts"]})
if not po_with_inactive_ports:
self.result.is_success()
else:
self.result.is_failure(f"The following port-channels have inactive port(s): {po_with_inactive_ports}")
for port_channel, port_channel_details in command_output["portChannels"].items():
# Verify that the no inactive ports in all port channels.
if inactive_ports := port_channel_details["inactivePorts"]:
self.result.is_failure(f"Port-Channel: {port_channel} - Inactive port(s) - {', '.join(inactive_ports.keys())}")


class VerifyIllegalLACP(AntaTest):
Expand All @@ -358,16 +355,13 @@ class VerifyIllegalLACP(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyIllegalLACP."""
self.result.is_success()
command_output = self.instance_commands[0].json_output
po_with_illegal_lacp: list[dict[str, dict[str, int]]] = []
for portchannel, portchannel_dict in command_output["portChannels"].items():
po_with_illegal_lacp.extend(
{portchannel: interface} for interface, interface_dict in portchannel_dict["interfaces"].items() if interface_dict["illegalRxCount"] != 0
)
if not po_with_illegal_lacp:
self.result.is_success()
else:
self.result.is_failure(f"The following port-channels have received illegal LACP packets on the following ports: {po_with_illegal_lacp}")
for port_channel, port_channel_dict in command_output["portChannels"].items():
for interface, interface_details in port_channel_dict["interfaces"].items():
# Verify that the no illegal LACP packets in all port channels.
if interface_details["illegalRxCount"] != 0:
self.result.is_failure(f"Port-Channel: {port_channel} Interface: {interface} - Illegal LACP packets found")


class VerifyLoopbackCount(AntaTest):
Expand Down Expand Up @@ -400,23 +394,20 @@ class Input(AntaTest.Input):
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyLoopbackCount."""
self.result.is_success()
command_output = self.instance_commands[0].json_output
loopback_count = 0
down_loopback_interfaces = []
for interface in command_output["interfaces"]:
interface_dict = command_output["interfaces"][interface]
for interface, interface_details in command_output["interfaces"].items():
if "Loopback" in interface:
loopback_count += 1
if not (interface_dict["lineProtocolStatus"] == "up" and interface_dict["interfaceStatus"] == "connected"):
down_loopback_interfaces.append(interface)
if loopback_count == self.inputs.number and len(down_loopback_interfaces) == 0:
self.result.is_success()
else:
self.result.is_failure()
if loopback_count != self.inputs.number:
self.result.is_failure(f"Found {loopback_count} Loopbacks when expecting {self.inputs.number}")
elif len(down_loopback_interfaces) != 0: # pragma: no branch
self.result.is_failure(f"The following Loopbacks are not up: {down_loopback_interfaces}")
if not ((status := interface_details["lineProtocolStatus"]) == "up" and interface_details["interfaceStatus"] == "connected"):
self.result.is_failure(
f"Interface: {interface} LineProtocolStatus: up interfaceStatus: Connected - Not up - Actual: "
f"LineProtocolStatus: {status} InterfaceStatus: {interface_details['interfaceStatus']}"
)

if loopback_count != self.inputs.number:
self.result.is_failure(f"Loopback interface(s) count mismatch: Expected {self.inputs.number} Actual: {loopback_count}")


class VerifySVI(AntaTest):
Expand All @@ -441,16 +432,14 @@ class VerifySVI(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifySVI."""
self.result.is_success()
command_output = self.instance_commands[0].json_output
down_svis = []
for interface in command_output["interfaces"]:
interface_dict = command_output["interfaces"][interface]
if "Vlan" in interface and not (interface_dict["lineProtocolStatus"] == "up" and interface_dict["interfaceStatus"] == "connected"):
down_svis.append(interface)
if len(down_svis) == 0:
self.result.is_success()
else:
self.result.is_failure(f"The following SVIs are not up: {down_svis}")
for interface, int_data in command_output["interfaces"].items():
if "Vlan" in interface and not ((status := int_data["lineProtocolStatus"]) == "up" and int_data["interfaceStatus"] == "connected"):
self.result.is_failure(
f"SVI: {interface} LineProtocolStatus: up interfaceStatus: Connected - Not up - Actual: "
f"LineProtocolStatus: {status} InterfaceStatus: {int_data['interfaceStatus']}"
)


class VerifyL3MTU(AntaTest):
Expand Down Expand Up @@ -495,8 +484,7 @@ class Input(AntaTest.Input):
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyL3MTU."""
# Parameter to save incorrect interface settings
wrong_l3mtu_intf: list[dict[str, int]] = []
self.result.is_success()
command_output = self.instance_commands[0].json_output
# Set list of interfaces with specific settings
specific_interfaces: list[str] = []
Expand All @@ -506,18 +494,18 @@ def test(self) -> None:
for interface, values in command_output["interfaces"].items():
if re.findall(r"[a-z]+", interface, re.IGNORECASE)[0] not in self.inputs.ignored_interfaces and values["forwardingModel"] == "routed":
if interface in specific_interfaces:
wrong_l3mtu_intf.extend({interface: values["mtu"]} for custom_data in self.inputs.specific_mtu if values["mtu"] != custom_data[interface])
invalid_mtu = next(
(values["mtu"] for custom_data in self.inputs.specific_mtu if values["mtu"] != (expected_mtu := custom_data[interface])), None
)
if invalid_mtu:
self.result.is_failure(f"Interface: {interface} - Incorrect MTU - Expected: {expected_mtu} Actual: {invalid_mtu}")
# Comparison with generic setting
elif values["mtu"] != self.inputs.mtu:
wrong_l3mtu_intf.append({interface: values["mtu"]})
if wrong_l3mtu_intf:
self.result.is_failure(f"Some interfaces do not have correct MTU configured:\n{wrong_l3mtu_intf}")
else:
self.result.is_success()
self.result.is_failure(f"Interface: {interface} - Incorrect MTU - Expected: {self.inputs.mtu} Actual: {values['mtu']}")


class VerifyIPProxyARP(AntaTest):
"""Verifies if Proxy-ARP is enabled for the provided list of interface(s).
"""Verifies if Proxy ARP is enabled.

Expected Results
----------------
Expand All @@ -535,7 +523,6 @@ class VerifyIPProxyARP(AntaTest):
```
"""

description = "Verifies if Proxy ARP is enabled."
categories: ClassVar[list[str]] = ["interfaces"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show ip interface {intf}", revision=2)]

Expand All @@ -552,15 +539,11 @@ def render(self, template: AntaTemplate) -> list[AntaCommand]:
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyIPProxyARP."""
disabled_intf = []
self.result.is_success()
for command in self.instance_commands:
intf = command.params.intf
if not command.json_output["interfaces"][intf]["proxyArp"]:
disabled_intf.append(intf)
if disabled_intf:
self.result.is_failure(f"The following interface(s) have Proxy-ARP disabled: {disabled_intf}")
else:
self.result.is_success()
interface = command.params.intf
if not command.json_output["interfaces"][interface]["proxyArp"]:
self.result.is_failure(f"Interface: {interface} - Proxy-ARP disabled")


class VerifyL2MTU(AntaTest):
Expand Down
98 changes: 90 additions & 8 deletions tests/units/anta_tests/test_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@
},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following port-channels have inactive port(s): ['Port-Channel42']"]},
"expected": {"result": "failure", "messages": ["Port-Channel: Port-Channel42 - Inactive port(s) - Ethernet8"]},
},
{
"name": "success",
Expand Down Expand Up @@ -1362,7 +1362,7 @@
"inputs": None,
"expected": {
"result": "failure",
"messages": ["The following port-channels have received illegal LACP packets on the following ports: [{'Port-Channel42': 'Ethernet8'}]"],
"messages": ["Port-Channel: Port-Channel42 Interface: Ethernet8 - Illegal LACP packets found"],
},
},
{
Expand Down Expand Up @@ -1417,7 +1417,7 @@
},
"Loopback666": {
"name": "Loopback666",
"interfaceStatus": "connected",
"interfaceStatus": "notconnect",
"interfaceAddress": {"ipAddr": {"maskLen": 32, "address": "6.6.6.6"}},
"ipv4Routable240": False,
"lineProtocolStatus": "down",
Expand All @@ -1427,7 +1427,12 @@
},
],
"inputs": {"number": 2},
"expected": {"result": "failure", "messages": ["The following Loopbacks are not up: ['Loopback666']"]},
"expected": {
"result": "failure",
"messages": [
"Interface: Loopback666 LineProtocolStatus: up interfaceStatus: Connected - Not up - Actual: LineProtocolStatus: down InterfaceStatus: notconnect"
],
},
},
{
"name": "failure-count-loopback",
Expand All @@ -1447,7 +1452,7 @@
},
],
"inputs": {"number": 2},
"expected": {"result": "failure", "messages": ["Found 1 Loopbacks when expecting 2"]},
"expected": {"result": "failure", "messages": ["Loopback interface(s) count mismatch: Expected 2 Actual: 1"]},
},
{
"name": "success",
Expand Down Expand Up @@ -1487,7 +1492,12 @@
},
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following SVIs are not up: ['Vlan42']"]},
"expected": {
"result": "failure",
"messages": [
"SVI: Vlan42 LineProtocolStatus: up interfaceStatus: Connected - Not up - Actual: LineProtocolStatus: lowerLayerDown InterfaceStatus: notconnect"
],
},
},
{
"name": "success",
Expand Down Expand Up @@ -1703,7 +1713,79 @@
},
],
"inputs": {"mtu": 1500},
"expected": {"result": "failure", "messages": ["Some interfaces do not have correct MTU configured:\n[{'Ethernet2': 1600}]"]},
"expected": {"result": "failure", "messages": ["Interface: Ethernet2 - Incorrect MTU - Expected: 1500 Actual: 1600"]},
},
{
"name": "failure-specified-interface-mtu",
"test": VerifyL3MTU,
"eos_data": [
{
"interfaces": {
"Ethernet2": {
"name": "Ethernet2",
"forwardingModel": "routed",
"lineProtocolStatus": "up",
"interfaceStatus": "connected",
"hardware": "ethernet",
"mtu": 1500,
"l3MtuConfigured": True,
"l2Mru": 0,
},
"Ethernet10": {
"name": "Ethernet10",
"forwardingModel": "routed",
"lineProtocolStatus": "up",
"interfaceStatus": "connected",
"hardware": "ethernet",
"mtu": 1502,
"l3MtuConfigured": False,
"l2Mru": 0,
},
"Management0": {
"name": "Management0",
"forwardingModel": "routed",
"lineProtocolStatus": "up",
"interfaceStatus": "connected",
"hardware": "ethernet",
"mtu": 1500,
"l3MtuConfigured": False,
"l2Mru": 0,
},
"Port-Channel2": {
"name": "Port-Channel2",
"forwardingModel": "bridged",
"lineProtocolStatus": "lowerLayerDown",
"interfaceStatus": "notconnect",
"hardware": "portChannel",
"mtu": 1500,
"l3MtuConfigured": False,
"l2Mru": 0,
},
"Loopback0": {
"name": "Loopback0",
"forwardingModel": "routed",
"lineProtocolStatus": "up",
"interfaceStatus": "connected",
"hardware": "loopback",
"mtu": 65535,
"l3MtuConfigured": False,
"l2Mru": 0,
},
"Vxlan1": {
"name": "Vxlan1",
"forwardingModel": "bridged",
"lineProtocolStatus": "down",
"interfaceStatus": "notconnect",
"hardware": "vxlan",
"mtu": 0,
"l3MtuConfigured": False,
"l2Mru": 0,
},
},
},
],
"inputs": {"mtu": 1500, "ignored_interfaces": ["Loopback", "Port-Channel", "Management", "Vxlan"], "specific_mtu": [{"Ethernet10": 1501}]},
"expected": {"result": "failure", "messages": ["Interface: Ethernet10 - Incorrect MTU - Expected: 1501 Actual: 1502"]},
},
{
"name": "success",
Expand Down Expand Up @@ -1959,7 +2041,7 @@
},
],
"inputs": {"interfaces": ["Ethernet1", "Ethernet2"]},
"expected": {"result": "failure", "messages": ["The following interface(s) have Proxy-ARP disabled: ['Ethernet2']"]},
"expected": {"result": "failure", "messages": ["Interface: Ethernet2 - Proxy-ARP disabled"]},
},
{
"name": "success",
Expand Down
Loading