def test_show_platform_syseeprom(localhost, ansible_adhoc, testbed): """ @summary: Check output of 'show platform syseeprom' """ hostname = testbed['dut'] ans_host = ansible_host(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 test_restart_syncd(localhost, ansible_adhoc, testbed): """ @summary: This test case is to restart the syncd service and check platform status """ hostname = testbed['dut'] ans_host = ansible_host(ansible_adhoc, hostname) restart_service_and_check(localhost, ans_host, "syncd")
def test_lldp(localhost, ansible_adhoc, testbed): """verify the lldp message on DUT and neighbors""" hostname = testbed['dut'] ans_host = ansible_host(ansible_adhoc, hostname) mg_facts = ans_host.minigraph_facts(host=hostname)['ansible_facts'] host_facts = ans_host.setup()['ansible_facts'] lldp_facts = ans_host.lldp()['ansible_facts'] res = ans_host.shell("docker exec -i lldp lldpcli show chassis | grep \"SysDescr:\" | sed -e 's/^\\s*SysDescr:\\s*//g'") dut_system_description = res['stdout'] minigraph_lldp_nei = {} for k, v in mg_facts['minigraph_neighbors'].items(): if 'server' not in v['name'].lower(): minigraph_lldp_nei[k] = v # Verify LLDP information is available on most interfaces assert len(lldp_facts['lldp']) > len(minigraph_lldp_nei) * 0.8 for k, v in lldp_facts['lldp'].items(): if k == 'eth0': continue # Compare the LLDP neighbor name with minigraph neigbhor name (exclude the management port) assert v['chassis']['name'] == minigraph_lldp_nei[k]['name'] # Compare the LLDP neighbor interface with minigraph neigbhor interface (exclude the management port) assert v['port']['ifname'] == mg_facts['minigraph_neighbors'][k]['port'] lhost = ansible_host(ansible_adhoc, 'localhost', True) for k, v in lldp_facts['lldp'].items(): hostip = v['chassis']['mgmt-ip'] nei_lldp_facts = lhost.lldp_facts(host=hostip, version='v2c', community='strcommunity')['ansible_facts'] print nei_lldp_facts neighbor_interface = v['port']['ifname'] # Verify the published DUT system name field is correct assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_sys_name'] == hostname # Verify the published DUT chassis id field is not empty assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_chassis_id'] == \ "0x%s" % (host_facts['ansible_eth0']['macaddress'].replace(':', '')) # Verify the published DUT system description field is correct assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_sys_desc'] == dut_system_description # Verify the published DUT port id field is correct assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_port_id'] == mg_facts['minigraph_ports'][k]['alias'] # Verify the published DUT port description field is correct assert nei_lldp_facts['ansible_lldp_facts'][neighbor_interface]['neighbor_port_desc'] == \ "%s:%s" % (mg_facts['minigraph_neighbors'][k]['name'], mg_facts['minigraph_neighbors'][k]['port'])
def test_cold_reboot(localhost, ansible_adhoc, testbed): """ @summary: This test case is to perform cold reboot and check platform status """ hostname = testbed['dut'] ans_host = ansible_host(ansible_adhoc, hostname) reboot_and_check(localhost, ans_host, reboot_type="cold")
def test_xcvr_info_in_db(localhost, ansible_adhoc, testbed): """ @summary: This test case is to verify that xcvrd works as expected by checking transceiver information in DB """ hostname = testbed['dut'] ans_host = ansible_host(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'] logging.info( "Check whether transceiver information of all ports are in redis") xcvr_info = ans_host.command("redis-cli -n 6 keys TRANSCEIVER_INFO*") parsed_xcvr_info = parse_transceiver_info(xcvr_info["stdout_lines"]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_xcvr_info, "TRANSCEIVER INFO of %s is not found in DB" % intf logging.info( "Check detailed transceiver information of each connected port") expected_fields = [ "type", "hardwarerev", "serialnum", "manufacturename", "modelname" ] for intf in conn_graph_facts["device_conn"]: port_xcvr_info = ans_host.command( 'redis-cli -n 6 hgetall "TRANSCEIVER_INFO|%s"' % intf) for field in expected_fields: assert port_xcvr_info["stdout"].find(field) >= 0, \ "Expected field %s is not found in %s while checking %s" % (field, port_xcvr_info["stdout"], intf) logging.info("Check whether TRANSCEIVER_DOM_SENSOR of all ports in redis") xcvr_dom_senspor = ans_host.command( "redis-cli -n 6 keys TRANSCEIVER_DOM_SENSOR*") parsed_xcvr_dom_senspor = parse_transceiver_dom_sensor( xcvr_dom_senspor["stdout_lines"]) for intf in conn_graph_facts["device_conn"]: assert intf in parsed_xcvr_dom_senspor, "TRANSCEIVER_DOM_SENSOR of %s is not found in DB" % intf logging.info( "Check detailed TRANSCEIVER_DOM_SENSOR information of each connected ports" ) expected_fields = [ "temperature", "voltage", "rx1power", "rx2power", "rx3power", "rx4power", "tx1bias", "tx2bias", "tx3bias", "tx4bias", "tx1power", "tx2power", "tx3power", "tx4power" ] for intf in conn_graph_facts["device_conn"]: port_xcvr_dom_sensor = ans_host.command( 'redis-cli -n 6 hgetall "TRANSCEIVER_DOM_SENSOR|%s"' % intf) for field in expected_fields: assert port_xcvr_dom_sensor["stdout"].find(field) >= 0, \ "Expected field %s is not found in %s while checking %s" % (field, port_xcvr_dom_sensor["stdout"], intf)
def test_show_platform_psustatus(localhost, ansible_adhoc, testbed): """ @summary: Check output of 'show platform psustatus' """ hostname = testbed['dut'] ans_host = ansible_host(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 = ansible_host(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_xcvr_info_in_db(localhost, ansible_adhoc, testbed): """ @summary: This test case is to verify that xcvrd works as expected by checking transceiver information in DB """ hostname = testbed['dut'] ans_host = ansible_host(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'] interfaces = conn_graph_facts["device_conn"] logging.info("Check transceiver status") check_transceiver_status(ans_host, interfaces)
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 = ansible_host(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_show_platform_summary(localhost, ansible_adhoc, testbed): """ @summary: Check output of 'show platform summary' """ hostname = testbed['dut'] ans_host = ansible_host(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_facts(ansible_adhoc, testbed): """compare the bgp facts between observed states and target state""" hostname = testbed['dut'] ans_host = ansible_host(ansible_adhoc, hostname) bgp_facts = ans_host.bgp_facts()['ansible_facts'] mg_facts = ans_host.minigraph_facts(host=hostname)['ansible_facts'] for k, v in bgp_facts['bgp_neighbors'].items(): # Verify bgp sessions are established assert v['state'] == 'established' # Verify locat ASNs in bgp sessions assert v['local AS'] == mg_facts['minigraph_bgp_asn'] for v in mg_facts['minigraph_bgp']: # Compare the bgp neighbors name with minigraph bgp neigbhors name assert v['name'] == bgp_facts['bgp_neighbors'][ v['addr'].lower()]['description'] # Compare the bgp neighbors ASN with minigraph assert v['asn'] == bgp_facts['bgp_neighbors'][ v['addr'].lower()]['remote AS']
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 = ansible_host(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
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 = ansible_host(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 = ansible_host(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_bgp_speaker(localhost, ansible_adhoc, testbed): """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 = ansible_host(ansible_adhoc, hostname) ptfhost = ansible_host(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/deployment_id_asn_map.yml -v \"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 = 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": True, "ipv6": False }, log_file="/tmp/bgp_speaker_test.FibTest.log") res = ptfhost.shell("pkill exabgp || true") for ip in vlan_ips: host.command("ip route flush %s/32" % ip.ip)
def test_fdb(localhost, ansible_adhoc, testbed): """ 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") hostname = testbed['dut'] ptf_hostname = testbed['ptf'] duthost = ansible_host(ansible_adhoc, hostname) ptfhost = ansible_host(ansible_adhoc, ptf_hostname) host_facts = duthost.setup()['ansible_facts'] mg_facts = duthost.minigraph_facts(host=hostname)['ansible_facts'] # remove existing IPs from PTF host ptfhost.script("fdb/remove_ip.sh") # Set unique MACs to PTF interfaces res = ptfhost.script("fdb/change_mac.sh") root_dir = "/root" ptfhost.copy(src="scripts/arp_responder.py", dest="/opt") extra_vars = {'arp_responder_args': None} ptfhost.host.options['variable_manager'].extra_vars = extra_vars ptfhost.template(src="scripts/arp_responder.conf.j2", dest="/etc/supervisor/conf.d/arp_responder.conf") ptfhost.shell("supervisorctl reread") ptfhost.shell("supervisorctl update") extra_vars = {'mg_facts': mg_facts} ptfhost.host.options['variable_manager'].extra_vars = extra_vars ptfhost.template(src="fdb/fdb.j2", dest="{}/fdb_info.txt".format(root_dir)) ptfhost.copy(src="ptftests", dest=root_dir) dummy_mac_prefix = "02:11:22:33" dummy_mac_number = 10 vlan_member_count = sum( [len(v['members']) for k, v in mg_facts['minigraph_vlans'].items()]) duthost.command("sonic-clear fdb all") # run ptf test ptf_runner(ptfhost, \ "ptftests", "fdb_test.FdbTest", platform_dir="ptftests", params={"testbed_type": "t0", "router_mac": host_facts['ansible_Ethernet0']['macaddress'], "fdb_info": "/root/fdb_info.txt", "vlan_ip": mg_facts['minigraph_vlan_interfaces'][0]['addr'], "dummy_mac_prefix": dummy_mac_prefix, "dummy_mac_number": dummy_mac_number }, log_file="/tmp/fdb_test.FdbTest.log") res = duthost.command("show mac") 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_number * vlan_member_count # Verify that total number of MAC entries is expected assert total_mac_count == dummy_mac_number * vlan_member_count + vlan_member_count duthost.command("sonic-clear fdb all")