def test_interfaces(ansible_adhoc, testbed): """compare the interfaces between observed states and target state""" hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) host_facts = ans_host.setup()['ansible_facts'] mg_facts = ans_host.minigraph_facts(host=hostname)['ansible_facts'] verify_port(host_facts, mg_facts['minigraph_portchannels'].keys()) for k, v in mg_facts['minigraph_portchannels'].items(): verify_port(host_facts, v['members']) # verify no ipv4 address for each port channel member for member in v['members']: ans_ifname = "ansible_%s" % member assert not host_facts[ans_ifname].has_key("ipv4") verify_port(host_facts, mg_facts['minigraph_vlans'].keys()) for k, v in mg_facts['minigraph_vlans'].items(): verify_port(host_facts, v['members']) # verify no ipv4 address for each vlan member for member in v['members']: ans_ifname = "ansible_%s" % member assert not host_facts[ans_ifname].has_key("ipv4") verify_ip_address(host_facts, mg_facts['minigraph_portchannel_interfaces']) verify_ip_address(host_facts, mg_facts['minigraph_vlan_interfaces']) verify_ip_address(host_facts, mg_facts['minigraph_lo_interfaces'])
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_snmp_cpu(ansible_adhoc, testbed, creds): """ Test SNMP CPU Utilization - Pulls CPU usage via shell commans - Polls SNMP for CPU usage - Difference should be < 2% (allowing float->int rounding on each result) TODO: abstract the snmp OID by SKU """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) lhost = AnsibleHost(ansible_adhoc, 'localhost', True) hostip = ans_host.host.options['inventory_manager'].get_host(hostname).vars['ansible_host'] host_facts = ans_host.setup()['ansible_facts'] host_vcpus = int(host_facts['ansible_processor_vcpus']) # Gather facts with SNMP version 2 snmp_facts = lhost.snmp_facts(host=hostip, version="v2c", community=creds["snmp_rocommunity"], is_dell=True)['ansible_facts'] assert int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']) try: for i in range(host_vcpus): ans_host.shell("nohup yes > /dev/null 2>&1 & sleep 1") # Wait for load to reflect in SNMP time.sleep(20) # Gather facts with SNMP version 2 snmp_facts = lhost.snmp_facts(host=hostip, version="v2c", community=creds["snmp_rocommunity"], is_dell=True)['ansible_facts'] # Pull CPU utilization via shell # Explanation: Run top command with 2 iterations, 5sec delay. # Discard the first iteration, then grap the CPU line from the second, # subtract 100% - idle, and round down to integer. output = ans_host.shell("top -bn2 -d5 | awk '/^top -/ { p=!p } { if (!p) print }' | awk '/Cpu/ { cpu = 100 - $8 };END { print cpu }' | awk '{printf \"%.0f\",$1}'") print int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']) print int(output['stdout']) cpu_diff = abs(int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']) - int(output['stdout'])) if cpu_diff > 5: pytest.fail("cpu diff large than 5%%, %d, %d" % (int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']), int(output['stdout']))) ans_host.shell("killall yes") except: ans_host.shell("killall yes") raise
def test_lldp_neighbor(localhost, ansible_adhoc, testbed, eos): """ verify LLDP information on neighbors """ hostname = testbed['dut'] ans_host = AnsibleHost(ansible_adhoc, hostname) mg_facts = ans_host.minigraph_facts(host=hostname)['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'] lldp_facts = ans_host.lldp()['ansible_facts'] host_facts = ans_host.setup()['ansible_facts'] lhost = AnsibleHost(ansible_adhoc, 'localhost', True) config_facts = ans_host.config_facts(host=hostname, source="running")['ansible_facts'] nei_meta = config_facts.get('DEVICE_NEIGHBOR_METADATA', {}) for k, v in lldp_facts['lldp'].items(): if k == 'eth0': # skip test on management interface continue try: hostip = v['chassis']['mgmt-ip'] except: logger.info( "Neighbor device {} does not sent management IP via lldp". format(v['chassis']['name'])) hostip = nei_meta[v['chassis']['name']]['mgmt_addr'] nei_lldp_facts = lhost.lldp_facts( host=hostip, version='v2c', community=eos['snmp_rocommunity'])['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_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]]))