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'])
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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'])
Beispiel #5
0
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]]))