Skip to content

Commit

Permalink
tests fixes for zero ports setups
Browse files Browse the repository at this point in the history
Signed-off-by: Sharon Lutati <slutati@nvidia.com>
  • Loading branch information
slutati1536 committed Jun 13, 2021
1 parent a26f2d5 commit 39f18e6
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 56 deletions.
65 changes: 35 additions & 30 deletions tests/common/platform/interface_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
This script contains re-usable functions for checking status of interfaces on SONiC.
"""
import json
import re
import logging
import pytest
from transceiver_utils import all_transceivers_detected


Expand Down Expand Up @@ -42,47 +44,39 @@ def check_interface_status(dut, asic_index, interfaces, xcvr_skip_list):
asichost = dut.asic_instance(asic_index)
namespace = asichost.get_asic_namespace()
logging.info("Check interface status using cmd 'show interface'")
#TODO Remove this logic when minigraph facts supports namespace in multi_asic
mg_ports = dut.minigraph_facts(host=dut.hostname)["ansible_facts"]["minigraph_ports"]
if asic_index is not None:
portmap = get_port_map(dut, asic_index)
# Check if the interfaces of this AISC is present in mg_ports
interface_list = {k:v for k, v in portmap.items() if k in mg_ports}
mg_ports = interface_list
ports = get_port_map(dut, asic_index)
output = dut.command("show interface description")
intf_status = parse_intf_status(output["stdout_lines"][2:])
check_intf_presence_command = 'show interface transceiver presence {}'
for intf in interfaces:
expected_oper = "up" if intf in mg_ports else "down"
expected_admin = "up" if intf in mg_ports else "down"
expected_oper = "up" if intf in ports else "down"
expected_admin = "up" if intf in ports else "down"
if intf not in intf_status:
logging.info("Missing status for interface %s" % intf)
return False
if intf_status[intf]["oper"] != expected_oper:
logging.info("Oper status of interface %s is %s, expected '%s'" % (intf, intf_status[intf]["oper"],
expected_oper))
logging.info("Oper status of interface %s is %s, expected '%s'" % (intf, intf_status[intf]["oper"], expected_oper))
return False
if intf_status[intf]["admin"] != expected_admin:
logging.info("Admin status of interface %s is %s, expected '%s'" % (intf, intf_status[intf]["admin"],
expected_admin))
logging.info("Admin status of interface %s is %s, expected '%s'" % (intf, intf_status[intf]["admin"], expected_admin))
return False

# Cross check the interface SFP presence status
if intf not in xcvr_skip_list[dut.hostname]:
if xcvr_skip_list and intf not in xcvr_skip_list[dut.hostname]:
check_presence_output = dut.command(check_intf_presence_command.format(intf))
presence_list = check_presence_output["stdout_lines"][2].split()
assert intf in presence_list, "Wrong interface name in the output: %s" % str(presence_list)
assert 'Present' in presence_list, "Status is not expected, presence status: %s" % str(presence_list)

logging.info("Check interface status using the interface_facts module")
intf_facts = dut.interface_facts(up_ports=mg_ports, namespace=namespace)["ansible_facts"]
intf_facts = dut.interface_facts(up_ports=ports, namespace=namespace)["ansible_facts"]
down_ports = intf_facts["ansible_interface_link_down_ports"]
if len(down_ports) != 0:
logging.info("Some interfaces are down: %s" % str(down_ports))
return False

return True


# This API to check the interface information actoss all front end ASIC's
def check_all_interface_information(dut, interfaces, xcvr_skip_list):
for asic_index in dut.get_frontend_asic_ids():
Expand All @@ -98,6 +92,7 @@ def check_all_interface_information(dut, interfaces, xcvr_skip_list):

return True


# This API to check the interface information per asic.
def check_interface_information(dut, asic_index, interfaces, xcvr_skip_list):
if not all_transceivers_detected(dut, asic_index, interfaces, xcvr_skip_list):
Expand All @@ -109,24 +104,34 @@ def check_interface_information(dut, asic_index, interfaces, xcvr_skip_list):

return True


def get_port_map(dut, asic_index=None):
"""
@summary: Get the port mapping info from the DUT
@return: a dictionary containing the port map
"""
logging.info("Retrieving port mapping from DUT")
# copy the helper to DUT
src_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'files/getportmap.py')
dest_path = os.path.join('/usr/share/sonic/device', dut.facts['platform'], 'plugins/getportmap.py')
dut.copy(src=src_path, dest=dest_path)

# execute command on the DUT to get portmap
get_portmap_cmd = "docker exec pmon python /usr/share/sonic/platform/plugins/getportmap.py -asicid {}".format(asic_index)
portmap_json_string = dut.command(get_portmap_cmd)["stdout"]

if asic_index is not None:
asichost = dut.asic_instance(asic_index)
cfg_facts = asichost.config_facts(host=dut.hostname, source="persistent", verbose=False)['ansible_facts']
else:
# execute command on the DUT to get port map from config_db.json
validate_config_db_file_exist(dut)
get_cfg_facts_cmd = "cat /etc/sonic/config_db.json"
portmap_json_string = dut.command(get_cfg_facts_cmd)["stdout"]
cfg_facts = json.loads(portmap_json_string)
# parse the json
port_mapping = json.loads(portmap_json_string)
assert port_mapping, "Retrieve port mapping from DUT failed"

return port_mapping

port_mapping_res = {}
port_mapping = cfg_facts.get("PORT", {})
for port, port_dict_info in port_mapping.items():
port_alias = port_dict_info["alias"]
port_alias_number = int(re.search('etp(\d+)', port_alias).group(1))
port_mapping_res[port] = [port_alias_number]
return port_mapping_res


def validate_config_db_file_exist(dut):
config_db_location_cmd = "ls /etc/sonic/config_db.json"
config_db_location_string = dut.command(config_db_location_cmd)["stdout"]
if re.search("No such file or directory", config_db_location_string):
assert False, "No /etc/sonic/config_db.json found on dut - please load a valid config_db.json to switch"
6 changes: 4 additions & 2 deletions tests/common/plugins/sanity_check/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,12 @@ def _check_interfaces_on_dut(*args, **kwargs):
check_result = {"failed": True, "check_item": "interfaces", "host": dut.hostname}
for asic in dut.asics:
ip_interfaces = []
phy_interfaces = []
cfg_facts = asic.config_facts(host=dut.hostname,
source="persistent", verbose=False)['ansible_facts']
phy_interfaces = [k for k, v in cfg_facts["PORT"].items() if
"admin_status" in v and v["admin_status"] == "up"]
if "PORT" in cfg_facts:
phy_interfaces = [k for k, v in cfg_facts["PORT"].items() if
"admin_status" in v and v["admin_status"] == "up"]
if "PORTCHANNEL_INTERFACE" in cfg_facts:
ip_interfaces = cfg_facts["PORTCHANNEL_INTERFACE"].keys()
if "VLAN_INTERFACE" in cfg_facts:
Expand Down
3 changes: 2 additions & 1 deletion tests/platform_tests/mellanox/test_check_sfp_presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
pytest.mark.topology('any')
]


def test_check_sfp_presence(duthosts, rand_one_dut_hostname, conn_graph_facts):
"""This test case is to check SFP presence status with CLI and sysfs.
"""
duthost = duthosts[rand_one_dut_hostname]
ports_config = json.loads(duthost.command("sudo sonic-cfggen -d --var-json PORT")["stdout"])
duthost.command("sudo sonic-cfggen -d --var-json PORT")
check_intf_presence_command = 'show interface transceiver presence {}'

logging.info("Use show interface status information")
Expand Down
17 changes: 10 additions & 7 deletions tests/platform_tests/mellanox/test_check_sfp_using_ethtool.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
https://github.com/Azure/SONiC/blob/master/doc/pmon/sonic_platform_test_plan.md
"""
import logging
import os
import json
import pytest
from tests.common.fixtures.conn_graph_facts import conn_graph_facts
from tests.common.platform.interface_utils import get_port_map, check_interface_status
from tests.common.mellanox_data import SPC3_HWSKUS
from check_hw_mgmt_service import check_hw_management_service

