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

Implement new TC for SNMP ifErrors/ifDiscard #14916

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
148 changes: 148 additions & 0 deletions tests/snmp/test_snmp_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import pytest
from tests.common.helpers.assertions import pytest_assert
from tests.common.helpers.snmp_helpers import get_snmp_facts
from tests.platform_tests.counterpoll.counterpoll_helper import ConterpollHelper
from tests.ip.ip_util import parse_rif_counters

pytestmark = [
pytest.mark.topology('any'),
Expand All @@ -10,6 +12,85 @@

logger = logging.getLogger(__name__)

SAI_PORT_STAT_IF_IN_ERRORS = 'SAI_PORT_STAT_IF_IN_ERRORS'
SAI_PORT_STAT_IF_OUT_ERRORS = 'SAI_PORT_STAT_IF_OUT_ERRORS'
SAI_PORT_STAT_IF_IN_DISCARDS = 'SAI_PORT_STAT_IF_IN_DISCARDS'
SAI_PORT_STAT_IF_OUT_DISCARDS = 'SAI_PORT_STAT_IF_OUT_DISCARDS'
SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS = 'SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS'
SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS = 'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS'

COUNTERS_PORT_NAME_MAP = 'COUNTERS_PORT_NAME_MAP'
COUNTERS_RIF_NAME_MAP = 'COUNTERS_RIF_NAME_MAP'
COUNTER_VALUE = 5000


@pytest.fixture()
def disable_conterpoll(duthost):
"""
Disable conterpoll for RIF and PORT and re-enable it when TC finished
:param duthost: DUT host object
:return: dict with data collected from DUT per each port
"""
ConterpollHelper.disable_counterpoll(duthost, counter_type_list=['port', 'rif'])
yield
ConterpollHelper.enable_counterpoll(duthost, counter_type_list=['port', 'rif'])


def get_interfaces(duthost, tbinfo):
"""
Method to get interfaces for testing
:param duthost: DUT host object
:return: RIF interface name in case available in topo. If not - return Port Channel name and interface in Port
Channel
"""
rif_counters = parse_rif_counters(duthost.command("show interfaces counters rif")["stdout_lines"])
for interface in rif_counters:
if 'Eth' in interface:
return interface, interface
else:
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
return mg_facts["minigraph_portchannels"][interface]['members'][0], interface


def get_oid_for_interface(duthost, table_name, interface_name):
"""
Method to get interface oid from Counters DB
:param duthost: DUT host object
:param table_name: table name
:param interface_name: interface name
:return: oid for specific interface
"""
return duthost.command(f"docker exec -i database redis-cli --raw -n 2 HMGET "
f"{table_name} {interface_name}")["stdout"]


def set_counters_value(duthost, interface_oid, counter_name, counter_value):
"""
Method to set interface counter value in Counters DB
:param duthost: DUT host object
:param interface_oid: oid value
:param counter_name: counter name
:param counter_value: counter value
"""
counters_oid = "COUNTERS:{}".format(interface_oid)
duthost.command(f"sudo redis-cli -n 2 hset {counters_oid} {counter_name} {counter_value}")


def get_port_interface_counter(duthost, interface_name):
"""
Method to set interface counter value in Counters DB
:param duthost: DUT host object
:param interface_name: name of interface to collect counters
:return : dict with counters
"""
port_counters = duthost.show_and_parse("show interfaces counters")
for port_counter in port_counters:
if port_counter['iface'] == interface_name:
for key, value in port_counter.items():
if ',' in value:
port_counter[key] = value.replace(',', '')
return port_counter


def collect_all_facts(duthost, ports_list, namespace=None):
"""
Expand Down Expand Up @@ -242,3 +323,70 @@ def test_snmp_interfaces_mibs(duthosts, enum_rand_one_per_hwsku_hostname, localh
result = verify_port_ifindex(snmp_facts, speed_snmp)
pytest_assert(
not result, "Unexpected comparsion of SNMP: {}".format(result))


def test_snmp_interfaces_error_discard(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_all_duts,
enum_asic_index, disable_conterpoll, tbinfo, mg_facts):
"""Verify correct behaviour of port MIBs ifInError, ifOutError, IfInDiscards, IfOutDiscards """
duthost = duthosts[enum_rand_one_per_hwsku_hostname]
hostip = duthost.host.options['inventory_manager'].get_host(
duthost.hostname).vars['ansible_host']
port_interface, rif_interface = get_interfaces(duthost, tbinfo)
logger.info(f'Selected interfaces: port {port_interface}, rif {rif_interface}')
# Get interfaces oid
port_oid = get_oid_for_interface(duthost, COUNTERS_PORT_NAME_MAP, port_interface)
rif_oid = get_oid_for_interface(duthost, COUNTERS_RIF_NAME_MAP, rif_interface)

logger.info('Set port and rif counters in COUNTERS DB')
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_IN_ERRORS} counter to {COUNTER_VALUE}')
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_IN_ERRORS, COUNTER_VALUE)
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_IN_DISCARDS} counter to {COUNTER_VALUE}')
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_IN_DISCARDS, COUNTER_VALUE)
logger.info(f'Set port {rif_interface} {SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS} counter to {COUNTER_VALUE}')
set_counters_value(duthost, rif_oid, SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS, COUNTER_VALUE)
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_OUT_DISCARDS} counter to {COUNTER_VALUE}')
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_OUT_DISCARDS, COUNTER_VALUE)
logger.info(f'Set port {rif_interface} {SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS} counter to {COUNTER_VALUE}')
set_counters_value(duthost, rif_oid, SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS, COUNTER_VALUE)
logger.info(f'Set port {port_interface} {SAI_PORT_STAT_IF_OUT_ERRORS} counter to {COUNTER_VALUE}')
set_counters_value(duthost, port_oid, SAI_PORT_STAT_IF_OUT_ERRORS, COUNTER_VALUE)

rif_counters = parse_rif_counters(duthost.command("show interfaces counters rif")["stdout_lines"])
port_counters = get_port_interface_counter(duthost, port_interface)

logger.info('Compare rif counters in COUNTERS DB and counters get from SONiC CLI')
assert int(rif_counters[rif_interface]['tx_err']) == COUNTER_VALUE, \
f"tx_err value is {rif_counters[rif_interface]['tx_err']} not set to {COUNTER_VALUE}"
assert int(rif_counters[rif_interface]['rx_err']) == COUNTER_VALUE, \
f"rx_err value is {rif_counters[rif_interface]['tx_err']} not set to {COUNTER_VALUE}"

logger.info('Compare port counters in COUNTERS DB and counters get from SONiC CLI')
assert int(port_counters['tx_err']) == COUNTER_VALUE, \
f"tx_err value is {port_counters['tx_err']} not set to {COUNTER_VALUE}"
assert int(port_counters['rx_err']) == COUNTER_VALUE, \
f"rx_err value is {port_counters['rx_err']} not set to {COUNTER_VALUE}"
assert int(port_counters['tx_drp']) == COUNTER_VALUE, \
f"tx_drp value is {port_counters['tx_drp']} not set to {COUNTER_VALUE}"
assert int(port_counters['rx_drp']) == COUNTER_VALUE, \
f"rx_drp value is {port_counters['rx_drp']} not set to {COUNTER_VALUE}"

snmp_facts = get_snmp_facts(
localhost, host=hostip, version="v2c",
community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts']
minigraph_port_name_to_alias_map = mg_facts['minigraph_port_name_to_alias_map']
snmp_port_map = {snmp_facts['snmp_interfaces'][idx]['name']: idx for idx in snmp_facts['snmp_interfaces']}
interface = rif_interface if 'PortChannel' in rif_interface else minigraph_port_name_to_alias_map[rif_interface]
rif_snmp_facts = snmp_facts['snmp_interfaces'][snmp_port_map[interface]]

assert (int(rif_snmp_facts['ifInDiscards']) == int(rif_counters[rif_interface]['rx_err']) +
int(port_counters['rx_drp'])), \
(f"ifInDiscards value is {rif_snmp_facts['ifInDiscards']} but must be "
f"{int(rif_counters[rif_interface]['rx_err']) + int(port_counters['rx_drp'])}")
assert (int(rif_snmp_facts['ifOutDiscards']) == int(rif_counters[rif_interface]['tx_err']) +
int(port_counters['tx_drp'])), \
(f"ifOutDiscards value is {rif_snmp_facts['ifOutDiscards']} but must be "
f"{int(rif_counters[rif_interface]['tx_err']) + int(port_counters['tx_drp'])}")
assert int(rif_snmp_facts['ifInErrors']) == COUNTER_VALUE, \
f"ifInErrors value is {rif_snmp_facts['ifInErrors']} but must be {COUNTER_VALUE}"
assert int(rif_snmp_facts['ifOutErrors']) == COUNTER_VALUE, \
f"ifOutErrors value is {rif_snmp_facts['ifOutErrors']} but must be {COUNTER_VALUE}"
Loading