def test_show_platform_syseeprom(localhost, ansible_adhoc, testbed): """ @summary: Check output of 'show platform syseeprom' """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) logging.info("Check output of '%s'" % CMD_PLATFORM_SYSEEPROM) platform_info = parse_platform_summary( ans_host.command(CMD_PLATFORM_SUMMARY)["stdout_lines"]) show_output = ans_host.command(CMD_PLATFORM_SYSEEPROM) assert show_output[ "rc"] == 0, "Run command '%s' failed" % CMD_PLATFORM_SYSEEPROM if platform_info["asic"] in ["mellanox"]: expected_fields = [ "Product Name", "Part Number", "Serial Number", "Base MAC Address", "Manufacture Date", "Device Version", "MAC Addresses", "Manufacturer", "Vendor Extension", "ONIE Version", "CRC-32" ] utility_cmd = "sudo python -c \"import imp; \ m = imp.load_source('eeprom', '/usr/share/sonic/device/%s/plugins/eeprom.py'); \ t = m.board('board', '', '', ''); e = t.read_eeprom(); t.decode_eeprom(e)\"" % platform_info[ "platform"] utility_cmd_output = ans_host.command(utility_cmd) for field in expected_fields: assert show_output["stdout"].find( field) >= 0, "Expected field %s is not found" % field assert utility_cmd_output["stdout"].find( field) >= 0, "Expected field %s is not found" % field for line in utility_cmd_output["stdout_lines"]: assert line in show_output["stdout"], \ "Line %s is not found in output of '%s'" % (line, CMD_PLATFORM_SYSEEPROM)
def ptfadapter(ansible_adhoc, testbed): """return ptf test adapter object. The fixture is module scope, because usually there is not need to restart PTF nn agent and reinitialize data plane thread on every test class or test function/method. Session scope should also be Ok, however if something goes really wrong in one test module it is safer to restart PTF before proceeding running other test modules """ ptfhost = AnsibleHost(ansible_adhoc, testbed['ptf']) # get the eth interfaces from PTF and initialize ifaces_map res = ptfhost.command('cat /proc/net/dev') ifaces = get_ifaces(res['stdout']) ifaces_map = { int(ifname.replace(ETH_PFX, '')): ifname for ifname in ifaces } # generate supervisor configuration for ptf_nn_agent ptfhost.host.options['variable_manager'].extra_vars = { 'device_num': DEFAULT_DEVICE_NUM, 'ptf_nn_port': DEFAULT_PTF_NN_PORT, 'ifaces_map': ifaces_map, } ptfhost.template(src='ptfadapter/templates/ptf_nn_agent.conf.ptf.j2', dest='/etc/supervisor/conf.d/ptf_nn_agent.conf') # reread configuration and update supervisor ptfhost.command('supervisorctl reread') ptfhost.command('supervisorctl update') with PtfTestAdapter(testbed['ptf_ip'], DEFAULT_PTF_NN_PORT, 0, len(ifaces_map)) as adapter: yield adapter
def fdb_cleanup(ansible_adhoc, testbed): """ cleanup FDB before and after test run """ duthost = AnsibleHost(ansible_adhoc, testbed['dut']) try: duthost.command('sonic-clear fdb all') yield finally: # in any case clear fdb after test duthost.command('sonic-clear fdb all')
def run_test(ansible_adhoc, testbed, conn_graph_facts, leaf_fanouts, is_pfc=True, pause_time=65535): """ @Summary: Run test for Ethernet flow control (FC) or priority-based flow control (PFC) @param ansible_adhoc: Fixture provided by the pytest-ansible package. Source of the various device objects. It is mandatory argument for the class constructors. @param testbed: Testbed information @param conn_graph_facts: Testbed topology connectivity information @param leaf_fanouts: Leaf fanout switches @param is_pfc: If this test is for PFC? @param pause_time: Pause time quanta (0-65535) in the frame. 0 means unpause. """ setup_testbed(ansible_adhoc, testbed, leaf_fanouts) conn_facts = conn_graph_facts['device_conn'] dut_hostname = testbed['dut'] dut_ans = AnsibleHost(ansible_adhoc, dut_hostname) int_status = dut_ans.show_interface( command="status")['ansible_facts']['int_status'] """ We only test active physical interfaces """ active_phy_intfs = [intf for intf in int_status if \ intf.startswith('Ethernet') and \ int_status[intf]['admin_state'] == 'up' and \ int_status[intf]['oper_state'] == 'up'] """ Generate PFC or FC packets for active physical interfaces """ for intf in active_phy_intfs: peer_device = conn_facts[intf]['peerdevice'] peer_port = conn_facts[intf]['peerport'] peer_port_name = eos_to_linux_intf(peer_port) peerdev_ans = AnsibleHost(ansible_adhoc, peer_device) if is_pfc: for priority in range(PRIO_COUNT): cmd = "sudo python %s -i %s -p %d -t %d -n %d" % ( PFC_GEN_FILE_DEST, peer_port_name, 2** priority, pause_time, PKT_COUNT) peerdev_ans.command(cmd) else: cmd = "sudo python %s -i %s -g -t %d -n %d" % ( PFC_GEN_FILE_DEST, peer_port_name, pause_time, PKT_COUNT) peerdev_ans.command(cmd) """ SONiC takes some time to update counters in database """ time.sleep(5) """ Check results """ counter_facts = dut_ans.sonic_pfc_counters(method="get")['ansible_facts'] for intf in active_phy_intfs: if is_pfc: assert counter_facts[intf]['Rx'] == [str(PKT_COUNT)] * PRIO_COUNT else: assert counter_facts[intf]['Rx'] == ['0'] * PRIO_COUNT
def test_reload_configuration(localhost, ansible_adhoc, testbed): """ @summary: This test case is to reload the configuration and check platform status """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) ans_host.command("show platform summary") lab_conn_graph_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), \ "../../ansible/files/lab_connection_graph.xml") conn_graph_facts = localhost.conn_graph_facts(host=hostname, filename=lab_conn_graph_file).\ contacted['localhost']['ansible_facts'] interfaces = conn_graph_facts["device_conn"] asic_type = ans_host.shell( "show platform summary | awk '/ASIC: / {print$2}'")["stdout"].strip() logging.info("Reload configuration") ans_host.command("sudo config reload -y") logging.info("Wait until all critical services are fully started") check_critical_services(ans_host) logging.info("Wait some time for all the transceivers to be detected") assert wait_until(300, 20, all_transceivers_detected, ans_host, interfaces), \ "Not all transceivers are detected in 300 seconds" logging.info("Check interface status") time.sleep(60) check_interface_status(ans_host, interfaces) logging.info("Check transceiver status") check_transceiver_basic(ans_host, interfaces) if asic_type in ["mellanox"]: current_file_dir = os.path.dirname(os.path.realpath(__file__)) sub_folder_dir = os.path.join(current_file_dir, "mellanox") if sub_folder_dir not in sys.path: sys.path.append(sub_folder_dir) from check_hw_mgmt_service import check_hw_management_service from check_sysfs import check_sysfs logging.info("Check the hw-management service") check_hw_management_service(ans_host) logging.info("Check sysfs") check_sysfs(ans_host)
def test_fdb(ansible_adhoc, testbed, ptfadapter): """ 1. verify fdb forwarding in T0 topology. 2. verify show mac command on DUT for learned mac. """ if testbed['topo'] not in ['t0', 't0-64', 't0-116']: pytest.skip('unsupported testbed type') duthost = AnsibleHost(ansible_adhoc, testbed['dut']) ptfhost = AnsibleHost(ansible_adhoc, testbed['ptf']) host_facts = duthost.setup()['ansible_facts'] mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] # remove existing IPs from PTF host ptfhost.script('scripts/remove_ip.sh') # set unique MACs to PTF interfaces ptfhost.script('scripts/change_mac.sh') # reinitialize data plane due to above changes on PTF interfaces ptfadapter.reinit() router_mac = host_facts['ansible_Ethernet0']['macaddress'] vlan_member_count = sum( [len(v['members']) for k, v in mg_facts['minigraph_vlans'].items()]) vlan_table = {} for vlan in mg_facts['minigraph_vlan_interfaces']: vlan_table[vlan['subnet']] = [] for ifname in mg_facts['minigraph_vlans'][vlan['attachto']]['members']: vlan_table[vlan['subnet']].append( mg_facts['minigraph_port_indices'][ifname]) fdb = setup_fdb(ptfadapter, vlan_table, router_mac) for vlan in vlan_table: for src, dst in itertools.combinations(vlan_table[vlan], 2): for src_mac, dst_mac in itertools.product(fdb[src], fdb[dst]): send_recv_eth(ptfadapter, src, src_mac, dst, dst_mac) # Should we have fdb_facts ansible module for this test? res = duthost.command('show mac') logger.info('"show mac" output on DUT:\n{}'.format( pprint.pformat(res['stdout_lines']))) dummy_mac_count = 0 total_mac_count = 0 for l in res['stdout_lines']: if DUMMY_MAC_PREFIX in l.lower(): dummy_mac_count += 1 if "dynamic" in l.lower(): total_mac_count += 1 # Verify that the number of dummy MAC entries is expected assert dummy_mac_count == DUMMY_MAC_COUNT * vlan_member_count # Verify that total number of MAC entries is expected assert total_mac_count == DUMMY_MAC_COUNT * vlan_member_count + vlan_member_count
def test_show_platform_psustatus(localhost, ansible_adhoc, testbed): """ @summary: Check output of 'show platform psustatus' """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) logging.info("Check PSU status using '%s', hostname: %s" % (CMD_PLATFORM_PSUSTATUS, hostname)) psu_status = ans_host.command(CMD_PLATFORM_PSUSTATUS) psu_line_pattern = re.compile(r"PSU\s+\d+\s+(OK|NOT OK)") for line in psu_status["stdout_lines"][2:]: assert psu_line_pattern.match(line), "Unexpected PSU status output"
def test_warm_reboot(localhost, ansible_adhoc, testbed): """ @summary: This test case is to perform cold reboot and check platform status """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) asic_type = ans_host.shell("show platform summary | awk '/ASIC: / {print$2}'")["stdout"].strip() if asic_type in ["mellanox"]: issu_capability = ans_host.command("show platform mlnx issu")["stdout"] if "disabled" in issu_capability: pytest.skip("ISSU is not supported on this DUT, skip this test case") reboot_and_check(localhost, ans_host, reboot_type="warm")
def test_show_platform_summary(localhost, ansible_adhoc, testbed): """ @summary: Check output of 'show platform summary' """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) logging.info("Check output of '%s'" % CMD_PLATFORM_SUMMARY) platform_summary = ans_host.command(CMD_PLATFORM_SUMMARY) expected_fields = set(["Platform", "HwSKU", "ASIC"]) actual_fields = set() for line in platform_summary["stdout_lines"]: key_value = line.split(":") assert len( key_value) == 2, "output format is not 'field_name: field_value'" assert len(key_value[1]) > 0, "No value for field %s" % key_value[0] actual_fields.add(line.split(":")[0]) assert actual_fields == expected_fields, \ "Unexpected output fields, actual=%s, expected=%s" % (str(actual_fields), str(expected_fields))
def test_bgp_speaker(localhost, ansible_adhoc, testbed, ipv4, ipv6, mtu): """setup bgp speaker on T0 topology and verify routes advertised by bgp speaker is received by T0 TOR """ hostname = testbed['dut'] ptf_hostname = testbed['ptf'] host = AnsibleHost(ansible_adhoc, hostname) ptfhost = AnsibleHost(ansible_adhoc, ptf_hostname) mg_facts = host.minigraph_facts(host=hostname)['ansible_facts'] host_facts = host.setup()['ansible_facts'] res = host.shell("sonic-cfggen -m -d -y /etc/sonic/constants.yml -v \"constants.deployment_id_asn_map[DEVICE_METADATA['localhost']['deployment_id']]\"") bgp_speaker_asn = res['stdout'] vlan_ips = generate_ips(3, \ "%s/%s" % (mg_facts['minigraph_vlan_interfaces'][0]['addr'], mg_facts['minigraph_vlan_interfaces'][0]['prefixlen']), [IPAddress(mg_facts['minigraph_vlan_interfaces'][0]['addr'])]) # three speaker ips, two from peer range, another is vlan ip [0] speaker_ips = generate_ips(2, mg_facts['minigraph_bgp_peers_with_range'][0]['ip_range'][0], []) speaker_ips.append(vlan_ips[0]) for ip in vlan_ips: host.command("ip route flush %s/32" % ip.ip) host.command("ip route add %s/32 dev %s" % (ip.ip, mg_facts['minigraph_vlan_interfaces'][0]['attachto'])) root_dir = "/root" exabgp_dir = "/root/exabgp" helper_dir = "/root/helpers" port_num = [5000, 6000, 7000] cfnames = ["config_1.ini", "config_2.ini", "config_3.ini"] vlan_ports = [] for i in range(0, 3): vlan_ports.append(mg_facts['minigraph_port_indices'][mg_facts['minigraph_vlans'][mg_facts['minigraph_vlan_interfaces'][0]['attachto']]['members'][i]]) ptfhost.file(path=exabgp_dir, state="directory") ptfhost.file(path=helper_dir, state="directory") ptfhost.copy(src="bgp_speaker/dump.py", dest=helper_dir) ptfhost.copy(src="bgp_speaker/http_api.py", dest=helper_dir) ptfhost.copy(src="bgp_speaker/announce_routes.py", dest=helper_dir) # deploy config file extra_vars = \ { 'helper_dir': helper_dir, 'exabgp_dir': exabgp_dir, 'lo_addr' : mg_facts['minigraph_lo_interfaces'][0]['addr'], 'lo_addr_prefixlen' : mg_facts['minigraph_lo_interfaces'][0]['prefixlen'], 'vlan_addr' : mg_facts['minigraph_vlan_interfaces'][0]['addr'], 'peer_range': mg_facts['minigraph_bgp_peers_with_range'][0]['ip_range'][0], 'announce_prefix': '10.10.10.0/26', 'minigraph_portchannels' : mg_facts['minigraph_portchannels'], 'minigraph_vlans' : mg_facts['minigraph_vlans'], 'minigraph_port_indices' : mg_facts['minigraph_port_indices'], 'peer_asn' : mg_facts['minigraph_bgp_asn'], 'peer_asn' : mg_facts['minigraph_bgp_asn'], 'my_asn' : bgp_speaker_asn, 'vlan_ports' : vlan_ports, 'port_num' : port_num, 'speaker_ips': [str(ip) for ip in speaker_ips], 'vlan_ips': [str(ip) for ip in vlan_ips], 'cfnames': cfnames } for i in range(0, 3): extra_vars.update({ 'cidx':i }) extra_vars.update({ 'speaker_ip': str(speaker_ips[i].ip) }) ptfhost.host.options['variable_manager'].extra_vars.update(extra_vars) ptfhost.template(src="bgp_speaker/config.j2", dest="%s/%s" % (exabgp_dir, cfnames[i])) # deploy routes ptfhost.template(src="bgp_speaker/routes.j2", dest="%s/%s" % (exabgp_dir, "routes")) # deploy start script ptfhost.template(src="bgp_speaker/start.j2", dest="%s/%s" % (exabgp_dir, "start.sh"), mode="u+rwx") # kill exabgp res = ptfhost.shell("pkill exabgp || true") print res # start exabgp instance res = ptfhost.shell("bash %s/start.sh" % exabgp_dir) print res time.sleep(10) # announce route res = ptfhost.shell("nohup python %s/announce_routes.py %s/routes >/dev/null 2>&1 &" % (helper_dir, exabgp_dir)) print res # make sure routes announced to dynamic bgp neighbors time.sleep(60) bgp_facts = host.bgp_facts()['ansible_facts'] # Verify bgp sessions are established for k, v in bgp_facts['bgp_neighbors'].items(): assert v['state'] == 'established' # Verify accepted prefixes of the dynamic neighbors are correct for ip in speaker_ips: assert bgp_facts['bgp_neighbors'][str(ip.ip)]['accepted prefixes'] == 1 assert bgp_facts['bgp_neighbors'][str(vlan_ips[0].ip)]['accepted prefixes'] == 1 # Generate route-port map information ptfhost.template(src="bgp_speaker/bgp_speaker_route.j2", dest="/root/bgp_speaker_route.txt") ptfhost.copy(src="ptftests", dest=root_dir) ptf_runner(ptfhost, \ "ptftests", "fib_test.FibTest", platform_dir="ptftests", params={"testbed_type": "t0", "router_mac": host_facts['ansible_Ethernet0']['macaddress'], "fib_info": "/root/bgp_speaker_route.txt", "ipv4": ipv4, "ipv6": ipv6, "testbed_mtu": mtu }, log_file="/tmp/bgp_speaker_test.FibTest.log", socket_recv_size=16384) res = ptfhost.shell("pkill exabgp || true") for ip in vlan_ips: host.command("ip route flush %s/32" % ip.ip) ptfhost.shell("ip addr flush dev eth{}".format(mg_facts['minigraph_port_indices'][mg_facts['minigraph_vlans'][mg_facts['minigraph_vlan_interfaces'][0]['attachto']]['members'][0]]))
def test_check_sfp_status_and_configure_sfp(localhost, ansible_adhoc, testbed): """ @summary: Check SFP status and configure SFP This case is to use the sfputil tool and show command to check SFP status and configure SFP. Currently the only configuration is to reset SFP. Commands to be tested: * sfputil show presence * show interface transceiver presence * sfputil show eeprom * show interface transceiver eeprom * sfputil reset <interface name> """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) localhost.command("who") lab_conn_graph_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), \ "../../ansible/files/lab_connection_graph.xml") conn_graph_facts = localhost.conn_graph_facts(host=hostname, filename=lab_conn_graph_file).\ contacted['localhost']['ansible_facts'] cmd_sfp_presence = "sudo sfputil show presence" cmd_sfp_eeprom = "sudo sfputil show eeprom" cmd_sfp_reset = "sudo sfputil reset" cmd_xcvr_presence = "show interface transceiver presence" cmd_xcvr_eeprom = "show interface transceiver eeprom" logging.info("Check output of '%s'" % cmd_sfp_presence) sfp_presence = ans_host.command(cmd_sfp_presence) parsed_presence = parse_output(sfp_presence["stdout_lines"][2:]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_presence, "Interface is not in output of '%s'" % cmd_sfp_presence assert parsed_presence[ intf] == "Present", "Interface presence is not 'Present'" logging.info("Check output of '%s'" % cmd_xcvr_presence) xcvr_presence = ans_host.command(cmd_xcvr_presence) parsed_presence = parse_output(xcvr_presence["stdout_lines"][2:]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_presence, "Interface is not in output of '%s'" % cmd_xcvr_presence assert parsed_presence[ intf] == "Present", "Interface presence is not 'Present'" logging.info("Check output of '%s'" % cmd_sfp_eeprom) sfp_eeprom = ans_host.command(cmd_sfp_eeprom) parsed_eeprom = parse_eeprom(sfp_eeprom["stdout_lines"]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_eeprom, "Interface is not in output of 'sfputil show eeprom'" assert parsed_eeprom[intf] == "SFP EEPROM detected" logging.info("Check output of '%s'" % cmd_xcvr_eeprom) xcvr_eeprom = ans_host.command(cmd_xcvr_eeprom) parsed_eeprom = parse_eeprom(xcvr_eeprom["stdout_lines"]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_eeprom, "Interface is not in output of '%s'" % cmd_xcvr_eeprom assert parsed_eeprom[intf] == "SFP EEPROM detected" logging.info("Test '%s <interface name>'" % cmd_sfp_reset) for intf in conn_graph_facts["device_conn"]: reset_result = ans_host.command("%s %s" % (cmd_sfp_reset, intf)) assert reset_result["rc"] == 0, "'%s %s' failed" % (cmd_sfp_reset, intf) time.sleep(120) # Wait some time for SFP to fully recover after reset logging.info("Check sfp presence again after reset") sfp_presence = ans_host.command(cmd_sfp_presence) parsed_presence = parse_output(sfp_presence["stdout_lines"][2:]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_presence, "Interface is not in output of '%s'" % cmd_sfp_presence assert parsed_presence[ intf] == "Present", "Interface presence is not 'Present'"
def test_check_sfp_low_power_mode(localhost, ansible_adhoc, testbed): """ @summary: Check SFP low power mode This case is to use the sfputil tool command to check and set SFP low power mode * sfputil show lpmode * sfputil lpmode off * sfputil lpmode on """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) localhost.command("who") lab_conn_graph_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), \ "../../ansible/files/lab_connection_graph.xml") conn_graph_facts = localhost.conn_graph_facts(host=hostname, filename=lab_conn_graph_file).\ contacted['localhost']['ansible_facts'] cmd_sfp_presence = "sudo sfputil show presence" cmd_sfp_show_lpmode = "sudo sfputil show lpmode" cmd_sfp_set_lpmode = "sudo sfputil lpmode" logging.info("Check output of '%s'" % cmd_sfp_show_lpmode) lpmode_show = ans_host.command(cmd_sfp_show_lpmode) parsed_lpmode = parse_output(lpmode_show["stdout_lines"][2:]) original_lpmode = copy.deepcopy(parsed_lpmode) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_lpmode, "Interface is not in output of '%s'" % cmd_sfp_show_lpmode assert parsed_lpmode[intf].lower() == "on" or parsed_lpmode[ intf].lower() == "off", "Unexpected SFP lpmode" logging.info("Try to change SFP lpmode") for intf in conn_graph_facts["device_conn"]: new_lpmode = "off" if original_lpmode[intf].lower() == "on" else "on" lpmode_set_result = ans_host.command( "%s %s %s" % (cmd_sfp_set_lpmode, new_lpmode, intf)) assert lpmode_set_result["rc"] == 0, "'%s %s %s' failed" % ( cmd_sfp_set_lpmode, new_lpmode, intf) time.sleep(10) logging.info("Check SFP lower power mode again after changing SFP lpmode") lpmode_show = ans_host.command(cmd_sfp_show_lpmode) parsed_lpmode = parse_output(lpmode_show["stdout_lines"][2:]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_lpmode, "Interface is not in output of '%s'" % cmd_sfp_show_lpmode assert parsed_lpmode[intf].lower() == "on" or parsed_lpmode[ intf].lower() == "off", "Unexpected SFP lpmode" logging.info("Try to change SFP lpmode") for intf in conn_graph_facts["device_conn"]: new_lpmode = original_lpmode[intf].lower() lpmode_set_result = ans_host.command( "%s %s %s" % (cmd_sfp_set_lpmode, new_lpmode, intf)) assert lpmode_set_result["rc"] == 0, "'%s %s %s' failed" % ( cmd_sfp_set_lpmode, new_lpmode, intf) time.sleep(10) logging.info("Check SFP lower power mode again after changing SFP lpmode") lpmode_show = ans_host.command(cmd_sfp_show_lpmode) parsed_lpmode = parse_output(lpmode_show["stdout_lines"][2:]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_lpmode, "Interface is not in output of '%s'" % cmd_sfp_show_lpmode assert parsed_lpmode[intf].lower() == "on" or parsed_lpmode[ intf].lower() == "off", "Unexpected SFP lpmode" logging.info("Check sfp presence again after setting lpmode") sfp_presence = ans_host.command(cmd_sfp_presence) parsed_presence = parse_output(sfp_presence["stdout_lines"][2:]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_presence, "Interface is not in output of '%s'" % cmd_sfp_presence assert parsed_presence[ intf] == "Present", "Interface presence is not 'Present'"
def test_turn_on_off_psu_and_check_psustatus(localhost, ansible_adhoc, testbed, psu_controller): """ @summary: Turn off/on PSU and check PSU status using 'show platform psustatus' """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) platform_info = parse_platform_summary( ans_host.command(CMD_PLATFORM_SUMMARY)["stdout_lines"]) psu_line_pattern = re.compile(r"PSU\s+\d+\s+(OK|NOT OK|NOT PRESENT)") cmd_num_psu = "sudo psuutil numpsus" logging.info("Check whether the DUT has enough PSUs for this testing") psu_num_out = ans_host.command(cmd_num_psu) psu_num = 0 try: psu_num = int(psu_num_out["stdout"]) except: assert False, "Unable to get the number of PSUs using command '%s'" % cmd_num_psu if psu_num < 2: pytest.skip( "At least 2 PSUs required for rest of the testing in this case") logging.info("Create PSU controller for testing") psu_ctrl = psu_controller(hostname, platform_info["asic"]) if psu_ctrl is None: pytest.skip( "No PSU controller for %s, skip rest of the testing in this case" % hostname) logging.info( "To avoid DUT losing power, need to turn on PSUs that are not powered") all_psu_status = psu_ctrl.get_psu_status() if all_psu_status: for psu in all_psu_status: if not psu["psu_on"]: psu_ctrl.turn_on_psu(psu["psu_id"]) time.sleep(5) logging.info("Initialize test results") cli_psu_status = ans_host.command(CMD_PLATFORM_PSUSTATUS) psu_test_results = {} for line in cli_psu_status["stdout_lines"][2:]: fields = line.split() psu_test_results[fields[1]] = False if " ".join(fields[2:]) == "NOT OK": pytest.skip( "Some PSUs are still not powered, it is not safe to proceed, skip testing" ) assert len(psu_test_results.keys()) == psu_num, \ "In consistent PSU number output by '%s' and '%s'" % (CMD_PLATFORM_PSUSTATUS, cmd_num_psu) logging.info("Start testing turn off/on PSUs") all_psu_status = psu_ctrl.get_psu_status() for psu in all_psu_status: psu_under_test = None logging.info("Turn off PSU %s" % str(psu["psu_id"])) psu_ctrl.turn_off_psu(psu["psu_id"]) time.sleep(5) cli_psu_status = ans_host.command(CMD_PLATFORM_PSUSTATUS) for line in cli_psu_status["stdout_lines"][2:]: assert psu_line_pattern.match(line), "Unexpected PSU status output" fields = line.split() if fields[2] != "OK": psu_under_test = fields[1] assert psu_under_test is not None, "No PSU is turned off" logging.info("Turn on PSU %s" % str(psu["psu_id"])) psu_ctrl.turn_on_psu(psu["psu_id"]) time.sleep(5) cli_psu_status = ans_host.command(CMD_PLATFORM_PSUSTATUS) for line in cli_psu_status["stdout_lines"][2:]: assert psu_line_pattern.match(line), "Unexpected PSU status output" fields = line.split() if fields[1] == psu_under_test: assert fields[ 2] == "OK", "Unexpected PSU status after turned it on" psu_test_results[psu_under_test] = True for psu in psu_test_results: assert psu_test_results[psu], "Test psu status of PSU %s failed" % psu