Expand All @@ -17,12 +17,16 @@
pytest.mark.topology('any')
]


def test_check_sfp_using_ethtool(duthosts, rand_one_dut_hostname, conn_graph_facts, tbinfo):
"""This test case is to check SFP using the ethtool.
"""
duthost = duthosts[rand_one_dut_hostname]
ports_config = json.loads(duthost.command("sudo sonic-cfggen -d --var-json PORT")["stdout"])

ports_config = {}
ports_config_output = duthost.command("sudo sonic-cfggen -d --var-json PORT")["stdout"]
if ports_config_output:
# in the case of zero ports the json output can be none
ports_config = json.loads(ports_config_output)
logging.info("Use the ethtool to check SFP information")
if duthost.facts["hwsku"] in SPC3_HWSKUS:
lanes_divider = 8
Expand All @@ -46,9 +50,8 @@ def test_check_sfp_using_ethtool(duthosts, rand_one_dut_hostname, conn_graph_fac
"Unexpected line %s in %s" % (line, str(ethtool_sfp_output["stdout_lines"]))

logging.info("Check interface status")
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
intf_facts = duthost.interface_facts(up_ports=mg_facts["minigraph_ports"])["ansible_facts"]
assert len(intf_facts["ansible_interface_link_down_ports"]) == 0, \
"Some interfaces are down: %s" % str(intf_facts["ansible_interface_link_down_ports"])
for asic_index in duthost.get_frontend_asic_ids():
interface_list = get_port_map(duthost, asic_index)
assert check_interface_status(duthost, asic_index, interface_list, []), "Not all interfaces are up"

check_hw_management_service(duthost)
8 changes: 4 additions & 4 deletions tests/platform_tests/sfp/test_sfputil.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from util import parse_eeprom
from util import parse_output
from util import get_dev_conn
from tests.common.platform.interface_utils import get_port_map, check_interface_status

cmd_sfp_presence = "sudo sfputil show presence"
cmd_sfp_eeprom = "sudo sfputil show eeprom"
Expand Down Expand Up @@ -90,10 +91,9 @@ def test_check_sfputil_reset(duthosts, enum_rand_one_per_hwsku_frontend_hostname
assert parsed_presence[intf] == "Present", "Interface presence is not 'Present'"

logging.info("Check interface status")
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
intf_facts = duthost.interface_facts(up_ports=mg_facts["minigraph_ports"])["ansible_facts"]
assert len(intf_facts["ansible_interface_link_down_ports"]) == 0, \
"Some interfaces are down: {}".format(intf_facts["ansible_interface_link_down_ports"])
for asic_index in duthost.get_frontend_asic_ids():
interface_list = get_port_map(duthost, asic_index)
assert check_interface_status(duthost, asic_index, interface_list, []), "Not all interfaces are up"


def test_check_sfputil_low_power_mode(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, conn_graph_facts, tbinfo):
Expand Down
22 changes: 10 additions & 12 deletions tests/snmp/test_snmp_lldp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import re
from tests.common.platform.interface_utils import get_port_map

pytestmark = [
pytest.mark.topology('any'),
Expand Down Expand Up @@ -38,11 +39,14 @@ def test_snmp_lldp(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_
hostip = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host']

snmp_facts = localhost.snmp_facts(host=hostip, version="v2c", community=creds_all_duts[duthost]["snmp_rocommunity"])['ansible_facts']
mg_facts = {}
for asic_id in duthost.get_asic_ids():
mg_facts_ns = duthost.asic_instance(asic_id).get_extended_minigraph_facts(tbinfo)['minigraph_neighbors']
if mg_facts_ns is not None:
mg_facts.update(mg_facts_ns)
for asic in duthost.asics:
lldp_nei = []
cfg_facts = asic.config_facts(host=duthost.hostname,
source="persistent", verbose=False)['ansible_facts']
if "PORT" in cfg_facts:
for port, port_info_dict in cfg_facts["PORT"].items():
if re.search('ARISTA', port_info_dict['description']):
lldp_nei.append(port)

print snmp_facts['snmp_lldp']
for k in ['lldpLocChassisIdSubtype', 'lldpLocChassisId', 'lldpLocSysName', 'lldpLocSysDesc']:
Expand All @@ -64,12 +68,6 @@ def test_snmp_lldp(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_
assert snmp_facts['snmp_lldp'][k]
assert "No Such Object currently exists" not in snmp_facts['snmp_lldp'][k]

minigraph_lldp_nei = []
for k, v in mg_facts.items():
if "server" not in v['name'].lower():
minigraph_lldp_nei.append(k)
print minigraph_lldp_nei

# Check if lldpRemTable is present
active_intf = []
for k, v in snmp_facts['snmp_interfaces'].items():
Expand All @@ -85,7 +83,7 @@ def test_snmp_lldp(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_
active_intf.append(k)
print "lldpRemTable: ", active_intf

assert len(active_intf) >= len(minigraph_lldp_nei) * 0.8
assert len(active_intf) >= len(lldp_nei) * 0.8

# skip neighbors that do not send chassis information via lldp
lldp_facts= {}
Expand Down

0 comments on commit 39f18e6

Please sign in to comment.