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

Modify tests to run on zero ports systems #3663

Merged
merged 21 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
39f18e6
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
cbb863c
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
4d061f5
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
b96e0f4
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
447d6fc
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
136d9b9
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
ba0f3ec
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
7e699c1
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
b392c01
tests fixes for zero ports setups
slutati1536 Jun 13, 2021
61d2798
use the ansible state module to check the existence of a file /etc/so…
slutati1536 Jul 21, 2021
21048f5
use the ansible state module to check the existence of a file /etc/so…
slutati1536 Jul 21, 2021
bd46535
fix indentation
slutati1536 Jul 21, 2021
fb0c4d4
Merge branch 'master' of github.com:Azure/sonic-mgmt into zero_ports_2
slutati1536 Jul 21, 2021
4a3d8bb
remove HEAD markers from test_sfputil.py
slutati1536 Jul 22, 2021
3273768
Merge branch 'master' of github.com:Azure/sonic-mgmt into zero_ports_2
slutati1536 Aug 17, 2021
bc97af9
add skip_if_no_ports fixture back to test_snmp_default_route, it was …
slutati1536 Aug 17, 2021
a9f9453
Merge branch 'master' of github.com:Azure/sonic-mgmt into zero_ports_2
slutati1536 Aug 18, 2021
998955e
Adding a few more fixes to the tests
slutati1536 Aug 18, 2021
74b9a83
remove unused import statement
slutati1536 Sep 12, 2021
15ad6f1
Merge branch 'master' of github.com:Azure/sonic-mgmt into zero_ports_2
slutati1536 Sep 12, 2021
4ce5ed0
Merge branch 'master' of github.com:Azure/sonic-mgmt into zero_ports_2
slutati1536 Sep 14, 2021
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
63 changes: 33 additions & 30 deletions tests/common/platform/interface_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This script contains re-usable functions for checking status of interfaces on SONiC.
"""
import json
import re
import logging
from transceiver_utils import all_transceivers_detected

Expand Down Expand Up @@ -42,47 +43,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 +91,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 +103,33 @@ 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_index = port_dict_info["index"]
port_mapping_res[port] = [int(port_index)]
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"]
slutati1536 marked this conversation as resolved.
Show resolved Hide resolved
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
4 changes: 2 additions & 2 deletions tests/platform_tests/mellanox/test_check_sfp_presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""
import logging
import os
import json
import pytest

from tests.common.fixtures.conn_graph_facts import conn_graph_facts
Expand All @@ -13,11 +12,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")
slutati1536 marked this conversation as resolved.
Show resolved Hide resolved
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
13 changes: 13 additions & 0 deletions tests/snmp/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from tests.common.platform.interface_utils import get_port_map
from tests.common.utilities import wait_until

@pytest.fixture(scope="module", autouse=True)
Expand All @@ -16,3 +17,15 @@ def pytest_addoption(parser):
default=False,
help="Set percentage difference for snmp test",
type=int)

@pytest.fixture(scope='function')
def skip_if_no_ports(duthosts, enum_rand_one_per_hwsku_frontend_hostname):
"""
Fixture that skips test execution in case dut doesn't have data ports
"""
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]
for asic_index in duthost.get_frontend_asic_ids():
interface_list = get_port_map(duthost, asic_index)
if not interface_list:
pytest.skip("This test is not supported as there are no data ports in dut")

2 changes: 1 addition & 1 deletion tests/snmp/test_snmp_default_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


@pytest.mark.bsl
def test_snmp_default_route(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost, creds_all_duts):
def test_snmp_default_route(duthosts, enum_rand_one_per_hwsku_frontend_hostname, skip_if_no_ports, localhost, creds_all_duts):
"""compare the snmp facts between observed states and target state"""

duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]
Expand Down
21 changes: 9 additions & 12 deletions tests/snmp/test_snmp_lldp.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,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 +67,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 +82,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
2 changes: 1 addition & 1 deletion tests/snmp/test_snmp_loopback.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_snmp_output(ip, duthost, nbr, creds_all_duts):


@pytest.mark.bsl
def test_snmp_loopback(duthosts, enum_rand_one_per_hwsku_frontend_hostname, nbrhosts, tbinfo, localhost, creds_all_duts):
def test_snmp_loopback(duthosts, enum_rand_one_per_hwsku_frontend_hostname, skip_if_no_ports, nbrhosts, tbinfo, localhost, creds_all_duts):
"""
Test SNMP query to DUT over loopback IP
- Send SNMP query over loopback IP from one of the BGP Neighbors
Expand Down
2 changes: 1 addition & 1 deletion tests/snmp/test_snmp_phy_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ def test_turn_off_psu_and_check_psu_info(duthosts, enum_rand_one_per_hwsku_hostn
pdu_controller.turn_off_outlet(first_outlet)
assert wait_until(30, 5, check_outlet_status, pdu_controller, first_outlet, False)
# wait for psud update the database
assert wait_until(120, 20, _check_psu_status_after_power_off, duthost, localhost, creds_all_duts)
assert wait_until(180, 20, _check_psu_status_after_power_off, duthost, localhost, creds_all_duts)
slutati1536 marked this conversation as resolved.
Show resolved Hide resolved


def _check_psu_status_after_power_off(duthost, localhost, creds_all_duts):
Expand Down
Loading