def scapy_sniff(self, sniff_timeout=180, sniff_filter=''): """ @summary: PTF runner - runs a sniffer in PTF container. Running sniffer in sonic-mgmt container has missing SOCKET problem and permission issues (scapy and tcpdump require root user) The remote function listens on all ports. Once found, all packets are dumped to local pcap file, and all packets are saved to self.all_packets as scapy type. Args: sniff_timeout (int): Duration in seconds to sniff the traffic sniff_filter (str): Filter that Scapy will use to collect only relevant packets """ capture_pcap = '/tmp/capture.pcap' sniffer_log = '/tmp/dualtor-sniffer.log' result = ptf_runner( self.ptfhost, "ptftests", "dualtor_sniffer.Sniff", qlen=PTFRUNNER_QLEN, platform_dir="ptftests", platform="remote", params={ "sniff_timeout" : sniff_timeout, "sniff_filter" : sniff_filter, "capture_pcap": capture_pcap, "sniffer_log": sniffer_log, "port_filter_expression": 'not (arp and ether src {})\ and not tcp'.format(self.dut_mac) }, log_file=sniffer_log, module_ignore_errors=False ) logger.debug("Ptf_runner result: {}".format(result)) logger.info('Fetching log files from ptf and dut hosts') logs_list = [ {'src': sniffer_log, 'dest': '/tmp/', 'flat': True, 'fail_on_missing': False}, {'src': capture_pcap, 'dest': '/tmp/', 'flat': True, 'fail_on_missing': False} ] for log_item in logs_list: self.ptfhost.fetch(**log_item) self.all_packets = scapyall.rdpcap(capture_pcap) logger.info("Number of all packets captured: {}".format(len(self.all_packets)))
def bgp_speaker_announce_routes_common(common_setup_teardown, testbed, duthost, ptfhost, ipv4, ipv6, mtu, family, prefix, nexthop_ips): """Setup bgp speaker on T0 topology and verify routes advertised by bgp speaker is received by T0 TOR """ ptfip, mg_facts, interface_facts, vlan_ips, _, vlan_if_name, speaker_ips, port_num, http_ready = common_setup_teardown assert http_ready logging.info("announce route") peer_range = mg_facts['minigraph_bgp_peers_with_range'][0]['ip_range'][0] lo_addr = mg_facts['minigraph_lo_interfaces'][0]['addr'] logging.info("Announce ip%s prefixes over ipv4 bgp sessions" % family) announce_route(ptfip, lo_addr, prefix, nexthop_ips[1].ip, port_num[0]) announce_route(ptfip, lo_addr, prefix, nexthop_ips[2].ip, port_num[1]) announce_route(ptfip, lo_addr, peer_range, vlan_ips[0].ip, port_num[2]) logging.info( "Wait some time to make sure routes announced to dynamic bgp neighbors" ) time.sleep(30) logging.info( "Verify accepted prefixes of the dynamic neighbors are correct") bgp_facts = duthost.bgp_facts()['ansible_facts'] for ip in speaker_ips: assert bgp_facts['bgp_neighbors'][str(ip.ip)]['accepted prefixes'] == 1 logging.info( "Verify nexthops and nexthop interfaces for accepted prefixes of the dynamic neighbors" ) rtinfo = duthost.get_ip_route_info(ipaddress.ip_network(unicode(prefix))) nexthops_ip_set = {str(nexthop.ip) for nexthop in nexthop_ips} assert len(rtinfo["nexthops"]) == 2 for i in [0, 1]: assert str(rtinfo["nexthops"][i][0]) in nexthops_ip_set assert rtinfo["nexthops"][i][1] == unicode(vlan_if_name) logging.info("Generate route-port map information") extra_vars = { 'announce_prefix': prefix, 'minigraph_portchannels': mg_facts['minigraph_portchannels'], 'minigraph_vlans': mg_facts['minigraph_vlans'], 'minigraph_port_indices': mg_facts['minigraph_port_indices'] } ptfhost.host.options['variable_manager'].extra_vars.update(extra_vars) logging.info("extra_vars: %s" % str(ptfhost.host.options['variable_manager'].extra_vars)) ptfhost.template(src="bgp_speaker/bgp_speaker_route.j2", dest="/root/bgp_speaker_route_%s.txt" % family) logging.info("run ptf test") ptf_runner(ptfhost, "ptftests", "fib_test.FibTest", platform_dir="ptftests", params={ "testbed_type": testbed['topo']['name'], "router_mac": interface_facts['ansible_interface_facts']['Ethernet0'] ['macaddress'], "fib_info": "/root/bgp_speaker_route_%s.txt" % family, "ipv4": ipv4, "ipv6": ipv6, "testbed_mtu": mtu }, log_file="/tmp/bgp_speaker_test.FibTest.log", socket_recv_size=16384) logging.info("Withdraw routes") withdraw_route(ptfip, lo_addr, prefix, nexthop_ips[1].ip, port_num[0]) withdraw_route(ptfip, lo_addr, prefix, nexthop_ips[2].ip, port_num[1]) withdraw_route(ptfip, lo_addr, peer_range, vlan_ips[0].ip, port_num[2]) logging.info("Nexthop ip%s tests are done" % family)
def test_dhcp_relay_start_with_uplinks_down(ptfhost, duthosts, rand_one_dut_hostname, dut_dhcp_relay_data, validate_dut_routes_exist): """Test DHCP relay functionality on T0 topology when relay agent starts with uplinks down For each DHCP relay agent running on the DuT, bring the uplinks down, then restart the relay agent while the uplinks are still down. Then test whether the DHCP relay agent relays packets properly. """ duthost = duthosts[rand_one_dut_hostname] skip_release(duthost, ["201811", "201911", "202106"]) for dhcp_relay in dut_dhcp_relay_data: # Bring all uplink interfaces down for iface in dhcp_relay['uplink_interfaces']: duthost.shell('ifconfig {} down'.format(iface)) # Sleep a bit to ensure uplinks are down time.sleep(20) # Restart DHCP relay service on DUT duthost.shell('systemctl restart dhcp_relay.service') # Sleep to give the DHCP relay container time to start up and # allow the relay agent to begin listening on the down interfaces time.sleep(40) # Bring all uplink interfaces back up for iface in dhcp_relay['uplink_interfaces']: duthost.shell('ifconfig {} up'.format(iface)) # Sleep a bit to ensure uplinks are up time.sleep(20) # Run the DHCP relay test on the PTF host ptf_runner( ptfhost, "ptftests", "dhcpv6_relay_test.DHCPTest", platform_dir="ptftests", params={ "hostname": duthost.hostname, "client_port_index": dhcp_relay['client_iface']['port_idx'], "leaf_port_indices": repr(dhcp_relay['uplink_port_indices']), "num_dhcp_servers": len(dhcp_relay['downlink_vlan_iface']['dhcpv6_server_addrs']), "server_ip": str(dhcp_relay['downlink_vlan_iface']['dhcpv6_server_addrs'] [0]), "relay_iface_ip": str(dhcp_relay['downlink_vlan_iface']['addr']), "relay_iface_mac": str(dhcp_relay['downlink_vlan_iface']['mac']), "relay_link_local": str(dhcp_relay['uplink_interface_link_local']), "vlan_ip": str(dhcp_relay['downlink_vlan_iface']['addr']) }, log_file="/tmp/dhcpv6_relay_test.DHCPTest.log")
def bgp_speaker_announce_routes_common(common_setup_teardown, tbinfo, duthost, ptfhost, ipv4, ipv6, mtu, family, prefix, nexthop_ips, vlan_mac): """Setup bgp speaker on T0 topology and verify routes advertised by bgp speaker is received by T0 TOR """ ptfip, mg_facts, interface_facts, vlan_ips, _, vlan_if_name, speaker_ips, port_num, http_ready = common_setup_teardown assert http_ready logger.info("announce route") peer_range = mg_facts['minigraph_bgp_peers_with_range'][0]['ip_range'][0] lo_addr = mg_facts['minigraph_lo_interfaces'][0]['addr'] logger.info("Announce ip%s prefixes over ipv4 bgp sessions" % family) announce_route(ptfip, lo_addr, prefix, nexthop_ips[1].ip, port_num[0]) announce_route(ptfip, lo_addr, prefix, nexthop_ips[2].ip, port_num[1]) announce_route(ptfip, lo_addr, peer_range, vlan_ips[0].ip, port_num[2]) logger.info( "Wait some time to make sure routes announced to dynamic bgp neighbors" ) time.sleep(30) logger.info( "Verify accepted prefixes of the dynamic neighbors are correct") bgp_facts = duthost.bgp_facts()['ansible_facts'] for ip in speaker_ips: assert bgp_facts['bgp_neighbors'][str(ip.ip)]['accepted prefixes'] == 1 logger.info( "Verify nexthops and nexthop interfaces for accepted prefixes of the dynamic neighbors" ) rtinfo = duthost.get_ip_route_info(ipaddress.ip_network(unicode(prefix))) nexthops_ip_set = {str(nexthop.ip) for nexthop in nexthop_ips} assert len(rtinfo["nexthops"]) == 2 for i in [0, 1]: assert str(rtinfo["nexthops"][i][0]) in nexthops_ip_set assert rtinfo["nexthops"][i][1] == unicode(vlan_if_name) logger.info("Generate route-port map information") extra_vars = { 'announce_prefix': prefix, 'minigraph_portchannels': mg_facts['minigraph_portchannels'], 'minigraph_vlans': mg_facts['minigraph_vlans'], 'minigraph_port_indices': mg_facts['minigraph_ptf_indices'] } ptfhost.host.options['variable_manager'].extra_vars.update(extra_vars) logger.info("extra_vars: %s" % str(ptfhost.host.options['variable_manager'].extra_vars)) ptfhost.template(src="bgp/templates/bgp_speaker_route.j2", dest="/root/bgp_speaker_route_%s.txt" % family) # For fib PTF testing, including dualtor ptf_test_port_map = {} enabled_ptf_ports = get_dut_enabled_ptf_ports(tbinfo, duthost.hostname) vlan_ptf_ports = get_dut_vlan_ptf_ports(mg_facts) logger.debug('enabled_ptf_ports={}, vlan_ptf_ports={}, vlan_mac={}'\ .format(enabled_ptf_ports, vlan_ptf_ports, vlan_mac)) for port in enabled_ptf_ports: if port in vlan_ptf_ports: target_mac = vlan_mac else: target_mac = duthost.facts['router_mac'] ptf_test_port_map[str(port)] = { 'target_dut': 0, 'target_mac': target_mac } ptfhost.copy(content=json.dumps(ptf_test_port_map), dest=PTF_TEST_PORT_MAP) logger.info("run ptf test") ptf_runner(ptfhost, "ptftests", "fib_test.FibTest", platform_dir="ptftests", params={ "router_macs": [duthost.facts['router_mac']], "ptf_test_port_map": PTF_TEST_PORT_MAP, "fib_info_files": ["/root/bgp_speaker_route_%s.txt" % family], "ipv4": ipv4, "ipv6": ipv6, "testbed_mtu": mtu, "test_balancing": False }, log_file="/tmp/bgp_speaker_test.FibTest.log", socket_recv_size=16384) logger.info("Withdraw routes") withdraw_route(ptfip, lo_addr, prefix, nexthop_ips[1].ip, port_num[0]) withdraw_route(ptfip, lo_addr, prefix, nexthop_ips[2].ip, port_num[1]) withdraw_route(ptfip, lo_addr, peer_range, vlan_ips[0].ip, port_num[2]) logger.info("Nexthop ip%s tests are done" % family)
def test_basic_fib( duthosts, ptfhost, ipv4, ipv6, mtu, # set_mux_random, fib_info_files, tbinfo, mux_server_url, router_macs, ignore_ttl, single_fib_for_duts): if 'dualtor' in tbinfo['topo']['name']: wait( 30, 'Wait some time for mux active/standby state to be stable after toggled mux state' ) timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') # do not test load balancing for vs platform as kernel 4.9 # can only do load balance base on L3 if duthosts[0].facts['asic_type'] in ["vs"]: test_balancing = False else: test_balancing = True logging.info("run ptf test") log_file = "/tmp/fib_test.FibTest.ipv4.{}.ipv6.{}.{}.log".format( ipv4, ipv6, timestamp) logging.info("PTF log file: %s" % log_file) ptf_runner( ptfhost, "ptftests", "fib_test.FibTest", platform_dir="ptftests", params={ "fib_info_files": fib_info_files[:3], # Test at most 3 DUTs "ptf_test_port_map": ptf_test_port_map(ptfhost, tbinfo, duthosts, mux_server_url), "router_macs": router_macs, "ipv4": ipv4, "ipv6": ipv6, "testbed_mtu": mtu, "test_balancing": test_balancing, "ignore_ttl": ignore_ttl, "single_fib_for_duts": single_fib_for_duts }, log_file=log_file, qlen=PTF_QLEN, socket_recv_size=16384)
def __runPtfRunner(self, rebootOper=None): ''' Run single PTF advanced-reboot.ReloadTest @param rebootOper:Reboot operation to conduct before/during reboot process ''' logger.info("Running PTF runner on PTF host: {0}".format(self.ptfhost)) # Non-routing neighbor/dut lag/bgp, vlan port up/down operation is performed before dut reboot process # lack of routing indicates it is preboot operation prebootOper = rebootOper if rebootOper is not None and 'routing' not in rebootOper else None # Routing add/remove is performed during dut reboot process # presence of routing in reboot operation indicates it is during reboot operation (inboot) inbootOper = rebootOper if rebootOper is not None and 'routing' in rebootOper else None self.__updateAndRestartArpResponder(rebootOper) logger.info('Run advanced-reboot ReloadTest on the PTF host') result = ptf_runner(self.ptfhost, "ptftests", "advanced-reboot.ReloadTest", qlen=PTFRUNNER_QLEN, platform_dir="ptftests", platform="remote", params={ "dut_username": self.rebootData['dut_username'], "dut_password": self.rebootData['dut_password'], "dut_hostname": self.rebootData['dut_hostname'], "reboot_limit_in_seconds": self.rebootLimit, "reboot_type": self.rebootType, "portchannel_ports_file": self.rebootData['portchannel_interfaces_file'], "vlan_ports_file": self.rebootData['vlan_interfaces_file'], "ports_file": self.rebootData['ports_file'], "dut_mac": self.rebootData['dut_mac'], "dut_vlan_ip": self.rebootData['dut_vlan_ip'], "default_ip_range": self.rebootData['default_ip_range'], "vlan_ip_range": self.rebootData['vlan_ip_range'], "lo_v6_prefix": self.rebootData['lo_v6_prefix'], "arista_vms": self.rebootData['arista_vms'], "preboot_files": self.prebootFiles, "preboot_oper": prebootOper, "inboot_oper": inbootOper, "nexthop_ips": self.rebootData['nexthop_ips'], "allow_vlan_flooding": self.allowVlanFlooding, "sniff_time_incr": self.sniffTimeIncr, "setup_fdb_before_test": True, "vnet": self.vnet, "vnet_pkts": self.vnetPkts, }, log_file=u'/tmp/advanced-reboot.ReloadTest.log', module_ignore_errors=self.moduleIgnoreErrors) return result
def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, localhost): logging.info( "Executing warm boot dynamic inner hash test for outer {} and inner {} with symmetric_hashing" " set to {}".format(outer_ipver, inner_ipver, str(symmetric_hashing))) with allure.step( 'Run ptf test InnerHashTest and warm-reboot in parallel'): timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') log_file = "/tmp/wr_inner_hash_test.DynamicInnerHashTest.{}.{}.{}.log".format( outer_ipver, inner_ipver, timestamp) logging.info("PTF log file: %s" % log_file) # to reduce test run time, check one of encapsulation formats outer_encap_format = random.choice(OUTER_ENCAP_FORMATS).split() logging.info("Tested encapsulation format: {}".format( outer_encap_format[0])) outer_src_ip_range, outer_dst_ip_range = get_src_dst_ip_range( outer_ipver) inner_src_ip_range, inner_dst_ip_range = get_src_dst_ip_range( inner_ipver) balancing_test_times = 200 balancing_range = 0.3 reboot_thr = threading.Thread(target=reboot, args=( duthost, localhost, 'warm', 10, 0, 0, True, True, )) reboot_thr.start() ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", platform_dir="ptftests", params={ "fib_info": FIB_INFO_FILE_DST, "router_mac": router_mac, "src_ports": vlan_ptf_ports, "hash_keys": hash_keys, "vxlan_port": VXLAN_PORT, "inner_src_ip_range": ",".join(inner_src_ip_range), "inner_dst_ip_range": ",".join(inner_dst_ip_range), "outer_src_ip_range": ",".join(outer_src_ip_range), "outer_dst_ip_range": ",".join(outer_dst_ip_range), "balancing_test_times": balancing_test_times, "balancing_range": balancing_range, "outer_encap_formats": outer_encap_format, "nvgre_tni": NVGRE_TNI, "symmetric_hashing": symmetric_hashing }, log_file=log_file, qlen=PTF_QLEN, socket_recv_size=16384) reboot_thr.join()
def test_dhcp_relay_start_with_uplinks_down(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config): """Test DHCP relay functionality on T0 topology when relay agent starts with uplinks down For each DHCP relay agent running on the DuT, bring the uplinks down, then restart the relay agent while the uplinks are still down. Then test whether the DHCP relay agent relays packets properly. """ testing_mode, duthost, testbed_mode = testing_config if testbed_mode == 'dual_testbed': pytest.skip("skip the uplinks down testcase on dual tor testbeds") if testing_mode == DUAL_TOR_MODE: skip_release(duthost, ["201811", "201911"]) for dhcp_relay in dut_dhcp_relay_data: # Bring all uplink interfaces down for iface in dhcp_relay['uplink_interfaces']: duthost.shell('ifconfig {} down'.format(iface)) pytest_assert( wait_until(50, 5, 0, check_link_status, duthost, dhcp_relay['uplink_interfaces'], "down"), "Not all uplinks go down") # Restart DHCP relay service on DUT duthost.shell('systemctl restart dhcp_relay.service') # Sleep to give the DHCP relay container time to start up and # allow the relay agent to begin listening on the down interfaces time.sleep(40) # Bring all uplink interfaces back up for iface in dhcp_relay['uplink_interfaces']: duthost.shell('ifconfig {} up'.format(iface)) # Wait until uplinks are up and routes are recovered pytest_assert( wait_until(50, 5, 0, check_routes_to_dhcp_server, duthost, dut_dhcp_relay_data), "Not all DHCP servers are routed") # Run the DHCP relay test on the PTF host ptf_runner( ptfhost, "ptftests", "dhcp_relay_test.DHCPTest", platform_dir="ptftests", params={ "hostname": duthost.hostname, "client_port_index": dhcp_relay['client_iface']['port_idx'], "client_iface_alias": str(dhcp_relay['client_iface']['alias']), "leaf_port_indices": repr(dhcp_relay['uplink_port_indices']), "num_dhcp_servers": len(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs']), "server_ip": str(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs'][0]), "relay_iface_ip": str(dhcp_relay['downlink_vlan_iface']['addr']), "relay_iface_mac": str(dhcp_relay['downlink_vlan_iface']['mac']), "relay_iface_netmask": str(dhcp_relay['downlink_vlan_iface']['mask']), "dest_mac_address": BROADCAST_MAC, "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), "testbed_mode": testbed_mode, "testing_mode": testing_mode }, log_file="/tmp/dhcp_relay_test.DHCPTest.log")
def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank_0_port, bank_1_port, prefix): if isinstance(ipaddress.ip_network(prefix), ipaddress.IPv4Network): ipcmd = "ip route" else: ipcmd = "ipv6 route" for nexthop in ip_to_port: duthost.shell("vtysh -c 'configure terminal' -c '{} {} {}'".format( ipcmd, prefix, nexthop)) time.sleep(1) test_time = str(datetime.now().strftime('%Y-%m-%d-%H:%M:%S')) log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.create_flows.log".format( test_time) exp_flow_count = {} flows_per_nh = NUM_FLOWS / len(port_list) for port in port_list: exp_flow_count[port] = flows_per_nh ptf_runner(ptfhost, "ptftests", "fg_ecmp_test.FgEcmpTest", platform_dir="ptftests", params={ "test_case": 'create_flows', "exp_flow_count": exp_flow_count, "config_file": FG_ECMP_CFG }, qlen=1000, log_file=log_file) log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.initial_hash_check.log".format( test_time) ptf_runner(ptfhost, "ptftests", "fg_ecmp_test.FgEcmpTest", platform_dir="ptftests", params={ "test_case": 'initial_hash_check', "exp_flow_count": exp_flow_count, "config_file": FG_ECMP_CFG }, qlen=1000, log_file=log_file) exp_flow_count = {} flows_for_withdrawn_nh_bank = (NUM_FLOWS / 2) / (len(bank_0_port) - 1) withdraw_nh_port = bank_0_port[1] for port in bank_1_port: exp_flow_count[port] = flows_per_nh for port in bank_0_port: if port != withdraw_nh_port: exp_flow_count[port] = flows_for_withdrawn_nh_bank for nexthop, port in ip_to_port.items(): if port == withdraw_nh_port: duthost.shell( "vtysh -c 'configure terminal' -c 'no {} {} {}'".format( ipcmd, prefix, nexthop)) log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.withdraw_nh.log".format( test_time) time.sleep(1) ptf_runner(ptfhost, "ptftests", "fg_ecmp_test.FgEcmpTest", platform_dir="ptftests", params={ "test_case": 'withdraw_nh', "config_file": FG_ECMP_CFG, "exp_flow_count": exp_flow_count, "withdraw_nh_port": withdraw_nh_port }, qlen=1000, log_file=log_file) exp_flow_count = {} for port in port_list: exp_flow_count[port] = flows_per_nh for nexthop, port in ip_to_port.items(): if port == withdraw_nh_port: duthost.shell("vtysh -c 'configure terminal' -c '{} {} {}'".format( ipcmd, prefix, nexthop)) log_file = "/tmp/fg_ecmp_test.FgEcmpTest.add_nh.{}.log".format(test_time) time.sleep(1) ptf_runner(ptfhost, "ptftests", "fg_ecmp_test.FgEcmpTest", platform_dir="ptftests", params={ "test_case": 'add_nh', "config_file": FG_ECMP_CFG, "exp_flow_count": exp_flow_count, "add_nh_port": withdraw_nh_port }, qlen=1000, log_file=log_file) withdraw_nh_bank = bank_0_port for nexthop, port in ip_to_port.items(): if port in withdraw_nh_bank: duthost.shell( "vtysh -c 'configure terminal' -c 'no {} {} {}'".format( ipcmd, prefix, nexthop)) log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.withdraw_bank.log".format( test_time) time.sleep(1) exp_flow_count = {} flows_per_nh = NUM_FLOWS / len(bank_1_port) for port in bank_1_port: exp_flow_count[port] = flows_per_nh ptf_runner(ptfhost, "ptftests", "fg_ecmp_test.FgEcmpTest", platform_dir="ptftests", params={ "test_case": 'withdraw_bank', "config_file": FG_ECMP_CFG, "exp_flow_count": exp_flow_count, "withdraw_nh_bank": withdraw_nh_bank }, qlen=1000, log_file=log_file) first_nh = bank_0_port[3] for nexthop, port in ip_to_port.items(): if port == first_nh: duthost.shell("vtysh -c 'configure terminal' -c '{} {} {}'".format( ipcmd, prefix, nexthop)) log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.add_first_nh.log".format( test_time) time.sleep(1) exp_flow_count = {} flows_per_nh = (NUM_FLOWS / 2) / (len(bank_1_port)) for port in bank_1_port: exp_flow_count[port] = flows_per_nh exp_flow_count[first_nh] = NUM_FLOWS / 2 ptf_runner(ptfhost, "ptftests", "fg_ecmp_test.FgEcmpTest", platform_dir="ptftests", params={ "test_case": 'add_first_nh', "config_file": FG_ECMP_CFG, "exp_flow_count": exp_flow_count, "first_nh": first_nh }, qlen=1000, log_file=log_file)
def test_inner_hashing(self, request, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, duthost, lag_mem_ptf_ports_groups): logging.info( "Executing dynamic inner hash test for outer {} and inner {} with symmetric_hashing set to {}" .format(outer_ipver, inner_ipver, str(symmetric_hashing))) with allure.step('Run ptf test InnerHashTest'): timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') log_file = "/tmp/inner_hash_test.DynamicInnerHashTest.{}.{}.{}.log".format( outer_ipver, inner_ipver, timestamp) logging.info("PTF log file: %s" % log_file) outer_src_ip_range, outer_dst_ip_range = get_src_dst_ip_range( outer_ipver) inner_src_ip_range, inner_dst_ip_range = get_src_dst_ip_range( inner_ipver) balancing_test_times = 120 balancing_range = 0.3 ptf_params = { "fib_info": FIB_INFO_FILE_DST, "router_mac": router_mac, "src_ports": vlan_ptf_ports, "exp_port_groups": lag_mem_ptf_ports_groups, "hash_keys": hash_keys, "vxlan_port": VXLAN_PORT, "inner_src_ip_range": ",".join(inner_src_ip_range), "inner_dst_ip_range": ",".join(inner_dst_ip_range), "outer_src_ip_range": ",".join(outer_src_ip_range), "outer_dst_ip_range": ",".join(outer_dst_ip_range), "balancing_test_times": balancing_test_times, "balancing_range": balancing_range, "outer_encap_formats": OUTER_ENCAP_FORMATS, "nvgre_tni": NVGRE_TNI, "symmetric_hashing": symmetric_hashing } duthost.shell("sonic-clear pbh statistics") ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", platform_dir="ptftests", params=ptf_params, log_file=log_file, qlen=PTF_QLEN, socket_recv_size=16384) retry_call(check_pbh_counters, fargs=[ duthost, outer_ipver, inner_ipver, balancing_test_times, symmetric_hashing, hash_keys, lag_mem_ptf_ports_groups ], tries=5, delay=5) if update_outer_ipver == outer_ipver and update_inner_ipver == inner_ipver: logging.info( "Validate dynamic inner hash Edit Flow for outer {} and inner {} ip versions with" " symmetric_hashing set to {}".format(outer_ipver, inner_ipver, str(symmetric_hashing))) swapped_outer_ipver = "ipv6" if outer_ipver == "ipv4" else "ipv4" swapped_inner_ipver = "ipv6" if inner_ipver == "ipv4" else "ipv4" with allure.step( 'Swap configuration of rules {}_{} with {}_{}'.format( outer_ipver, inner_ipver, swapped_outer_ipver, swapped_inner_ipver)): request.getfixturevalue("update_rule") with allure.step( 'Run again the ptf test InnerHashTest after updating the rules' ): duthost.shell("sonic-clear pbh statistics") ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", platform_dir="ptftests", params=ptf_params, log_file=log_file, qlen=PTF_QLEN, socket_recv_size=16384) retry_call(check_pbh_counters, fargs=[ duthost, swapped_outer_ipver, swapped_inner_ipver, balancing_test_times, symmetric_hashing, hash_keys, lag_mem_ptf_ports_groups ], tries=5, delay=5)
def __runPtfRunner(self, rebootOper=None): ''' Run single PTF advanced-reboot.ReloadTest @param rebootOper:Reboot operation to conduct before/during reboot process ''' logger.info("Running PTF runner on PTF host: {0}".format(self.ptfhost)) params = { "dut_username": self.rebootData['dut_username'], "dut_password": self.rebootData['dut_password'], "dut_hostname": self.rebootData['dut_hostname'], "reboot_limit_in_seconds": self.rebootLimit, "reboot_type": self.rebootType, "portchannel_ports_file": self.rebootData['portchannel_interfaces_file'], "vlan_ports_file": self.rebootData['vlan_interfaces_file'], "ports_file": self.rebootData['ports_file'], "dut_mac": self.rebootData['dut_mac'], "default_ip_range": self.rebootData['default_ip_range'], "vlan_ip_range": self.rebootData['vlan_ip_range'], "lo_v6_prefix": self.rebootData['lo_v6_prefix'], "arista_vms": self.rebootData['arista_vms'], "nexthop_ips": self.rebootData['nexthop_ips'], "allow_vlan_flooding": self.allowVlanFlooding, "sniff_time_incr": self.sniffTimeIncr, "setup_fdb_before_test": True, "vnet": self.vnet, "vnet_pkts": self.vnetPkts, "bgp_v4_v6_time_diff": self.bgpV4V6TimeDiff, "asic_type": self.duthost.facts["asic_type"], "allow_mac_jumping": self.allowMacJump, "preboot_files": self.prebootFiles, "alt_password": self.duthost.host.options['variable_manager']._hostvars[ self.duthost.hostname].get("ansible_altpassword") } if not isinstance(rebootOper, SadOperation): # Non-routing neighbor/dut lag/bgp, vlan port up/down operation is performed before dut reboot process # lack of routing indicates it is preboot operation prebootOper = rebootOper if rebootOper is not None and 'routing' not in rebootOper else None # Routing add/remove is performed during dut reboot process # presence of routing in reboot operation indicates it is during reboot operation (inboot) inbootOper = rebootOper if rebootOper is not None and 'routing' in rebootOper else None params.update({ "preboot_oper": prebootOper, "inboot_oper": inbootOper, }) else: params.update({'logfile_suffix': str(rebootOper)}) self.__updateAndRestartArpResponder(rebootOper) logger.info('Run advanced-reboot ReloadTest on the PTF host. TestCase: {}, sub-case: {}'.format(\ self.request.node.name, str(rebootOper))) result = ptf_runner(self.ptfhost, "ptftests", "advanced-reboot.ReloadTest", qlen=PTFRUNNER_QLEN, platform_dir="ptftests", platform="remote", params=params, log_file=u'/tmp/advanced-reboot.ReloadTest.log', module_ignore_errors=self.moduleIgnoreErrors, timeout=REBOOT_CASE_TIMEOUT) return result
def test_dhcp_relay_after_link_flap(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config): """Test DHCP relay functionality on T0 topology after uplinks flap For each DHCP relay agent running on the DuT, with relay agent running, flap the uplinks, then test whether the DHCP relay agent relays packets properly. """ testing_mode, duthost, testbed_mode = testing_config if testbed_mode == 'dual_testbed': pytest.skip("skip the link flap testcase on dual tor testbeds") for dhcp_relay in dut_dhcp_relay_data: # Bring all uplink interfaces down for iface in dhcp_relay['uplink_interfaces']: duthost.shell('ifconfig {} down'.format(iface)) pytest_assert( wait_until(50, 5, 0, check_link_status, duthost, dhcp_relay['uplink_interfaces'], "down"), "Not all uplinks go down") # Bring all uplink interfaces back up for iface in dhcp_relay['uplink_interfaces']: duthost.shell('ifconfig {} up'.format(iface)) # Wait until uplinks are up and routes are recovered pytest_assert( wait_until(50, 5, 0, check_routes_to_dhcp_server, duthost, dut_dhcp_relay_data), "Not all DHCP servers are routed") # Run the DHCP relay test on the PTF host ptf_runner( ptfhost, "ptftests", "dhcp_relay_test.DHCPTest", platform_dir="ptftests", params={ "hostname": duthost.hostname, "client_port_index": dhcp_relay['client_iface']['port_idx'], "client_iface_alias": str(dhcp_relay['client_iface']['alias']), "leaf_port_indices": repr(dhcp_relay['uplink_port_indices']), "num_dhcp_servers": len(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs']), "server_ip": str(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs'][0]), "relay_iface_ip": str(dhcp_relay['downlink_vlan_iface']['addr']), "relay_iface_mac": str(dhcp_relay['downlink_vlan_iface']['mac']), "relay_iface_netmask": str(dhcp_relay['downlink_vlan_iface']['mask']), "dest_mac_address": BROADCAST_MAC, "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), "testbed_mode": testbed_mode, "testing_mode": testing_mode }, log_file="/tmp/dhcp_relay_test.DHCPTest.log")
def test_bgp_speaker_announce_routes(common_setup_teardown, testbed, duthost, ptfhost, ipv4, ipv6, mtu, collect_techsupport): """Setup bgp speaker on T0 topology and verify routes advertised by bgp speaker is received by T0 TOR """ ptfip, mg_facts, interface_facts, vlan_ips, speaker_ips, port_num, http_ready = common_setup_teardown assert http_ready logging.info("announce route") peer_range = mg_facts['minigraph_bgp_peers_with_range'][0]['ip_range'][0] lo_addr = mg_facts['minigraph_lo_interfaces'][0]['addr'] lo_addr_prefixlen = int( mg_facts['minigraph_lo_interfaces'][0]['prefixlen']) prefix = '10.10.10.0/26' announce_route(ptfip, lo_addr, prefix, vlan_ips[1].ip, port_num[0]) announce_route(ptfip, lo_addr, prefix, vlan_ips[2].ip, port_num[1]) announce_route(ptfip, lo_addr, peer_range, vlan_ips[0].ip, port_num[2]) logging.info( "Wait some time to make sure routes announced to dynamic bgp neighbors" ) time.sleep(30) # The ping here is workaround for known issue: # https://github.com/Azure/SONiC/issues/387 Pre-ARP support for static route config # When there is no arp entry for next hop, routes learnt from exabgp will not be set down to ASIC # Traffic to prefix 10.10.10.0 will be routed to vEOS VMs via default gateway. duthost.shell("ping %s -c 3" % vlan_ips[1].ip) duthost.shell("ping %s -c 3" % vlan_ips[2].ip) time.sleep(5) logging.info( "Verify accepted prefixes of the dynamic neighbors are correct") bgp_facts = duthost.bgp_facts()['ansible_facts'] for ip in speaker_ips: assert bgp_facts['bgp_neighbors'][str(ip.ip)]['accepted prefixes'] == 1 logging.info("Generate route-port map information") extra_vars = { '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'] } ptfhost.host.options['variable_manager'].extra_vars.update(extra_vars) logging.info("extra_vars: %s" % str(ptfhost.host.options['variable_manager'].extra_vars)) ptfhost.template(src="bgp_speaker/bgp_speaker_route.j2", dest="/root/bgp_speaker_route.txt") logging.info("run ptf test") ptf_runner(ptfhost, "ptftests", "fib_test.FibTest", platform_dir="ptftests", params={ "testbed_type": testbed['topo']['name'], "router_mac": interface_facts['ansible_interface_facts']['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)