Skip to content

Commit b17949c

Browse files
author
Roman Savchuk
committed
Implement new TC for SNMP ifErrors/ifDiscard
1 parent 525c3df commit b17949c

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

tests/snmp/test_snmp_interfaces.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import pytest
33
from tests.common.helpers.assertions import pytest_assert
44
from tests.common.helpers.snmp_helpers import get_snmp_facts
5+
from tests.platform_tests.counterpoll.counterpoll_helper import ConterpollHelper # noqa: F401
6+
from tests.platform_tests.counterpoll.counterpoll_constants import CounterpollConstants # noqa: F401
7+
from tests.ip.ip_util import parse_rif_counters
58

69
pytestmark = [
710
pytest.mark.topology('any'),
@@ -10,6 +13,87 @@
1013

1114
logger = logging.getLogger(__name__)
1215

16+
SAI_PORT_STAT_IF_IN_ERRORS = 'SAI_PORT_STAT_IF_IN_ERRORS'
17+
SAI_PORT_STAT_IF_OUT_ERRORS = 'SAI_PORT_STAT_IF_OUT_ERRORS'
18+
SAI_PORT_STAT_IF_IN_DISCARDS = 'SAI_PORT_STAT_IF_IN_DISCARDS'
19+
SAI_PORT_STAT_IF_OUT_DISCARDS = 'SAI_PORT_STAT_IF_OUT_DISCARDS'
20+
SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS = 'SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS'
21+
SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS = 'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS'
22+
23+
COUNTERS_PORT_NAME_MAP = 'COUNTERS_PORT_NAME_MAP'
24+
COUNTERS_RIF_NAME_MAP = 'COUNTERS_RIF_NAME_MAP'
25+
COUNTER_VALUE = 5000
26+
27+
28+
@pytest.fixture()
29+
def disable_conterpoll(duthost):
30+
"""
31+
Disable conterpoll for RIF and PORT and re-enable it when TC finished
32+
:param duthost: DUT host object
33+
:return: dict with data collected from DUT per each port
34+
"""
35+
ConterpollHelper.disable_counterpoll(duthost, counter_type_list=[CounterpollConstants.PORT,
36+
CounterpollConstants.RIF])
37+
yield
38+
ConterpollHelper.enable_counterpoll(duthost, counter_type_list=[CounterpollConstants.PORT,
39+
CounterpollConstants.RIF])
40+
41+
42+
def get_interfaces(duthost, tbinfo):
43+
"""
44+
Method to get interfaces for testing
45+
:param duthost: DUT host object
46+
:return: RIF interface name in case available in topo. If not - return Port Channel name and interface in Port
47+
Channel
48+
"""
49+
rif_counters = parse_rif_counters(duthost.command("show interfaces counters rif")["stdout_lines"])
50+
for interface in rif_counters:
51+
if 'Eth' in interface:
52+
return interface, interface
53+
else:
54+
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
55+
return mg_facts["minigraph_portchannels"][interface]['members'][0], interface
56+
57+
58+
def get_oid_for_interface(duthost, table_name, interface_name):
59+
"""
60+
Method to get interface oid from Counters DB
61+
:param duthost: DUT host object
62+
:param table_name: table name
63+
:param interface_name: interface name
64+
:return: oid for specific interface
65+
"""
66+
return duthost.command(f"docker exec -i database redis-cli --raw -n 2 HMGET "
67+
f"{table_name} {interface_name}")["stdout"]
68+
69+
70+
def set_counters_value(duthost, interface_oid, counter_name, counter_value):
71+
"""
72+
Method to set interface counter value in Counters DB
73+
:param duthost: DUT host object
74+
:param interface_oid: oid value
75+
:param counter_name: counter name
76+
:param counter_value: counter value
77+
"""
78+
counters_oid = "COUNTERS:{}".format(interface_oid)
79+
duthost.command(f"sudo redis-cli -n 2 hset {counters_oid} {counter_name} {counter_value}")
80+
81+
82+
def get_port_interface_counter(duthost, interface_name):
83+
"""
84+
Method to set interface counter value in Counters DB
85+
:param duthost: DUT host object
86+
:param interface_name: name of interface to collect counters
87+
:return : dict with counters
88+
"""
89+
port_counters = duthost.show_and_parse("show interfaces counters")
90+
for port_counter in port_counters:
91+
if port_counter['iface'] == interface_name:
92+
for key, value in port_counter.items():
93+
if ',' in value:
94+
port_counter[key] = value.replace(',', '')
95+
return port_counter
96+
1397

1498
def collect_all_facts(duthost, ports_list, namespace=None):
1599
"""
@@ -242,3 +326,70 @@ def test_snmp_interfaces_mibs(duthosts, enum_rand_one_per_hwsku_hostname, localh
242326
result = verify_port_ifindex(snmp_facts, speed_snmp)
243327
pytest_assert(
244328
not result, "Unexpected comparsion of SNMP: {}".format(result))
329+
330+
331+
def test_snmp_interfaces_error_discard(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts,
332+
enum_asic_index, disable_conterpoll, tbinfo, mg_facts):
333+
"""Verify correct behaviour of port MIBs ifInError, ifOutError, IfInDiscards, IfOutDiscards """
334+
duthost = duthosts[enum_rand_one_per_hwsku_hostname]
335+
hostip = duthost.host.options['inventory_manager'].get_host(
336+
duthost.hostname).vars['ansible_host']
337+
port_interface, rif_interface = get_interfaces(duthost, tbinfo)
338+
logger.info(f'Selected interfaces: port {port_interface}, rif {rif_interface}')
339+
# Get interfaces oid
340+
port_oid = get_oid_for_interface(duthost, COUNTERS_PORT_NAME_MAP, port_interface)
341+
rif_oid = get_oid_for_interface(duthost, COUNTERS_RIF_NAME_MAP, rif_interface)
342+
343+
logger.info('Set port and rif counters in COUNTERS DB')
344+
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_IN_ERRORS} counter to {COUNTER_VALUE}')
345+
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_IN_ERRORS, COUNTER_VALUE)
346+
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_IN_DISCARDS} counter to {COUNTER_VALUE}')
347+
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_IN_DISCARDS, COUNTER_VALUE)
348+
logger.info(f'Set port {rif_interface} {SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS} counter to {COUNTER_VALUE}')
349+
set_counters_value(duthost, rif_oid, SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS, COUNTER_VALUE)
350+
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_OUT_DISCARDS} counter to {COUNTER_VALUE}')
351+
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_OUT_DISCARDS, COUNTER_VALUE)
352+
logger.info(f'Set port {rif_interface} {SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS} counter to {COUNTER_VALUE}')
353+
set_counters_value(duthost, rif_oid, SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS, COUNTER_VALUE)
354+
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_OUT_ERRORS} counter to {COUNTER_VALUE}')
355+
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_OUT_ERRORS, COUNTER_VALUE)
356+
357+
rif_counters = parse_rif_counters(duthost.command("show interfaces counters rif")["stdout_lines"])
358+
port_counters = get_port_interface_counter(duthost, port_interface)
359+
360+
logger.info('Compare rif counters in COUNTERS DB and counters get from SONiC CLI')
361+
assert int(rif_counters[rif_interface]['tx_err']) == COUNTER_VALUE, \
362+
f"tx_err value is {rif_counters[rif_interface]['tx_err']} not set to {COUNTER_VALUE}"
363+
assert int(rif_counters[rif_interface]['rx_err']) == COUNTER_VALUE, \
364+
f"rx_err value is {rif_counters[rif_interface]['tx_err']} not set to {COUNTER_VALUE}"
365+
366+
logger.info('Compare port counters in COUNTERS DB and counters get from SONiC CLI')
367+
assert int(port_counters['tx_err']) == COUNTER_VALUE, \
368+
f"tx_err value is {port_counters['tx_err']} not set to {COUNTER_VALUE}"
369+
assert int(port_counters['rx_err']) == COUNTER_VALUE, \
370+
f"rx_err value is {port_counters['rx_err']} not set to {COUNTER_VALUE}"
371+
assert int(port_counters['tx_drp']) == COUNTER_VALUE, \
372+
f"tx_drp value is {port_counters['tx_drp']} not set to {COUNTER_VALUE}"
373+
assert int(port_counters['rx_drp']) == COUNTER_VALUE, \
374+
f"rx_drp value is {port_counters['rx_drp']} not set to {COUNTER_VALUE}"
375+
376+
snmp_facts = get_snmp_facts(
377+
localhost, host=hostip, version="v2c",
378+
community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts']
379+
minigraph_port_name_to_alias_map = mg_facts['minigraph_port_name_to_alias_map']
380+
snmp_port_map = {snmp_facts['snmp_interfaces'][idx]['name']: idx for idx in snmp_facts['snmp_interfaces']}
381+
interface = rif_interface if 'PortChannel' in rif_interface else minigraph_port_name_to_alias_map[rif_interface]
382+
rif_snmp_facts = snmp_facts['snmp_interfaces'][snmp_port_map[interface]]
383+
384+
assert (int(rif_snmp_facts['ifInDiscards']) == int(rif_counters[rif_interface]['rx_err']) +
385+
int(port_counters['rx_drp'])), \
386+
(f"ifInDiscards value is {rif_snmp_facts['ifInDiscards']} but must be "
387+
f"{int(rif_counters[rif_interface]['rx_err']) + int(port_counters['rx_drp'])}")
388+
assert (int(rif_snmp_facts['ifOutDiscards']) == int(rif_counters[rif_interface]['tx_err']) +
389+
int(port_counters['tx_drp'])), \
390+
(f"ifOutDiscards value is {rif_snmp_facts['ifOutDiscards']} but must be "
391+
f"{int(rif_counters[rif_interface]['tx_err']) + int(port_counters['tx_drp'])}")
392+
assert int(rif_snmp_facts['ifInErrors']) == COUNTER_VALUE, \
393+
f"ifInErrors value is {rif_snmp_facts['ifInErrors']} but must be {COUNTER_VALUE}"
394+
assert int(rif_snmp_facts['ifOutErrors']) == COUNTER_VALUE, \
395+
f"ifOutErrors value is {rif_snmp_facts['ifOutErrors']} but must be {COUNTER_VALUE}"

0 commit comments

Comments
 (0)