def test_ospf_convergence(): logger.info("Test: check OSPF adjacencies") tgen = get_topogen() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) # Old output (before FRR PR1383) didn't show a list of neighbors. # Check for dict object and compare to old output if this is the case tgen = get_topogen() router = tgen.gears['r1'] output = router.vtysh_cmd("show ip ospf neighbor json", isjson=True) # We could have either old format (without "neighbors" and direct list # of IP's or new format from PR1659 with "neighbors". # Trying old formats first and fall back to new format # # New format: neighbors have dict instead of list of dicts (PR1723). if output.has_key('neighbors'): if isinstance(output['neighbors'], dict): reffile = "show_ip_ospf_neighbor.json" else: reffile = "show_ip_ospf_neighbor.ref" else: if isinstance(output["2.2.2.2"], dict): reffile = "show_ip_ospf_neighbor.ref-old-nolist" else: reffile = "show_ip_ospf_neighbor.ref-no-neigh" for rname in ['r1', 'r2', 'r3']: router_compare_json_output(rname, "show ip ospf neighbor json", reffile)
def test_ldp_pseudowires_after_link_down(): logger.info("Test: verify LDP pseudowires after r1-r2 link goes down") tgen = get_topogen() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) # Shut down r1-r2 link */ tgen = get_topogen() tgen.gears['r1'].peer_link_enable('r1-eth1', False) # check if the pseudowire is still up (using an alternate path for nexthop resolution) for rname in ['r1', 'r2', 'r3']: router_compare_json_output(rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref")
def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() logger.info('\n\n---- OSPF Segment Routing tests End ----\n')
def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # FRR routers for router in ['lm', 'ce1', 'pe1', 'p1', 'pe2', 'ce2']: tgen.add_router(router); # Connections switch = tgen.add_switch('s1') switch.add_link(tgen.gears['ce1'], nodeif='ce1-eth0') switch.add_link(tgen.gears['pe1'], nodeif='pe1-eth0') switch = tgen.add_switch('s2') switch.add_link(tgen.gears['pe1'], nodeif='pe1-eth1') switch.add_link(tgen.gears['p1'], nodeif='p1-eth0') switch = tgen.add_switch('s3') switch.add_link(tgen.gears['p1'], nodeif='p1-eth1') switch.add_link(tgen.gears['pe2'], nodeif='pe2-eth1') switch = tgen.add_switch('s4') switch.add_link(tgen.gears['ce2'], nodeif='ce2-eth0') switch.add_link(tgen.gears['pe2'], nodeif='pe2-eth0')
def test_pim_send_mcast_stream(): "Establish a Multicast stream from r2 -> r1 and then ensure S,G is created as appropriate" logger.info("Establish a Mcast stream from r2->r1 and then ensure S,G created") tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) r2 = tgen.gears['r2'] r1 = tgen.gears['r1'] # Let's establish a S,G stream from r2 -> r1 CWD = os.path.dirname(os.path.realpath(__file__)) r2.run("{}/mcast-tx.py --ttl 5 --count 5 --interval 10 229.1.1.1 r2-eth0 > /tmp/bar".format(CWD)) # Let's see that it shows up and we have established some basic state out = r1.vtysh_cmd("show ip pim upstream json", isjson=True) expected = { '229.1.1.1': { '10.0.20.2': { 'firstHopRouter': 1, 'joinState': 'NotJoined', 'regState': 'RegPrune', 'inboundInterface': 'r1-eth0', } } } assert topotest.json_cmp(out, expected) is None, 'failed to converge pim'
def test_bgp_maximum_prefix_invalid(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) def _bgp_converge(router): while True: output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) if output['192.168.255.1']['connectionsEstablished'] > 3: return True time.sleep(1) def _bgp_parsing_nlri(router): cmd_max_exceeded = 'grep "%MAXPFXEXCEED: No. of IPv4 Unicast prefix received" bgpd.log' cmdt_error_parsing_nlri = 'grep "Error parsing NLRI" bgpd.log' output_max_exceeded = tgen.gears[router].run(cmd_max_exceeded) output_error_parsing_nlri = tgen.gears[router].run(cmdt_error_parsing_nlri) if len(output_max_exceeded) > 0: if len(output_error_parsing_nlri) > 0: return False return True if _bgp_converge('r2'): assert _bgp_parsing_nlri('r2') == True
def test_pim_igmp_report(): "Send a igmp report from r2->r1 and ensure that the *,G state is created on r1" logger.info("Send a igmp report from r2-r1 and ensure *,G created") tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) r2 = tgen.gears['r2'] r1 = tgen.gears['r1'] # Let's send a igmp report from r2->r1 CWD = os.path.dirname(os.path.realpath(__file__)) r2.run("{}/mcast-rx.py 229.1.1.2 r2-eth0 &".format(CWD)) out = r1.vtysh_cmd("show ip pim upstream json", isjson=True) expected = { '229.1.1.2': { '*': { 'sourceIgmp': 1, 'joinState': 'Joined', 'regState': 'RegNoInfo', 'sptBit': 0, } } } assert topotest.json_cmp(out, expected) is None, 'failed to converge pim'
def test_ospf_link_down(): "Test OSPF convergence after a link goes down" tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip('skipped because of router(s) failure') # Simulate a network down event on router3 switch3 interface. router3 = tgen.gears['r3'] topotest.interface_set_status(router3, 'r3-eth0', ifaceaction=False, vrf_name='r3-cust1') # Expect convergence on all routers for rname, router in tgen.routers().iteritems(): logger.info('Waiting for router "%s" convergence after link failure', rname) # Load expected results from the command reffile = os.path.join(CWD, '{}/ospfroute_down.txt'.format(rname)) expected = open(reffile).read() # Run test function until we get an result. Wait at most 60 seconds. test_func = partial(topotest.router_output_cmp, router, 'show ip ospf vrf {0}-cust1 route'.format(rname), expected) result, diff = topotest.run_and_expect(test_func, '', count=140, wait=0.5) assertmsg = 'OSPF did not converge on {}:\n{}'.format(rname, diff) assert result, assertmsg
def build(self): "Build function" tgen = get_topogen(self) # Check for mpls if tgen.hasmpls is not True: tgen.set_error('MPLS not available, tests will be skipped') # Create 4 routers for routern in range(1, 5): tgen.add_router('r{}'.format(routern)) # Interconect router 1 and 2 switch = tgen.add_switch('s1') switch.add_link(tgen.gears['r1']) switch.add_link(tgen.gears['r2']) # Interconect router 3 and 2 switch = tgen.add_switch('s2') switch.add_link(tgen.gears['r3']) switch.add_link(tgen.gears['r2']) # Interconect router 4 and 2 switch = tgen.add_switch('s3') switch.add_link(tgen.gears['r4']) switch.add_link(tgen.gears['r2'])
def test_protocols_convergence(): """ Assert that all protocols have converged before checking for the BFD statuses as they depend on it. """ tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) # Check IPv6 routing tables. logger.info("Checking IPv6 routes for convergence") for router in tgen.routers().values(): if router.name == 'r2': continue json_file = '{}/{}/ipv6_routes.json'.format(CWD, router.name) if not os.path.isfile(json_file): logger.info('skipping file {}'.format(json_file)) continue expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, 'show ipv6 route json', expected) _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg
def test_bfd_comes_back_again(): """ Assert that BFD notices the bfd link up and that ipv6 entries appear back """ tgen = get_topogen() logger.info('re-adding IPv6 address from r2 to simulate connectivity is back') # adds back r2-eth0 ipv6 address cmd = 'vtysh -c \"configure terminal\" -c \"interface r2-eth1\" -c "ipv6 address 2001:db8:4::2/64\"' tgen.net['r2'].cmd(cmd) # Wait the minimum time we can before checking that BGP/BFD # converged. logger.info('waiting for BFD to converge up') # Check that BGP converged quickly. for router in tgen.routers().values(): if router.name == 'r2': continue json_file = '{}/{}/peers.json'.format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, 'show bfd peers json', expected) _, result = topotest.run_and_expect(test_func, None, count=8, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg
def test_bgp_ecmp(): tgen = get_topogen() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) expect = { 'routerId': '10.0.255.1', 'routes': { }, } for net in range(1, 5): for subnet in range(0, 10): netkey = '10.20{}.{}.0/24'.format(net, subnet) expect['routes'][netkey] = [] for _ in range(0, 10): peer = {'multipath': True, 'valid': True} expect['routes'][netkey].append(peer) test_func = functools.partial(topotest.router_json_cmp, tgen.gears['r1'], 'show ip bgp json', expect) _, res = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assertmsg = 'expected multipath routes in "show ip bgp" output' assert res is None, assertmsg
def test_bgp_fast_reconvergence(): "Assert that BGP is converging after setting a link down." tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info('waiting for BGP re convergence') # Check that BGP converged quickly. for router in tgen.routers().values(): ref_file = '{}/{}/bgp_prefixes.json'.format(CWD, router.name) expected = json.loads(open(ref_file).read()) # Load the same file as previous test, but set networks to None # to test absence. if router.name == 'r1': expected['routes']['10.254.254.2/32'] = None expected['routes']['10.254.254.3/32'] = None expected['routes']['10.254.254.4/32'] = None else: expected['routes']['10.254.254.1/32'] = None test_func = partial(topotest.router_json_cmp, router, 'show ip bgp vrf {}-cust1 json'.format(router.name), expected) _, res = topotest.run_and_expect( test_func, None, count=3, wait=1 ) assertmsg = '{}: bgp did not converge'.format(router.name) assert res is None, assertmsg
def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # This function only purpose is to define allocation and relationship # between routers, switches and hosts. # # Create P/PE routers tgen.add_router('r1') for routern in range(2, 5): tgen.add_router('r{}'.format(routern)) # Create a switch with just one router connected to it to simulate a # empty network. switch = {} switch[0] = tgen.add_switch('sw0') switch[0].add_link(tgen.gears['r1'], nodeif='r1-eth0') switch[0].add_link(tgen.gears['r2'], nodeif='r2-eth0') switch[1] = tgen.add_switch('sw1') switch[1].add_link(tgen.gears['r2'], nodeif='r2-eth1') switch[1].add_link(tgen.gears['r3'], nodeif='r3-eth0') switch[1].add_link(tgen.gears['r4'], nodeif='r4-eth0') switch[2] = tgen.add_switch('sw2') switch[2].add_link(tgen.gears['r2'], nodeif='r2-eth2') switch[2].add_link(tgen.gears['r3'], nodeif='r3-eth1')
def test_bgp_convergence(): "Test for BGP topology convergence" tgen = get_topogen() # uncomment if you want to troubleshoot # tgen.mininet_cli() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info('waiting for bgp convergence') # Expected result router = tgen.gears['r1'] if router.has_version('<', '3.0'): reffile = os.path.join(CWD, 'r1/summary20.txt') else: reffile = os.path.join(CWD, 'r1/summary.txt') expected = json.loads(open(reffile).read()) test_func = functools.partial(topotest.router_json_cmp, router, 'show bgp vrf r1-cust1 summary json', expected) _, res = topotest.run_and_expect(test_func, None, count=90, wait=0.5) assertmsg = 'BGP router network did not converge' assert res is None, assertmsg
def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # Add ISIS routers: # r1 r2 # | sw1 | sw2 # r3 r4 # | | # sw3 sw4 # \ / # r5 for routern in range(1, 6): tgen.add_router('r{}'.format(routern)) # r1 <- sw1 -> r3 sw = tgen.add_switch('sw1') sw.add_link(tgen.gears['r1']) sw.add_link(tgen.gears['r3']) # r2 <- sw2 -> r4 sw = tgen.add_switch('sw2') sw.add_link(tgen.gears['r2']) sw.add_link(tgen.gears['r4']) # r3 <- sw3 -> r5 sw = tgen.add_switch('sw3') sw.add_link(tgen.gears['r3']) sw.add_link(tgen.gears['r5']) # r4 <- sw4 -> r5 sw = tgen.add_switch('sw4') sw.add_link(tgen.gears['r4']) sw.add_link(tgen.gears['r5'])
def test_isis_route6_installation(): "Check whether all expected routes are present" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info('Checking routers for installed ISIS IPv6 routes') # Check for routes in 'show ip route json' for rname, router in tgen.routers().iteritems(): filename = '{0}/{1}/{1}_route6.json'.format(CWD, rname) expected = json.loads(open(filename, 'r').read()) actual = router.vtysh_cmd('show ipv6 route json', isjson=True) # Older FRR versions don't list interfaces in some ISIS routes if router.has_version('<', '3.1'): for network, routes in expected.iteritems(): for route in routes: # Older versions display different metrics for IPv6 routes route.pop('metric', None) if route['protocol'] != 'isis': continue for nexthop in route['nexthops']: nexthop.pop('interfaceIndex', None) nexthop.pop('interfaceName', None) assertmsg = "Router '{}' routes mismatch".format(rname) assert topotest.json_cmp(actual, expected) is None, assertmsg
def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): pytest.skip('Memory leak test/report is disabled') tgen.report_memory_leaks()
def test_bgp_maximum_prefix_invalid(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) def _bgp_converge(router, neighbor): cmd = "show ip bgp neighbor {0} json".format(neighbor) while True: output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) if output[neighbor]['bgpState'] == 'Established': time.sleep(3) return True def _bgp_show_nexthop(router, prefix): cmd = "show ip bgp json" output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) for nh in output['routes'][prefix][0]['nexthops']: if 'fqdn' in nh: return 'fqdn' return 'ip' if _bgp_converge('r2', '192.168.255.1'): assert _bgp_show_nexthop('r2', '172.16.255.254/32') == 'fqdn' if _bgp_converge('r1', '192.168.255.2'): assert _bgp_show_nexthop('r1', '172.16.255.253/32') == 'ip'
def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # Create 3 routers for routern in range(1, 4): tgen.add_router('r{}'.format(routern)) # Create a empty network for router 1 switch = tgen.add_switch('s1') switch.add_link(tgen.gears['r1']) # Create a empty network for router 2 switch = tgen.add_switch('s2') switch.add_link(tgen.gears['r2']) # Interconect router 1, 2 and 3 switch = tgen.add_switch('s3') switch.add_link(tgen.gears['r1']) switch.add_link(tgen.gears['r2']) switch.add_link(tgen.gears['r3']) # Create empty netowrk for router3 switch = tgen.add_switch('s4') switch.add_link(tgen.gears['r3'])
def test_bgp_remove_private_as(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) def _bgp_converge(router): while True: cmd = "show ip bgp neighbor 192.168.255.1 json" output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) if output['192.168.255.1']['bgpState'] == 'Established': time.sleep(3) return True def _bgp_ebgp_requires_policy(router): cmd = "show ip bgp 172.16.255.254/32 json" output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) if 'prefix' in output: return True return False if _bgp_converge('r2'): assert _bgp_ebgp_requires_policy('r2') == True if _bgp_converge('r4'): assert _bgp_ebgp_requires_policy('r4') == False
def ltemplatePreRouterStartHook(): cc = ltemplateRtrCmd() tgen = get_topogen() logger.info('pre router-start hook') #check for mpls if tgen.hasmpls != True: logger.info('MPLS not available, skipping setup') return False #check for normal init if len(tgen.net) == 1: logger.info('Topology not configured, skipping setup') return False #configure r2 mpls interfaces intfs = ['lo', 'r2-eth0', 'r2-eth1', 'r2-eth2'] for intf in intfs: cc.doCmd(tgen, 'r2', 'echo 1 > /proc/sys/net/mpls/conf/{}/input'.format(intf)) #configure MPLS rtrs = ['r1', 'r3', 'r4'] cmds = ['echo 1 > /proc/sys/net/mpls/conf/lo/input'] for rtr in rtrs: router = tgen.gears[rtr] for cmd in cmds: cc.doCmd(tgen, rtr, cmd) intfs = ['lo', rtr+'-eth0', rtr+'-eth4'] for intf in intfs: cc.doCmd(tgen, rtr, 'echo 1 > /proc/sys/net/mpls/conf/{}/input'.format(intf)) logger.info('setup mpls input') return True
def test_isis_convergence(): "Wait for the protocol to converge before starting to test" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info("waiting for ISIS protocol to converge") # Code to generate the json files. # for rname, router in tgen.routers().iteritems(): # open('/tmp/{}_topology.json'.format(rname), 'w').write( # json.dumps(show_isis_topology(router), indent=2, sort_keys=True) # ) for rname, router in tgen.routers().iteritems(): filename = '{0}/{1}/{1}_topology.json'.format(CWD, rname) expected = json.loads(open(filename).read()) def compare_isis_topology(router, expected): "Helper function to test ISIS topology convergence." actual = show_isis_topology(router) return topotest.json_cmp(actual, expected) test_func = functools.partial(compare_isis_topology, router, expected) (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=120) assert result, 'ISIS did not converge on {}:\n{}'.format(rname, diff)
def test_bfd_loss_intermediate(): """ Assert that BFD notices the bfd link down failure. but BGP entries should still be present """ tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info('removing IPv6 address from r2 to simulate loss of connectivity') # Disable r2-eth0 ipv6 address cmd = 'vtysh -c \"configure terminal\" -c \"interface r2-eth1\" -c "no ipv6 address 2001:db8:4::2/64\"' tgen.net['r2'].cmd(cmd) # Wait the minimum time we can before checking that BGP/BFD # converged. logger.info('waiting for BFD converge down') # Check that BGP converged quickly. for router in tgen.routers().values(): if router.name == 'r2': continue json_file = '{}/{}/peers_down.json'.format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, 'show bfd peers json', expected) _, result = topotest.run_and_expect(test_func, None, count=8, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg logger.info('waiting for BGP entries to become stale') for router in tgen.routers().values(): if router.name == 'r2': continue json_file = '{}/{}/bgp_ipv6_routes_down.json'.format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, 'show bgp ipv6 json', expected) _, result = topotest.run_and_expect(test_func, None, count=50, wait=1) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg logger.info("Checking IPv6 routes on r1 should still be present") for router in tgen.routers().values(): if router.name == 'r2': continue if router.name == 'r3': continue json_file = '{}/r1/ipv6_routes.json'.format(CWD) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, 'show ipv6 route json', expected) _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg
def ltemplatePreRouterStartHook(): cc = ltemplateRtrCmd() tgen = get_topogen() logger.info('pre router-start hook') #check for normal init if len(tgen.net) == 1: logger.info('Topology not configured, skipping setup') return False return True
def build(self, *_args, **_opts): tgen = get_topogen(self) for routern in range(1, 3): tgen.add_router('r{}'.format(routern)) switch = tgen.add_switch('s1') switch.add_link(tgen.gears['r1']) switch.add_link(tgen.gears['r2'])
def test_call_mininet_cli(): "Dummy test that just calls mininet CLI so we can interact with the build." tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info('calling mininet CLI') tgen.mininet_cli()
def compare_mpls_table(rname, expected): """ Calls 'show mpls table json' for router `rname` and compare the obtained result with the expected output. """ tgen = get_topogen() current = tgen.gears[rname].vtysh_cmd('show mpls table json') return topotest.difflines(current, expected, title1="Current output", title2="Expected output")
def teardown_module(module): tgen = get_topogen() # move back r1-eth0 to default VRF # delete VRF r1-cust1 cmds = ['ip netns exec {0}-cust1 ip link set {0}-eth0 netns 1', 'ip netns delete {0}-cust1'] for cmd in cmds: tgen.net['r1'].cmd(cmd.format('r1')) tgen.stop_topology()
def test_ldp_pseudowires(): logger.info("Test: verify LDP pseudowires") tgen = get_topogen() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) for rname in ['r1', 'r2', 'r3']: router_compare_json_output(rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref")
def test_r1_mplsvpn_VrfTable(): tgen = get_topogen() r1 = tgen.net.get("r1") r1r = tgen.gears["r1"] r1_snmp = SnmpTester(r1, "10.1.1.1", "public", "2c") # tgen.mininet_cli() oids = [] oids.append(snmp_str_to_oid("VRF-a")) oids.append(snmp_str_to_oid("VRF-b")) # check items for item in vrftable_test.keys(): assertmsg = "{} should be {} oids {} full dict {}:".format( item, vrftable_test[item], oids, r1_snmp.walk(item)) assert r1_snmp.test_oid_walk(item, vrftable_test[item], oids), assertmsg # check timetick set and stable ts_a = r1_snmp.get("mplsL3VpnVrfCreationTime.{}".format( snmp_str_to_oid("VRF-a"))) ts_b = r1_snmp.get("mplsL3VpnVrfCreationTime.{}".format( snmp_str_to_oid("VRF-b"))) ts_val_a1 = get_timetick_val(ts_a) ts_val_b1 = get_timetick_val(ts_b) ts_a = r1_snmp.get("mplsL3VpnVrfCreationTime.{}".format( snmp_str_to_oid("VRF-a"))) ts_b = r1_snmp.get("mplsL3VpnVrfCreationTime.{}".format( snmp_str_to_oid("VRF-b"))) ts_val_a2 = get_timetick_val(ts_a) ts_val_b2 = get_timetick_val(ts_b) assertmsg = "timestamp values for VRF-a do not match {} {}".format( ts_val_a1, ts_val_a2) assert ts_val_a1 == ts_val_a2, assertmsg assertmsg = "timestamp values for VRF-b do not match {} {}".format( ts_val_b1, ts_val_b2) assert ts_val_b1 == ts_val_b2, assertmsg # take Last changed time, fiddle with active interfaces, ensure # time changes and active interfaces change ts_last = r1_snmp.get("mplsL3VpnVrfConfLastChanged.{}".format( snmp_str_to_oid("VRF-a"))) ts_val_last_1 = get_timetick_val(ts_last) r1r.vtysh_cmd("conf t\ninterface r1-eth3\nshutdown") active_int = r1_snmp.get("mplsL3VpnVrfActiveInterfaces.{}".format( snmp_str_to_oid("VRF-a"))) assertmsg = "mplsL3VpnVrfActiveInterfaces incorrect should be 1 value {}".format( active_int) assert active_int == "1", assertmsg ts_last = r1_snmp.get("mplsL3VpnVrfConfLastChanged.{}".format( snmp_str_to_oid("VRF-a"))) ts_val_last_2 = get_timetick_val(ts_last) assertmsg = "mplsL3VpnVrfConfLastChanged does not update on interface change" assert ts_val_last_2 > ts_val_last_1, assertmsg r1r.vtysh_cmd("conf t\ninterface r1-eth3\nno shutdown") # take Last changed time, fiddle with associated interfaces, ensure # time changes and active interfaces change ts_last = r1_snmp.get("mplsL3VpnVrfConfLastChanged.{}".format( snmp_str_to_oid("VRF-a"))) ts_val_last_1 = get_timetick_val(ts_last) r1.cmd("ip link set r1-eth6 master VRF-a") r1.cmd("ip link set r1-eth6 up") associated_int = r1_snmp.get("mplsL3VpnVrfAssociatedInterfaces.{}".format( snmp_str_to_oid("VRF-a"))) assertmsg = ( "mplsL3VpnVrfAssociatedInterfaces incorrect should be 3 value {}". format(associated_int)) assert associated_int == "3", assertmsg ts_last = r1_snmp.get("mplsL3VpnVrfConfLastChanged.{}".format( snmp_str_to_oid("VRF-a"))) ts_val_last_2 = get_timetick_val(ts_last) assertmsg = "mplsL3VpnVrfConfLastChanged does not update on interface change" assert ts_val_last_2 > ts_val_last_1, assertmsg r1.cmd("ip link del r1-eth6 master VRF-a") r1.cmd("ip link set r1-eth6 down")
def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() # move back rx-eth0 to default VRF # delete rx-vrf tgen.stop_topology()
def test_bgp_tcp_mss(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) router1 = tgen.gears["r1"] router2 = tgen.gears["r2"] def _bgp_converge(router): output = json.loads( router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) expected = { "192.168.255.2": { "bgpState": "Established", "addressFamilyInfo": { "ipv4Unicast": { "acceptedPrefixCounter": 0 } }, } } return topotest.json_cmp(output, expected) def _bgp_conf_tcp_mss(router, as_num, neigh): router.vtysh_cmd("""configure terminal router bgp {0} neighbor {1} tcp-mss 500""".format(as_num, neigh)) def _bgp_clear_session(router): router.vtysh_cmd("clear bgp *") def _bgp_check_neighbor_tcp_mss(router, neigh): output = json.loads( router.vtysh_cmd("show bgp neighbor {} json".format(neigh))) expected = { "{}".format(neigh): { "bgpTcpMssConfigured": 500, "bgpTcpMssSynced": 488 } } return topotest.json_cmp(output, expected) logger.info("Check if neighbor sessions are up in {}".format(router1.name)) test_func = functools.partial(_bgp_converge, router1) success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence in "{}"'.format( router1.name) logger.info("BGP neighbor session is up in {}".format(router1.name)) logger.info("Configure tcp-mss 500 on {} and reset the session".format( router1.name)) _bgp_conf_tcp_mss(router1, "65000", "192.168.255.2") _bgp_clear_session(router1) logger.info("Configure tcp-mss 500 on {} and reset the session".format( router2.name)) _bgp_conf_tcp_mss(router2, "65001", "192.168.255.1") _bgp_clear_session(router2) logger.info("Check if neighbor session is up after reset in {}".format( router1.name)) test_func = functools.partial(_bgp_converge, router1) success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence after reset in "{}"'.format( router1.name) logger.info("Verify if TCP MSS value is synced with neighbor in {}".format( router1.name)) test_func = functools.partial(_bgp_check_neighbor_tcp_mss, router1, "192.168.255.2") success, result = topotest.run_and_expect(test_func, None, count=3, wait=0.5) assert (result is None ), 'Failed to sync TCP MSS value over BGP session in "{}"'.format( router1.name) logger.info("TCP MSS value is synced with neighbor in {}".format( router1.name)) logger.info("Verify if TCP MSS value is synced with neighbor in {}".format( router2.name)) test_func = functools.partial(_bgp_check_neighbor_tcp_mss, router2, "192.168.255.1") success, result = topotest.run_and_expect(test_func, None, count=3, wait=0.5) assert (result is None ), 'Failed to sync TCP MSS value over BGP session in "{}"'.format( router2.name) logger.info("TCP MSS value is synced with neighbor in {}".format( router2.name))
def pytest_runtest_makereport(item, call): "Log all assert messages to default logger with error level" # Nothing happened if call.when == "call": pause = topotest_extra_config["pause"] else: pause = False title = "unset" if call.excinfo is None: error = False else: parent = item.parent modname = parent.module.__name__ # Treat skips as non errors, don't pause after if call.excinfo.typename == "Skipped": pause = False error = False logger.info('test skipped at "{}/{}": {}'.format( modname, item.name, call.excinfo.value)) else: error = True # Handle assert failures parent._previousfailed = item # pylint: disable=W0212 logger.error('test failed at "{}/{}": {}'.format( modname, item.name, call.excinfo.value)) title = "{}/{}".format(modname, item.name) # We want to pause, if requested, on any error not just test cases # (e.g., call.when == "setup") if not pause: pause = (topotest_extra_config["pause_on_error"] or topotest_extra_config["pause"]) # (topogen) Set topology error to avoid advancing in the test. tgen = get_topogen() if tgen is not None: # This will cause topogen to report error on `routers_have_failure`. tgen.set_error("{}/{}".format(modname, item.name)) commander = Commander("pytest") isatty = sys.stdout.isatty() error_cmd = None if error and topotest_extra_config["vtysh_on_error"]: error_cmd = commander.get_exec_path(["vtysh"]) elif error and topotest_extra_config["shell_on_error"]: error_cmd = os.getenv("SHELL", commander.get_exec_path(["bash"])) if error_cmd: is_tmux = bool(os.getenv("TMUX", "")) is_screen = not is_tmux and bool(os.getenv("STY", "")) is_xterm = not is_tmux and not is_screen and bool( os.getenv("DISPLAY", "")) channel = None win_info = None wait_for_channels = [] wait_for_procs = [] # Really would like something better than using this global here. # Not all tests use topogen though so get_topogen() won't work. for node in Mininet.g_mnet_inst.hosts.values(): pause = True if is_tmux: channel = ("{}-{}".format(os.getpid(), Commander.tmux_wait_gen) if not isatty else None) Commander.tmux_wait_gen += 1 wait_for_channels.append(channel) pane_info = node.run_in_window( error_cmd, new_window=win_info is None, background=True, title="{} ({})".format(title, node.name), name=title, tmux_target=win_info, wait_for=channel, ) if is_tmux: if win_info is None: win_info = pane_info elif is_xterm: assert isinstance(pane_info, subprocess.Popen) wait_for_procs.append(pane_info) # Now wait on any channels for channel in wait_for_channels: logger.debug("Waiting on TMUX channel %s", channel) commander.cmd_raises( [commander.get_exec_path("tmux"), "wait", channel]) for p in wait_for_procs: logger.debug("Waiting on TMUX xterm process %s", p) o, e = p.communicate() if p.wait(): logger.warning("xterm proc failed: %s:", proc_error(p, o, e)) if error and topotest_extra_config["cli_on_error"]: # Really would like something better than using this global here. # Not all tests use topogen though so get_topogen() won't work. if Mininet.g_mnet_inst: cli(Mininet.g_mnet_inst, title=title, background=False) else: logger.error("Could not launch CLI b/c no mininet exists yet") while pause and isatty: try: user = raw_input( 'PAUSED, "cli" for CLI, "pdb" to debug, "Enter" to continue: ') except NameError: user = input( 'PAUSED, "cli" for CLI, "pdb" to debug, "Enter" to continue: ') user = user.strip() if user == "cli": cli(Mininet.g_mnet_inst) elif user == "pdb": pdb.set_trace() elif user: print('Unrecognized input: "%s"' % user) else: break
def test_ospf_lan_ecmp_tc18_p0(request): """ OSPF ECMP. Verify OSPF ECMP with max path configured as 8 (Edge having 1 uplink port as broadcast network, connect to 8 TORs - LAN case) """ tc_name = request.node.name write_test_header(tc_name) tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) global topo step("Bring up the base config as per the topology") step(". Configure ospf in all the routers on LAN interface.") reset_config_on_routers(tgen) step("Verify that OSPF is up with 8 neighborship sessions.") ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True) assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( ospf_covergence ) step( "Configure a static route in all the routes and " "redistribute static/connected in OSPF." ) for rtr in topo["routers"]: input_dict = { rtr: { "static_routes": [ {"network": NETWORK["ipv4"][0], "no_of_ip": 5, "next_hop": "Null0"} ] } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result ) dut = rtr redistribute_ospf(tgen, topo, dut, "static") step( "Verify that route in R0 in stalled with 8 hops. " "Verify ospf route table and ip route table." ) nh = [] for rtr in topo["routers"]: nh.append(topo["routers"][rtr]["links"]["s1"]["ipv4"].split("/")[0]) nh.remove(topo["routers"]["r1"]["links"]["s1"]["ipv4"].split("/")[0]) dut = "r1" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) protocol = "ospf" result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step(" clear ip ospf interface on DUT(r0)") clear_ospf(tgen, "r0") step( "Verify that after clearing the ospf interface all the " "neighbours are up and routes are installed with 8 next hop " "in ospf and ip route tables on R0" ) dut = "r0" ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, lan=True) assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( ospf_covergence ) step(" clear ip ospf interface on R2") clear_ospf(tgen, "r2") dut = "r2" ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, lan=True) assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( ospf_covergence ) step("Delete static/connected cmd in ospf in all the routes one by one.") for rtr in topo["routers"]: input_dict = { rtr: { "static_routes": [ { "network": NETWORK["ipv4"][0], "no_of_ip": 5, "next_hop": "Null0", "delete": True, } ] } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result ) step("Verify that all the routes are withdrawn from R0") dut = "r1" result = verify_ospf_rib( tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False ) assert result is not True, ("Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result )) protocol = "ospf" result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh, attempts=5, expected=False, ) assert result is not True, ("Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result )) write_test_footer(tc_name)
def test_modify_and_delete_router_id(request): """ Test to modify, delete and verify router-id. """ tgen = get_topogen() if BGP_CONVERGENCE is not True: pytest.skip('skipped because of BGP Convergence failure') # test case name tc_name = request.node.name write_test_header(tc_name) # Modify router id input_dict = { 'r1': { "bgp": { 'router_id': '12.12.12.12' } }, 'r2': { "bgp": { 'router_id': '22.22.22.22' } }, 'r3': { "bgp": { 'router_id': '33.33.33.33' } }, } result = create_router_bgp(tgen, topo, input_dict) assert result is True, "Testcase {} :Failed \n Error: {}".\ format(tc_name, result) # Verifying router id once modified result = verify_router_id(tgen, topo, input_dict) assert result is True, "Testcase {} :Failed \n Error: {}".\ format(tc_name, result) # Delete router id input_dict = { 'r1': { "bgp": { 'del_router_id': True } }, 'r2': { "bgp": { 'del_router_id': True } }, 'r3': { "bgp": { 'del_router_id': True } }, } result = create_router_bgp(tgen, topo, input_dict) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) # Verifying router id once deleted # Once router-id is deleted, highest interface ip should become # router-id result = verify_router_id(tgen, topo, input_dict) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) write_test_footer(tc_name)
def test_next_hop_attribute(request): """ Verifying route are not getting installed in, as next_hop is unreachable, Making next hop reachable using next_hop_self command and verifying routes are installed. """ tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) # test case name tc_name = request.node.name write_test_header(tc_name) # Creating configuration from JSON reset_config_on_routers(tgen) # Api call to advertise networks input_dict = { "r7": { "bgp":{ "address_family": { "ipv4": { "unicast": { "advertise_networks": [ { "network": "200.50.2.0/32" }, { "network": "200.60.2.0/32" } ] } } } } } } result = create_router_bgp(tgen, topo, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Verifying RIB routes dut = "r1" protocol = "bgp" result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False) assert result is not True, "Testcase {} : Failed \n Error: Routes still" \ " present in RIB".format(tc_name) # Configure next-hop-self to bgp neighbor input_dict_1 = { "r2": { "bgp": { "address_family": { "ipv4": { "unicast": { "neighbor": { "r1": { "dest_link": { "r2": {"next_hop_self": True} } } } } } } } }, "r3": { "bgp": { "address_family": { "ipv4": { "unicast": { "neighbor": { "r1": { "dest_link": { "r3": {"next_hop_self": True} } } } } } } } } } result = create_router_bgp(tgen, topo, input_dict_1) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Verifying RIB routes dut = "r1" protocol = "bgp" result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) write_test_footer(tc_name)
def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # Building topology and configuration from json file build_topo_from_json(tgen, topo)
def test_admin_distance(request): " Verifying admin distance functionality" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) # test case name tc_name = request.node.name write_test_header(tc_name) # Creating configuration from JSON reset_config_on_routers(tgen) # Api call to create static routes input_dict = { "r2": { "static_routes": [ { "network": "200.50.2.0/32", "admin_distance": 80, "next_hop": "10.0.0.14" }, { "network": "200.50.2.0/32", "admin_distance": 60, "next_hop": "10.0.0.18" } ] } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Api call to redistribute static routes input_dict_2 = { "r2": { "bgp": { "address_family": { "ipv4": { "unicast": { "redistribute": [ {"redist_type": "static"}, {"redist_type": "connected"} ] } } } } } } result = create_router_bgp(tgen, input_dict_2) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Verifying best path dut = "r1" attribute = "admin_distance" result = verify_best_path_as_per_admin_distance(tgen, "ipv4", dut, input_dict, attribute) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) write_test_footer(tc_name)
def teardown_module(mod): tgen = get_topogen() tgen.stop_topology()
def test_RP_hash_p0(request): """ Verify RP is selected based on hash function, when BSR advertising the group to RP mapping with same priority Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = pre_config_to_bsm(tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) GROUP_ADDRESS = "225.1.1.1" # Use scapy to send pre-defined packet from senser to receiver result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet7") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"][ "bsr"].split("/")[0] time.sleep(1) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) dut = "l1" # Verify bsr state in FHR step("Verify if b1 chosen as BSR in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) group = "225.1.1.0/24" # Find the elected rp from bsrp-info step("Find the elected rp from bsrp-info in LHR l1") rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) assert rp is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Verify if RP with highest hash value is chosen step("Verify if RP(2.2.2.2) with highest hash value is chosen in l1") if rp[group] == "2.2.2.2": result = True else: result = "rp expected: 2.2.2.2 got:" + rp[group] assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Check RP detail in LHR step("Verify RP in LHR") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def test_BSM_fragmentation_p1(request): """ Verify fragmentation of bootstrap message Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = pre_config_to_bsm(tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) GROUP_ADDRESS = "225.1.1.1" bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"][ "bsr"].split("/")[0] step("Send BSM and verify if all routers have same bsrp before fragment") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") # Verify bsr state in FHR step("Verify if b1 chosen as BSR in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) fhr_node = tgen.routers()["f1"] inter_node = tgen.routers()["i1"] lhr_node = tgen.routers()["l1"] # Verify if bsrp list is same across f1, i1 and l1 step("Verify if bsrp list is same across f1, i1 and l1") bsrp_f1 = fhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) logger.info("show_ip_pim_bsrp_info_json f1: \n %s", bsrp_f1) bsrp_i1 = inter_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) logger.info("show_ip_pim_bsrp_info_json i1: \n %s", bsrp_i1) bsrp_l1 = lhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) logger.info("show_ip_pim_bsrp_info_json l1: \n %s", bsrp_l1) if bsrp_f1 == bsrp_l1: result = True else: result = "bsrp info in f1 is not same in l1" assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # set mtu of fhr(f1) to i1 interface to 100 so that bsm fragments step("set mtu of fhr(f1) to i1 interface to 100 so that bsm fragments") fhr_node.run("ip link set f1-i1-eth2 mtu 100") inter_node.run("ip link set i1-f1-eth0 mtu 100") # Use scapy to send pre-defined packet from senser to receiver result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet2") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify bsr state in FHR step("Verify if b1 chosen as BSR") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Verify if bsrp list is same across f1, i1 and l1 step( "Verify if bsrp list is same across f1, i1 and l1 after fragmentation") bsrp_f1 = fhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) logger.info("show_ip_pim_bsrp_info_json f1: \n %s", bsrp_f1) bsrp_i1 = inter_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) logger.info("show_ip_pim_bsrp_info_json i1: \n %s", bsrp_i1) bsrp_l1 = lhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) logger.info("show_ip_pim_bsrp_info_json l1: \n %s", bsrp_l1) if bsrp_f1 == bsrp_l1: result = True else: result = "bsrp info in f1 is not same in l1" assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def test_RP_with_all_ip_octet_p1(request): """ Verify when candidate RP advertised with 32 mask length and contain all the contacts Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) step("pre-configure BSM packet") result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) step( "Send the IGMP group (225.100.100.100) from receiver connected to FRR") GROUP_ADDRESS = "225.200.100.100" # Use scapy to send pre-defined packet from senser to receiver step("Configure cisco-1 as BSR1") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet8") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet8"][ "bsr"].split("/")[0] time.sleep(1) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) dut = "l1" step( "Groups are shown with candidate RP with correct mask length 'show ip pim bsrp-info'" ) step("Verify if b1 chosen as BSR in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) group = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet9"]["group"] step("Find the elected rp from bsrp-info in LHR l1") rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) assert rp is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) step("Verify RP in LHR") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def test_origin_attribute(request): " Verifying ORIGIN attribute functionality" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) # test case name tc_name = request.node.name write_test_header(tc_name) # Creating configuration from JSON reset_config_on_routers(tgen) # Api call to advertise networks input_dict = { "r4": { "bgp": { "address_family": { "ipv4": { "unicast": { "advertise_networks": [ { "network": "200.50.2.0/32" }, { "network": "200.60.2.0/32" } ] } } } } }, "r2": { "bgp": { "address_family": { "ipv4": { "unicast": { "neighbor": { "r1": { "dest_link": { "r2": {"next_hop_self": True} } } } } } } } }, "r3": { "bgp": { "address_family": { "ipv4": { "unicast": { "neighbor": { "r1": { "dest_link": { "r3": {"next_hop_self": True} } } } } } } } }, "r5": { "bgp": { "address_family": { "ipv4": { "unicast": { "redistribute": [ {"redist_type": "static"}, {"redist_type": "connected"} ] } } } } } } result = create_router_bgp(tgen, topo, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Api call to create static routes input_dict_3 = { "r5": { "static_routes": [ { "network": "200.50.2.0/32", "next_hop": "10.0.0.26" }, { "network": "200.60.2.0/32", "next_hop": "10.0.0.26" } ] } } result = create_static_routes(tgen, input_dict_3) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Api call to redistribute static routes # Configure next-hop-self to bgp neighbor # Verifying best path dut = "r1" attribute = "origin" result = verify_best_path_as_per_bgp_attribute(tgen, "ipv4", dut, input_dict, attribute) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) write_test_footer(tc_name)
def test_bgp_with_loopback_interface(request): """ Test BGP with loopback interface Adding keys:value pair "dest_link": "lo" and "source_link": "lo" peer dict of input json file for all router's creating config using loopback interface. Once BGP neighboship is up then verifying BGP convergence """ tgen = get_topogen() if BGP_CONVERGENCE is not True: pytest.skip('skipped because of BGP Convergence failure') # test case name tc_name = request.node.name write_test_header(tc_name) # Creating configuration from JSON reset_config_on_routers(tgen) for routerN in sorted(topo['routers'].keys()): for bgp_neighbor in \ topo['routers'][routerN]['bgp']['address_family']['ipv4'][ 'unicast']['neighbor'].keys(): # Adding ['source_link'] = 'lo' key:value pair topo['routers'][routerN]['bgp']['address_family']['ipv4'][ 'unicast']['neighbor'][bgp_neighbor]["dest_link"] = { 'lo': { "source_link": "lo", } } # Creating configuration from JSON build_config_from_json(tgen, topo) input_dict = { "r1": { "static_routes": [{ "network": "1.0.2.17/32", "next_hop": "10.0.0.2" }, { "network": "1.0.3.17/32", "next_hop": "10.0.0.6" }] }, "r2": { "static_routes": [{ "network": "1.0.1.17/32", "next_hop": "10.0.0.1" }, { "network": "1.0.3.17/32", "next_hop": "10.0.0.10" }] }, "r3": { "static_routes": [{ "network": "1.0.1.17/32", "next_hop": "10.0.0.5" }, { "network": "1.0.2.17/32", "next_hop": "10.0.0.9" }, { "network": "1.0.4.17/32", "next_hop": "10.0.0.14" }] }, "r4": { "static_routes": [{ "network": "1.0.3.17/32", "next_hop": "10.0.0.13" }] } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) # Api call verify whether BGP is converged result = verify_bgp_convergence(tgen, topo) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) write_test_footer(tc_name)
def test_med_attribute(request): " Verifying MED attribute functionality" tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) # test case name tc_name = request.node.name write_test_header(tc_name) # Creating configuration from JSON reset_config_on_routers(tgen) # Api call to advertise networks input_dict = { "r4": { "bgp":{ "address_family": { "ipv4": { "unicast": { "advertise_networks": [ { "network": "200.50.2.0/32" }, { "network": "200.60.2.0/32" } ] } } } } } } result = create_router_bgp(tgen, topo, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Api call to advertise networks # Configure next-hop-self to bgp neighbor # Create Prefix list input_dict_3 = { "r2": { "prefix_lists": { "ipv4": { "pf_ls_r2": [{ "seqid": 10, "network": "200.0.0.0/8", "le": "32", "action": "permit" }] } } }, "r3": { "prefix_lists": { "ipv4": { "pf_ls_r3": [{ "seqid": 10, "network": "200.0.0.0/8", "le": "32", "action": "permit" }] } } } } result = create_prefix_lists(tgen, input_dict_3) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Create route map input_dict_3 = { "r2": { "route_maps": { "RMAP_MED_R2": [{ "action": "permit", "match": { "ipv4": { "prefix_lists": "pf_ls_r2" } }, "set": { "med": 100 } }] } }, "r3": { "route_maps": { "RMAP_MED_R3": [{ "action": "permit", "match": { "ipv4": { "prefix_lists": "pf_ls_r3" } }, "set": { "med": 10 } }] } } } result = create_route_maps(tgen, input_dict_3) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Configure neighbor for route map input_dict_4 = { "r5": { "bgp": { "address_family": { "ipv4": { "unicast": { "advertise_networks": [ { "network": "200.50.2.0/32" }, { "network": "200.60.2.0/32" } ] } } } } }, "r2": { "bgp": { "address_family": { "ipv4": { "unicast": { "neighbor": { "r4": { "dest_link": { "r2-link1": { "route_maps": [ {"name": "RMAP_MED_R2", "direction": "in"} ] } } }, "r1": { "dest_link": { "r2": {"next_hop_self": True} } } } } } } } }, "r3": { "bgp": { "address_family": { "ipv4": { "unicast": { "neighbor": { "r1": { "dest_link": { "r3": {"next_hop_self": True} } }, "r5": { "dest_link": { "r3": { "route_maps": [ {"name": "RMAP_MED_R3", "direction": "in"} ] } } } } } } } } } } result = create_router_bgp(tgen, topo, input_dict_4) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) # Verifying best path dut = "r1" attribute = "med" result = verify_best_path_as_per_bgp_attribute(tgen, "ipv4", dut, input_dict, attribute) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) logger.info("Testcase %s :Passed \n", tc_name)
def test_static_routes(request): """ Test to create and verify static routes. """ tgen = get_topogen() if BGP_CONVERGENCE is not True: pytest.skip('skipped because of BGP Convergence failure') # test case name tc_name = request.node.name write_test_header(tc_name) # Creating configuration from JSON reset_config_on_routers(tgen) # Api call to create static routes input_dict = { "r1": { "static_routes": [{ "network": "10.0.20.1/32", "no_of_ip": 9, "admin_distance": 100, "next_hop": "10.0.0.2" }] } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) # Api call to redistribute static routes input_dict_1 = { "r1": { "bgp": { "address_family": { "ipv4": { "unicast": { "redistribute": [{ "redist_type": "static" }, { "redist_type": "connected" }] } } } } } } result = create_router_bgp(tgen, topo, input_dict_1) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) # Verifying RIB routes dut = 'r3' protocol = 'bgp' next_hop = ['10.0.0.2', '10.0.0.5'] result = verify_rib(tgen, 'ipv4', dut, input_dict, next_hop=next_hop, protocol=protocol) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) write_test_footer(tc_name)
def test_bgp_best_path_with_dynamic_import_p0(request): """ TC6_FUNC_6: 1.5.6. Verify BGP best path selection algorithm works fine when routes are imported from ISR to default vrf and vice versa. """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) build_config_from_json(tgen, topo) if tgen.routers_have_failure(): check_router_status(tgen) for addr_type in ADDR_TYPES: step("Redistribute configured static routes into BGP process" " on R1/R2 and R3") input_dict_1 = {} DUT = ["r1", "r2", "r3", "r4"] VRFS = ["ISR", "ISR", "default", "default"] AS_NUM = [100, 100, 300, 400] for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): temp = {dut: {"bgp": []}} input_dict_1.update(temp) temp[dut]["bgp"].append({ "local_as": as_num, "vrf": vrf, "address_family": { addr_type: { "unicast": { "redistribute": [{ "redist_type": "static" }] } } } }) result = create_router_bgp(tgen, topo, input_dict_1) assert result is True, "Testcase {} :Failed \n Error: {}". \ format(tc_name, result) for addr_type in ADDR_TYPES: step("Import from default vrf into vrf ISR on R1 and R2 as below") input_dict_vrf = {} DUT = ["r1", "r2"] VRFS = ["ISR", "ISR"] AS_NUM = [100, 100] for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): temp = {dut: {"bgp": []}} input_dict_vrf.update(temp) temp[dut]["bgp"].append({ "local_as": as_num, "vrf": vrf, "address_family": { addr_type: { "unicast": { "import": { "vrf": "default" } } } } }) result = create_router_bgp(tgen, topo, input_dict_vrf) assert result is True, "Testcase {} : Failed \n Error: {}". \ format(tc_name, result) input_dict_default = {} DUT = ["r1", "r2"] VRFS = ["default", "default"] AS_NUM = [100, 100] for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): temp = {dut: {"bgp": []}} input_dict_default.update(temp) temp[dut]["bgp"].append({ "local_as": as_num, "vrf": vrf, "address_family": { addr_type: { "unicast": { "import": { "vrf": "ISR" } } } } }) result = create_router_bgp(tgen, topo, input_dict_default) assert result is True, "Testcase {} : Failed \n Error: {}". \ format(tc_name, result) step("Verify ECMP/Next-hop/Imported routes Vs Locally originated " "routes/eBGP routes vs iBGP routes --already covered in almost" " all tests") for addr_type in ADDR_TYPES: step("Verify Pre-emption") input_routes_r3 = { "r3": { "static_routes": [{ "network": [NETWORK3_3[addr_type]] }] } } intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"] if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) else: nh_r3_r1 = topo["routers"]["r3"]["links"]\ ["r1-link1"][addr_type].split("/")[0] nh_r4_r1 = topo["routers"]["r4"]["links"]\ ["r1-link1"][addr_type].split("/")[0] result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r4_r1]) assert result is True, ( "Testcase {} : Failed \n Error {}". \ format(tc_name, result)) step("Shutdown interface connected to r1 from r4:") shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, False) for addr_type in ADDR_TYPES: input_routes_r3 = { "r3": { "static_routes": [{ "network": [NETWORK3_3[addr_type]] }] } } intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"] if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) else: nh_r3_r1 = topo["routers"]["r3"]["links"]\ ["r1-link1"][addr_type].split("/")[0] nh_r4_r1 = topo["routers"]["r4"]["links"]\ ["r1-link1"][addr_type].split("/")[0] step("Verify next-hop is changed") result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1]) assert result is True, ( "Testcase {} : Failed \n Error {}". \ format(tc_name, result)) step("Bringup interface connected to r1 from r4:") shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, True) for addr_type in ADDR_TYPES: input_routes_r3 = { "r3": { "static_routes": [{ "network": [NETWORK3_3[addr_type]] }] } } intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"] if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) else: nh_r3_r1 = topo["routers"]["r3"]["links"]\ ["r1-link1"][addr_type].split("/")[0] nh_r4_r1 = topo["routers"]["r4"]["links"]\ ["r1-link1"][addr_type].split("/")[0] step("Verify next-hop is not chnaged aftr shutdown:") result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1]) assert result is True, ( "Testcase {} : Failed \n Error {}". \ format(tc_name, result)) step("Active-Standby scenario(as-path prepend and Local pref)") for addr_type in ADDR_TYPES: step("Create prefix-list") input_dict_pf = { "r1": { "prefix_lists": { addr_type: { "pf_ls_{}".format(addr_type): [{ "seqid": 10, "network": NETWORK3_4[addr_type], "action": "permit" }] } } } } result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) for addr_type in ADDR_TYPES: step("Create route-map to match prefix-list and set localpref 500") input_dict_rm = { "r1": { "route_maps": { "rmap_PATH1_{}".format(addr_type): [{ "action": "permit", "seq_id": 10, "match": { addr_type: { "prefix_lists": "pf_ls_{}".format(addr_type) } }, "set": { "locPrf": 500 } }] } } } result = create_route_maps(tgen, input_dict_rm) assert result is True, 'Testcase {} : Failed \n Error: {}'.format( tc_name, result) step("Create route-map to match prefix-list and set localpref 600") input_dict_rm = { "r1": { "route_maps": { "rmap_PATH2_{}".format(addr_type): [{ "action": "permit", "seq_id": 20, "match": { addr_type: { "prefix_lists": "pf_ls_{}".format(addr_type) } }, "set": { "locPrf": 600 } }] } } } result = create_route_maps(tgen, input_dict_rm) assert result is True, 'Testcase {} : Failed \n Error: {}'.format( tc_name, result) input_dict_rma={ "r1": { "bgp": [ { "local_as": "100", "address_family": { addr_type: { "unicast": { "neighbor": { "r3": { "dest_link": { "r1-link1": { "route_maps": [{ "name": "rmap_PATH1_{}".\ format(addr_type), "direction": "in" }] } } }, "r4": { "dest_link": { "r1-link1": { "route_maps": [{ "name": "rmap_PATH2_{}".\ format(addr_type), "direction": "in" }] } } } } } } } } ]} } result = create_router_bgp(tgen, topo, input_dict_rma) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) dut = "r1" attribute = "locPrf" for addr_type in ADDR_TYPES: step("Verify bestpath is installed as per highest localpref") input_routes_r3 = { "r3": { "static_routes": [{ "network": [ NETWORK3_3[addr_type], \ NETWORK3_4[addr_type] ] }] } } result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut, input_routes_r3, attribute) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) for addr_type in ADDR_TYPES: step("Create route-map to match prefix-list and set localpref 700") input_dict_rm = { "r1": { "route_maps": { "rmap_PATH1_{}".format(addr_type): [{ "action": "permit", "seq_id": 10, "match": { addr_type: { "prefix_lists": "pf_ls_{}".format(addr_type) } }, "set": { "locPrf": 700 } }] } } } result = create_route_maps(tgen, input_dict_rm) assert result is True, 'Testcase {} : Failed \n Error: {}'.format( tc_name, result) for addr_type in ADDR_TYPES: step("Verify bestpath is changed as per highest localpref") input_routes_r3 = { "r3": { "static_routes": [{ "network": [ NETWORK3_3[addr_type], \ NETWORK3_4[addr_type] ] }] } } result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut, input_routes_r3, attribute) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) for addr_type in ADDR_TYPES: step("Create route-map to match prefix-list and set as-path prepend") input_dict_rm = { "r1": { "route_maps": { "rmap_PATH2_{}".format(addr_type): [{ "action": "permit", "seq_id": 20, "match": { addr_type: { "prefix_lists": "pf_ls_{}".format(addr_type) } }, "set": { "localpref": 700, "path": { "as_num": "111", "as_action": "prepend" } } }] } } } result = create_route_maps(tgen, input_dict_rm) assert result is True, 'Testcase {} : Failed \n Error: {}'.format( tc_name, result) attribute = "path" for addr_type in ADDR_TYPES: step("Verify bestpath is changed as per shortest as-path") input_routes_r3 = { "r3": { "static_routes": [{ "network": [ NETWORK3_3[addr_type], \ NETWORK3_4[addr_type] ] }] } } result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut, input_routes_r3, attribute) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) write_test_footer(tc_name)
def test_verify_zebra_nh_resolution(request): tgen = get_topogen() tc_name = request.node.name if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info("Starting Zebra NH resolution testcase") r1 = tgen.gears["r1"] step("Configure static route") input_dict_1 = { "r1": { "static_routes": [{ "network": "2.2.2.0/24", "next_hop": "r1-eth0" }] } } result = create_static_routes(tgen, input_dict_1) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) step("Verify static routes in RIB of R1") input_dict_2 = {"r1": {"static_routes": [{"network": "2.2.2.0/24"}]}} dut = "r1" result = verify_rib(tgen, "ipv4", dut, input_dict_2) assert result is True, "Testcase {} :Failed \n Error: {}".format( tc_name, result) step("Set the connected flag on the NH tracking entry") r1.vtysh_cmd("sharp watch nexthop 2.2.2.32 connected") step("Verify that NH 2.2.2.32 gets resolved over static route") input_dict_nh = { "r1": { NH1: { "Address": "2.2.2.0/24", "resolvedVia": "static", "nexthops": { "nexthop1": { "Interfcae": "r1-eth0" } }, } } } result = verify_ip_nht(tgen, input_dict_nh) assert result is True, "Testcase {} : Failed \n" "Error: Nexthop is missing in RIB".format(tc_name, result) step("Add a .32/32 route with the NH as itself") r1.vtysh_cmd("sharp install routes 2.2.2.32 nexthop 2.2.2.32 1") step("Verify that the installation of .32/32 has no effect on the NHT") input_dict_nh = { "r1": { NH1: { "Address": "2.2.2.0/24", "resolvedVia": "static", "nexthops": { "nexthop1": { "Interface": "r1-eth0" } }, } } } result = verify_ip_nht(tgen, input_dict_nh) assert result is True, "Testcase {} : Failed \n" "Error: Nexthop became unresolved".format(tc_name, result) step("Add a .31/32 route with the NH as 2.2.2.32" "to verify the NH Resolution behaviour") r1.vtysh_cmd("sharp install routes 2.2.2.31 nexthop 2.2.2.32 1") step("Verify that NH 2.2.2.2/32 doesn't become unresolved") input_dict_nh = { "r1": { NH1: { "Address": "2.2.2.0/24", "resolvedVia": "static", "nexthops": { "nexthop1": { "Interface": "r1-eth0" } }, } } } result = verify_ip_nht(tgen, input_dict_nh) assert result is True, "Testcase {} : Failed \n" "Error: Nexthop became unresolved".format(tc_name, result)
def test_BSR_election_p0(request): """ Verify group to RP mapping in FRR node when 2 BSR are present in the network and both are having same BSR priority Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = pre_config_to_bsm(tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) GROUP_ADDRESS = "225.1.1.1" # Use scapy to send pre-defined packet from senser to receiver step("Send BSR packet from b1 to FHR") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet3") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip1 = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"][ "bsr"].split("/")[0] time.sleep(1) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify bsr state in FHR step("Verify if b1 is chosen as bsr in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip1) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) dut = "l1" group = "225.1.1.0/24" # Find the elected rp from bsrp-info step("Find the elected rp from bsrp-info in LHR in l1") rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip1, group) assert rp is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Check RP detail in LHR step("Verify RP in LHR l1") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Send BSR packet from b2 with same priority step("Send BSR packet from b2 to FHR with same priority") result = scapy_send_bsr_raw_packet(tgen, topo, "b2", "f1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip2 = topo["routers"]["b2"]["bsm"]["bsr_packets"]["packet2"][ "bsr"].split("/")[0] time.sleep(1) logger.info("BSR b1:" + bsr_ip1 + " BSR b2:" + bsr_ip2) # Verify bsr state in FHR step("Verify if b2 is not chosen as bsr in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip2, expected=False) assert ( result is not True ), "Testcase {} : Failed \n " "b2 is chosen as bsr in f1 \n Error: {}".format( tc_name, result) # Verify if b1 is still chosen as bsr step("Verify if b1 is still chosen as bsr in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip1) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Verify if that rp is installed step("Verify that same RP in istalled in LHR l1") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def build(self, *_args, **_opts): """Build function.""" tgen = get_topogen(self) # Building topology from json file build_topo_from_json(tgen, topo)
def test_RP_priority_p0(request): """ Verify group to RP info is updated correctly, when BSR advertising the same RP with different priority Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = pre_config_to_bsm(tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) GROUP_ADDRESS = "225.1.1.1" # Use scapy to send pre-defined packet from senser to receiver step("Send BSR packet from b1 to FHR") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"][ "bsr"].split("/")[0] time.sleep(1) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify bsr state in FHR step("Verify if b1 is chosen as bsr in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) dut = "l1" group = "225.1.1.0/24" # Find the elected rp from bsrp-info step("Find the elected rp from bsrp-info in LHR l1") rp1 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) assert rp1 is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Check RP detail in LHR step("Verify RP in LHR l1") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp1[group]) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Send BSR packet from b1 after deleting high prio rp for 225.1.1.0/24 step("Send BSM from b1 to FHR deleting high prio rp for 225.1.1.0/24") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet6") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Find the elected rp from bsrp-info step("Find the elected rp from bsrp-info in LHR l1") rp2 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) assert rp2 is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) logger.info("RP old: {} RP2 new: {} ".format(rp1[group], rp2[group])) # Verify is the rp is different now assert rp1[group] != rp2[group], "Testcase {} :Failed \n Error {}".format( tc_name, result) rp_add1 = rp1[group] rp_add2 = rp2[group] # Verify if that rp is installed step("Verify new RP in LHR installed") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp_add2) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Send BSR packet from b1 after putting back high prio rp for 225.1.1.0/24 step("Send BSM from b1 to FHR put back old high prio rp for 225.1.1.0/24") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Find the elected rp from bsrp-info step("Find the elected rp from bsrp-info in LHR") rp2 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) assert rp2 is not {}, "Testcase {} :Failed \n Error : RP not Found".format( tc_name) # Verify is the rp is different now step("Verify now old RP is elected again") assert ( rp_add1 == rp2[group] ), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format( tc_name, rp_add1, rp2[group] if group in rp2 else None) # Verify if that rp is installed step("Verify new RP in LHR installed") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp_add1) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def test_linux_ipv6_kernel_routingTable(): # Required linux kernel version for this suite to run. result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") # iproute2 needs to support VRFs for this suite to run. if not iproute2_is_vrf_capable(): pytest.skip("Installed iproute2 version does not support VRFs") tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip("skipped because of router(s) failure") # Verify Linux Kernel Routing Table logger.info("Verifying Linux IPv6 Kernel Routing Table") failures = 0 # Get a list of all current link-local addresses first as they change for # each run and we need to translate them linklocals = [] for i in range(1, 5): linklocals += tgen.net["r{}".format(i)].get_ipv6_linklocal() # Now compare the routing tables (after substituting link-local addresses) for i in range(1, 5): # Actual output from router actual = (tgen.gears["r{}".format(i)].run( "ip -6 route show vrf r{}-cust1".format(i)).rstrip()) if "nhid" in actual: refTableFile = os.path.join(CWD, "r{}/ip_6_address.nhg.ref".format(i)) else: refTableFile = os.path.join(CWD, "r{}/ip_6_address.ref".format(i)) if os.path.isfile(refTableFile): expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) expected = ("\n".join(expected.splitlines())).splitlines(1) # Mask out Link-Local mac addresses for ll in linklocals: actual = actual.replace(ll[1], "fe80::__(%s)__" % ll[0]) # Mask out protocol name or number actual = re.sub(r"[ ]+proto [0-9a-z]+ +", " proto XXXX ", actual) actual = re.sub(r"[ ]+nhid [0-9]+ +", " nhid XXXX ", actual) # Remove ff00::/8 routes (seen on some kernels - not from FRR) actual = re.sub(r"ff00::/8.*", "", actual) # Strip empty lines actual = actual.lstrip() actual = actual.rstrip() actual = re.sub(r" +", " ", actual) filtered_lines = [] for line in sorted(actual.splitlines()): if line.startswith("fe80::/64 ") or line.startswith( "unreachable fe80::/64 "): continue if "anycast" in line: continue if "multicast" in line: continue filtered_lines.append(line) actual = "\n".join(filtered_lines).splitlines(1) # Print Actual table # logger.info("Router r%s table" % i) # for line in actual: # logger.info(line.rstrip()) # Generate Diff diff = topotest.get_textdiff( actual, expected, title1="actual OSPFv3 IPv6 routing table", title2="expected OSPFv3 IPv6 routing table", ) # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( "r%s failed Linux IPv6 Kernel Routing Table Check:\n%s\n" % (i, diff)) failures += 1 else: logger.info("r%s ok" % i) assert failures == 0, ( "Linux Kernel IPv6 Routing Table verification failed for router r%s:\n%s" % (i, diff))
def test_overlapping_group_p0(request): """ Verify group to RP updated correctly on FRR router, when BSR advertising the overlapping group address Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = pre_config_to_bsm(tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) GROUP_ADDRESS = "225.1.1.1" # Use scapy to send pre-defined packet from senser to receiver step("Send BSR packet from b1 to FHR") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet4") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"][ "bsr"].split("/")[0] time.sleep(1) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify bsr state in FHR step("Verify if b1 is chosen as bsr in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) dut = "l1" group1 = "225.1.1.1/32" # Find the elected rp from bsrp-info fro group 225.1.1.1/32 step("Find the elected rp from bsrp-info in LHR for 225.1.1.1/32") rp1 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group1) assert rp1 is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) group2 = "225.1.1.0/24" # Find the elected rp from bsrp-info fro group 225.1.1.0/24 step("Find the elected rp from bsrp-info in LHR for 225.1.1.0/24") rp2 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group2) assert rp2 is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) iif = "l1-i1-eth0" # Verify upstream rpf for 225.1.1.1 is chosen as rp1 step("Verify upstream rpf for 225.1.1.1 is chosen as rp1 in l1") result = verify_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, rp1) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Send BSR packet from b1 with rp for 225.1.1.1/32 removed step("Send BSR packet from b1 with rp for 225.1.1.1/32 removed") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet5") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Verify upstream rpf for 225.1.1.1 is chosen as rp1 step("Verify upstream rpf for 225.1.1.1 is chosen as rp2 in l1") result = verify_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, rp2) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify IIF/OIL in pim state step("Verify iif is installed after rp change in l1") oil = "l1-r1-eth1" result = verify_pim_state(tgen, dut, iif, oil, GROUP_ADDRESS) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def test_ospf_learning_tc15_p0(request): """Verify OSPF can learn different types of LSA and processes them. OSPF Learning : Edge learning different types of LSAs. """ tc_name = request.node.name write_test_header(tc_name) tgen = get_topogen() # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) global topo step("Bring up the base config as per the topology") step("Configure area 1 as NSSA Area") reset_config_on_routers(tgen) step("Verify that Type 3 summary LSA is originated for the same Area 0") ip = topo["routers"]["r1"]["links"]["r3-link0"]["ipv4"] ip_net = str(ipaddress.ip_interface(u"{}".format(ip)).network) dut = "r0" input_dict = { "r1": { "static_routes": [{ "network": ip_net, "no_of_ip": 1, "routeType": "N IA" }] } } dut = "r0" result = verify_ospf_rib(tgen, dut, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) protocol = "ospf" result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) input_dict = { "r2": { "static_routes": [{ "network": NETWORK["ipv4"][0], "no_of_ip": 5, "next_hop": "Null0" }] } } result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) step("Redistribute static route in R2 ospf.") dut = "r2" red_static(dut) step("Verify that Type 5 LSA is originated by R2.") dut = "r0" protocol = "ospf" result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) step("Verify that R0 receives Type 4 summary LSA.") dut = "r0" input_dict = { "r1": { "static_routes": [{ "network": NETWORK["ipv4"][0], "no_of_ip": 1, "routeType": "N E2" }] } } dut = "r1" result = verify_ospf_rib(tgen, dut, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) ospf_covergence = verify_ospf_neighbor(tgen, topo) assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format( ospf_covergence) step("Change area 1 as non nssa area (on the fly changing area" " type on DUT).") for rtr in ["r1", "r2", "r3"]: input_dict = { rtr: { "ospf": { "area": [{ "id": "0.0.0.2", "type": "nssa", "delete": True }] } } } result = create_router_ospf(tgen, topo, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) step("Verify that OSPF neighbours are reset after changing area type.") step("Verify that ABR R2 originates type 5 LSA in area 1.") step("Verify that route is calculated and installed in R1.") input_dict = { "r1": { "static_routes": [{ "network": NETWORK["ipv4"][0], "no_of_ip": 1, "routeType": "N E2" }] } } dut = "r1" result = verify_ospf_rib(tgen, dut, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol) assert result is True, "Testcase {} : Failed \n Error: {}".format( tc_name, result) write_test_footer(tc_name)
def test_starg_mroute_p0(request): """ 1. Verify (*,G) mroute detail on FRR router after BSM rp installed Topology used: b1_____ | | s1-----f1-----i1-----l1----r1 | ______| b2 b1 - BSR 1 b2 - BSR 2 s1 - Source f1 - FHR i1 - Intermediate Router (also RP) r1 - Receiver """ tgen = get_topogen() tc_name = request.node.name write_test_header(tc_name) # Don"t run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) app_helper.stop_all_hosts() clear_mroute(tgen) reset_config_on_routers(tgen) clear_pim_interface_traffic(tgen, topo) result = pre_config_to_bsm(tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) result = pre_config_to_bsm(tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) GROUP_ADDRESS = "226.1.1.1" # Use scapy to send pre-defined packet from senser to receiver result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"][ "bsr"].split("/")[0] time.sleep(1) result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify bsr state in FHR result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Check igmp groups step("Verify IGMP groups in LHR l1") dut = "l1" intf = "l1-r1-eth1" result = verify_igmp_groups(tgen, dut, intf, GROUP_ADDRESS) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) group = "226.1.1.1/32" src_addr = "*" # Find the elected rp from bsrp-info step("Find the elected rp from bsrp-info in LHR in l1") rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) assert rp is not {}, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Check RP detail in LHR step("Verify RP in LHR in l1") result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify join state and join timer step("Verify join state and join timer in l1") iif = "l1-i1-eth0" result = verify_join_state_and_timer(tgen, dut, iif, src_addr, GROUP_ADDRESS) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify upstream IIF interface step("Verify upstream IIF interface in l1") result = verify_upstream_iif(tgen, dut, iif, src_addr, GROUP_ADDRESS) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify IIF/OIL in pim state oil = "l1-r1-eth1" result = verify_pim_state(tgen, dut, iif, oil, GROUP_ADDRESS) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify ip mroute step("Verify ip mroute in l1") src_addr = "*" result = verify_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Remove the group rp mapping and send bsm step( "Remove the grp-rp mapping by sending bsm with hold time 0 for grp-rp") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet2") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Check RP unreachable step("Check RP unreachability in l1") iif = "Unknown" result = verify_upstream_iif(tgen, dut, iif, src_addr, GROUP_ADDRESS, joinState="NotJoined") assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify that it is not installed step("Verify that iif is not installed in l1") iif = "<iif?>" result = verify_pim_state(tgen, dut, iif, oil, GROUP_ADDRESS, installed_fl=0) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) # Verify mroute not installed step("Verify mroute not installed in l1") result = verify_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, retry_timeout=20, expected=False) assert ( result is not True ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( tc_name, result) # Send BSM again to configure rp step("Add back RP by sending BSM from b1") result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") assert result is True, "Testcase {} :Failed \n Error {}".format( tc_name, result) # Verify that (*,G) installed in mroute again iif = "l1-i1-eth0" result = verify_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil) assert result is True, "Testcase {}:Failed \n Error: {}".format( tc_name, result) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) write_test_footer(tc_name)
def test_bfd_loss_intermediate(): """ Assert that BFD notices the bfd link down failure. but BGP entries should still be present """ tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info( "removing IPv6 address from r2 to simulate loss of connectivity") # Disable r2-eth0 ipv6 address cmd = 'vtysh -c "configure terminal" -c "interface r2-eth1" -c "no ipv6 address 2001:db8:4::2/64"' tgen.net["r2"].cmd(cmd) # Wait the minimum time we can before checking that BGP/BFD # converged. logger.info("waiting for BFD converge down") # Check that BGP converged quickly. for router in tgen.routers().values(): if router.name == "r2": continue json_file = "{}/{}/peers_down.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, "show bfd peers json", expected) _, result = topotest.run_and_expect(test_func, None, count=32, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg logger.info("waiting for BGP entries to become stale") for router in tgen.routers().values(): if router.name == "r2": continue json_file = "{}/{}/bgp_ipv6_routes_down.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, "show bgp ipv6 json", expected) _, result = topotest.run_and_expect(test_func, None, count=50, wait=1) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg logger.info("Checking IPv6 routes on r1 should still be present") for router in tgen.routers().values(): if router.name == "r2": continue if router.name == "r3": continue json_file = "{}/r1/ipv6_routes.json".format(CWD) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, "show ipv6 route json", expected) _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg
def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() # This function tears down the whole topology. tgen.stop_topology()
def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # This function only purpose is to define allocation and relationship # between routers, switches and hosts. # # # Create routers tgen.add_router("r1") tgen.add_router("r2") tgen.add_router("r3") tgen.add_router("r4") tgen.add_router("ce1") tgen.add_router("ce2") tgen.add_router("ce3") tgen.add_router("ce4") # r1-r2 switch = tgen.add_switch("s1") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) # r1-r3 switch = tgen.add_switch("s2") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r3"]) # r1-r4 switch = tgen.add_switch("s3") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r4"]) # r1-ce1 switch = tgen.add_switch("s4") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["ce1"]) # r1-ce3 switch = tgen.add_switch("s5") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["ce3"]) # r1-ce4 switch = tgen.add_switch("s6") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["ce4"]) # r1-dangling switch = tgen.add_switch("s7") switch.add_link(tgen.gears["r1"]) # r2-r3 switch = tgen.add_switch("s8") switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r3"]) # r3-r4 switch = tgen.add_switch("s9") switch.add_link(tgen.gears["r3"]) switch.add_link(tgen.gears["r4"]) # r4-ce2 switch = tgen.add_switch("s10") switch.add_link(tgen.gears["r4"]) switch.add_link(tgen.gears["ce2"])
def teardown_module(_mod): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology()