def test_verify_status(duthost): """Verify procdockerstatsd is active and running """ status = duthost.get_service_props('procdockerstatsd') pytest_assert( status["ActiveState"] == "active" and status["SubState"] == "running", "Procdockerstatsd either not active or not running")
def test_neighbors_health(duthosts, localhost, nbrhosts, eos, enum_dut_hostname): """Check each neighbor device health""" fails = [] duthost = duthosts[enum_dut_hostname] config_facts = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts'] nei_meta = config_facts.get('DEVICE_NEIGHBOR_METADATA', {}) for k, v in nei_meta.items(): failmsg = check_snmp(k, v['mgmt_addr'], localhost, eos['snmp_rocommunity']) if failmsg: fails.append(failmsg) eoshost = nbrhosts[k]['host'] failmsg = check_eos_facts(k, v['mgmt_addr'], eoshost) if failmsg: fails.append(failmsg) failmsg = check_bgp_facts(k, eoshost) if failmsg: fails.append(failmsg) # TODO: check link, bgp, etc. on pytest_assert(len(fails) == 0, "\n".join(fails))
def setup_ntp(ptfhost, duthost, creds): """setup ntp client and server""" if creds.get('proxy_env'): # If testbed is behaind proxy then force ntpd inside ptf use local time ptfhost.lineinfile(path="/etc/ntp.conf", line="server 127.127.1.0 prefer") # enable ntp server ntp_en_res = ptfhost.service(name="ntp", state="started") # setup ntp on dut to sync with ntp server config_facts = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts'] ntp_servers = config_facts.get('NTP_SERVER', {}) for ntp_server in ntp_servers: duthost.command("config ntp del %s" % ntp_server) ptfip = ptfhost.host.options['inventory_manager'].get_host( ptfhost.hostname).vars['ansible_host'] duthost.command("config ntp add %s" % ptfip) pytest_assert(wait_until(120, 5, check_ntp_status, ptfhost), \ "NTP server was not started in PTF container {}; NTP service start result {}".format(ptfhost.hostname, ntp_en_res)) yield # stop ntp server ptfhost.service(name="ntp", state="stopped") # reset ntp client configuration duthost.command("config ntp del %s" % ptfip) for ntp_server in ntp_servers: duthost.command("config ntp add %s" % ntp_server)
def test_ntp(duthost, setup_ntp): """ verify the LLDP message on DUT """ duthost.service(name='ntp', state='stopped') duthost.command("ntpd -gq") duthost.service(name='ntp', state='restarted') pytest_assert(wait_until(120, 5, check_ntp_status, duthost), "NTP not in sync")
def test_arp_garp_no_update(common_setup_teardown): duthost, ptfhost, int_facts, intf1, intf2, intf1_indice, intf2_indice = common_setup_teardown params = { 'acs_mac': int_facts['ansible_interface_facts'][intf1]['macaddress'], 'port': intf1_indice } # Test Gratuitous ARP behavior, no Gratuitous ARP installed when arp was not resolved before clear_dut_arp_cache(duthost) log_file = "/tmp/arptest.GarpNoUpdate.{0}.log".format( datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.GarpNoUpdate", '/root/ptftests', params=params, log_file=log_file) switch_arptable = duthost.switch_arptable()['ansible_facts'] for ip in switch_arptable['arptable']['v4'].keys(): pytest_assert(ip != '10.10.1.7') # Test Gratuitous ARP upate case, when received garp, no arp reply, update arp table if it was solved before log_file = "/tmp/arptest.ExpectReply.{0}.log".format( datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.ExpectReply", '/root/ptftests', params=params, log_file=log_file) switch_arptable = duthost.switch_arptable()['ansible_facts'] pytest_assert(switch_arptable['arptable']['v4']['10.10.1.3']['macaddress'] == '00:06:07:08:09:0a') pytest_assert( switch_arptable['arptable']['v4']['10.10.1.3']['interface'] == intf1) time.sleep(2) log_file = "/tmp/arptest.GarpUpdate.{0}.log".format( datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.GarpUpdate", '/root/ptftests', params=params, log_file=log_file) switch_arptable = duthost.switch_arptable()['ansible_facts'] pytest_assert(switch_arptable['arptable']['v4']['10.10.1.3']['macaddress'] == '00:00:07:08:09:0a') pytest_assert( switch_arptable['arptable']['v4']['10.10.1.3']['interface'] == intf1)
def test_get_reboot_cause(self, duthost, localhost, platform_api_conn): # TODO: Compare return values to potential combinations reboot_cause = chassis.get_reboot_cause(platform_api_conn) # Actual return value is a tuple, but since we're using the HTTP server # to make the call and it uses JSON, the tuple is changed to a list pytest_assert(reboot_cause is not None, "Failed to retrieve reboot cause") pytest_assert( isinstance(reboot_cause, list) and len(reboot_cause) == 2, "Reboot cause appears to be incorrect")
def test_portstat_display_all(duthost, command): base_portstat = parse_portstat(duthost.command('portstat')['stdout_lines']) all_portstats = parse_portstat(duthost.command(command)['stdout_lines']) pytest_assert(base_portstat and all_portstats, 'No parsed command output') logger.info( 'Verify the all number of columns is greater than the base number of columns' ) for intf in all_portstats.keys(): pytest_assert( len(all_portstats[intf].keys()) > len(base_portstat[intf].keys()))
def test_default_ipv6_route_next_hop_global_address(duthost): """ check if ipv6 default route nexthop address uses global address """ rtinfo = duthost.get_ip_route_info(ipaddress.ip_address(u"::")) pytest_assert(rtinfo['nexthops'] > 0, "cannot find ipv6 nexthop for default route") for nh in rtinfo['nexthops']: pytest_assert(not nh[0].is_link_local, \ "use link local address {} for nexthop".format(nh[0]))
def testFdbMacExpire(self, request, testbed, duthost, ptfhost): """ TestFdbMacExpire Verifies FDb aging timer is respected The test updates fdb_aging_time value, restarts swssconfig in order to pickup the new value, populated the FDB table with dummy MAC entry, and then waits for fdb_aging_time and makes sure FDB entry with dummy MAC is cleared. Args: request (Fixture): pytest request object testbed (Fixture, dict): Map containing testbed information duthost (AnsibleHost): Device Under Test (DUT) ptfhost (AnsibleHost): Packet Test Framework (PTF) Returns: None """ if "t0" not in testbed["topo"]["type"]: pytest.skip( "FDB MAC Expire test case is not supported on this DUT topology '{0}'" .format(testbed["topo"]["type"])) fdbAgingTime = request.config.getoption('--fdb_aging_time') hostFacts = duthost.setup()['ansible_facts'] testParams = { "testbed_type": testbed["topo"]["name"], "router_mac": hostFacts['ansible_Ethernet0']['macaddress'], "fdb_info": self.FDB_INFO_FILE, "dummy_mac_prefix": self.DUMMY_MAC_PREFIX, } self.__runPtfTest(ptfhost, "fdb_mac_expire_test.FdbMacExpireTest", testParams) logger.info( "wait for FDB aging time of '{0}' secs".format(fdbAgingTime)) time.sleep(fdbAgingTime) count = 0 dummyMacCount = self.__getFdbTableCount(duthost, self.DUMMY_MAC_PREFIX) while count * self.POLLING_INTERVAL_SEC < fdbAgingTime and dummyMacCount != 0: time.sleep(self.POLLING_INTERVAL_SEC) dummyMacCount = self.__getFdbTableCount(duthost, self.DUMMY_MAC_PREFIX) count += 1 logger.info("MAC table entries count: {0}, after {1} sec".format( dummyMacCount, fdbAgingTime + count * self.POLLING_INTERVAL_SEC)) pytest_assert( dummyMacCount == 0, "Failed! MAC did not expire after expected FDB aging time expired")
def validateDummyMacAbsent(self, duthost): """ Validates that test/dummy MAC entry is absent before the test runs Args: duthost (AnsibleHost): Device Under Test (DUT) Returns: None """ pytest_assert( self.__getFdbTableCount(duthost, self.DUMMY_MAC_PREFIX) == 0, "Test dummy MAC is already present")
def test_telemetry_enabledbydefault(duthost): """Verify telemetry should be enabled by default """ status = duthost.shell( '/usr/bin/redis-cli -n 4 hgetall "FEATURE|telemetry"', module_ignore_errors=False)['stdout_lines'] status_list = get_list_stdout(status) # Elements in list alternate between key and value. Separate them and combine into a dict. status_key_list = status_list[0::2] status_value_list = status_list[1::2] status_dict = dict(zip(status_key_list, status_value_list)) for k, v in status_dict.items(): if str(k) == "status": status_expected = "enabled" pytest_assert( str(v) == status_expected, "Telemetry feature is not enabled")
def test_verify_redisexport(duthost): """Verify procdockerstatsd is exporting values to redis. """ docker_stdout = duthost.shell( '/usr/bin/redis-cli -n 6 KEYS "DOCKER_STATS|*" | wc -l', module_ignore_errors=False)['stdout_lines'] docker_keys_count = get_count_fromredisout(docker_stdout) process_stdout = duthost.shell( '/usr/bin/redis-cli -n 6 KEYS "PROCESS_STATS|*" | wc -l', module_ignore_errors=False)['stdout_lines'] process_keys_count = get_count_fromredisout(process_stdout) # if entry for process or docker data found then daemon is upload is sucessful pytest_assert( int(docker_keys_count) > 1, "No data docker data upload found by Procdockerstatsd daemon to state_db" ) pytest_assert( int(process_keys_count) > 1, "No data process data upload found by Procdockerstatsd daemon to state_db" )
def test_neighbors_health(duthosts, localhost, nbrhosts, eos, enum_frontend_dut_hostname): """Check each neighbor device health""" fails = [] duthost = duthosts[enum_frontend_dut_hostname] config_facts = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts'] nei_meta = config_facts.get('DEVICE_NEIGHBOR_METADATA', {}) dut_type = None dev_meta = config_facts.get('DEVICE_METADATA', {}) if "localhost" in dev_meta and "type" in dev_meta["localhost"]: dut_type = dev_meta["localhost"]["type"] for k, v in nei_meta.items(): if v['type'] in ['SmartCable', 'Server'] or dut_type == v['type']: # Smart cable doesn't respond to snmp, it doesn't have BGP session either. # DualToR has the peer ToR listed in device as well. If the device type # is the same as testing DUT, then it is the peer. # The server neighbors need to be skipped too. continue failmsg = check_snmp(k, v['mgmt_addr'], localhost, eos['snmp_rocommunity']) if failmsg: fails.append(failmsg) eoshost = nbrhosts[k]['host'] failmsg = check_eos_facts(k, v['mgmt_addr'], eoshost) if failmsg: fails.append(failmsg) failmsg = check_bgp_facts(k, eoshost) if failmsg: fails.append(failmsg) # TODO: check link, bgp, etc. on pytest_assert(len(fails) == 0, "\n".join(fails))
def test_portstat_delete_all(duthost, command): stats_files = ('test_1', 'test_2', 'test_test') logger.info('Create several test stats files') for stats_file in stats_files: duthost.command('portstat -c -t {}'.format(stats_file)) logger.info('Verify that the file names are in the /tmp directory') uid = duthost.command('id -u')['stdout'].strip() for stats_file in stats_files: pytest_assert(duthost.stat(path='/tmp/portstat-{uid}/{uid}-{filename}'\ .format(uid=uid, filename=stats_file))['stat']['exists']) logger.info('Run the command to be tested "{}"'.format(command)) duthost.command(command) logger.info('Verify that the file names are not in the /tmp directory') for stats_file in stats_files: pytest_assert(not duthost.stat(path='/tmp/portstat-{uid}/{uid}-{filename}'\ .format(uid=uid, filename=stats_file))['stat']['exists'])
def test_sensors(duthost, creds): # Get platform name platform = duthost.get_platform_info()['platform'] # Prepare check list sensors_checks = creds['sensors_checks'] # Gather sensors if platform not in sensors_checks.keys(): pytest.skip( "Skip test due to not support check sensors for current platform({})" .format(platform)) sensors_facts = duthost.sensors_facts( checks=sensors_checks[platform])['ansible_facts'] pytest_assert(not sensors_facts['sensors']['alarm'], "sensors facts: {}".format(sensors_facts)) if sensors_facts['sensors']['warning']: logging.debug("Show warnings: %s" % sensors_facts['sensors']['warning'])
def test_arp_no_reply_src_out_range(common_setup_teardown): duthost, ptfhost, int_facts, intf1, intf2, intf1_indice, intf2_indice = common_setup_teardown params = { 'acs_mac': int_facts['ansible_interface_facts'][intf1]['macaddress'], 'port': intf1_indice } # Check DUT won't reply ARP and install ARP entry when src address is not in interface subnet range clear_dut_arp_cache(duthost) log_file = "/tmp/arptest.SrcOutRangeNoReply.{0}.log".format( datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.SrcOutRangeNoReply", '/root/ptftests', params=params, log_file=log_file) switch_arptable = duthost.switch_arptable()['ansible_facts'] for ip in switch_arptable['arptable']['v4'].keys(): pytest_assert(ip != '10.10.1.22')
def test_portstat_delete_tag(duthost, command): stats_files = ('test_1', 'test_2', 'test_delete_me') file_to_delete = stats_files[2] files_not_deleted = stats_files[:2] logger.info('Create several test stats files') for stats_file in stats_files: duthost.command('portstat -c -t {}'.format(stats_file)) logger.info('Verify that the file names are in the /tmp directory') uid = duthost.command('id -u')['stdout'].strip() for stats_file in stats_files: pytest_assert(duthost.stat(path='/tmp/portstat-{uid}/{uid}-{filename}'\ .format(uid=uid, filename=stats_file))['stat']['exists']) full_delete_command = command + ' ' + file_to_delete logger.info( 'Run the command to be tested "{}"'.format(full_delete_command)) duthost.command(full_delete_command) logger.info('Verify that the deleted file name is not in the directory') pytest_assert(not duthost.stat(path='/tmp/portstat-{uid}/{uid}-{filename}'\ .format(uid=uid, filename=file_to_delete))['stat']['exists']) logger.info('Verify that the remaining file names are in the directory') for stats_file in files_not_deleted: pytest_assert(duthost.stat(path='/tmp/portstat-{uid}/{uid}-{filename}'\ .format(uid=uid, filename=stats_file))['stat']['exists'])
def execute_test(self, duthost, syslog_marker, ignore_regex=None, expect_regex=None, expect_errors=False): """ Helper function that loads each template on the DUT and verifies the expected behavior Args: duthost (AnsibleHost): instance syslog_marker (string): marker prefix name to be inserted in the syslog ignore_regex (string): file containing regexs to be ignored by loganalyzer expect_regex (string): regex pattern that is expected to be present in the syslog expect_erros (bool): if the test expects an error msg in the syslog or not. Default: False Returns: None """ loganalyzer = LogAnalyzer(ansible_host=duthost, marker_prefix=syslog_marker) if ignore_regex: ignore_file = os.path.join(TEMPLATES_DIR, ignore_regex) reg_exp = loganalyzer.parse_regexp_file(src=ignore_file) loganalyzer.ignore_regex.extend(reg_exp) if expect_regex: loganalyzer.expect_regex = [] loganalyzer.expect_regex.extend(expect_regex) loganalyzer.match_regex = [] with loganalyzer(fail=not expect_errors): cmd = "sonic-cfggen -j {}/{}.json --write-to-db".format( DUT_RUN_DIR, syslog_marker) out = duthost.command(cmd) pytest_assert( out["rc"] == 0, "Failed to execute cmd {}: Error: {}".format( cmd, out["stderr"]))
def test_arp_expect_reply(common_setup_teardown): duthost, ptfhost, int_facts, intf1, intf2, intf1_indice, intf2_indice = common_setup_teardown params = { 'acs_mac': int_facts['ansible_interface_facts'][intf1]['macaddress'], 'port': intf1_indice } # Start PTF runner and send correct arp packets clear_dut_arp_cache(duthost) log_file = "/tmp/arptest.ExpectReply.{0}.log".format( datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.ExpectReply", '/root/ptftests', params=params, log_file=log_file) switch_arptable = duthost.switch_arptable()['ansible_facts'] pytest_assert(switch_arptable['arptable']['v4']['10.10.1.3']['macaddress'] == '00:06:07:08:09:0a') pytest_assert( switch_arptable['arptable']['v4']['10.10.1.3']['interface'] == intf1)
def verify_pfcwd_timers(self): """ Compare the timestamps obtained and verify the timer accuracy """ logger.info( "Verify that real detection time is not greater than configured") config_detect_time = self.timers['pfc_wd_detect_time'] + self.timers[ 'pfc_wd_poll_time'] err_msg = ( "Real detection time is greater than configured: Real detect time: {} " "Expected: {} (wd_detect_time + wd_poll_time)".format( self.all_detect_time[9], config_detect_time)) pytest_assert(self.all_detect_time[9] < config_detect_time, err_msg) logger.info( "Verify that real detection time is not less than configured") err_msg = ( "Real detection time is less than configured: Real detect time: {} " "Expected: {} (wd_detect_time)".format( self.all_detect_time[9], self.timers['pfc_wd_detect_time'])) pytest_assert( self.all_detect_time[9] > self.timers['pfc_wd_detect_time'], err_msg) logger.info( "Verify that real restoration time is not less than configured") err_msg = ( "Real restoration time is less than configured: Real restore time: {} " "Expected: {} (wd_restore_time)".format( self.all_restore_time[9], self.timers['pfc_wd_restore_time'])) pytest_assert( self.all_restore_time[9] > self.timers['pfc_wd_restore_time'], err_msg) logger.info( "Verify that real restoration time is less than configured") config_restore_time = self.timers['pfc_wd_restore_time'] + self.timers[ 'pfc_wd_poll_time'] err_msg = ( "Real restoration time is greater than configured: Real restore time: {} " "Expected: {} (wd_restore_time + wd_poll_time)".format( self.all_restore_time[9], config_restore_time)) pytest_assert(self.all_restore_time[9] < config_restore_time, err_msg)
def test_portstat_clear(duthost, command): before_portstat = parse_portstat( duthost.command('portstat')['stdout_lines']) pytest_assert(before_portstat, 'No parsed command output') duthost.command(command) wait(5, 'Wait for portstat counters to refresh') after_portstat = parse_portstat( duthost.command('portstat')['stdout_lines']) pytest_assert(after_portstat, 'No parsed command output') for intf in before_portstat: pytest_assert( int(before_portstat[intf]['rx_ok']) >= int( after_portstat[intf]['rx_ok']), 'Value of RX_OK after clear should be lesser') pytest_assert( int(before_portstat[intf]['tx_ok']) >= int( after_portstat[intf]['rx_ok']), 'Value of RX_OK after clear should be lesser')
def test_modules(self, duthost, localhost, platform_api_conn): # TODO: Ensure the number of modules and that the returned list is correct for this platform try: num_modules = int(chassis.get_num_modules(platform_api_conn)) except: pytest.fail("num_modules is not an integer") module_list = chassis.get_all_modules(platform_api_conn) pytest_assert(module_list is not None, "Failed to retrieve modules") pytest_assert( isinstance(module_list, list) and len(module_list) == num_modules, "Modules appear to be incorrect") for i in range(num_modules): module = chassis.get_module(platform_api_conn, i) pytest_assert(module and module == module_list[i], "Module {} is incorrect".format(i))
def test_fans(self, duthost, localhost, platform_api_conn): # TODO: Ensure the number of fans and that the returned list is correct for this platform try: num_fans = int(chassis.get_num_fans(platform_api_conn)) except: pytest.fail("num_fans is not an integer") fan_list = chassis.get_all_fans(platform_api_conn) pytest_assert(fan_list is not None, "Failed to retrieve fans") pytest_assert( isinstance(fan_list, list) and len(fan_list) == num_fans, "Fans appear to be incorrect") for i in range(num_fans): fan = chassis.get_fan(platform_api_conn, i) pytest_assert(fan and fan == fan_list[i], "Fan {} is incorrect".format(i))
def test_psus(self, duthost, localhost, platform_api_conn): # TODO: Ensure the number of PSUs and that the returned list is correct for this platform try: num_psus = int(chassis.get_num_psus(platform_api_conn)) except: pytest.fail("num_psus is not an integer") psu_list = chassis.get_all_psus(platform_api_conn) pytest_assert(psu_list is not None, "Failed to retrieve PSUs") pytest_assert( isinstance(psu_list, list) and len(psu_list) == num_psus, "PSUs appear to be incorrect") for i in range(num_psus): psu = chassis.get_psu(platform_api_conn, i) pytest_assert(psu and psu == psu_list[i], "PSU {} is incorrect".format(i))
def test_sfps(self, duthost, localhost, platform_api_conn): # TODO: Ensure the number of SFPs and that the returned list is correct for this platform try: num_sfps = int(chassis.get_num_sfps(platform_api_conn)) except: pytest.fail("num_sfps is not an integer") sfp_list = chassis.get_all_sfps(platform_api_conn) pytest_assert(sfp_list is not None, "Failed to retrieve SFPs") pytest_assert( isinstance(sfp_list, list) and len(sfp_list) == num_sfps, "SFPs appear to be incorrect") for i in range(num_sfps): sfp = chassis.get_sfp(platform_api_conn, i) pytest_assert(sfp and sfp == sfp_list[i], "SFP {} is incorrect".format(i))
def test_thermals(self, duthost, localhost, platform_api_conn): # TODO: Ensure the number of thermals and that the returned list is correct for this platform try: num_thermals = int(chassis.get_num_thermals(platform_api_conn)) except: pytest.fail("num_thermals is not an integer") thermal_list = chassis.get_all_thermals(platform_api_conn) pytest_assert(thermal_list is not None, "Failed to retrieve thermals") pytest_assert( isinstance(thermal_list, list) and len(thermal_list) == num_thermals, "Thermalss appear to be incorrect") for i in range(num_thermals): thermal = chassis.get_thermal(platform_api_conn, i) pytest_assert(thermal and thermal == thermal_list[i], "Thermal {} is incorrect".format(i))
def test_components(self, duthost, localhost, platform_api_conn): # TODO: Ensure the number of components and that the returned list is correct for this platform try: num_components = int(chassis.get_num_components(platform_api_conn)) except: pytest.fail("num_components is not an integer") component_list = chassis.get_all_components(platform_api_conn) pytest_assert(component_list is not None, "Failed to retrieve componenets") pytest_assert( isinstance(component_list, list) and len(component_list) == num_components, "Components appear to be incorrect") for i in range(num_components): component = chassis.get_component(platform_api_conn, i) pytest_assert(component and component == component_list[i], "Component {} is incorrect".format(i))
def test_get_base_mac(self, duthost, localhost, platform_api_conn): # Ensure the base MAC address is sane base_mac = chassis.get_base_mac(platform_api_conn) pytest_assert(base_mac is not None, "Failed to retrieve base MAC address") pytest_assert(re.match(REGEX_MAC_ADDRESS, base_mac), "Base MAC address appears to be incorrect") if 'base_mac' in duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars: expected_base_mac = duthost.host.options[ 'inventory_manager'].get_host( duthost.hostname).vars['base_mac'] pytest_assert(base_mac == expected_base_mac, "Base MAC address is incorrect") else: logger.warning( 'Inventory file does not contain base MAC address for {}'. format(duthost.hostname))
def test_get_serial_number(self, duthost, localhost, platform_api_conn): # Ensure the serial number is sane # Note: It appears that when retrieving some variable-length fields, # the value is padded with trailing '\x00' bytes because the field # length is longer than the actual value, so we strip those bytes # here before comparing. We may want to change the EEPROM parsing # logic to ensure that trailing '\x00' bytes are removed when retreiving # a variable-length value. serial = chassis.get_serial_number(platform_api_conn).rstrip('\x00') pytest_assert(serial is not None, "Failed to retrieve serial number") pytest_assert(re.match(REGEX_SERIAL_NUMBER, serial), "Serial number appears to be incorrect") if 'serial' in duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars: expected_serial = duthost.host.options[ 'inventory_manager'].get_host(duthost.hostname).vars['serial'] pytest_assert(serial == expected_serial, "Serial number is incorrect") else: logger.warning( 'Inventory file does not contain serial number for {}'.format( duthost.hostname))
def test_bgp_gr_helper_routes_perserved(duthost, nbrhosts, setup_bgp_graceful_restart): """ Verify that DUT routes are preserved when peer performed graceful restart """ config_facts = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts'] bgp_neighbors = config_facts.get('BGP_NEIGHBOR', {}) po = config_facts.get('PORTCHANNEL', {}) dev_nbr = config_facts.get('DEVICE_NEIGHBOR', {}) rtinfo_v4 = duthost.get_ip_route_info(ipaddress.ip_address(u'0.0.0.0')) if len(rtinfo_v4['nexthops']) == 0: pytest.skip("there is no next hop for v4 default route") rtinfo_v6 = duthost.get_ip_route_info(ipaddress.ip_address(u'::')) if len(rtinfo_v6['nexthops']) == 0: pytest.skip("there is no next hop for v6 default route") ifnames_v4 = [nh[1] for nh in rtinfo_v4['nexthops']] ifnames_v6 = [nh[1] for nh in rtinfo_v6['nexthops']] ifnames_common = [ifname for ifname in ifnames_v4 if ifname in ifnames_v6] ifname = ifnames_common[0] # get neighbor device connected ports nbr_ports = [] if ifname.startswith("PortChannel"): for member in po[ifname]['members']: nbr_ports.append(dev_nbr[member]['port']) else: pytest.skip( "Do not support peer device not connected via port channel") logger.info("neighbor device connected ports {}".format(nbr_ports)) # get nexthop ip for nh in rtinfo_v4['nexthops']: if nh[1] == ifname: bgp_nbr_ipv4 = nh[0] for nh in rtinfo_v6['nexthops']: if nh[1] == ifname: bgp_nbr_ipv6 = nh[0] # get the bgp neighbor bgp_nbr = bgp_neighbors[str(bgp_nbr_ipv4)] nbr_hostname = bgp_nbr['name'] nbrhost = nbrhosts[nbr_hostname]['host'] exabgp_sessions = ['exabgp_v4', 'exabgp_v6'] pytest_assert(nbrhost.check_bgp_session_state([], exabgp_sessions), \ "exabgp sessions {} are not up before graceful restart".format(exabgp_sessions)) # shutdown Rib agent, starting gr process logger.info("shutdown rib process on neighbor {}".format(nbr_hostname)) nbrhost.kill_bgpd() # wait till DUT enter NSF state pytest_assert(wait_until(60, 5, duthost.check_bgp_session_nsf, bgp_nbr_ipv4), \ "neighbor {} does not enter NSF state".format(bgp_nbr_ipv4)) pytest_assert(wait_until(60, 5, duthost.check_bgp_session_nsf, bgp_nbr_ipv6), \ "neighbor {} does not enter NSF state".format(bgp_nbr_ipv6)) # confirm ip route still there rtinfo_v4 = duthost.get_ip_route_info(ipaddress.ip_address(u'0.0.0.0')) pytest_assert(ipaddress.ip_address(bgp_nbr_ipv4) in [ nh[0] for nh in rtinfo_v4['nexthops'] ], \ "cannot find nexthop {} in the new default route nexthops. {}".format(bgp_nbr_ipv4, rtinfo_v4)) rtinfo_v6 = duthost.get_ip_route_info(ipaddress.ip_address(u'::')) pytest_assert(ipaddress.ip_address(bgp_nbr_ipv6) in [ nh[0] for nh in rtinfo_v6['nexthops'] ], \ "cannot find nexthop {} in the new default route nexthops. {}".format(bgp_nbr_ipv6, rtinfo_v6)) # shutdown the connected ports from nbr for nbr_port in nbr_ports: nbrhost.shutdown(nbr_port) try: # start Rib agent logger.info("startup rib process on neighbor {}".format(nbr_hostname)) nbrhost.start_bgpd() # wait for exabgp sessions to establish pytest_assert(wait_until(300, 10, nbrhost.check_bgp_session_state, [], exabgp_sessions), \ "exabgp sessions {} are not coming back".format(exabgp_sessions)) except: raise finally: # unshut the connected ports from nbr for nbr_port in nbr_ports: nbrhost.no_shutdown(nbr_port) # confirm bgp session up graceful_restarted_bgp_sessions = [str(bgp_nbr_ipv4), str(bgp_nbr_ipv6)] pytest_assert(wait_until(300, 10, duthost.check_bgp_session_state, graceful_restarted_bgp_sessions), \ "graceful restarted bgp sessions {} are not coming back".format(graceful_restarted_bgp_sessions))