Skip to content

Commit

Permalink
feat(anta): Added test case to verify SNMP Trap PDUs counters (#828)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitthalmagadum authored Oct 11, 2024
1 parent 387c281 commit 839f70a
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 3 deletions.
1 change: 1 addition & 0 deletions anta/custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,4 @@ def validate_regex(value: str) -> str:
]
BgpUpdateError = Literal["inUpdErrWithdraw", "inUpdErrIgnore", "inUpdErrDisableAfiSafi", "disabledAfiSafi", "lastUpdErrTime"]
BfdProtocol = Literal["bgp", "isis", "lag", "ospf", "ospfv3", "pim", "route-input", "static-bfd", "static-route", "vrrp", "vxlan"]
SnmpPdu = Literal["inGetPdus", "inGetNextPdus", "inSetPdus", "outGetResponsePdus", "outTrapPdus"]
61 changes: 59 additions & 2 deletions anta/tests/snmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
# mypy: disable-error-code=attr-defined
from __future__ import annotations

from typing import TYPE_CHECKING, ClassVar
from typing import TYPE_CHECKING, ClassVar, get_args

from anta.custom_types import PositiveInteger
from anta.custom_types import PositiveInteger, SnmpPdu
from anta.models import AntaCommand, AntaTest
from anta.tools import get_value

Expand Down Expand Up @@ -237,3 +237,60 @@ def test(self) -> None:
self.result.is_failure(f"Expected `{self.inputs.contact}` as the contact, but found `{contact}` instead.")
else:
self.result.is_success()


class VerifySnmpPDUCounters(AntaTest):
"""Verifies the SNMP PDU counters.
By default, all SNMP PDU counters will be checked for any non-zero values.
An optional list of specific SNMP PDU(s) can be provided for granular testing.
Expected Results
----------------
* Success: The test will pass if the SNMP PDU counter(s) are non-zero/greater than zero.
* Failure: The test will fail if the SNMP PDU counter(s) are zero/None/Not Found.
Examples
--------
```yaml
anta.tests.snmp:
- VerifySnmpPDUCounters:
pdus:
- outTrapPdus
- inGetNextPdus
```
"""

name = "VerifySnmpPDUCounters"
description = "Verifies the SNMP PDU counters."
categories: ClassVar[list[str]] = ["snmp"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp", revision=1)]

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

pdus: list[SnmpPdu] | None = None
"""Optional list of SNMP PDU counters to be verified. If not provided, test will verifies all PDU counters."""

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifySnmpPDUCounters."""
snmp_pdus = self.inputs.pdus
command_output = self.instance_commands[0].json_output

# Verify SNMP PDU counters.
if not (pdu_counters := get_value(command_output, "counters")):
self.result.is_failure("SNMP counters not found.")
return

# In case SNMP PDUs not provided, It will check all the update error counters.
if not snmp_pdus:
snmp_pdus = list(get_args(SnmpPdu))

failures = {pdu: value for pdu in snmp_pdus if (value := pdu_counters.get(pdu, "Not Found")) == "Not Found" or value == 0}

# Check if any failures
if not failures:
self.result.is_success()
else:
self.result.is_failure(f"The following SNMP PDU counters are not found or have zero PDU counters:\n{failures}")
3 changes: 3 additions & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@ anta.tests.snmp:
location: New York
- VerifySnmpContact:
contact: [email protected]
- VerifySnmpPDUCounters:
pdus:
- outTrapPdus

anta.tests.software:
- VerifyEOSVersion:
Expand Down
85 changes: 84 additions & 1 deletion tests/units/anta_tests/test_snmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from typing import Any

from anta.tests.snmp import VerifySnmpContact, VerifySnmpIPv4Acl, VerifySnmpIPv6Acl, VerifySnmpLocation, VerifySnmpStatus
from anta.tests.snmp import VerifySnmpContact, VerifySnmpIPv4Acl, VerifySnmpIPv6Acl, VerifySnmpLocation, VerifySnmpPDUCounters, VerifySnmpStatus
from tests.units.anta_tests import test

DATA: list[dict[str, Any]] = [
Expand Down Expand Up @@ -152,4 +152,87 @@
"messages": ["SNMP contact is not configured."],
},
},
{
"name": "success",
"test": VerifySnmpPDUCounters,
"eos_data": [
{
"counters": {
"inGetPdus": 3,
"inGetNextPdus": 2,
"inSetPdus": 3,
"outGetResponsePdus": 3,
"outTrapPdus": 9,
},
}
],
"inputs": {},
"expected": {"result": "success"},
},
{
"name": "success-specific-pdus",
"test": VerifySnmpPDUCounters,
"eos_data": [
{
"counters": {
"inGetPdus": 3,
"inGetNextPdus": 0,
"inSetPdus": 0,
"outGetResponsePdus": 0,
"outTrapPdus": 9,
},
}
],
"inputs": {"pdus": ["inGetPdus", "outTrapPdus"]},
"expected": {"result": "success"},
},
{
"name": "failure-counters-not-found",
"test": VerifySnmpPDUCounters,
"eos_data": [
{
"counters": {},
}
],
"inputs": {},
"expected": {"result": "failure", "messages": ["SNMP counters not found."]},
},
{
"name": "failure-incorrect-counters",
"test": VerifySnmpPDUCounters,
"eos_data": [
{
"counters": {
"inGetPdus": 0,
"inGetNextPdus": 2,
"inSetPdus": 0,
"outGetResponsePdus": 3,
"outTrapPdus": 9,
},
}
],
"inputs": {},
"expected": {
"result": "failure",
"messages": ["The following SNMP PDU counters are not found or have zero PDU counters:\n{'inGetPdus': 0, 'inSetPdus': 0}"],
},
},
{
"name": "failure-pdu-not-found",
"test": VerifySnmpPDUCounters,
"eos_data": [
{
"counters": {
"inGetNextPdus": 0,
"inSetPdus": 0,
"outGetResponsePdus": 0,
},
}
],
"inputs": {"pdus": ["inGetPdus", "outTrapPdus"]},
"expected": {
"result": "failure",
"messages": ["The following SNMP PDU counters are not found or have zero PDU counters:\n{'inGetPdus': 'Not Found', 'outTrapPdus': 'Not Found'}"],
},
},
]

0 comments on commit 839f70a

Please sign in to comment.