Skip to content

Commit

Permalink
refactor(anta.tests): Nicer result failure messages Vxlan test module (
Browse files Browse the repository at this point in the history
…#1032)

Updated failure msgs for vxlan suite
  • Loading branch information
vitthalmagadum authored Feb 10, 2025
1 parent bdc0e68 commit e587f3f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 66 deletions.
74 changes: 33 additions & 41 deletions anta/tests/vxlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,26 @@ class VerifyVxlan1Interface(AntaTest):
```
"""

description = "Verifies the Vxlan1 interface status."
categories: ClassVar[list[str]] = ["vxlan"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces description", revision=1)]

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyVxlan1Interface."""
self.result.is_success()
command_output = self.instance_commands[0].json_output
if "Vxlan1" not in command_output["interfaceDescriptions"]:
self.result.is_skipped("Vxlan1 interface is not configured")
elif (
command_output["interfaceDescriptions"]["Vxlan1"]["lineProtocolStatus"] == "up"
and command_output["interfaceDescriptions"]["Vxlan1"]["interfaceStatus"] == "up"
):
self.result.is_success()
else:
self.result.is_failure(
f"Vxlan1 interface is {command_output['interfaceDescriptions']['Vxlan1']['lineProtocolStatus']}"
f"/{command_output['interfaceDescriptions']['Vxlan1']['interfaceStatus']}",
)

# Skipping the test if the Vxlan1 interface is not configured
if "Vxlan1" not in (interface_details := command_output["interfaceDescriptions"]):
self.result.is_skipped("Interface: Vxlan1 - Not configured")
return

line_protocol_status = interface_details["Vxlan1"]["lineProtocolStatus"]
interface_status = interface_details["Vxlan1"]["interfaceStatus"]

# Checking against both status and line protocol status
if interface_status != "up" or line_protocol_status != "up":
self.result.is_failure(f"Interface: Vxlan1 - Incorrect Line protocol status/Status - Expected: up/up Actual: {line_protocol_status}/{interface_status}")


class VerifyVxlanConfigSanity(AntaTest):
Expand All @@ -86,19 +86,19 @@ class VerifyVxlanConfigSanity(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyVxlanConfigSanity."""
self.result.is_success()
command_output = self.instance_commands[0].json_output

# Skipping the test if VXLAN is not configured
if "categories" not in command_output or len(command_output["categories"]) == 0:
self.result.is_skipped("VXLAN is not configured")
return
failed_categories = {
category: content
for category, content in command_output["categories"].items()
if category in ["localVtep", "mlag", "pd"] and content["allCheckPass"] is not True
}
if len(failed_categories) > 0:
self.result.is_failure(f"VXLAN config sanity check is not passing: {failed_categories}")
else:
self.result.is_success()

# Verifies the Vxlan config sanity
categories_to_check = ["localVtep", "mlag", "pd"]
for category in categories_to_check:
if not get_value(command_output, f"categories.{category}.allCheckPass"):
self.result.is_failure(f"Vxlan Category: {category} - Config sanity check is not passing")


class VerifyVxlanVniBinding(AntaTest):
Expand Down Expand Up @@ -135,31 +135,23 @@ def test(self) -> None:
"""Main test function for VerifyVxlanVniBinding."""
self.result.is_success()

no_binding = []
wrong_binding = []

if (vxlan1 := get_value(self.instance_commands[0].json_output, "vxlanIntfs.Vxlan1")) is None:
self.result.is_skipped("Vxlan1 interface is not configured")
return

for vni, vlan in self.inputs.bindings.items():
str_vni = str(vni)
retrieved_vlan = ""
if str_vni in vxlan1["vniBindings"]:
retrieved_vlan = vxlan1["vniBindings"][str_vni]["vlan"]
retrieved_vlan = get_value(vxlan1, f"vniBindings..{str_vni}..vlan", separator="..")
elif str_vni in vxlan1["vniBindingsToVrf"]:
retrieved_vlan = vxlan1["vniBindingsToVrf"][str_vni]["vlan"]
else:
no_binding.append(str_vni)
retrieved_vlan = None

if retrieved_vlan and vlan != retrieved_vlan:
wrong_binding.append({str_vni: retrieved_vlan})
retrieved_vlan = get_value(vxlan1, f"vniBindingsToVrf..{str_vni}..vlan", separator="..")

if no_binding:
self.result.is_failure(f"The following VNI(s) have no binding: {no_binding}")
if not retrieved_vlan:
self.result.is_failure(f"Interface: Vxlan1 VNI: {str_vni} - Binding not found")

if wrong_binding:
self.result.is_failure(f"The following VNI(s) have the wrong VLAN binding: {wrong_binding}")
elif vlan != retrieved_vlan:
self.result.is_failure(f"Interface: Vxlan1 VNI: {str_vni} VLAN: {vlan} - Wrong VLAN binding - Actual: {retrieved_vlan}")


class VerifyVxlanVtep(AntaTest):
Expand Down Expand Up @@ -206,10 +198,10 @@ def test(self) -> None:
difference2 = set(vxlan1["vteps"]).difference(set(inputs_vteps))

if difference1:
self.result.is_failure(f"The following VTEP peer(s) are missing from the Vxlan1 interface: {sorted(difference1)}")
self.result.is_failure(f"The following VTEP peer(s) are missing from the Vxlan1 interface: {', '.join(sorted(difference1))}")

if difference2:
self.result.is_failure(f"Unexpected VTEP peer(s) on Vxlan1 interface: {sorted(difference2)}")
self.result.is_failure(f"Unexpected VTEP peer(s) on Vxlan1 interface: {', '.join(sorted(difference2))}")


class VerifyVxlan1ConnSettings(AntaTest):
Expand Down Expand Up @@ -259,6 +251,6 @@ def test(self) -> None:

# Check vxlan1 source interface and udp port
if src_intf != self.inputs.source_interface:
self.result.is_failure(f"Source interface is not correct. Expected `{self.inputs.source_interface}` as source interface but found `{src_intf}` instead.")
self.result.is_failure(f"Interface: Vxlan1 - Incorrect Source interface - Expected: {self.inputs.source_interface} Actual: {src_intf}")
if port != self.inputs.udp_port:
self.result.is_failure(f"UDP port is not correct. Expected `{self.inputs.udp_port}` as UDP port but found `{port}` instead.")
self.result.is_failure(f"Interface: Vxlan1 - Incorrect UDP port - Expected: {self.inputs.udp_port} Actual: {port}")
2 changes: 1 addition & 1 deletion examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ anta.tests.vxlan:
source_interface: Loopback1
udp_port: 4789
- VerifyVxlan1Interface:
# Verifies the Vxlan1 interface status.
# Verifies if the Vxlan1 interface is configured and 'up/up'.
- VerifyVxlanConfigSanity:
# Verifies there are no VXLAN config-sanity inconsistencies.
- VerifyVxlanVniBinding:
Expand Down
40 changes: 16 additions & 24 deletions tests/units/anta_tests/test_vxlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Loopback0": {"lineProtocolStatus": "up", "interfaceStatus": "up"}}}],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Vxlan1 interface is not configured"]},
"expected": {"result": "skipped", "messages": ["Interface: Vxlan1 - Not configured"]},
},
{
"name": "failure-down-up",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "down", "interfaceStatus": "up"}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Vxlan1 interface is down/up"]},
"expected": {"result": "failure", "messages": ["Interface: Vxlan1 - Incorrect Line protocol status/Status - Expected: up/up Actual: down/up"]},
},
{
"name": "failure-up-down",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "up", "interfaceStatus": "down"}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Vxlan1 interface is up/down"]},
"expected": {"result": "failure", "messages": ["Interface: Vxlan1 - Incorrect Line protocol status/Status - Expected: up/up Actual: up/down"]},
},
{
"name": "failure-down-down",
"test": VerifyVxlan1Interface,
"eos_data": [{"interfaceDescriptions": {"Vxlan1": {"lineProtocolStatus": "down", "interfaceStatus": "down"}}}],
"inputs": None,
"expected": {"result": "failure", "messages": ["Vxlan1 interface is down/down"]},
"expected": {"result": "failure", "messages": ["Interface: Vxlan1 - Incorrect Line protocol status/Status - Expected: up/up Actual: down/down"]},
},
{
"name": "success",
Expand Down Expand Up @@ -176,15 +176,7 @@
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"VXLAN config sanity check is not passing: {'localVtep': {'description': 'Local VTEP Configuration Check', "
"'allCheckPass': False, 'detail': '', 'hasWarning': True, 'items': [{'name': 'Loopback IP Address', 'checkPass': True, "
"'hasWarning': False, 'detail': ''}, {'name': 'VLAN-VNI Map', 'checkPass': False, 'hasWarning': False, 'detail': "
"'No VLAN-VNI mapping in Vxlan1'}, {'name': 'Flood List', 'checkPass': False, 'hasWarning': True, 'detail': "
"'No VXLAN VLANs in Vxlan1'}, {'name': 'Routing', 'checkPass': True, 'hasWarning': False, 'detail': ''}, {'name': "
"'VNI VRF ACL', 'checkPass': True, 'hasWarning': False, 'detail': ''}, {'name': 'VRF-VNI Dynamic VLAN', 'checkPass': True, "
"'hasWarning': False, 'detail': ''}, {'name': 'Decap VRF-VNI Map', 'checkPass': True, 'hasWarning': False, 'detail': ''}]}}",
],
"messages": ["Vxlan Category: localVtep - Config sanity check is not passing"],
},
},
{
Expand Down Expand Up @@ -228,7 +220,7 @@
},
],
"inputs": {"bindings": {10010: 10, 10020: 20, 500: 1199}},
"expected": {"result": "failure", "messages": ["The following VNI(s) have no binding: ['10010']"]},
"expected": {"result": "failure", "messages": ["Interface: Vxlan1 VNI: 10010 - Binding not found"]},
},
{
"name": "failure-wrong-binding",
Expand All @@ -246,7 +238,7 @@
},
],
"inputs": {"bindings": {10020: 20, 500: 1199}},
"expected": {"result": "failure", "messages": ["The following VNI(s) have the wrong VLAN binding: [{'10020': 30}]"]},
"expected": {"result": "failure", "messages": ["Interface: Vxlan1 VNI: 10020 VLAN: 20 - Wrong VLAN binding - Actual: 30"]},
},
{
"name": "failure-no-and-wrong-binding",
Expand All @@ -266,7 +258,7 @@
"inputs": {"bindings": {10010: 10, 10020: 20, 500: 1199}},
"expected": {
"result": "failure",
"messages": ["The following VNI(s) have no binding: ['10010']", "The following VNI(s) have the wrong VLAN binding: [{'10020': 30}]"],
"messages": ["Interface: Vxlan1 VNI: 10010 - Binding not found", "Interface: Vxlan1 VNI: 10020 VLAN: 20 - Wrong VLAN binding - Actual: 30"],
},
},
{
Expand All @@ -288,21 +280,21 @@
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": ["10.1.1.5", "10.1.1.6"]}}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6", "10.1.1.7"]},
"expected": {"result": "failure", "messages": ["The following VTEP peer(s) are missing from the Vxlan1 interface: ['10.1.1.7']"]},
"expected": {"result": "failure", "messages": ["The following VTEP peer(s) are missing from the Vxlan1 interface: 10.1.1.7"]},
},
{
"name": "failure-no-vtep",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": []}}}],
"inputs": {"vteps": ["10.1.1.5", "10.1.1.6"]},
"expected": {"result": "failure", "messages": ["The following VTEP peer(s) are missing from the Vxlan1 interface: ['10.1.1.5', '10.1.1.6']"]},
"expected": {"result": "failure", "messages": ["The following VTEP peer(s) are missing from the Vxlan1 interface: 10.1.1.5, 10.1.1.6"]},
},
{
"name": "failure-no-input-vtep",
"test": VerifyVxlanVtep,
"eos_data": [{"vteps": {}, "interfaces": {"Vxlan1": {"vteps": ["10.1.1.5"]}}}],
"inputs": {"vteps": []},
"expected": {"result": "failure", "messages": ["Unexpected VTEP peer(s) on Vxlan1 interface: ['10.1.1.5']"]},
"expected": {"result": "failure", "messages": ["Unexpected VTEP peer(s) on Vxlan1 interface: 10.1.1.5"]},
},
{
"name": "failure-missmatch",
Expand All @@ -312,8 +304,8 @@
"expected": {
"result": "failure",
"messages": [
"The following VTEP peer(s) are missing from the Vxlan1 interface: ['10.1.1.5']",
"Unexpected VTEP peer(s) on Vxlan1 interface: ['10.1.1.7', '10.1.1.8']",
"The following VTEP peer(s) are missing from the Vxlan1 interface: 10.1.1.5",
"Unexpected VTEP peer(s) on Vxlan1 interface: 10.1.1.7, 10.1.1.8",
],
},
},
Expand Down Expand Up @@ -345,7 +337,7 @@
"inputs": {"source_interface": "lo1", "udp_port": 4789},
"expected": {
"result": "failure",
"messages": ["Source interface is not correct. Expected `Loopback1` as source interface but found `Loopback10` instead."],
"messages": ["Interface: Vxlan1 - Incorrect Source interface - Expected: Loopback1 Actual: Loopback10"],
},
},
{
Expand All @@ -356,8 +348,8 @@
"expected": {
"result": "failure",
"messages": [
"Source interface is not correct. Expected `Loopback1` as source interface but found `Loopback10` instead.",
"UDP port is not correct. Expected `4780` as UDP port but found `4789` instead.",
"Interface: Vxlan1 - Incorrect Source interface - Expected: Loopback1 Actual: Loopback10",
"Interface: Vxlan1 - Incorrect UDP port - Expected: 4780 Actual: 4789",
],
},
},
Expand Down

0 comments on commit e587f3f

Please sign in to comment.