diff options
Diffstat (limited to 'tests')
98 files changed, 3830 insertions, 3077 deletions
diff --git a/tests/topotests/bfd_topo3/r3/bfd-static-down.json b/tests/topotests/bfd_topo3/r3/bfd-static-down.json new file mode 100644 index 0000000000..60752d3aa1 --- /dev/null +++ b/tests/topotests/bfd_topo3/r3/bfd-static-down.json @@ -0,0 +1,12 @@ +{ + "path-list": { + "ipv4-multicast": [], + "ipv4-unicast": [], + "ipv6-unicast": [ + { + "prefix": "2001:db8:5::\/64", + "vrf": "default", + "installed": false + } + ] + }} diff --git a/tests/topotests/bfd_topo3/r3/bfd-static.json b/tests/topotests/bfd_topo3/r3/bfd-static.json new file mode 100644 index 0000000000..c65060c7b0 --- /dev/null +++ b/tests/topotests/bfd_topo3/r3/bfd-static.json @@ -0,0 +1,13 @@ +{ + "path-list": { + "ipv4-multicast": [], + "ipv4-unicast": [], + "ipv6-unicast": [ + { + "prefix": "2001:db8:5::\/64", + "vrf": "default", + "installed": true + } + ] + } +} diff --git a/tests/topotests/bfd_topo3/r3/staticd.conf b/tests/topotests/bfd_topo3/r3/staticd.conf new file mode 100644 index 0000000000..44f91f3f34 --- /dev/null +++ b/tests/topotests/bfd_topo3/r3/staticd.conf @@ -0,0 +1 @@ +ipv6 route 2001:db8:5::/64 2001:db8:4::3 bfd multi-hop profile slow-tx diff --git a/tests/topotests/bfd_topo3/r4/bfd-peers.json b/tests/topotests/bfd_topo3/r4/bfd-peers.json index 2f41f25c58..4f71d75389 100644 --- a/tests/topotests/bfd_topo3/r4/bfd-peers.json +++ b/tests/topotests/bfd_topo3/r4/bfd-peers.json @@ -19,7 +19,8 @@ "remote-transmit-interval": 2000, "status": "up", "uptime": "*", - "transmit-interval": 2000 + "transmit-interval": 2000, + "vrf": "default" }, { "detect-multiplier": 3, @@ -41,6 +42,49 @@ "remote-transmit-interval": 2000, "status": "up", "uptime": "*", - "transmit-interval": 2000 + "transmit-interval": 2000, + "vrf": "default" + }, + { + "detect-multiplier": 3, + "diagnostic": "ok", + "echo-receive-interval": 50, + "echo-transmit-interval": 0, + "id": "*", + "multihop": false, + "passive-mode": false, + "peer": "192.168.4.3", + "receive-interval": 2000, + "remote-detect-multiplier": 3, + "remote-diagnostic": "ok", + "remote-echo-receive-interval": 50, + "remote-id": "*", + "remote-receive-interval": 2000, + "remote-transmit-interval": 2000, + "status": "up", + "transmit-interval": 2000, + "uptime": "*", + "vrf": "default" + }, + { + "detect-multiplier": 3, + "diagnostic": "ok", + "echo-receive-interval": 50, + "echo-transmit-interval": 0, + "id": "*", + "multihop": false, + "passive-mode": false, + "peer": "192.168.4.2", + "receive-interval": 2000, + "remote-detect-multiplier": 3, + "remote-diagnostic": "ok", + "remote-echo-receive-interval": 50, + "remote-id": "*", + "remote-receive-interval": 2000, + "remote-transmit-interval": 2000, + "status": "up", + "transmit-interval": 2000, + "uptime": "*", + "vrf": "default" } ] diff --git a/tests/topotests/bfd_topo3/r4/bgpd.conf b/tests/topotests/bfd_topo3/r4/bgpd.conf index 0aab6e3017..bfad78a7ad 100644 --- a/tests/topotests/bfd_topo3/r4/bgpd.conf +++ b/tests/topotests/bfd_topo3/r4/bgpd.conf @@ -9,6 +9,7 @@ router bgp 400 neighbor 2001:db8:1::1 bfd profile slow-tx-mh address-family ipv4 unicast redistribute connected + redistribute static exit-address-family address-family ipv6 unicast redistribute connected diff --git a/tests/topotests/bfd_topo3/r4/staticd.conf b/tests/topotests/bfd_topo3/r4/staticd.conf new file mode 100644 index 0000000000..3b1c5bfb66 --- /dev/null +++ b/tests/topotests/bfd_topo3/r4/staticd.conf @@ -0,0 +1,2 @@ +ip route 10.254.254.5/32 192.168.4.2 bfd profile slow-tx +ip route 10.254.254.6/32 192.168.4.3 bfd profile slow-tx diff --git a/tests/topotests/bfd_topo3/r4/zebra.conf b/tests/topotests/bfd_topo3/r4/zebra.conf index bf0cfcf42c..2574941724 100644 --- a/tests/topotests/bfd_topo3/r4/zebra.conf +++ b/tests/topotests/bfd_topo3/r4/zebra.conf @@ -8,3 +8,7 @@ interface r4-eth0 ip address 192.168.3.1/24 ipv6 address 2001:db8:3::1/64 ! +interface r4-eth1 + ip address 192.168.4.1/24 + ipv6 address 2001:db8:4::1/64 +! diff --git a/tests/topotests/bfd_topo3/r5/bfd-peers.json b/tests/topotests/bfd_topo3/r5/bfd-peers.json new file mode 100644 index 0000000000..777b1dd9cc --- /dev/null +++ b/tests/topotests/bfd_topo3/r5/bfd-peers.json @@ -0,0 +1,23 @@ +[ + { + "detect-multiplier": 3, + "diagnostic": "ok", + "echo-receive-interval": 50, + "echo-transmit-interval": 0, + "id": "*", + "multihop": false, + "passive-mode": false, + "peer": "192.168.4.1", + "receive-interval": 2000, + "remote-detect-multiplier": 3, + "remote-diagnostic": "ok", + "remote-echo-receive-interval": 50, + "remote-id": "*", + "remote-receive-interval": 2000, + "remote-transmit-interval": 2000, + "status": "up", + "transmit-interval": 2000, + "uptime": "*", + "vrf": "default" + } +] diff --git a/tests/topotests/bfd_topo3/r5/bfdd.conf b/tests/topotests/bfd_topo3/r5/bfdd.conf new file mode 100644 index 0000000000..6d4483acc4 --- /dev/null +++ b/tests/topotests/bfd_topo3/r5/bfdd.conf @@ -0,0 +1,11 @@ +debug bfd network +debug bfd peer +debug bfd zebra +! +bfd + profile slow-tx + receive-interval 2000 + transmit-interval 2000 + minimum-ttl 250 + ! +! diff --git a/tests/topotests/bfd_topo3/r5/staticd.conf b/tests/topotests/bfd_topo3/r5/staticd.conf new file mode 100644 index 0000000000..9828cffe0c --- /dev/null +++ b/tests/topotests/bfd_topo3/r5/staticd.conf @@ -0,0 +1,2 @@ +ip route 0.0.0.0/0 192.168.4.1 +ip route 10.254.254.4/32 192.168.4.1 bfd profile slow-tx diff --git a/tests/topotests/bfd_topo3/r5/zebra.conf b/tests/topotests/bfd_topo3/r5/zebra.conf new file mode 100644 index 0000000000..f84ce7e7f0 --- /dev/null +++ b/tests/topotests/bfd_topo3/r5/zebra.conf @@ -0,0 +1,10 @@ +ip forwarding +ipv6 forwarding +! +interface lo + ip address 10.254.254.5/32 +! +interface r5-eth0 + ip address 192.168.4.2/24 + ipv6 address 2001:db8:4::2/64 +! diff --git a/tests/topotests/bfd_topo3/r6/bfd-peers.json b/tests/topotests/bfd_topo3/r6/bfd-peers.json new file mode 100644 index 0000000000..4de451d15b --- /dev/null +++ b/tests/topotests/bfd_topo3/r6/bfd-peers.json @@ -0,0 +1,46 @@ +[ + { + "detect-multiplier": 3, + "diagnostic": "ok", + "echo-receive-interval": 50, + "echo-transmit-interval": 0, + "id": "*", + "multihop": false, + "passive-mode": false, + "peer": "192.168.4.1", + "receive-interval": 2000, + "remote-detect-multiplier": 3, + "remote-diagnostic": "ok", + "remote-echo-receive-interval": 50, + "remote-id": "*", + "remote-receive-interval": 2000, + "remote-transmit-interval": 2000, + "status": "up", + "transmit-interval": 2000, + "uptime": "*", + "vrf": "default" + }, + { + "detect-multiplier": 3, + "diagnostic": "ok", + "echo-receive-interval": 50, + "echo-transmit-interval": 0, + "id": "*", + "local": "2001:db8:4::3", + "minimum-ttl": 2, + "multihop": true, + "passive-mode": false, + "peer": "2001:db8:3::2", + "receive-interval": 2000, + "remote-detect-multiplier": 3, + "remote-diagnostic": "ok", + "remote-echo-receive-interval": 50, + "remote-id": "*", + "remote-receive-interval": 2000, + "remote-transmit-interval": 2000, + "status": "up", + "transmit-interval": 2000, + "uptime": "*", + "vrf": "default" + } +] diff --git a/tests/topotests/bfd_topo3/r6/bfd-static-down.json b/tests/topotests/bfd_topo3/r6/bfd-static-down.json new file mode 100644 index 0000000000..4dadff2251 --- /dev/null +++ b/tests/topotests/bfd_topo3/r6/bfd-static-down.json @@ -0,0 +1,19 @@ +{ + "path-list": { + "ipv4-multicast": [], + "ipv4-unicast": [ + { + "installed": true, + "prefix": "10.254.254.4/32", + "vrf": "default" + } + ], + "ipv6-unicast": [ + { + "prefix": "2001:db8:1::\/64", + "vrf": "default", + "installed": false + } + ] + } +} diff --git a/tests/topotests/bfd_topo3/r6/bfd-static.json b/tests/topotests/bfd_topo3/r6/bfd-static.json new file mode 100644 index 0000000000..d042889d50 --- /dev/null +++ b/tests/topotests/bfd_topo3/r6/bfd-static.json @@ -0,0 +1,19 @@ +{ + "path-list": { + "ipv4-multicast": [], + "ipv4-unicast": [ + { + "installed": true, + "prefix": "10.254.254.4/32", + "vrf": "default" + } + ], + "ipv6-unicast": [ + { + "prefix": "2001:db8:1::\/64", + "vrf": "default", + "installed": true + } + ] + } +} diff --git a/tests/topotests/bfd_topo3/r6/bfdd.conf b/tests/topotests/bfd_topo3/r6/bfdd.conf new file mode 100644 index 0000000000..6d4483acc4 --- /dev/null +++ b/tests/topotests/bfd_topo3/r6/bfdd.conf @@ -0,0 +1,11 @@ +debug bfd network +debug bfd peer +debug bfd zebra +! +bfd + profile slow-tx + receive-interval 2000 + transmit-interval 2000 + minimum-ttl 250 + ! +! diff --git a/tests/topotests/bfd_topo3/r6/staticd.conf b/tests/topotests/bfd_topo3/r6/staticd.conf new file mode 100644 index 0000000000..28da508fc2 --- /dev/null +++ b/tests/topotests/bfd_topo3/r6/staticd.conf @@ -0,0 +1,5 @@ +ip route 0.0.0.0/0 192.168.4.1 +ip route 10.254.254.4/32 192.168.4.1 bfd profile slow-tx +! +ipv6 route 2001:db8:3::/64 2001:db8:4::1 +ipv6 route 2001:db8:1::/64 2001:db8:3::2 bfd multi-hop source 2001:db8:4::3 profile slow-tx diff --git a/tests/topotests/bfd_topo3/r6/zebra.conf b/tests/topotests/bfd_topo3/r6/zebra.conf new file mode 100644 index 0000000000..b8f2ea4c03 --- /dev/null +++ b/tests/topotests/bfd_topo3/r6/zebra.conf @@ -0,0 +1,10 @@ +ip forwarding +ipv6 forwarding +! +interface lo + ip address 10.254.254.6/32 +! +interface r6-eth0 + ip address 192.168.4.3/24 + ipv6 address 2001:db8:4::3/64 +! diff --git a/tests/topotests/bfd_topo3/test_bfd_topo3.dot b/tests/topotests/bfd_topo3/test_bfd_topo3.dot index 502cea11f2..8d18783d54 100644 --- a/tests/topotests/bfd_topo3/test_bfd_topo3.dot +++ b/tests/topotests/bfd_topo3/test_bfd_topo3.dot @@ -40,6 +40,18 @@ graph template { fillcolor="#f08080", style=filled, ]; + r5 [ + shape=doubleoctagon + label="r5", + fillcolor="#f08080", + style=filled, + ]; + r6 [ + shape=doubleoctagon + label="r6", + fillcolor="#f08080", + style=filled, + ]; # Switches sw1 [ @@ -60,6 +72,12 @@ graph template { fillcolor="#d0e0d0", style=filled, ]; + sw4 [ + shape=oval, + label="sw4\n192.168.4.0/24\n2001:db8:4::/64", + fillcolor="#d0e0d0", + style=filled, + ]; # Connections r1 -- sw1 [label="eth0\n.1"]; @@ -70,4 +88,8 @@ graph template { r4 -- sw3 [label="eth0\n.1"]; r3 -- sw3 [label="eth2\n.2"]; + + r4 -- sw4 [label="eth1\n.1"]; + r5 -- sw4 [label="eth0\n.2"]; + r6 -- sw4 [label="eth0\n.3"]; } diff --git a/tests/topotests/bfd_topo3/test_bfd_topo3.jpg b/tests/topotests/bfd_topo3/test_bfd_topo3.jpg Binary files differindex 6b532560bf..f100eae712 100644 --- a/tests/topotests/bfd_topo3/test_bfd_topo3.jpg +++ b/tests/topotests/bfd_topo3/test_bfd_topo3.jpg diff --git a/tests/topotests/bfd_topo3/test_bfd_topo3.py b/tests/topotests/bfd_topo3/test_bfd_topo3.py index 978593e41a..ea9f981d9b 100644 --- a/tests/topotests/bfd_topo3/test_bfd_topo3.py +++ b/tests/topotests/bfd_topo3/test_bfd_topo3.py @@ -51,6 +51,7 @@ def setup_module(mod): "s1": ("r1", "r2"), "s2": ("r2", "r3"), "s3": ("r3", "r4"), + "s4": ("r4", "r5", "r6"), } tgen = Topogen(topodef, mod.__name__) tgen.start_topology() @@ -69,6 +70,10 @@ def setup_module(mod): if os.path.isfile(daemon_file): router.load_config(TopoRouter.RD_BGP, daemon_file) + daemon_file = "{}/{}/staticd.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_STATIC, daemon_file) + # Initialize all routers. tgen.start_router() @@ -100,6 +105,10 @@ def test_wait_bgp_convergence(): expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp") # Wait for R1 <-> R4 convergence. expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp") + # Wait for R1 <-> R5 convergence. + expect_loopback_route("r1", "ip", "10.254.254.5/32", "bgp") + # Wait for R1 <-> R6 convergence. + expect_loopback_route("r1", "ip", "10.254.254.6/32", "bgp") # Wait for R2 <-> R1 convergence. expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp") @@ -107,6 +116,10 @@ def test_wait_bgp_convergence(): expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp") # Wait for R2 <-> R4 convergence. expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp") + # Wait for R2 <-> R5 convergence. + expect_loopback_route("r2", "ip", "10.254.254.5/32", "bgp") + # Wait for R2 <-> R6 convergence. + expect_loopback_route("r2", "ip", "10.254.254.6/32", "bgp") # Wait for R3 <-> R1 convergence. expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp") @@ -114,6 +127,10 @@ def test_wait_bgp_convergence(): expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp") # Wait for R3 <-> R4 convergence. expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp") + # Wait for R3 <-> R5 convergence. + expect_loopback_route("r3", "ip", "10.254.254.5/32", "bgp") + # Wait for R3 <-> R6 convergence. + expect_loopback_route("r3", "ip", "10.254.254.6/32", "bgp") # Wait for R4 <-> R1 convergence. expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp") @@ -121,6 +138,15 @@ def test_wait_bgp_convergence(): expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp") # Wait for R4 <-> R3 convergence. expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp") + # Wait for R4 <-> R5 convergence. + expect_loopback_route("r4", "ip", "10.254.254.5/32", "static") + # Wait for R4 <-> R6 convergence. + expect_loopback_route("r4", "ip", "10.254.254.6/32", "static") + + # Wait for R5 <-> R6 convergence. + expect_loopback_route("r3", "ipv6", "2001:db8:5::/64", "static") + # Wait for R6 <-> R5 convergence. + expect_loopback_route("r6", "ipv6", "2001:db8:1::/64", "static") def test_wait_bfd_convergence(): @@ -149,6 +175,70 @@ def test_wait_bfd_convergence(): expect_bfd_configuration("r2") expect_bfd_configuration("r3") expect_bfd_configuration("r4") + expect_bfd_configuration("r5") + expect_bfd_configuration("r6") + + +def test_static_route_monitoring(): + "Test static route monitoring output." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("test BFD static route status") + + def expect_static_bfd_output(router, filename): + "Load JSON file and compare with 'show bfd peer json'" + logger.info("waiting BFD configuration on router {}".format(router)) + bfd_config = json.loads( + open("{}/{}/{}.json".format(CWD, router, filename)).read() + ) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show bfd static route json", + bfd_config, + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assertmsg = '"{}" BFD static route status failure'.format(router) + assert result is None, assertmsg + + expect_static_bfd_output("r3", "bfd-static") + expect_static_bfd_output("r6", "bfd-static") + + logger.info("Setting r4 link down ...") + + tgen.gears["r4"].link_enable("r4-eth0", False) + + expect_static_bfd_output("r3", "bfd-static-down") + expect_static_bfd_output("r6", "bfd-static-down") + + +def test_expect_static_rib_removal(): + "Test that route got removed from RIB (staticd and bgpd)." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def expect_route_missing(router, iptype, route): + "Wait until route is present on RIB for protocol." + logger.info("waiting route {} to disapear in {}".format(route, router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show {} route json".format(iptype), + {route: None}, + ) + rv, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg + + expect_route_missing("r1", "ip", "10.254.254.5/32") + expect_route_missing("r2", "ip", "10.254.254.5/32") + expect_route_missing("r3", "ip", "10.254.254.5/32") + expect_route_missing("r3", "ipv6", "2001:db8:5::/64") + expect_route_missing("r6", "ipv6", "2001:db8:1::/64") def teardown_module(_mod): diff --git a/tests/topotests/bgp_accept_own/pe1/bgpd.conf b/tests/topotests/bgp_accept_own/pe1/bgpd.conf index 8631293730..109e0eadbb 100644 --- a/tests/topotests/bgp_accept_own/pe1/bgpd.conf +++ b/tests/topotests/bgp_accept_own/pe1/bgpd.conf @@ -24,6 +24,7 @@ router bgp 65001 vrf Customer neighbor 192.168.1.1 timers 1 3 neighbor 192.168.1.1 timers connect 1 address-family ipv4 unicast + redistribute connected label vpn export 10 rd vpn export 192.168.1.2:2 rt vpn import 192.168.1.2:2 diff --git a/tests/topotests/bgp_accept_own/pe1/zebra.conf b/tests/topotests/bgp_accept_own/pe1/zebra.conf index 71476d2aef..2b7aefadf2 100644 --- a/tests/topotests/bgp_accept_own/pe1/zebra.conf +++ b/tests/topotests/bgp_accept_own/pe1/zebra.conf @@ -11,5 +11,8 @@ interface pe1-eth1 vrf Service interface pe1-eth2 ip address 10.0.1.1/24 ! +interface pe1-eth3 vrf Customer + ip address 192.0.2.1/24 +! ip forwarding ! diff --git a/tests/topotests/bgp_accept_own/test_bgp_accept_own.py b/tests/topotests/bgp_accept_own/test_bgp_accept_own.py index 161530b483..daef6dcd52 100644 --- a/tests/topotests/bgp_accept_own/test_bgp_accept_own.py +++ b/tests/topotests/bgp_accept_own/test_bgp_accept_own.py @@ -58,6 +58,9 @@ def build_topo(tgen): switch.add_link(tgen.gears["pe1"]) switch.add_link(tgen.gears["rr1"]) + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["pe1"]) + def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) @@ -72,6 +75,7 @@ def setup_module(mod): pe1.run("ip link add Service type vrf table 1002") pe1.run("ip link set up dev Service") pe1.run("ip link set pe1-eth1 master Service") + pe1.run("ip link set pe1-eth3 master Customer") pe1.run("sysctl -w net.mpls.conf.pe1-eth2.input=1") rr1.run("sysctl -w net.mpls.conf.rr1-eth0.input=1") @@ -112,7 +116,7 @@ def test_bgp_accept_own(): def _bgp_check_received_routes_due_originator_id(): output = json.loads(pe1.vtysh_cmd("show bgp ipv4 vpn summary json")) - expected = {"peers": {"10.10.10.101": {"pfxRcd": 0, "pfxSnt": 4}}} + expected = {"peers": {"10.10.10.101": {"pfxRcd": 0, "pfxSnt": 5}}} return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_check_received_routes_due_originator_id) @@ -134,7 +138,7 @@ def test_bgp_accept_own(): def _bgp_check_received_routes_with_modified_rts(): output = json.loads(pe1.vtysh_cmd("show bgp ipv4 vpn summary json")) - expected = {"peers": {"10.10.10.101": {"pfxRcd": 4, "pfxSnt": 4}}} + expected = {"peers": {"10.10.10.101": {"pfxRcd": 5, "pfxSnt": 5}}} return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_check_received_routes_with_modified_rts) @@ -154,9 +158,7 @@ def test_bgp_accept_own(): expected = { "paths": [ { - "community": { - "string": "65001:111" - }, + "community": {"string": "65001:111"}, "extendedCommunity": { "string": "RT:192.168.1.2:2 RT:192.168.2.2:2" }, @@ -171,6 +173,37 @@ def test_bgp_accept_own(): result is None ), "Failed, routes are not imported from RR1 with modified RT list" + step("Check if 192.0.2.0/24 is imported to vrf Service from vrf Customer") + + def _bgp_check_imported_local_routes_from_vrf_service(): + output = json.loads( + pe1.vtysh_cmd("show ip route vrf Service 192.0.2.0/24 json") + ) + expected = { + "192.0.2.0/24": [ + { + "vrfName": "Service", + "table": 1002, + "installed": True, + "selected": True, + "nexthops": [ + { + "fib": True, + "vrf": "Customer", + "active": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_imported_local_routes_from_vrf_service) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assert ( + result is None + ), "Failed, didn't import local route 192.0.2.0/24 from vrf Customer to vrf Service" + step("Check if 172.16.255.1/32 is announced to CE2") def _bgp_check_received_routes_from_pe(): @@ -188,9 +221,7 @@ def test_bgp_accept_own(): test_func = functools.partial(_bgp_check_received_routes_from_pe) _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) - assert ( - result is None - ), "Failed, didn't receive 172.16.255.1/32 from PE1" + assert result is None, "Failed, didn't receive 172.16.255.1/32 from PE1" if __name__ == "__main__": diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf index 375bbea9ff..46831bb711 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf @@ -4,8 +4,6 @@ hostname ce1 ! interface lo ip address 99.0.0.1/32 - ip address 5.1.0.1/24 - ip address 6.0.2.1/24 ! interface ce1-eth0 description to r1 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf index 90dd3c55b4..fb4d8cc9c4 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf @@ -4,8 +4,6 @@ hostname ce2 ! interface lo ip address 99.0.0.2/32 - ip address 5.1.0.1/24 - ip address 6.0.2.1/24 ! interface ce2-eth0 description to r3 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf index cf7396eb12..e316de5690 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf @@ -19,7 +19,6 @@ router bgp 5227 network 5.1.3.0/24 route-map rm-nh network 6.0.1.0/24 route-map rm-nh network 6.0.2.0/24 route-map rm-nh-same - network 6.0.3.0/24 route-map rm-nh-same neighbor 192.168.1.1 activate exit-address-family ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf index df6ac47b08..77a1163a4b 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf @@ -4,7 +4,6 @@ hostname ce3 ! interface lo ip address 99.0.0.3/32 - ip address 6.0.3.1/24 ! interface ce3-eth0 description to r4 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf index 9a6ca08a0b..60d9e93108 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf @@ -19,7 +19,6 @@ router bgp 5228 vrf ce4-cust2 network 5.4.3.0/24 route-map rm-nh network 6.0.1.0/24 route-map rm-nh network 6.0.2.0/24 route-map rm-nh-same - network 6.0.3.0/24 route-map rm-nh-same neighbor 192.168.2.1 activate exit-address-family ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf index 0e3a736292..e55c9e779a 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf @@ -4,7 +4,6 @@ hostname ce4 ! interface ce4-cust2 ip address 99.0.0.4/32 - ip address 6.0.3.1/24 ! interface ce4-eth0 description to r4 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py index b2bf5f5f63..5161d8471f 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py @@ -175,20 +175,6 @@ def ltemplatePreRouterStartHook(): "setup {0} vrf {0}-cust1, {0}-eth4. enabled mpls input.".format(rtr) ) # configure cust2 VRFs & MPLS - rtrs = ["r1"] - cmds = [ - "ip link add {0}-cust3 type vrf table 20", - "ip link set dev {0}-cust3 up", - "ip link add {0}-cust4 type vrf table 30", - "ip link set dev {0}-cust4 up", - "ip link add {0}-cust5 type vrf table 40", - "ip link set dev {0}-cust5 up", - ] - for rtr in rtrs: - for cmd in cmds: - cc.doCmd(tgen, rtr, cmd.format(rtr)) - logger.info("setup {0} vrf {0}-cust3 and{0}-cust4.".format(rtr)) - # configure cust2 VRFs & MPLS rtrs = ["r4"] cmds = [ "ip link add {0}-cust2 type vrf table 20", diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf index 24e9f95372..8d42cfc0d8 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf @@ -11,7 +11,6 @@ log file bgpd.log debugging #debug bgp vpn leak-from-vrf #debug bgp vpn label #debug bgp updates out -#debug bgp nht router bgp 5226 bgp router-id 1.1.1.1 @@ -40,11 +39,6 @@ router bgp 5227 vrf r1-cust1 neighbor 192.168.1.2 timers 3 10 address-family ipv4 unicast - network 10.2.3.4/32 - network 192.0.0.0/24 - - redistribute connected - neighbor 192.168.1.2 activate neighbor 192.168.1.2 next-hop-self @@ -57,47 +51,5 @@ router bgp 5227 vrf r1-cust1 exit-address-family -router bgp 5228 vrf r1-cust3 - bgp router-id 192.168.1.1 - - address-family ipv4 unicast - rd vpn export 10:13 - rt vpn import 52:100 - - import vpn - export vpn - exit-address-family - - -router bgp 5227 vrf r1-cust4 - no bgp network import-check - - bgp router-id 192.168.1.1 - - address-family ipv4 unicast - network 28.0.0.0/24 - - rd vpn export 10:14 - rt vpn export 52:100 - - import vpn - export vpn - exit-address-family - - -router bgp 5227 vrf r1-cust5 - bgp router-id 192.168.1.1 - - address-family ipv4 unicast - redistribute connected - - label vpn export 105 - rd vpn export 10:15 - rt vpn both 52:100 - - import vpn - export vpn - exit-address-family - ! end diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf deleted file mode 100644 index 59430fdf99..0000000000 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf +++ /dev/null @@ -1,6 +0,0 @@ -hostname r1 -log file staticd.log -! -vrf r1-cust1 - ip route 192.0.0.0/24 192.168.1.2 -exit-vrf diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf index e81bc6b2ab..221bc7a839 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf @@ -4,9 +4,6 @@ hostname r1 password zebra #debug zebra packet -#debug zebra rib detailed -#debug zebra dplane detailed -#debug zebra nexthop detail interface lo ip address 1.1.1.1/32 @@ -21,14 +18,6 @@ interface r1-eth4 ip address 192.168.1.1/24 no link-detect -interface r1-cust1 - ip address 10.4.5.6/24 - no link-detect - -interface r1-cust5 - ip address 29.0.0.1/32 - no link-detect - ip forwarding diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py index 89369241a8..91a7adf997 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py @@ -81,24 +81,3 @@ if ret != False and found != None: "wait", "CE3->CE4 (loopback) ping", ) - luCommand( - "r1", - "ip vrf exec r1-cust1 ping 6.0.3.1 -I 10.4.5.6 -c 1", - " 0. packet loss", - "wait", - "R1(r1-cust1)->CE3/4 (loopback) ping", - ) - luCommand( - "r1", - "ip vrf exec r1-cust1 ping 6.0.3.1 -I 10.4.5.6 -c 1", - " 0. packet loss", - "pass", - "R1(r1-cust1)->CE3/4 (loopback) ping", - ) - luCommand( - "r1", - "ip vrf exec r1-cust5 ping 6.0.3.1 -I 29.0.0.1 -c 1", - " 0. packet loss", - "pass", - "R1(r1-cust5)->CE3/4 ( (loopback) ping", - ) diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py index e9647898ab..75158b127e 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py @@ -72,53 +72,3 @@ luCommand( "wait", "CE4->PE4 ping", ) -ret = luCommand( - "r1", - "ip vrf exec r1-cust5 ping 29.0.0.1 -I 29.0.0.1 -c 1", - " 0. packet loss", - "pass", - "Ping its own IP. Check https://bugzilla.kernel.org/show_bug.cgi?id=203483 if it fails", -) -luCommand( - "r1", - "ip vrf exec r1-cust5 ping 192.168.1.1 -I 29.0.0.1 -c 1", - " 0. packet loss", - "pass", - "R1(r1-cust5)->R1(r1-cust1 - r1-eth4) ping", -) -luCommand( - "r1", - "ip vrf exec r1-cust5 ping 192.168.1.2 -I 29.0.0.1 -c 1", - " 0. packet loss", - "wait", - "R1(r1-cust5)->CE1 ping", -) -luCommand( - "r1", - "ip vrf exec r1-cust5 ping 192.168.1.2 -I 29.0.0.1 -c 1", - " 0. packet loss", - "pass", - "R1(r1-cust5)->CE1 ping", -) -luCommand( - "r1", - "ip vrf exec r1-cust5 ping 99.0.0.1 -I 29.0.0.1 -c 1", - " 0. packet loss", - "pass", - "R1(r1-cust5)->CE1 (loopback) ping", -) -luCommand( - "r1", - "ip vrf exec r1-cust5 ping 5.1.0.1 -I 29.0.0.1 -c 1", - " 0. packet loss", - "wait", - "R1(r1-cust5)->CE1 (loopback) ping", - time=30, -) -luCommand( - "r1", - "ip vrf exec r1-cust5 ping 5.1.0.1 -I 29.0.0.1 -c 1", - " 0. packet loss", - "pass", - "R1(r1-cust5)->CE1 (loopback) ping", -) diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py index 3242e3bd3a..1e2758c1c9 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py @@ -54,44 +54,15 @@ bgpribRequireUnicastRoutes("ce4", "ipv4", "ce4-cust2", "Cust 4 routes in ce1", w # # r1 vtysh -c "show bgp vrf r1-cust1 ipv4" # -want_r1_cust1_3_5_routes = [ +want_r1_cust1_routes = [ {"p": "5.1.0.0/24", "n": "99.0.0.1"}, {"p": "5.1.1.0/24", "n": "99.0.0.1"}, {"p": "6.0.1.0/24", "n": "99.0.0.1"}, {"p": "6.0.2.0/24", "n": "99.0.0.1"}, - {"p": "10.2.3.4/32", "n": "0.0.0.0", "bp": False}, - {"p": "10.4.5.0/24", "n": "0.0.0.0", "bp": True}, - {"p": "28.0.0.0/24", "n": "0.0.0.0", "bp": True}, - {"p": "29.0.0.1/32", "n": "0.0.0.0", "bp": True}, {"p": "99.0.0.1/32", "n": "192.168.1.2"}, - {"p": "192.0.0.0/24", "n": "0.0.0.0", "bp": True}, - {"p": "192.168.1.0/24", "n": "0.0.0.0", "bp": True}, ] bgpribRequireUnicastRoutes( - "r1", "ipv4", "r1-cust1", "Customer 1 routes in r1 vrf", want_r1_cust1_3_5_routes -) -bgpribRequireUnicastRoutes( - "r1", "ipv4", "r1-cust3", "Customer 3 routes in r1 vrf", want_r1_cust1_3_5_routes -) -bgpribRequireUnicastRoutes( - "r1", "ipv4", "r1-cust5", "Customer 5 routes in r1 vrf", want_r1_cust1_3_5_routes -) - -want_r1_cust4_routes = [ - {"p": "5.1.0.0/24", "n": "99.0.0.1", "exist": False}, - {"p": "5.1.1.0/24", "n": "99.0.0.1", "exist": False}, - {"p": "6.0.1.0/24", "n": "99.0.0.1", "exist": False}, - {"p": "6.0.2.0/24", "n": "99.0.0.1", "exist": False}, - {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, - {"p": "10.4.5.0/24", "n": "0.0.0.0", "exist": False}, - {"p": "28.0.0.0/24", "n": "0.0.0.0", "bp": True}, - {"p": "29.0.0.1/32", "n": "0.0.0.0", "exist": False}, - {"p": "99.0.0.1/32", "n": "192.168.1.2", "exist": False}, - {"p": "192.0.0.0/24", "n": "0.0.0.0", "exist": False}, - {"p": "192.168.1.0/24", "n": "0.0.0.0", "exist": False}, -] -bgpribRequireUnicastRoutes( - "r1", "ipv4", "r1-cust4", "Customer 4 routes in r1 vrf", want_r1_cust4_routes + "r1", "ipv4", "r1-cust1", "Customer 1 routes in r1 vrf", want_r1_cust1_routes ) want_r3_cust1_routes = [ @@ -99,20 +70,10 @@ want_r3_cust1_routes = [ {"p": "5.1.1.0/24", "n": "99.0.0.2"}, {"p": "6.0.1.0/24", "n": "99.0.0.2"}, {"p": "6.0.2.0/24", "n": "99.0.0.2"}, - {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, - {"p": "28.0.0.0/24", "n": "1.1.1.1", "bp": True}, - {"p": "29.0.0.1/32", "n": "1.1.1.1", "bp": True}, {"p": "99.0.0.2/32", "n": "192.168.1.2"}, - {"p": "192.0.0.0/24", "n": "1.1.1.1", "bp": True}, - {"p": "192.168.1.0/24", "n": "1.1.1.1", "bp": True}, ] bgpribRequireUnicastRoutes( - "r3", - "ipv4", - "r3-cust1", - "Customer 1 routes in r3 vrf", - want_r3_cust1_routes, - retry=30, + "r3", "ipv4", "r3-cust1", "Customer 1 routes in r3 vrf", want_r3_cust1_routes ) want_r4_cust1_routes = [ @@ -120,20 +81,10 @@ want_r4_cust1_routes = [ {"p": "5.1.3.0/24", "n": "99.0.0.3"}, {"p": "6.0.1.0/24", "n": "99.0.0.3"}, {"p": "6.0.2.0/24", "n": "99.0.0.3"}, - {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, - {"p": "28.0.0.0/24", "n": "1.1.1.1", "bp": True}, - {"p": "29.0.0.1/32", "n": "1.1.1.1", "bp": True}, {"p": "99.0.0.3/32", "n": "192.168.1.2"}, - {"p": "192.0.0.0/24", "n": "1.1.1.1", "bp": True}, - {"p": "192.168.1.0/24", "n": "1.1.1.1", "bp": True}, ] bgpribRequireUnicastRoutes( - "r4", - "ipv4", - "r4-cust1", - "Customer 1 routes in r4 vrf", - want_r4_cust1_routes, - retry=30, + "r4", "ipv4", "r4-cust1", "Customer 1 routes in r4 vrf", want_r4_cust1_routes ) want_r4_cust2_routes = [ @@ -141,20 +92,10 @@ want_r4_cust2_routes = [ {"p": "5.4.3.0/24", "n": "99.0.0.4"}, {"p": "6.0.1.0/24", "n": "99.0.0.4"}, {"p": "6.0.2.0/24", "n": "99.0.0.4"}, - {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, - {"p": "28.0.0.0/24", "n": "1.1.1.1", "bp": True}, - {"p": "29.0.0.1/32", "n": "1.1.1.1", "bp": True}, {"p": "99.0.0.4/32", "n": "192.168.2.2"}, - {"p": "192.0.0.0/24", "n": "1.1.1.1", "bp": True}, - {"p": "192.168.1.0/24", "n": "1.1.1.1", "bp": True}, ] bgpribRequireUnicastRoutes( - "r4", - "ipv4", - "r4-cust2", - "Customer 2 routes in r4 vrf", - want_r4_cust2_routes, - retry=30, + "r4", "ipv4", "r4-cust2", "Customer 2 routes in r4 vrf", want_r4_cust2_routes ) ######################################################################## @@ -726,7 +667,7 @@ bgpribRequireUnicastRoutes( luCommand( "ce1", 'vtysh -c "show bgp ipv4 uni"', - "18 routes and 19", + "12 routes and 12", "wait", "Local and remote routes", 10, @@ -748,7 +689,7 @@ bgpribRequireUnicastRoutes( luCommand( "ce2", 'vtysh -c "show bgp ipv4 uni"', - "18 routes and 22", + "12 routes and 15", "wait", "Local and remote routes", 10, @@ -780,7 +721,7 @@ luCommand("r4", 'vtysh -c "show ip route vrf r4-cust2"') luCommand( "ce3", 'vtysh -c "show bgp ipv4 uni"', - "18 routes and 19", + "12 routes and 13", "wait", "Local and remote routes", 10, @@ -802,7 +743,7 @@ bgpribRequireUnicastRoutes( luCommand( "ce4", 'vtysh -c "show bgp vrf ce4-cust2 ipv4 uni"', - "18 routes and 21", + "12 routes and 14", "wait", "Local and remote routes", 10, diff --git a/tests/topotests/bgp_path_attribute_discard/__init__.py b/tests/topotests/bgp_path_attribute_discard/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/__init__.py diff --git a/tests/topotests/bgp_path_attribute_discard/exabgp.env b/tests/topotests/bgp_path_attribute_discard/exabgp.env new file mode 100644 index 0000000000..28e642360a --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/exabgp.env @@ -0,0 +1,53 @@ +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' +##daemonize = false + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg b/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg new file mode 100644 index 0000000000..7fb9210ecf --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg @@ -0,0 +1,24 @@ +neighbor 10.0.0.1 { + router-id 10.0.0.2; + local-address 10.0.0.2; + local-as 65001; + peer-as 65002; + + capability { + route-refresh; + } + + static { + route 192.168.100.101/32 { + atomic-aggregate; + community 65001:101; + next-hop 10.0.0.2; + } + + route 192.168.100.102/32 { + originator-id 10.0.0.2; + community 65001:102; + next-hop 10.0.0.2; + } + } +} diff --git a/tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf b/tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf new file mode 100644 index 0000000000..c96f354cc5 --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf @@ -0,0 +1,6 @@ +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.0.2 remote-as external + neighbor 10.0.0.2 timers 3 10 +! diff --git a/tests/topotests/bgp_path_attribute_discard/r1/zebra.conf b/tests/topotests/bgp_path_attribute_discard/r1/zebra.conf new file mode 100644 index 0000000000..51a1b2657c --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/r1/zebra.conf @@ -0,0 +1,4 @@ +! +interface r1-eth0 + ip address 10.0.0.1/24 +! diff --git a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py new file mode 100644 index 0000000000..4badf64c37 --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2022 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if `neighbor path-attribute discard` command works correctly, +can discard unwanted attributes from UPDATE messages, and ignore them +by continuing to process UPDATE messages. +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + r1 = tgen.add_router("r1") + peer1 = tgen.add_exabgp_peer("peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(peer1) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router = tgen.gears["r1"] + router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf")) + router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf")) + router.start() + + peer = tgen.gears["peer1"] + peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env")) + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_path_attribute_discard(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json detail")) + expected = { + "routes": { + "192.168.100.101/32": [ + { + "valid": True, + "atomicAggregate": True, + "community": { + "string": "65001:101", + }, + } + ], + "192.168.100.102/32": [ + { + "valid": True, + "originatorId": "10.0.0.2", + "community": { + "string": "65001:102", + }, + } + ], + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Failed bgp convergence" + + step("Discard atomic-aggregate, community, and originator-id attributes from peer1") + r1.vtysh_cmd( + """ + configure terminal + router bgp + neighbor 10.0.0.2 path-attribute discard 6 8 9 + """ + ) + + def _bgp_check_if_attributes_discarded(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json detail")) + expected = { + "routes": { + "192.168.100.101/32": [ + { + "valid": True, + "atomicAggregate": None, + "community": None, + } + ], + "192.168.100.102/32": [ + { + "valid": True, + "originatorId": None, + "community": None, + } + ], + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_if_attributes_discarded) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert ( + result is None + ), "Failed to discard path attributes (atomic-aggregate, community, and originator-id)" + + +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() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_sender_as_path_loop_detection/r1/bgpd.conf b/tests/topotests/bgp_sender_as_path_loop_detection/r1/bgpd.conf index 719d76392d..409be74740 100644 --- a/tests/topotests/bgp_sender_as_path_loop_detection/r1/bgpd.conf +++ b/tests/topotests/bgp_sender_as_path_loop_detection/r1/bgpd.conf @@ -1,14 +1,19 @@ ! exit1 router bgp 65001 - no bgp ebgp-requires-policy - neighbor 192.168.255.1 remote-as 65002 - neighbor 192.168.255.1 timers 3 10 - address-family ipv4 unicast - neighbor 192.168.255.1 route-map prepend out - redistribute connected - exit-address-family - ! + no bgp ebgp-requires-policy + neighbor 192.168.255.1 remote-as 65002 + neighbor 192.168.255.1 timers 3 10 + address-family ipv4 unicast + neighbor 192.168.255.1 route-map prepend out + redistribute connected + exit-address-family + ! +! +ip prefix-list p1 seq 5 permit 172.16.255.253/32 ! route-map prepend permit 10 - set as-path prepend 65003 + match ip address prefix-list p1 + set as-path prepend 65003 +! +route-map prepend permit 20 ! diff --git a/tests/topotests/bgp_sender_as_path_loop_detection/r1/zebra.conf b/tests/topotests/bgp_sender_as_path_loop_detection/r1/zebra.conf index 9904bb4e16..74489a0571 100644 --- a/tests/topotests/bgp_sender_as_path_loop_detection/r1/zebra.conf +++ b/tests/topotests/bgp_sender_as_path_loop_detection/r1/zebra.conf @@ -1,5 +1,6 @@ ! exit1 interface lo + ip address 172.16.255.253/32 ip address 172.16.255.254/32 ! interface r1-eth0 diff --git a/tests/topotests/bgp_sender_as_path_loop_detection/r2/bgpd.conf b/tests/topotests/bgp_sender_as_path_loop_detection/r2/bgpd.conf index a4a654d7b5..dcb52a2e7d 100644 --- a/tests/topotests/bgp_sender_as_path_loop_detection/r2/bgpd.conf +++ b/tests/topotests/bgp_sender_as_path_loop_detection/r2/bgpd.conf @@ -1,11 +1,10 @@ ! spine router bgp 65002 - no bgp ebgp-requires-policy - neighbor 192.168.255.2 remote-as 65001 - neighbor 192.168.255.2 timers 3 10 - neighbor 192.168.255.2 solo - neighbor 192.168.254.2 remote-as 65003 - neighbor 192.168.254.2 timers 3 10 - neighbor 192.168.254.2 solo - neighbor 192.168.254.2 sender-as-path-loop-detection + no bgp ebgp-requires-policy + neighbor 192.168.255.2 remote-as 65001 + neighbor 192.168.255.2 timers 3 10 + neighbor 192.168.255.2 sender-as-path-loop-detection + neighbor 192.168.254.2 remote-as 65003 + neighbor 192.168.254.2 timers 3 10 + neighbor 192.168.254.2 sender-as-path-loop-detection ! diff --git a/tests/topotests/bgp_sender_as_path_loop_detection/r3/bgpd.conf b/tests/topotests/bgp_sender_as_path_loop_detection/r3/bgpd.conf index 2e24de0b2d..519273d30d 100644 --- a/tests/topotests/bgp_sender_as_path_loop_detection/r3/bgpd.conf +++ b/tests/topotests/bgp_sender_as_path_loop_detection/r3/bgpd.conf @@ -1,6 +1,6 @@ ! exit2 router bgp 65003 - no bgp ebgp-requires-policy - neighbor 192.168.254.1 remote-as 65002 - neighbor 192.168.254.1 timers 3 10 + no bgp ebgp-requires-policy + neighbor 192.168.254.1 remote-as 65002 + neighbor 192.168.254.1 timers 3 10 ! diff --git a/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py b/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py index b5c33f359b..ebeab05648 100644 --- a/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py +++ b/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py @@ -85,20 +85,20 @@ def test_bgp_sender_as_path_loop_detection(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - router = tgen.gears["r2"] + r2 = tgen.gears["r2"] - def _bgp_converge(router): - output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) + def _bgp_converge(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) expected = { "192.168.255.2": { "bgpState": "Established", - "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 3}}, } } return topotest.json_cmp(output, expected) - def _bgp_has_route_from_r1(router): - output = json.loads(router.vtysh_cmd("show ip bgp 172.16.255.254/32 json")) + def _bgp_has_route_from_r1(): + output = json.loads(r2.vtysh_cmd("show ip bgp 172.16.255.253/32 json")) expected = { "paths": [ { @@ -111,31 +111,35 @@ def test_bgp_sender_as_path_loop_detection(): } return topotest.json_cmp(output, expected) - def _bgp_suppress_route_to_r3(router): + def _bgp_suppress_route_to_r1(): output = json.loads( - router.vtysh_cmd( - "show ip bgp neighbor 192.168.254.2 advertised-routes json" - ) + r2.vtysh_cmd("show ip bgp neighbor 192.168.255.2 advertised-routes json") ) expected = {"totalPrefixCounter": 0} return topotest.json_cmp(output, expected) - test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - - assert result is None, 'Failed bgp convergence in "{}"'.format(router) + def _bgp_suppress_route_to_r3(): + output = json.loads( + r2.vtysh_cmd("show ip bgp neighbor 192.168.254.2 advertised-routes json") + ) + expected = {"totalPrefixCounter": 2} + return topotest.json_cmp(output, expected) - test_func = functools.partial(_bgp_has_route_from_r1, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Failed bgp to convergence" - assert result is None, 'Failed to see a route from r1 in "{}"'.format(router) + test_func = functools.partial(_bgp_has_route_from_r1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Failed to see a route from r1" - test_func = functools.partial(_bgp_suppress_route_to_r3, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + test_func = functools.partial(_bgp_suppress_route_to_r3) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Route 172.16.255.253/32 should not be sent to r3 from r2" - assert ( - result is None - ), 'Route 172.16.255.254/32 should not be sent to r3 "{}"'.format(router) + test_func = functools.partial(_bgp_suppress_route_to_r1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Routes should not be sent to r1 from r2" if __name__ == "__main__": diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/bgpd.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/bgpd.conf diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/staticd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/staticd.conf new file mode 100644 index 0000000000..0c88575abd --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/staticd.conf @@ -0,0 +1,4 @@ +! +ip route 0.0.0.0/0 192.168.3.254 +ipv6 route ::/0 2001:3::ffff +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/zebra.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/zebra.conf new file mode 100644 index 0000000000..3f75641ea7 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/zebra.conf @@ -0,0 +1,6 @@ +hostname c31 +! +interface eth0 + ip address 192.168.3.1/24 + ipv6 address 2001:3::1/64 +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/bgpd.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/bgpd.conf diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/staticd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/staticd.conf new file mode 100644 index 0000000000..0c88575abd --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/staticd.conf @@ -0,0 +1,4 @@ +! +ip route 0.0.0.0/0 192.168.3.254 +ipv6 route ::/0 2001:3::ffff +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/zebra.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/zebra.conf new file mode 100644 index 0000000000..c06a7d19f5 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/zebra.conf @@ -0,0 +1,6 @@ +hostname c32 +! +interface eth0 + ip address 192.168.3.1/24 + ipv6 address 2001:3::1/64 +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/bgpd.conf index 048702f918..22b9014291 100644 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/bgpd.conf @@ -11,16 +11,21 @@ router bgp 65001 bgp router-id 192.0.2.1 no bgp ebgp-requires-policy no bgp default ipv4-unicast - neighbor 2001:db8::2 remote-as 65002 - neighbor 2001:db8::2 timers 3 10 - neighbor 2001:db8::2 timers connect 1 - neighbor 2001:db8::2 capability extended-nexthop + neighbor 2001:db8:12::2 remote-as 65002 + neighbor 2001:db8:12::2 timers 3 10 + neighbor 2001:db8:12::2 timers connect 1 + neighbor 2001:db8:12::2 capability extended-nexthop + neighbor 2001:db8:13::3 remote-as 65001 + neighbor 2001:db8:13::3 timers 3 10 + neighbor 2001:db8:13::3 timers connect 1 + neighbor 2001:db8:13::3 capability extended-nexthop ! segment-routing srv6 locator default ! address-family ipv4 vpn - neighbor 2001:db8::2 activate + neighbor 2001:db8:12::2 activate + neighbor 2001:db8:13::3 activate exit-address-family ! ! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/staticd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/staticd.conf index 662856f476..49b64fd7af 100644 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/staticd.conf +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/staticd.conf @@ -1,3 +1,4 @@ ! -ipv6 route 2001:db8:2:2::/64 2001:db8::2 +ipv6 route 2001:db8:2:2::/64 2001:db8:12::2 +ipv6 route 2001:db8:3:3::/64 2001:db8:13::3 ! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/zebra.conf index 066748bec5..79dbf95593 100644 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/zebra.conf @@ -6,12 +6,15 @@ interface lo ipv6 address 2001:db8:1:1::1/128 ! interface eth0 - ipv6 address 2001:db8::1/64 + ipv6 address 2001:db8:12::1/64 ! -interface eth1 vrf vrf10 +interface eth1 + ipv6 address 2001:db8:13::1/64 +! +interface eth2 vrf vrf10 ip address 192.168.1.254/24 ! -interface eth2 vrf vrf20 +interface eth3 vrf vrf20 ip address 192.168.1.254/24 ! segment-routing diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/bgpd.conf index 33b9103aaf..42b9d511d9 100644 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/bgpd.conf +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/bgpd.conf @@ -11,16 +11,16 @@ router bgp 65002 bgp router-id 192.0.2.2 no bgp ebgp-requires-policy no bgp default ipv4-unicast - neighbor 2001:db8::1 remote-as 65001 - neighbor 2001:db8::1 timers 3 10 - neighbor 2001:db8::1 timers connect 1 - neighbor 2001:db8::1 capability extended-nexthop + neighbor 2001:db8:12::1 remote-as 65001 + neighbor 2001:db8:12::1 timers 3 10 + neighbor 2001:db8:12::1 timers connect 1 + neighbor 2001:db8:12::1 capability extended-nexthop ! segment-routing srv6 locator default ! address-family ipv4 vpn - neighbor 2001:db8::1 activate + neighbor 2001:db8:12::1 activate exit-address-family ! ! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/staticd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/staticd.conf index a2f54b7333..8d80c1ead2 100644 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/staticd.conf +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/staticd.conf @@ -1,3 +1,4 @@ ! -ipv6 route 2001:db8:1:1::/64 2001:db8::1 +ipv6 route 2001:db8:1:1::/64 2001:db8:12::1 +ipv6 route 2001:db8:3:3::/64 2001:db8:12::1 ! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/zebra.conf index dc03389fcb..09a65b989c 100644 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/zebra.conf +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/zebra.conf @@ -6,7 +6,7 @@ interface lo ipv6 address 2001:db8:2:2::1/128 ! interface eth0 - ipv6 address 2001:db8::2/64 + ipv6 address 2001:db8:12::2/64 ! interface eth1 vrf vrf10 ip address 192.168.2.254/24 diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/bgpd.conf new file mode 100644 index 0000000000..339b4eb089 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/bgpd.conf @@ -0,0 +1,52 @@ +frr defaults traditional +! +hostname r2 +password zebra +! +log stdout notifications +log monitor notifications +log commands +! +router bgp 65001 + bgp router-id 192.0.2.3 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor 2001:db8:13::1 remote-as 65001 + neighbor 2001:db8:13::1 timers 3 10 + neighbor 2001:db8:13::1 timers connect 1 + neighbor 2001:db8:13::1 capability extended-nexthop + ! + segment-routing srv6 + locator default + ! + address-family ipv4 vpn + neighbor 2001:db8:13::1 activate + exit-address-family + ! +! +router bgp 65001 vrf vrf10 + bgp router-id 192.0.2.3 + ! + address-family ipv4 unicast + redistribute connected + sid vpn export 1 + rd vpn export 65001:10 + rt vpn both 0:10 + import vpn + export vpn + exit-address-family + ! +! +router bgp 65001 vrf vrf20 + bgp router-id 192.0.2.2 + ! + address-family ipv4 unicast + redistribute connected + sid vpn export 2 + rd vpn export 65001:20 + rt vpn both 0:20 + import vpn + export vpn + exit-address-family + ! +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/staticd.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/staticd.conf new file mode 100644 index 0000000000..9d672d51ba --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/staticd.conf @@ -0,0 +1,6 @@ +! +ipv6 route 2001:db8:12::/64 2001:db8:13::1 +! +ipv6 route 2001:db8:1:1::/64 2001:db8:13::1 +ipv6 route 2001:db8:2:2::/64 2001:db8:13::1 +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/zebra.conf new file mode 100644 index 0000000000..a20cb76a74 --- /dev/null +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/zebra.conf @@ -0,0 +1,29 @@ +log file zebra.log +! +hostname r2 +! +interface lo + ipv6 address 2001:db8:3:3::1/128 +! +interface eth0 + ipv6 address 2001:db8:13::3/64 +! +interface eth1 vrf vrf10 + ip address 192.168.3.254/24 +! +interface eth2 vrf vrf20 + ip address 192.168.3.254/24 +! +segment-routing + srv6 + locators + locator default + prefix 2001:db8:3:3::/64 + ! + ! +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py b/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py index 6a75fb82f4..0b8870cdca 100755 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py @@ -44,17 +44,23 @@ pytestmark = [pytest.mark.bgpd] def build_topo(tgen): tgen.add_router("r1") tgen.add_router("r2") + tgen.add_router("r3") tgen.add_router("c11") tgen.add_router("c12") tgen.add_router("c21") tgen.add_router("c22") + tgen.add_router("c31") + tgen.add_router("c32") tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "eth0", "eth0") - tgen.add_link(tgen.gears["r1"], tgen.gears["c11"], "eth1", "eth0") - tgen.add_link(tgen.gears["r1"], tgen.gears["c12"], "eth2", "eth0") + tgen.add_link(tgen.gears["r1"], tgen.gears["r3"], "eth1", "eth0") + tgen.add_link(tgen.gears["r1"], tgen.gears["c11"], "eth2", "eth0") + tgen.add_link(tgen.gears["r1"], tgen.gears["c12"], "eth3", "eth0") tgen.add_link(tgen.gears["r2"], tgen.gears["c21"], "eth1", "eth0") tgen.add_link(tgen.gears["r2"], tgen.gears["c22"], "eth2", "eth0") + tgen.add_link(tgen.gears["r3"], tgen.gears["c31"], "eth1", "eth0") + tgen.add_link(tgen.gears["r3"], tgen.gears["c32"], "eth2", "eth0") def setup_module(mod): @@ -66,20 +72,23 @@ def setup_module(mod): tgen.start_topology() for rname, router in tgen.routers().items(): - router.load_config(TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname))) - router.load_config(TopoRouter.RD_STATIC, - os.path.join(CWD, '{}/staticd.conf'.format(rname))) - router.load_config(TopoRouter.RD_BGP, - os.path.join(CWD, '{}/bgpd.conf'.format(rname))) + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_STATIC, os.path.join(CWD, "{}/staticd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) tgen.gears["r1"].run("sysctl net.vrf.strict_mode=1") tgen.gears["r1"].run("ip link add vrf10 type vrf table 10") tgen.gears["r1"].run("ip link set vrf10 up") tgen.gears["r1"].run("ip link add vrf20 type vrf table 20") tgen.gears["r1"].run("ip link set vrf20 up") - tgen.gears["r1"].run("ip link set eth1 master vrf10") - tgen.gears["r1"].run("ip link set eth2 master vrf20") + tgen.gears["r1"].run("ip link set eth2 master vrf10") + tgen.gears["r1"].run("ip link set eth3 master vrf20") tgen.gears["r2"].run("sysctl net.vrf.strict_mode=1") tgen.gears["r2"].run("ip link add vrf10 type vrf table 10") @@ -89,6 +98,14 @@ def setup_module(mod): tgen.gears["r2"].run("ip link set eth1 master vrf10") tgen.gears["r2"].run("ip link set eth2 master vrf20") + tgen.gears["r3"].run("sysctl net.vrf.strict_mode=1") + tgen.gears["r3"].run("ip link add vrf10 type vrf table 10") + tgen.gears["r3"].run("ip link set vrf10 up") + tgen.gears["r3"].run("ip link add vrf20 type vrf table 20") + tgen.gears["r3"].run("ip link set vrf20 up") + tgen.gears["r3"].run("ip link set eth1 master vrf10") + tgen.gears["r3"].run("ip link set eth2 master vrf20") + tgen.start_router() @@ -115,12 +132,13 @@ def check_ping4(name, dest_addr, expected): def test_ping(): tgen = get_topogen() - logger.info(tgen.gears["c11"].run("ip route show")) - # tests for ipv4-vpn + check_ping4("c11", "192.168.2.1", True) + check_ping4("c11", "192.168.3.1", True) check_ping4("c12", "192.168.2.1", True) - check_ping4("c21", "192.168.1.1", True) - check_ping4("c22", "192.168.1.1", True) + check_ping4("c12", "192.168.3.1", True) + check_ping4("c21", "192.168.3.1", True) + check_ping4("c22", "192.168.3.1", True) if __name__ == "__main__": diff --git a/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json b/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json index 2ce936b291..9f78447255 100644 --- a/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json +++ b/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json @@ -12,7 +12,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "vrf10", + "interfaceName": "eth0", "vrf": "vrf10", "active": true } diff --git a/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf b/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf index 0e2d3a8248..295811bfd0 100644 --- a/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf +++ b/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf @@ -14,6 +14,7 @@ router bgp 65500 vrf vrf1 bgp router-id 192.0.2.1 address-family ipv4 unicast redistribute connected + distance bgp 21 201 41 label vpn export 101 rd vpn export 444:1 rt vpn both 52:100 diff --git a/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json b/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json index 5f2732aab0..e57e21bb12 100644 --- a/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json +++ b/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json @@ -7,7 +7,7 @@ "vrfName": "vrf1", "selected": true, "destSelected": true, - "distance": 20, + "distance": 201, "metric": 0, "nexthops": [ { diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py new file mode 100644 index 0000000000..c51beca72a --- /dev/null +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py @@ -0,0 +1,407 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2021 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking: +1. Verify recursive import among Tenant VRFs. +2. Verify that dynamic import works fine between two different Tenant VRFs. + When next-hop IPs are same across all VRFs. + When next-hop IPs are different across all VRFs. +3. Verify that with multiple tenant VRFs, dynamic import works fine between + Tenant VRFs to default VRF. + When next-hop IPs and prefixes are same across all VRFs. + When next-hop IPs and prefixes are different across all VRFs. +""" + +import os +import sys +import time +import pytest +import platform +from time import sleep + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# Required to instantiate the topology builder class. + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib.topogen import Topogen, get_topogen +from lib.topotest import version_cmp + +from lib.common_config import ( + start_topology, + write_test_header, + check_address_types, + write_test_footer, + reset_config_on_routers, + verify_rib, + step, + create_route_maps, + create_static_routes, + create_prefix_lists, + create_bgp_community_lists, + get_frr_ipv6_linklocal, +) + +from lib.topolog import logger +from lib.bgp import ( + verify_bgp_convergence, + create_router_bgp, + verify_bgp_community, + verify_bgp_rib, +) +from lib.topojson import build_config_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + +# Global variables +NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"} +NETWORK1_2 = {"ipv4": "11.11.11.11/32", "ipv6": "11:11::11/128"} +NETWORK1_3 = {"ipv4": "10.10.10.1/32", "ipv6": "10:10::1/128"} +NETWORK1_4 = {"ipv4": "10.10.10.100/32", "ipv6": "10:10::100/128"} +NETWORK1_5 = {"ipv4": "110.110.110.1/32", "ipv6": "110:110::1/128"} +NETWORK1_6 = {"ipv4": "110.110.110.100/32", "ipv6": "110:110::100/128"} + +NETWORK2_1 = {"ipv4": "22.22.22.2/32", "ipv6": "22:22::2/128"} +NETWORK2_2 = {"ipv4": "22.22.22.22/32", "ipv6": "22:22::22/128"} +NETWORK2_3 = {"ipv4": "20.20.20.20/32", "ipv6": "20:20::20/128"} +NETWORK2_4 = {"ipv4": "20.20.20.200/32", "ipv6": "20:20::200/128"} +NETWORK2_5 = {"ipv4": "220.220.220.20/32", "ipv6": "220:220::20/128"} +NETWORK2_6 = {"ipv4": "220.220.220.200/32", "ipv6": "220:220::200/128"} + +NETWORK3_1 = {"ipv4": "30.30.30.3/32", "ipv6": "30:30::3/128"} +NETWORK3_2 = {"ipv4": "30.30.30.30/32", "ipv6": "30:30::30/128"} + +PREFIX_LIST = { + "ipv4": ["11.11.11.1", "22.22.22.2", "22.22.22.22"], + "ipv6": ["11:11::1", "22:22::2", "22:22::22"], +} +PREFERRED_NEXT_HOP = "global" +VRF_LIST = ["RED", "BLUE", "GREEN"] +COMM_VAL_1 = "100:100" +COMM_VAL_2 = "500:500" +COMM_VAL_3 = "600:600" + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/bgp_vrf_dynamic_route_leak_topo4.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global topo + topo = tgen.json_topo + # ... and here it calls Mininet initialization functions. + + # Starting topology, create tmp files which are loaded to routers + # to start daemons and then start routers + start_topology(tgen) + + # Run these tests for kernel version 4.19 or above + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + "BGP vrf dynamic route leak tests will not run " + '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) + ) + pytest.skip(error_msg) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + global BGP_CONVERGENCE + global ADDR_TYPES + ADDR_TYPES = check_address_types() + + BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) + assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( + BGP_CONVERGENCE + ) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +##################################################### +# +# Testcases +# +##################################################### + + +def test_dynamic_import_recursive_import_tenant_vrf_p1(request): + """ + Verify recursive import among Tenant VRFs. + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + reset_config_on_routers(tgen) + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step( + "Configure static routes on R2 for vrf RED and redistribute in " + "respective BGP instance" + ) + for addr_type in ADDR_TYPES: + static_routes = { + "r2": { + "static_routes": [ + { + "network": [NETWORK2_1[addr_type]], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + + result = create_static_routes(tgen, static_routes) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Redistribute static route on BGP VRF RED") + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} + ) + + redist_dict = { + "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that R2 has installed redistributed routes in vrf RED only") + for addr_type in ADDR_TYPES: + static_routes = { + "r2": { + "static_routes": [{"network": [NETWORK2_1[addr_type]], "vrf": "RED"}] + } + } + result = verify_bgp_rib(tgen, addr_type, "r2", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r2", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Import vrf RED's routes into vrf GREEN on R2") + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": "RED"}}}}) + + import_dict = { + "r2": {"bgp": [{"vrf": "GREEN", "local_as": 2, "address_family": temp}]} + } + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify on R2, that it installs imported routes from vrf RED to vrf " + "GREEN's RIB/FIB pointing next-hop to vrf RED" + ) + for addr_type in ADDR_TYPES: + static_routes = { + "r2": { + "static_routes": [{"network": [NETWORK2_1[addr_type]], "vrf": "GREEN"}] + } + } + result = verify_bgp_rib(tgen, addr_type, "r2", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r2", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("On R3 import routes from vrf GREEN to vrf default") + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": "GREEN"}}}}) + + import_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify on R3, that it installs imported routes from vrf GREEN to " + "vrf default RIB/FIB pointing next-hop to vrf GREEN. " + ) + for addr_type in ADDR_TYPES: + static_routes = { + "r2": {"static_routes": [{"network": [NETWORK2_1[addr_type]]}]} + } + result = verify_bgp_rib(tgen, addr_type, "r3", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r3", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("On R4 import routes from vrf default to vrf BLUE") + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": "default"}}}}) + + import_dict = { + "r4": {"bgp": [{"vrf": "BLUE", "local_as": 4, "address_family": temp}]} + } + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify on R4, that it installs imported routes from vrf default to " + "vrf BLUE RIB/FIB pointing next-hop to vrf default." + ) + for addr_type in ADDR_TYPES: + static_routes = { + "r4": { + "static_routes": [{"network": [NETWORK2_1[addr_type]], "vrf": "BLUE"}] + } + } + result = verify_bgp_rib(tgen, addr_type, "r4", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r4", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for dut, vrf_name, vrf_import, as_num in zip( + ["r2", "r4"], ["GREEN", "BLUE"], ["RED", "default"], [2, 4] + ): + + for action, value in zip(["Delete", "Re-add"], [True, False]): + step("{} the import command on {} router".format(action, dut)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": {"import": {"vrf": vrf_import, "delete": value}} + } + } + ) + + import_dict = { + dut: { + "bgp": [ + {"vrf": vrf_name, "local_as": as_num, "address_family": temp} + ] + } + } + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for addr_type in ADDR_TYPES: + static_routes = { + "r4": { + "static_routes": [ + {"network": [NETWORK2_1[addr_type]], "vrf": "BLUE"} + ] + } + } + if value: + result = verify_bgp_rib( + tgen, addr_type, "r4", static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes["r4"]["static_routes"][0]["network"], + ) + + result = verify_rib( + tgen, addr_type, "r4", static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( + tc_name, + result, + static_routes["r4"]["static_routes"][0]["network"], + ) + else: + result = verify_bgp_rib(tgen, addr_type, "r4", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r4", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py new file mode 100644 index 0000000000..bfeaaa17df --- /dev/null +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py @@ -0,0 +1,932 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2021 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking: +1. Verify recursive import among Tenant VRFs. +2. Verify that dynamic import works fine between two different Tenant VRFs. + When next-hop IPs are same across all VRFs. + When next-hop IPs are different across all VRFs. +3. Verify that with multiple tenant VRFs, dynamic import works fine between + Tenant VRFs to default VRF. + When next-hop IPs and prefixes are same across all VRFs. + When next-hop IPs and prefixes are different across all VRFs. +""" + +import os +import sys +import time +import pytest +import platform +from time import sleep + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# Required to instantiate the topology builder class. + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib.topogen import Topogen, get_topogen +from lib.topotest import version_cmp + +from lib.common_config import ( + start_topology, + write_test_header, + check_address_types, + write_test_footer, + reset_config_on_routers, + verify_rib, + step, + create_route_maps, + create_static_routes, + create_prefix_lists, + create_bgp_community_lists, + get_frr_ipv6_linklocal, +) + +from lib.topolog import logger +from lib.bgp import ( + verify_bgp_convergence, + create_router_bgp, + verify_bgp_community, + verify_bgp_rib, +) +from lib.topojson import build_config_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + +# Global variables +NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"} +NETWORK1_2 = {"ipv4": "11.11.11.11/32", "ipv6": "11:11::11/128"} +NETWORK1_3 = {"ipv4": "10.10.10.1/32", "ipv6": "10:10::1/128"} +NETWORK1_4 = {"ipv4": "10.10.10.100/32", "ipv6": "10:10::100/128"} +NETWORK1_5 = {"ipv4": "110.110.110.1/32", "ipv6": "110:110::1/128"} +NETWORK1_6 = {"ipv4": "110.110.110.100/32", "ipv6": "110:110::100/128"} + +NETWORK2_1 = {"ipv4": "22.22.22.2/32", "ipv6": "22:22::2/128"} +NETWORK2_2 = {"ipv4": "22.22.22.22/32", "ipv6": "22:22::22/128"} +NETWORK2_3 = {"ipv4": "20.20.20.20/32", "ipv6": "20:20::20/128"} +NETWORK2_4 = {"ipv4": "20.20.20.200/32", "ipv6": "20:20::200/128"} +NETWORK2_5 = {"ipv4": "220.220.220.20/32", "ipv6": "220:220::20/128"} +NETWORK2_6 = {"ipv4": "220.220.220.200/32", "ipv6": "220:220::200/128"} + +NETWORK3_1 = {"ipv4": "30.30.30.3/32", "ipv6": "30:30::3/128"} +NETWORK3_2 = {"ipv4": "30.30.30.30/32", "ipv6": "30:30::30/128"} + +PREFIX_LIST = { + "ipv4": ["11.11.11.1", "22.22.22.2", "22.22.22.22"], + "ipv6": ["11:11::1", "22:22::2", "22:22::22"], +} +PREFERRED_NEXT_HOP = "global" +VRF_LIST = ["RED", "BLUE", "GREEN"] +COMM_VAL_1 = "100:100" +COMM_VAL_2 = "500:500" +COMM_VAL_3 = "600:600" + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/bgp_vrf_dynamic_route_leak_topo4.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global topo + topo = tgen.json_topo + # ... and here it calls Mininet initialization functions. + + # Starting topology, create tmp files which are loaded to routers + # to start daemons and then start routers + start_topology(tgen) + + # Run these tests for kernel version 4.19 or above + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + "BGP vrf dynamic route leak tests will not run " + '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) + ) + pytest.skip(error_msg) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + global BGP_CONVERGENCE + global ADDR_TYPES + ADDR_TYPES = check_address_types() + + BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) + assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( + BGP_CONVERGENCE + ) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +##################################################### +# +# Testcases +# +##################################################### + + +def test_dynamic_import_routes_between_two_tenant_vrf_p0(request): + """ + Verify that dynamic import works fine between two different Tenant VRFs. + + When next-hop IPs are same across all VRFs. + When next-hop IPs are different across all VRFs. + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + reset_config_on_routers(tgen) + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step( + "Configure static routes on R3 for each vrf and redistribute in " + "respective BGP instance" + ) + + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + step("Configure static route for VRF : {}".format(vrf_name)) + for addr_type in ADDR_TYPES: + static_routes = { + "r3": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + "vrf": vrf_name, + } + ] + } + } + + result = create_static_routes(tgen, static_routes) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Redistribute static route on BGP VRF : {}".format(vrf_name)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} + ) + + redist_dict = { + "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + step( + "Verify that R3 has installed redistributed routes in respective " + "vrfs: {}".format(vrf_name) + ) + for addr_type in ADDR_TYPES: + static_routes = { + "r3": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + "vrf": vrf_name, + } + ] + } + } + + result = verify_rib(tgen, addr_type, "r3", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Import from vrf GREEN+BLUE into vrf RED on R3") + + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + import_dict = { + "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify on R1, that it installs all the routes(local+imported) in " + "vrf RED's RIB/FIB and doesn't get confuse with next-hop attribute, " + "as all vrfs on R1 are using same IP address for next-hop" + ) + + for addr_type in ADDR_TYPES: + static_routes = { + "r3": { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + + next_hop_1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[0] + result = verify_bgp_rib( + tgen, addr_type, "r1", static_routes, next_hop=next_hop_1 + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r1", static_routes, next_hop=next_hop_1) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Remove import vrf GREEN/BLUE/Both command from vrf RED's instance on" " R3") + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} + ) + + import_dict = { + "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Verify that R1,R2 & R3 withdraw imported routes from vrf RED's RIB") + for dut in ["r1", "r2", "r3"]: + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, ( + "Testcase {} : Failed \nError {}\n" + "Routes {} still in BGP table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + ) + + result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, ( + "Testcase {} : Failed \nError {}\n" + "Routes {} still in Route table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + ) + + step("Add import vrf GREEN/BLUE/Both command from vrf RED's instance on " "R3") + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + import_dict = { + "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for dut in ["r1", "r2", "r3"]: + step("Verify that {} reinstall imported routes from vrf RED's RIB".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value in zip(["Shut", "No shut"], [True, False]): + step( + "{} the neighborship between R1-R3 and R1-R2 for vrf GREEN, BLUE " + "and default".format(action) + ) + bgp_disable = {"r3": {"bgp": []}} + for vrf_name in ["GREEN", "BLUE", "default"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r1": { + "dest_link": {"r3-link1": {"shutdown": value}} + }, + "r2": { + "dest_link": {"r3-link1": {"shutdown": value}} + }, + } + } + } + } + ) + + bgp_disable["r3"]["bgp"].append( + {"vrf": vrf_name, "local_as": 3, "address_family": temp} + ) + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Verify RIB/FIB of vrf RED will be unchanged on all 3 routers") + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value, status in zip( + ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] + ): + step("{} the neighborship between R1-R3 and R1-R2 for vrf RED".format(action)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r1": {"dest_link": {"r3-link1": {"shutdown": value}}}, + "r2": {"dest_link": {"r3-link1": {"shutdown": value}}}, + } + } + } + } + ) + + bgp_disable = { + "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} + } + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that R1 and R2 {} all the routes from RED vrf's RIB and" + " FIB".format(status) + ) + for dut in ["r1", "r2"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + + if value: + result = verify_bgp_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + + result = verify_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in Route table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + else: + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Remove import command from router R3 and configure the same on R2") + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} + ) + + import_dict = { + "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that once import commands are removed from R3, all imported " + "routes are withdrawn from RIB/FIB of vrf RED on R1/R2/R3" + ) + + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, ( + "Testcase {} : Failed \nError {}\n" + "Routes {} still in BGP table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + ) + + result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + + step( + "Configure static routes on R2 for each vrf and redistribute in " + "respective BGP instance" + ) + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + step("Configure static route for VRF : {}".format(vrf_name)) + for addr_type in ADDR_TYPES: + static_routes = { + "r2": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + "vrf": vrf_name, + } + ] + } + } + + result = create_static_routes(tgen, static_routes) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Redistribute static route on BGP VRF : {}".format(vrf_name)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} + ) + + redist_dict = { + "r2": {"bgp": [{"vrf": vrf_name, "local_as": 2, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Remove redistribute static route on BGP VRF : {} on r3".format(vrf_name)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "redistribute": [{"redist_type": "static", "delete": True}] + } + } + } + ) + + redist_dict = { + "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + import_dict = { + "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify after import commands are re-configured on R2's vrf RED, all " + "those routes are installed again in vrf RED of R1,R2,R3" + ) + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step( + "Remove/add import vrf GREEN/BLUE/both command from vrf RED's " "instance on R2" + ) + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} + ) + + redist_dict = { + "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Verify that R1,R2 & R3 withdraw imported routes from vrf RED's RIB") + for dut in ["r1", "r2", "r3"]: + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, ( + "Testcase {} : Failed \nError {}\n" + "Routes {} still in BGP table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + ) + + result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + + step("Add import vrf GREEN/BLUE/Both command from vrf RED's instance on " "R2") + for vrf_name in ["BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + redist_dict = { + "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for dut in ["r1", "r2", "r3"]: + step("Verify that {} reinstall imported routes from vrf RED's RIB".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value in zip(["Shut", "No shut"], [True, False]): + step( + "{} the neighborship between R2-R3 for vrf GREEN, BLUE and default".format( + action + ) + ) + bgp_disable = {"r2": {"bgp": []}} + for vrf_name in ["GREEN", "BLUE", "default"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r3": { + "dest_link": {"r2-link1": {"shutdown": value}} + } + } + } + } + } + ) + + bgp_disable["r2"]["bgp"].append( + {"vrf": vrf_name, "local_as": 2, "address_family": temp} + ) + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Verify RIB/FIB of vrf RED will be unchanged on all 3 routers") + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value, status in zip( + ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] + ): + step("{} the neighborship between R2-R3 for vrf RED".format(action)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r2": {"dest_link": {"r3-link1": {"shutdown": value}}} + } + } + } + } + ) + + bgp_disable = { + "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} + } + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that R1 and R2 {} all the routes from RED vrf's RIB and" + " FIB".format(status) + ) + for dut in ["r1", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + "vrf": "RED", + } + ] + } + } + + if value: + result = verify_bgp_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + + result = verify_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + else: + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py new file mode 100644 index 0000000000..1d80a2a64a --- /dev/null +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py @@ -0,0 +1,932 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2021 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking: +1. Verify recursive import among Tenant VRFs. +2. Verify that dynamic import works fine between two different Tenant VRFs. + When next-hop IPs are same across all VRFs. + When next-hop IPs are different across all VRFs. +3. Verify that with multiple tenant VRFs, dynamic import works fine between + Tenant VRFs to default VRF. + When next-hop IPs and prefixes are same across all VRFs. + When next-hop IPs and prefixes are different across all VRFs. +""" + +import os +import sys +import time +import pytest +import platform +from time import sleep + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# Required to instantiate the topology builder class. + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib.topogen import Topogen, get_topogen +from lib.topotest import version_cmp + +from lib.common_config import ( + start_topology, + write_test_header, + check_address_types, + write_test_footer, + reset_config_on_routers, + verify_rib, + step, + create_route_maps, + create_static_routes, + create_prefix_lists, + create_bgp_community_lists, + get_frr_ipv6_linklocal, +) + +from lib.topolog import logger +from lib.bgp import ( + verify_bgp_convergence, + create_router_bgp, + verify_bgp_community, + verify_bgp_rib, +) +from lib.topojson import build_config_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + +# Global variables +NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"} +NETWORK1_2 = {"ipv4": "11.11.11.11/32", "ipv6": "11:11::11/128"} +NETWORK1_3 = {"ipv4": "10.10.10.1/32", "ipv6": "10:10::1/128"} +NETWORK1_4 = {"ipv4": "10.10.10.100/32", "ipv6": "10:10::100/128"} +NETWORK1_5 = {"ipv4": "110.110.110.1/32", "ipv6": "110:110::1/128"} +NETWORK1_6 = {"ipv4": "110.110.110.100/32", "ipv6": "110:110::100/128"} + +NETWORK2_1 = {"ipv4": "22.22.22.2/32", "ipv6": "22:22::2/128"} +NETWORK2_2 = {"ipv4": "22.22.22.22/32", "ipv6": "22:22::22/128"} +NETWORK2_3 = {"ipv4": "20.20.20.20/32", "ipv6": "20:20::20/128"} +NETWORK2_4 = {"ipv4": "20.20.20.200/32", "ipv6": "20:20::200/128"} +NETWORK2_5 = {"ipv4": "220.220.220.20/32", "ipv6": "220:220::20/128"} +NETWORK2_6 = {"ipv4": "220.220.220.200/32", "ipv6": "220:220::200/128"} + +NETWORK3_1 = {"ipv4": "30.30.30.3/32", "ipv6": "30:30::3/128"} +NETWORK3_2 = {"ipv4": "30.30.30.30/32", "ipv6": "30:30::30/128"} + +PREFIX_LIST = { + "ipv4": ["11.11.11.1", "22.22.22.2", "22.22.22.22"], + "ipv6": ["11:11::1", "22:22::2", "22:22::22"], +} +PREFERRED_NEXT_HOP = "global" +VRF_LIST = ["RED", "BLUE", "GREEN"] +COMM_VAL_1 = "100:100" +COMM_VAL_2 = "500:500" +COMM_VAL_3 = "600:600" + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/bgp_vrf_dynamic_route_leak_topo4.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global topo + topo = tgen.json_topo + # ... and here it calls Mininet initialization functions. + + # Starting topology, create tmp files which are loaded to routers + # to start daemons and then start routers + start_topology(tgen) + + # Run these tests for kernel version 4.19 or above + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + "BGP vrf dynamic route leak tests will not run " + '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) + ) + pytest.skip(error_msg) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + global BGP_CONVERGENCE + global ADDR_TYPES + ADDR_TYPES = check_address_types() + + BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) + assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( + BGP_CONVERGENCE + ) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +##################################################### +# +# Testcases +# +##################################################### + + +def test_dynamic_import_routes_between_tenant_to_default_vrf_p0(request): + """ + Verify that with multiple tenant VRFs, dynamic import works fine between + Tenant VRFs to default VRF. + + When next-hop IPs and prefixes are same across all VRFs. + When next-hop IPs and prefixes are different across all VRFs. + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + reset_config_on_routers(tgen) + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step( + "Configure static routes on R3 for each vrf and redistribute in " + "respective BGP instance" + ) + + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + step("Configure static route for VRF : {}".format(vrf_name)) + for addr_type in ADDR_TYPES: + static_routes = { + "r3": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + "vrf": vrf_name, + } + ] + } + } + + result = create_static_routes(tgen, static_routes) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Redistribute static route on BGP VRF : {}".format(vrf_name)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} + ) + + redist_dict = { + "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + step( + "Verify that R3 has installed redistributed routes in respective " + "vrfs: {}".format(vrf_name) + ) + for addr_type in ADDR_TYPES: + static_routes = { + "r3": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + "vrf": vrf_name, + } + ] + } + } + + result = verify_rib(tgen, addr_type, "r3", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Import all tenant vrfs(GREEN+BLUE+RED) in default vrf on R3") + + for vrf_name in ["RED", "BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + redist_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify on R3 that it installs all the routes(imported from tenant " + "VRFs) in default vrf. Additionally, verify that R1 & R2 also " + "receive these routes from R3 and install in default vrf, next-hop " + "pointing to R3" + ) + + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + for addr_type in ADDR_TYPES: + static_routes = { + "r3": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + } + ] + } + } + + for dut in ["r2", "r1"]: + next_hop_val = topo["routers"]["r3"]["links"]["{}-link4".format(dut)][ + addr_type + ].split("/")[0] + + result = verify_bgp_rib( + tgen, addr_type, dut, static_routes, next_hop=next_hop_val + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib( + tgen, addr_type, dut, static_routes, next_hop=next_hop_val + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_bgp_rib(tgen, addr_type, "r3", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, "r3", static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value, status in zip( + ["Remove", "Add"], [True, False], ["withdraw", "re-install"] + ): + step( + "{} import vrf GREEN/BLUE/RED/all command from default vrf " + "instance on R3".format(action) + ) + for vrf_name in ["RED", "BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": {"import": {"vrf": vrf_name, "delete": value}} + } + } + ) + + import_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that R1,R2 & R3 {} imported routes from GREEN/BLUE/RED/all" + " in default vrf's RIB".format(status) + ) + for dut in ["r1", "r2", "r3"]: + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + + if value: + result = verify_bgp_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + + result = verify_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + else: + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value in zip(["Shut", "No shut"], [True, False]): + step( + "{} the neighborship between R1-R3 and R1-R2 for vrf RED, GREEN " + "and BLUE".format(action) + ) + bgp_disable = {"r3": {"bgp": []}} + for vrf_name in ["RED", "GREEN", "BLUE"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r1": { + "dest_link": {"r3-link4": {"shutdown": value}} + }, + "r2": { + "dest_link": {"r3-link4": {"shutdown": value}} + }, + } + } + } + } + ) + + bgp_disable["r3"]["bgp"].append( + {"vrf": vrf_name, "local_as": 3, "address_family": temp} + ) + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that when peering is shutdown for tenant vrfs, it " + "doesn't impact the RIB/FIB of default vrf on router R1 and R2" + ) + for dut in ["r1", "r2"]: + step("Verify RIB/FIB for default vrf on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value, status in zip( + ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] + ): + step( + "{} the neighborship between R1-R3 and R2-R3 for default vrf".format(action) + ) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r1": {"dest_link": {"r3-link4": {"shutdown": value}}}, + "r2": {"dest_link": {"r3-link4": {"shutdown": value}}}, + } + } + } + } + ) + + bgp_disable = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that R1 and R2 {} all the routes from default vrf's RIB" + " and FIB".format(status) + ) + for dut in ["r1", "r2"]: + step("Verify RIB/FIB for default vrf on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + + if value: + result = verify_bgp_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + + result = verify_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + else: + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Remove import command from router R3 and configure the same on R2") + temp = {} + for vrf_name in VRF_LIST: + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} + ) + + import_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that once import commands are removed from R3, all imported " + "routes are withdrawn from RIB/FIB of default vrf on R1/R2/R3" + ) + + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for default vrf on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, ( + "Testcase {} : Failed \nError {}\n" + "Routes {} still in BGP table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + ) + + result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): + step("Configure static route for VRF : {} on r2".format(vrf_name)) + for addr_type in ADDR_TYPES: + static_routes = { + "r2": { + "static_routes": [ + { + "network": [network[addr_type]], + "next_hop": "blackhole", + "vrf": vrf_name, + } + ] + } + } + + result = create_static_routes(tgen, static_routes) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Redistribute static route on BGP VRF : {}".format(vrf_name)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} + ) + + redist_dict = { + "r2": {"bgp": [{"vrf": vrf_name, "local_as": 2, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Remove redistribute static route on BGP VRF : {} on r3".format(vrf_name)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "redistribute": [{"redist_type": "static", "delete": True}] + } + } + } + ) + + redist_dict = { + "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} + } + + result = create_router_bgp(tgen, topo, redist_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for vrf_name in ["RED", "BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + import_dict = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify after import commands are re-configured on R2's vrf RED, all " + "those routes are installed again in default vrf of R1,R2,R3" + ) + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Remove import vrf RED/GREEN/BLUE/all one by one from default vrf" " on R2") + for vrf_name in ["RED", "BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} + ) + + import_dict = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that R1, R2 and R3 withdraws imported routes from default " + "vrf's RIB and FIB " + ) + for dut in ["r1", "r2", "r3"]: + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, ( + "Testcase {} : Failed \nError {}\n" + "Routes {} still in BGP table".format( + tc_name, result, static_routes[dut]["static_routes"][0]["network"] + ) + ) + + result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) + assert result is not True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + step("Add import vrf RED/GREEN/BLUE/all one by one from default vrf on R2") + for vrf_name in ["RED", "BLUE", "GREEN"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) + + import_dict = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} + + result = create_router_bgp(tgen, topo, import_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + for dut in ["r1", "r2", "r3"]: + step("Verify that {} reinstall imported routes from vrf RED's RIB".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value in zip(["Shut", "No shut"], [True, False]): + step( + "{} the neighborship between R2-R3 for vrf GREEN, BLUE and RED".format( + action + ) + ) + bgp_disable = {"r2": {"bgp": []}} + for vrf_name in ["GREEN", "BLUE", "RED"]: + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r3": { + "dest_link": {"r2-link4": {"shutdown": value}} + } + } + } + } + } + ) + + bgp_disable["r2"]["bgp"].append( + {"vrf": vrf_name, "local_as": 2, "address_family": temp} + ) + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("Verify RIB/FIB of vrf RED will be unchanged on all 3 routers") + for dut in ["r1", "r2", "r3"]: + step("Verify RIB/FIB for vrf RED on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for action, value, status in zip( + ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] + ): + step("{} the neighborship between R2-R3 for default vrf".format(action)) + temp = {} + for addr_type in ADDR_TYPES: + temp.update( + { + addr_type: { + "unicast": { + "neighbor": { + "r3": {"dest_link": {"r2-link4": {"shutdown": value}}} + } + } + } + } + ) + + bgp_disable = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} + result = create_router_bgp(tgen, topo, bgp_disable) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify that R1 and R2 {} all the routes from default vrfs RIB and" + " FIB".format(status) + ) + for dut in ["r1", "r3"]: + step("Verify RIB/FIB for default vrf on {}".format(dut)) + for addr_type in ADDR_TYPES: + static_routes = { + dut: { + "static_routes": [ + { + "network": [ + NETWORK1_1[addr_type], + NETWORK2_1[addr_type], + NETWORK3_1[addr_type], + ], + "next_hop": "blackhole", + } + ] + } + } + + if value: + result = verify_bgp_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + + result = verify_rib( + tgen, addr_type, dut, static_routes, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( + tc_name, + result, + static_routes[dut]["static_routes"][0]["network"], + ) + else: + result = verify_bgp_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + result = verify_rib(tgen, addr_type, dut, static_routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py deleted file mode 100644 index 97016caa75..0000000000 --- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py +++ /dev/null @@ -1,1909 +0,0 @@ -#!/usr/bin/env python - -# -# Copyright (c) 2021 by VMware, Inc. ("VMware") -# Used Copyright (c) 2018 by Network Device Education Foundation, -# Inc. ("NetDEF") in this file. -# -# Permission to use, copy, modify, and/or distribute this software -# for any purpose with or without fee is hereby granted, provided -# that the above copyright notice and this permission notice appear -# in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# - -""" -Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking: -1. Verify recursive import among Tenant VRFs. -2. Verify that dynamic import works fine between two different Tenant VRFs. - When next-hop IPs are same across all VRFs. - When next-hop IPs are different across all VRFs. -3. Verify that with multiple tenant VRFs, dynamic import works fine between - Tenant VRFs to default VRF. - When next-hop IPs and prefixes are same across all VRFs. - When next-hop IPs and prefixes are different across all VRFs. -""" - -import os -import sys -import time -import pytest -import platform -from time import sleep - -# Save the Current Working Directory to find configuration files. -CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, "../")) -sys.path.append(os.path.join(CWD, "../lib/")) - -# Required to instantiate the topology builder class. - -# pylint: disable=C0413 -# Import topogen and topotest helpers -from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp - -from lib.common_config import ( - start_topology, - write_test_header, - check_address_types, - write_test_footer, - reset_config_on_routers, - verify_rib, - step, - create_route_maps, - create_static_routes, - create_prefix_lists, - create_bgp_community_lists, - get_frr_ipv6_linklocal, -) - -from lib.topolog import logger -from lib.bgp import ( - verify_bgp_convergence, - create_router_bgp, - verify_bgp_community, - verify_bgp_rib, -) -from lib.topojson import build_config_from_json - -pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] - -# Global variables -NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"} -NETWORK1_2 = {"ipv4": "11.11.11.11/32", "ipv6": "11:11::11/128"} -NETWORK1_3 = {"ipv4": "10.10.10.1/32", "ipv6": "10:10::1/128"} -NETWORK1_4 = {"ipv4": "10.10.10.100/32", "ipv6": "10:10::100/128"} -NETWORK1_5 = {"ipv4": "110.110.110.1/32", "ipv6": "110:110::1/128"} -NETWORK1_6 = {"ipv4": "110.110.110.100/32", "ipv6": "110:110::100/128"} - -NETWORK2_1 = {"ipv4": "22.22.22.2/32", "ipv6": "22:22::2/128"} -NETWORK2_2 = {"ipv4": "22.22.22.22/32", "ipv6": "22:22::22/128"} -NETWORK2_3 = {"ipv4": "20.20.20.20/32", "ipv6": "20:20::20/128"} -NETWORK2_4 = {"ipv4": "20.20.20.200/32", "ipv6": "20:20::200/128"} -NETWORK2_5 = {"ipv4": "220.220.220.20/32", "ipv6": "220:220::20/128"} -NETWORK2_6 = {"ipv4": "220.220.220.200/32", "ipv6": "220:220::200/128"} - -NETWORK3_1 = {"ipv4": "30.30.30.3/32", "ipv6": "30:30::3/128"} -NETWORK3_2 = {"ipv4": "30.30.30.30/32", "ipv6": "30:30::30/128"} - -PREFIX_LIST = { - "ipv4": ["11.11.11.1", "22.22.22.2", "22.22.22.22"], - "ipv6": ["11:11::1", "22:22::2", "22:22::22"], -} -PREFERRED_NEXT_HOP = "global" -VRF_LIST = ["RED", "BLUE", "GREEN"] -COMM_VAL_1 = "100:100" -COMM_VAL_2 = "500:500" -COMM_VAL_3 = "600:600" - - -def setup_module(mod): - """ - Sets up the pytest environment - - * `mod`: module name - """ - - testsuite_run_time = time.asctime(time.localtime(time.time())) - logger.info("Testsuite start time: {}".format(testsuite_run_time)) - logger.info("=" * 40) - - logger.info("Running setup_module to create topology") - - # This function initiates the topology build with Topogen... - json_file = "{}/bgp_vrf_dynamic_route_leak_topo4.json".format(CWD) - tgen = Topogen(json_file, mod.__name__) - global topo - topo = tgen.json_topo - # ... and here it calls Mininet initialization functions. - - # Starting topology, create tmp files which are loaded to routers - # to start daemons and then start routers - start_topology(tgen) - - # Run these tests for kernel version 4.19 or above - if version_cmp(platform.release(), "4.19") < 0: - error_msg = ( - "BGP vrf dynamic route leak tests will not run " - '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) - ) - pytest.skip(error_msg) - - # Creating configuration from JSON - build_config_from_json(tgen, topo) - - global BGP_CONVERGENCE - global ADDR_TYPES - ADDR_TYPES = check_address_types() - - BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) - assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( - BGP_CONVERGENCE - ) - - logger.info("Running setup_module() done") - - -def teardown_module(): - """Teardown the pytest environment""" - - logger.info("Running teardown_module to delete topology") - - tgen = get_topogen() - - # Stop toplogy and Remove tmp files - tgen.stop_topology() - - logger.info( - "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) - ) - logger.info("=" * 40) - - -##################################################### -# -# Testcases -# -##################################################### - - -def test_dynamic_import_recursive_import_tenant_vrf_p1(request): - """ - Verify recursive import among Tenant VRFs. - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - reset_config_on_routers(tgen) - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step( - "Configure static routes on R2 for vrf RED and redistribute in " - "respective BGP instance" - ) - for addr_type in ADDR_TYPES: - static_routes = { - "r2": { - "static_routes": [ - { - "network": [NETWORK2_1[addr_type]], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - - result = create_static_routes(tgen, static_routes) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Redistribute static route on BGP VRF RED") - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} - ) - - redist_dict = { - "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("Verify that R2 has installed redistributed routes in vrf RED only") - for addr_type in ADDR_TYPES: - static_routes = { - "r2": { - "static_routes": [{"network": [NETWORK2_1[addr_type]], "vrf": "RED"}] - } - } - result = verify_bgp_rib(tgen, addr_type, "r2", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r2", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Import vrf RED's routes into vrf GREEN on R2") - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": "RED"}}}}) - - import_dict = { - "r2": {"bgp": [{"vrf": "GREEN", "local_as": 2, "address_family": temp}]} - } - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step( - "Verify on R2, that it installs imported routes from vrf RED to vrf " - "GREEN's RIB/FIB pointing next-hop to vrf RED" - ) - for addr_type in ADDR_TYPES: - static_routes = { - "r2": { - "static_routes": [{"network": [NETWORK2_1[addr_type]], "vrf": "GREEN"}] - } - } - result = verify_bgp_rib(tgen, addr_type, "r2", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r2", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("On R3 import routes from vrf GREEN to vrf default") - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": "GREEN"}}}}) - - import_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step( - "Verify on R3, that it installs imported routes from vrf GREEN to " - "vrf default RIB/FIB pointing next-hop to vrf GREEN. " - ) - for addr_type in ADDR_TYPES: - static_routes = { - "r2": {"static_routes": [{"network": [NETWORK2_1[addr_type]]}]} - } - result = verify_bgp_rib(tgen, addr_type, "r3", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r3", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("On R4 import routes from vrf default to vrf BLUE") - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": "default"}}}}) - - import_dict = { - "r4": {"bgp": [{"vrf": "BLUE", "local_as": 4, "address_family": temp}]} - } - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step( - "Verify on R4, that it installs imported routes from vrf default to " - "vrf BLUE RIB/FIB pointing next-hop to vrf default." - ) - for addr_type in ADDR_TYPES: - static_routes = { - "r4": { - "static_routes": [{"network": [NETWORK2_1[addr_type]], "vrf": "BLUE"}] - } - } - result = verify_bgp_rib(tgen, addr_type, "r4", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r4", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for dut, vrf_name, vrf_import, as_num in zip( - ["r2", "r4"], ["GREEN", "BLUE"], ["RED", "default"], [2, 4] - ): - - for action, value in zip(["Delete", "Re-add"], [True, False]): - step("{} the import command on {} router".format(action, dut)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": {"import": {"vrf": vrf_import, "delete": value}} - } - } - ) - - import_dict = { - dut: { - "bgp": [ - {"vrf": vrf_name, "local_as": as_num, "address_family": temp} - ] - } - } - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for addr_type in ADDR_TYPES: - static_routes = { - "r4": { - "static_routes": [ - {"network": [NETWORK2_1[addr_type]], "vrf": "BLUE"} - ] - } - } - if value: - result = verify_bgp_rib( - tgen, addr_type, "r4", static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes["r4"]["static_routes"][0]["network"], - ) - - result = verify_rib( - tgen, addr_type, "r4", static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( - tc_name, - result, - static_routes["r4"]["static_routes"][0]["network"], - ) - else: - result = verify_bgp_rib(tgen, addr_type, "r4", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r4", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - write_test_footer(tc_name) - - -def test_dynamic_import_routes_between_two_tenant_vrf_p0(request): - """ - Verify that dynamic import works fine between two different Tenant VRFs. - - When next-hop IPs are same across all VRFs. - When next-hop IPs are different across all VRFs. - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - reset_config_on_routers(tgen) - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step( - "Configure static routes on R3 for each vrf and redistribute in " - "respective BGP instance" - ) - - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - step("Configure static route for VRF : {}".format(vrf_name)) - for addr_type in ADDR_TYPES: - static_routes = { - "r3": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - "vrf": vrf_name, - } - ] - } - } - - result = create_static_routes(tgen, static_routes) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Redistribute static route on BGP VRF : {}".format(vrf_name)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} - ) - - redist_dict = { - "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - step( - "Verify that R3 has installed redistributed routes in respective " - "vrfs: {}".format(vrf_name) - ) - for addr_type in ADDR_TYPES: - static_routes = { - "r3": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - "vrf": vrf_name, - } - ] - } - } - - result = verify_rib(tgen, addr_type, "r3", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Import from vrf GREEN+BLUE into vrf RED on R3") - - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - import_dict = { - "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify on R1, that it installs all the routes(local+imported) in " - "vrf RED's RIB/FIB and doesn't get confuse with next-hop attribute, " - "as all vrfs on R1 are using same IP address for next-hop" - ) - - for addr_type in ADDR_TYPES: - static_routes = { - "r3": { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - - next_hop_1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[0] - result = verify_bgp_rib( - tgen, addr_type, "r1", static_routes, next_hop=next_hop_1 - ) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r1", static_routes, next_hop=next_hop_1) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Remove import vrf GREEN/BLUE/Both command from vrf RED's instance on" " R3") - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} - ) - - import_dict = { - "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Verify that R1,R2 & R3 withdraw imported routes from vrf RED's RIB") - for dut in ["r1", "r2", "r3"]: - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, ( - "Testcase {} : Failed \nError {}\n" - "Routes {} still in BGP table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - ) - - result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, ( - "Testcase {} : Failed \nError {}\n" - "Routes {} still in Route table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - ) - - step("Add import vrf GREEN/BLUE/Both command from vrf RED's instance on " "R3") - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - import_dict = { - "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for dut in ["r1", "r2", "r3"]: - step("Verify that {} reinstall imported routes from vrf RED's RIB".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value in zip(["Shut", "No shut"], [True, False]): - step( - "{} the neighborship between R1-R3 and R1-R2 for vrf GREEN, BLUE " - "and default".format(action) - ) - bgp_disable = {"r3": {"bgp": []}} - for vrf_name in ["GREEN", "BLUE", "default"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r1": { - "dest_link": {"r3-link1": {"shutdown": value}} - }, - "r2": { - "dest_link": {"r3-link1": {"shutdown": value}} - }, - } - } - } - } - ) - - bgp_disable["r3"]["bgp"].append( - {"vrf": vrf_name, "local_as": 3, "address_family": temp} - ) - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Verify RIB/FIB of vrf RED will be unchanged on all 3 routers") - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value, status in zip( - ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] - ): - step("{} the neighborship between R1-R3 and R1-R2 for vrf RED".format(action)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r1": {"dest_link": {"r3-link1": {"shutdown": value}}}, - "r2": {"dest_link": {"r3-link1": {"shutdown": value}}}, - } - } - } - } - ) - - bgp_disable = { - "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} - } - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that R1 and R2 {} all the routes from RED vrf's RIB and" - " FIB".format(status) - ) - for dut in ["r1", "r2"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - - if value: - result = verify_bgp_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - - result = verify_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in Route table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - else: - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Remove import command from router R3 and configure the same on R2") - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} - ) - - import_dict = { - "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that once import commands are removed from R3, all imported " - "routes are withdrawn from RIB/FIB of vrf RED on R1/R2/R3" - ) - - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, ( - "Testcase {} : Failed \nError {}\n" - "Routes {} still in BGP table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - ) - - result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - - step( - "Configure static routes on R2 for each vrf and redistribute in " - "respective BGP instance" - ) - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - step("Configure static route for VRF : {}".format(vrf_name)) - for addr_type in ADDR_TYPES: - static_routes = { - "r2": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - "vrf": vrf_name, - } - ] - } - } - - result = create_static_routes(tgen, static_routes) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Redistribute static route on BGP VRF : {}".format(vrf_name)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} - ) - - redist_dict = { - "r2": {"bgp": [{"vrf": vrf_name, "local_as": 2, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Remove redistribute static route on BGP VRF : {} on r3".format(vrf_name)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "redistribute": [{"redist_type": "static", "delete": True}] - } - } - } - ) - - redist_dict = { - "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - import_dict = { - "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify after import commands are re-configured on R2's vrf RED, all " - "those routes are installed again in vrf RED of R1,R2,R3" - ) - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step( - "Remove/add import vrf GREEN/BLUE/both command from vrf RED's " "instance on R2" - ) - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} - ) - - redist_dict = { - "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Verify that R1,R2 & R3 withdraw imported routes from vrf RED's RIB") - for dut in ["r1", "r2", "r3"]: - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, ( - "Testcase {} : Failed \nError {}\n" - "Routes {} still in BGP table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - ) - - result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - - step("Add import vrf GREEN/BLUE/Both command from vrf RED's instance on " "R2") - for vrf_name in ["BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - redist_dict = { - "r2": {"bgp": [{"vrf": "RED", "local_as": 2, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for dut in ["r1", "r2", "r3"]: - step("Verify that {} reinstall imported routes from vrf RED's RIB".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [NETWORK2_1[addr_type], NETWORK3_1[addr_type]], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value in zip(["Shut", "No shut"], [True, False]): - step( - "{} the neighborship between R2-R3 for vrf GREEN, BLUE and default".format( - action - ) - ) - bgp_disable = {"r2": {"bgp": []}} - for vrf_name in ["GREEN", "BLUE", "default"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r3": { - "dest_link": {"r2-link1": {"shutdown": value}} - } - } - } - } - } - ) - - bgp_disable["r2"]["bgp"].append( - {"vrf": vrf_name, "local_as": 2, "address_family": temp} - ) - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Verify RIB/FIB of vrf RED will be unchanged on all 3 routers") - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value, status in zip( - ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] - ): - step("{} the neighborship between R2-R3 for vrf RED".format(action)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r2": {"dest_link": {"r3-link1": {"shutdown": value}}} - } - } - } - } - ) - - bgp_disable = { - "r3": {"bgp": [{"vrf": "RED", "local_as": 3, "address_family": temp}]} - } - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that R1 and R2 {} all the routes from RED vrf's RIB and" - " FIB".format(status) - ) - for dut in ["r1", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - "vrf": "RED", - } - ] - } - } - - if value: - result = verify_bgp_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - - result = verify_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - else: - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - write_test_footer(tc_name) - - -def test_dynamic_import_routes_between_tenant_to_default_vrf_p0(request): - """ - Verify that with multiple tenant VRFs, dynamic import works fine between - Tenant VRFs to default VRF. - - When next-hop IPs and prefixes are same across all VRFs. - When next-hop IPs and prefixes are different across all VRFs. - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - reset_config_on_routers(tgen) - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step( - "Configure static routes on R3 for each vrf and redistribute in " - "respective BGP instance" - ) - - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - step("Configure static route for VRF : {}".format(vrf_name)) - for addr_type in ADDR_TYPES: - static_routes = { - "r3": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - "vrf": vrf_name, - } - ] - } - } - - result = create_static_routes(tgen, static_routes) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Redistribute static route on BGP VRF : {}".format(vrf_name)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} - ) - - redist_dict = { - "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - step( - "Verify that R3 has installed redistributed routes in respective " - "vrfs: {}".format(vrf_name) - ) - for addr_type in ADDR_TYPES: - static_routes = { - "r3": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - "vrf": vrf_name, - } - ] - } - } - - result = verify_rib(tgen, addr_type, "r3", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Import all tenant vrfs(GREEN+BLUE+RED) in default vrf on R3") - - for vrf_name in ["RED", "BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - redist_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify on R3 that it installs all the routes(imported from tenant " - "VRFs) in default vrf. Additionally, verify that R1 & R2 also " - "receive these routes from R3 and install in default vrf, next-hop " - "pointing to R3" - ) - - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - for addr_type in ADDR_TYPES: - static_routes = { - "r3": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - } - ] - } - } - - for dut in ["r2", "r1"]: - next_hop_val = topo["routers"]["r3"]["links"]["{}-link4".format(dut)][ - addr_type - ].split("/")[0] - - result = verify_bgp_rib( - tgen, addr_type, dut, static_routes, next_hop=next_hop_val - ) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib( - tgen, addr_type, dut, static_routes, next_hop=next_hop_val - ) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_bgp_rib(tgen, addr_type, "r3", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, "r3", static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value, status in zip( - ["Remove", "Add"], [True, False], ["withdraw", "re-install"] - ): - step( - "{} import vrf GREEN/BLUE/RED/all command from default vrf " - "instance on R3".format(action) - ) - for vrf_name in ["RED", "BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": {"import": {"vrf": vrf_name, "delete": value}} - } - } - ) - - import_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that R1,R2 & R3 {} imported routes from GREEN/BLUE/RED/all" - " in default vrf's RIB".format(status) - ) - for dut in ["r1", "r2", "r3"]: - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - - if value: - result = verify_bgp_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - - result = verify_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - else: - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value in zip(["Shut", "No shut"], [True, False]): - step( - "{} the neighborship between R1-R3 and R1-R2 for vrf RED, GREEN " - "and BLUE".format(action) - ) - bgp_disable = {"r3": {"bgp": []}} - for vrf_name in ["RED", "GREEN", "BLUE"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r1": { - "dest_link": {"r3-link4": {"shutdown": value}} - }, - "r2": { - "dest_link": {"r3-link4": {"shutdown": value}} - }, - } - } - } - } - ) - - bgp_disable["r3"]["bgp"].append( - {"vrf": vrf_name, "local_as": 3, "address_family": temp} - ) - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that when peering is shutdown for tenant vrfs, it " - "doesn't impact the RIB/FIB of default vrf on router R1 and R2" - ) - for dut in ["r1", "r2"]: - step("Verify RIB/FIB for default vrf on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value, status in zip( - ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] - ): - step( - "{} the neighborship between R1-R3 and R2-R3 for default vrf".format(action) - ) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r1": {"dest_link": {"r3-link4": {"shutdown": value}}}, - "r2": {"dest_link": {"r3-link4": {"shutdown": value}}}, - } - } - } - } - ) - - bgp_disable = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that R1 and R2 {} all the routes from default vrf's RIB" - " and FIB".format(status) - ) - for dut in ["r1", "r2"]: - step("Verify RIB/FIB for default vrf on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - - if value: - result = verify_bgp_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - - result = verify_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - else: - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Remove import command from router R3 and configure the same on R2") - temp = {} - for vrf_name in VRF_LIST: - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} - ) - - import_dict = {"r3": {"bgp": [{"local_as": 3, "address_family": temp}]}} - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that once import commands are removed from R3, all imported " - "routes are withdrawn from RIB/FIB of default vrf on R1/R2/R3" - ) - - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for default vrf on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, ( - "Testcase {} : Failed \nError {}\n" - "Routes {} still in BGP table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - ) - - result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for vrf_name, network in zip(VRF_LIST, [NETWORK1_1, NETWORK2_1, NETWORK3_1]): - step("Configure static route for VRF : {} on r2".format(vrf_name)) - for addr_type in ADDR_TYPES: - static_routes = { - "r2": { - "static_routes": [ - { - "network": [network[addr_type]], - "next_hop": "blackhole", - "vrf": vrf_name, - } - ] - } - } - - result = create_static_routes(tgen, static_routes) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Redistribute static route on BGP VRF : {}".format(vrf_name)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"redistribute": [{"redist_type": "static"}]}}} - ) - - redist_dict = { - "r2": {"bgp": [{"vrf": vrf_name, "local_as": 2, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Remove redistribute static route on BGP VRF : {} on r3".format(vrf_name)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "redistribute": [{"redist_type": "static", "delete": True}] - } - } - } - ) - - redist_dict = { - "r3": {"bgp": [{"vrf": vrf_name, "local_as": 3, "address_family": temp}]} - } - - result = create_router_bgp(tgen, topo, redist_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for vrf_name in ["RED", "BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - import_dict = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify after import commands are re-configured on R2's vrf RED, all " - "those routes are installed again in default vrf of R1,R2,R3" - ) - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Remove import vrf RED/GREEN/BLUE/all one by one from default vrf" " on R2") - for vrf_name in ["RED", "BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - {addr_type: {"unicast": {"import": {"vrf": vrf_name, "delete": True}}}} - ) - - import_dict = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that R1, R2 and R3 withdraws imported routes from default " - "vrf's RIB and FIB " - ) - for dut in ["r1", "r2", "r3"]: - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, ( - "Testcase {} : Failed \nError {}\n" - "Routes {} still in BGP table".format( - tc_name, result, static_routes[dut]["static_routes"][0]["network"] - ) - ) - - result = verify_rib(tgen, addr_type, dut, static_routes, expected=False) - assert result is not True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - step("Add import vrf RED/GREEN/BLUE/all one by one from default vrf on R2") - for vrf_name in ["RED", "BLUE", "GREEN"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update({addr_type: {"unicast": {"import": {"vrf": vrf_name}}}}) - - import_dict = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} - - result = create_router_bgp(tgen, topo, import_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - for dut in ["r1", "r2", "r3"]: - step("Verify that {} reinstall imported routes from vrf RED's RIB".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value in zip(["Shut", "No shut"], [True, False]): - step( - "{} the neighborship between R2-R3 for vrf GREEN, BLUE and RED".format( - action - ) - ) - bgp_disable = {"r2": {"bgp": []}} - for vrf_name in ["GREEN", "BLUE", "RED"]: - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r3": { - "dest_link": {"r2-link4": {"shutdown": value}} - } - } - } - } - } - ) - - bgp_disable["r2"]["bgp"].append( - {"vrf": vrf_name, "local_as": 2, "address_family": temp} - ) - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("Verify RIB/FIB of vrf RED will be unchanged on all 3 routers") - for dut in ["r1", "r2", "r3"]: - step("Verify RIB/FIB for vrf RED on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - for action, value, status in zip( - ["Shut", "No shut"], [True, False], ["Withdraw", "Reinstall"] - ): - step("{} the neighborship between R2-R3 for default vrf".format(action)) - temp = {} - for addr_type in ADDR_TYPES: - temp.update( - { - addr_type: { - "unicast": { - "neighbor": { - "r3": {"dest_link": {"r2-link4": {"shutdown": value}}} - } - } - } - } - ) - - bgp_disable = {"r2": {"bgp": [{"local_as": 2, "address_family": temp}]}} - result = create_router_bgp(tgen, topo, bgp_disable) - assert result is True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step( - "Verify that R1 and R2 {} all the routes from default vrfs RIB and" - " FIB".format(status) - ) - for dut in ["r1", "r3"]: - step("Verify RIB/FIB for default vrf on {}".format(dut)) - for addr_type in ADDR_TYPES: - static_routes = { - dut: { - "static_routes": [ - { - "network": [ - NETWORK1_1[addr_type], - NETWORK2_1[addr_type], - NETWORK3_1[addr_type], - ], - "next_hop": "blackhole", - } - ] - } - } - - if value: - result = verify_bgp_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed \nError {}\n" "Routes {} still in BGP table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - - result = verify_rib( - tgen, addr_type, dut, static_routes, expected=False - ) - assert ( - result is not True - ), "Testcase {} : Failed Error {}" "Routes {} still in Route table".format( - tc_name, - result, - static_routes[dut]["static_routes"][0]["network"], - ) - else: - result = verify_bgp_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - result = verify_rib(tgen, addr_type, dut, static_routes) - assert result is True, "Testcase {} : Failed \n Error {}".format( - tc_name, result - ) - - write_test_footer(tc_name) - - -if __name__ == "__main__": - args = ["-s"] + sys.argv[1:] - sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf b/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf index 0540a62096..03dfbf9322 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf +++ b/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf @@ -1,11 +1,5 @@ hostname r1 - -#debug bgp vpn leak-to-vrf -#debug bgp vpn leak-from-vrf -#debug bgp nht - - router bgp 99 vrf DONNA no bgp ebgp-requires-policy address-family ipv4 unicast diff --git a/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf b/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf index 731a00829d..35038557df 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf +++ b/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf @@ -16,9 +16,3 @@ int dummy4 ip address 10.0.3.1/24 no shut ! -int EVA - no shut -! -int DONNA - no shut -! diff --git a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py index be07c85997..191a0b53ec 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py +++ b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py @@ -29,7 +29,6 @@ import os import sys from functools import partial import pytest -import time CWD = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CWD, "../")) @@ -78,117 +77,7 @@ def teardown_module(mod): tgen.stop_topology() -def check_bgp_rib(router, vrf, in_fib): - if in_fib: - attr = [{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}] - else: - attr = [{"protocol": "bgp", "nexthops": []}] - - if vrf == "DONNA": - expect = { - "10.0.0.0/24": [ - { - "protocol": "connected", - } - ], - "10.0.1.0/24": attr, - "10.0.2.0/24": [{"protocol": "connected"}], - "10.0.3.0/24": attr, - } - else: - expect = { - "10.0.0.0/24": attr, - "10.0.1.0/24": [ - { - "protocol": "connected", - } - ], - "10.0.2.0/24": attr, - "10.0.3.0/24": [ - { - "protocol": "connected", - } - ], - } - - test_func = partial( - topotest.router_json_cmp, router, "show ip route vrf %s json" % vrf, expect - ) - return topotest.run_and_expect(test_func, None, count=10, wait=0.5) - - -def check_bgp_fib(router, vrf, in_rib): - # Check FIB - # DONNA - # 10.0.1.0/24 dev EVA proto bgp metric 20 - # 10.0.3.0/24 dev EVA proto bgp metric 20 - # EVA - # 10.0.0.0/24 dev DONNA proto bgp metric 20 - # 10.0.2.0/24 dev DONNA proto bgp metric 20 - - if vrf == "DONNA": - table = 1001 - nh_vrf = "EVA" - else: - table = 1002 - nh_vrf = "DONNA" - - negate = "" if in_rib else "! " - - cmd = "%sip route show table %s | grep %s" % (negate, table, nh_vrf) - result = False - retry = 5 - output = "" - while retry: - retry -= 1 - try: - output = router.cmd_raises(cmd) - result = True - break - except: - time.sleep(0.1) - - logger.info("VRF %s leaked FIB content %s: %s", vrf, cmd, output) - - return result, output - - -def check_bgp_ping(router, vrf): - if vrf == "DONNA": - cmd = "ip vrf exec DONNA ping -c1 10.0.1.1 -I 10.0.0.1" - else: - cmd = "ip vrf exec EVA ping -c1 10.0.0.1 -I 10.0.1.1" - - result = False - retry = 5 - output = "" - while retry: - retry -= 1 - try: - output = router.cmd_raises(cmd) - result = True - break - except: - time.sleep(0.1) - - return result, output - - -def check_bgp_ping_own_ip(router): - cmd = "ip vrf exec DONNA ping -c1 10.0.0.1 -I 10.0.0.1" - - output = "" - try: - output = router.cmd_raises(cmd) - result = True - except: - result = False - pass - - return result, output - - -def test_vrf_route_leak_test1(): +def test_vrf_route_leak(): logger.info("Ensure that routes are leaked back and forth") tgen = get_topogen() # Don't run this test if we have any failure. @@ -197,86 +86,53 @@ def test_vrf_route_leak_test1(): r1 = tgen.gears["r1"] - result, output = check_bgp_ping_own_ip(r1) - assert ( - result - ), "Ping from VRF fails - check https://bugzilla.kernel.org/show_bug.cgi?id=203483\n:{}".format( - output - ) - - for vrf in ["EVA", "DONNA"]: - result, diff = check_bgp_rib(r1, vrf, True) - assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) - result, output = check_bgp_fib(r1, vrf, True) - assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) - result, output = check_bgp_ping(r1, vrf) - assert result, "Ping from VRF {} failed:\n{}".format(vrf, output) - + # Test DONNA VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "connected", + } + ], + "10.0.1.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + ], + "10.0.2.0/24": [{"protocol": "connected"}], + "10.0.3.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + ], + } -def test_vrf_route_leak_test2(): - logger.info( - "Ensure that leaked are still present after VRF iface IP address deletion" + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect ) - tgen = get_topogen() - # Don't run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - r1 = tgen.gears["r1"] - - logger.info("Adding and removing an IPv4 address to EVA and DONNA VRF ifaces") - r1.cmd("ip address add 1.1.1.1/32 dev EVA && ip address del 1.1.1.1/32 dev EVA") - r1.cmd("ip address add 2.2.2.2/32 dev DONNA && ip address del 2.2.2.2/32 dev DONNA") - - for vrf in ["EVA", "DONNA"]: - result, diff = check_bgp_rib(r1, vrf, True) - assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) - result, output = check_bgp_fib(r1, vrf, True) - assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) - result, output = check_bgp_ping(r1, vrf) - assert result, "Ping from VRF {} failed:\n{}".format(vrf, output) - - -def test_vrf_route_leak_test3(): - logger.info("Ensure that setting down the VRF ifaces invalidates leaked routes") - tgen = get_topogen() - # Don't run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - r1 = tgen.gears["r1"] + result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + # Test EVA VRF. + expect = { + "10.0.0.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + ], + "10.0.1.0/24": [ + { + "protocol": "connected", + } + ], + "10.0.2.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + ], + "10.0.3.0/24": [ + { + "protocol": "connected", + } + ], + } - logger.info("Setting down EVA and DONNA VRF ifaces") - r1.cmd("ip link set EVA down") - r1.cmd("ip link set DONNA down") - - for vrf in ["EVA", "DONNA"]: - result, diff = check_bgp_rib(r1, vrf, False) - assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) - result, output = check_bgp_fib(r1, vrf, False) - assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) - - -def test_vrf_route_leak_test4(): - logger.info("Ensure that setting up the VRF ifaces validates leaked routes") - tgen = get_topogen() - # Don't run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - r1 = tgen.gears["r1"] - - logger.info("Setting up EVA and DONNA VRF ifaces") - r1.cmd("ip link set EVA up") - r1.cmd("ip link set DONNA up") - - for vrf in ["EVA", "DONNA"]: - result, diff = check_bgp_rib(r1, vrf, True) - assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) - result, output = check_bgp_fib(r1, vrf, True) - assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) - result, output = check_bgp_ping(r1, vrf) - assert result, "Ping from VRF {} failed:\n{}".format(vrf, output) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert result, "BGP VRF EVA check failed:\n{}".format(diff) def test_memory_leak(): diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py index 332ffdf6d5..e92c1c30d1 100644 --- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py +++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py @@ -829,10 +829,11 @@ def test_RT_verification_auto_p0(request): } result = verify_rib(tgen, addr_type, "d2", input_routes, expected=False) - assert ( - result is not True - ), "Testcase {} :Failed \n Routes are still present: {}".format(tc_name, result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "d2", result) + ) step( "Revert back to original VNI number for all 3 VRFs on Edge-1 " @@ -965,12 +966,11 @@ def test_RT_verification_auto_p0(request): result = verify_attributes_for_evpn_routes( tgen, topo, "d2", input_routes_1, rt="auto", rt_peer="e1", expected=False ) - assert ( - result is not True - ), "Testcase {} :Failed \n Malfaromed Auto-RT value accepted: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Malformed Auto-RT value should not be accepted in {} \n " + "Found: {}".format(tc_name, "d2", result) ) - logger.info("Expected Behavior: {}".format(result)) step("Configure VNI number more than boundary limit (16777215)") @@ -1000,12 +1000,11 @@ def test_RT_verification_auto_p0(request): result = verify_attributes_for_evpn_routes( tgen, topo, "d2", input_routes_1, rt="auto", rt_peer="e1", expected=False ) - assert ( - result is not True - ), "Testcase {} :Failed \n Malfaromed Auto-RT value accepted: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Malformed Auto-RT value should not be accepted in {} \n " + "Found: {}".format(tc_name, "d2", result) ) - logger.info("Expected Behavior: {}".format(result)) step("Un-configure VNI number more than boundary limit (16777215)") diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py index b6a6037128..3ce6c6cb5c 100644 --- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py +++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py @@ -848,17 +848,17 @@ def test_RT_verification_manual_p0(request): } result = verify_rib(tgen, addr_type, "d1", input_routes, expected=False) assert result is not True, ( - "Testcase {} :Failed \n Expected Behavior: Routes are still " - "present \n Error: {}".format(tc_name, result) + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "d1", result) ) - logger.info("Expected Behavior: {}".format(result)) result = verify_rib(tgen, addr_type, "d2", input_routes, expected=False) assert result is not True, ( - "Testcase {} :Failed \n Expected Behavior: Routes are still " - "present \n Error: {}".format(tc_name, result) + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "d2", result) ) - logger.info("Expected Behavior: {}".format(result)) step( "Configure RT value as 100:100000010000010000101010 to check " @@ -900,10 +900,10 @@ def test_RT_verification_manual_p0(request): tgen, topo, dut, input_routes, rt="100:100000010000010000101010", expected=False ) assert result is not True, ( - "Testcase {} :Failed \n Expected Behavior: RT value of out" - " of boundary \n Error: {}".format(tc_name, result) + "Testcase {} : Failed \n " + "Expected: RT value out of boundary error in {} \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behavior: {}".format(result)) write_test_footer(tc_name) @@ -1316,18 +1316,20 @@ def test_evpn_routes_from_VNFs_p1(request): for addr_type in ADDR_TYPES: input_routes = {key: topo["routers"][key] for key in ["r1"]} result = verify_rib(tgen, addr_type, "d2", input_routes, expected=False) - assert ( - result is not True - ), "Testcase :Failed \n Routes are still present: {}".format(result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "d2", result) + ) for addr_type in ADDR_TYPES: input_routes = {key: topo["routers"][key] for key in ["r1"]} result = verify_rib(tgen, addr_type, "r3", input_routes, expected=False) - assert ( - result is not True - ), "Testcase {} :Failed \n Routes are still present: {}".format(tc_name, result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "r3", result) + ) step("Re-advertise IP prefixes from VFN(R1).") step( @@ -1401,16 +1403,18 @@ def test_evpn_routes_from_VNFs_p1(request): } result = verify_rib(tgen, addr_type, "d2", input_routes, expected=False) - assert ( - result is not True - ), "Testcase {} :Failed \n Routes are still present: {}".format(tc_name, result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "d2", result) + ) result = verify_rib(tgen, addr_type, "r4", input_routes, expected=False) - assert ( - result is not True - ), "Testcase {} :Failed \n Routes are still present: {}".format(tc_name, result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "r4", result) + ) step("Add vrf BLUE on router Edge-1 again.") interface = topo["routers"]["e1"]["links"]["r2-link1"]["interface"] @@ -1504,16 +1508,18 @@ def test_evpn_routes_from_VNFs_p1(request): } result = verify_rib(tgen, addr_type, "d2", input_routes, expected=False) - assert ( - result is not True - ), "Testcase {} :Failed \n Routes are still present: {}".format(tc_name, result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "d2", result) + ) result = verify_rib(tgen, addr_type, "r4", input_routes, expected=False) - assert ( - result is not True - ), "Testcase {} :Failed \n Routes are still present: {}".format(tc_name, result) - logger.info("Expected Behavior: {}".format(result)) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "r4", result) + ) step("Advertise IPv6 address-family in EVPN advertisements " "for VRF GREEN.") addr_type = "ipv6" diff --git a/tests/topotests/lib/bgprib.py b/tests/topotests/lib/bgprib.py index 01439373c5..35a57d0a99 100644 --- a/tests/topotests/lib/bgprib.py +++ b/tests/topotests/lib/bgprib.py @@ -37,7 +37,6 @@ from lib.lutil import luCommand, luResult, LUtil import json import re -import time # gpz: get rib in json form and compare against desired routes class BgpRib: @@ -49,15 +48,7 @@ class BgpRib: for pfx in pfxtbl.keys(): if debug: self.log("trying pfx %s" % pfx) - if "exist" in want and want["exist"] == False: - if pfx == want["p"]: - if debug: - self.log("unexpected route: pfx=" + want["p"]) - return 0 - if debug: - self.log("unwant pfx=" + want["p"] + ", not " + pfx) - continue - elif pfx != want["p"]: + if pfx != want["p"]: if debug: self.log("want pfx=" + want["p"] + ", not " + pfx) continue @@ -84,67 +75,53 @@ class BgpRib: if debug: self.log("missing route: pfx=" + want["p"] + ", nh=" + want["n"]) return 0 - if "exist" in want and want["exist"] == False: - return 1 - return 0 - def RequireVpnRoutes(self, target, title, wantroutes, retry=0, wait=1, debug=0): + def RequireVpnRoutes(self, target, title, wantroutes, debug=0): import json logstr = "RequireVpnRoutes " + str(wantroutes) - retry += 1 - while retry: - retry -= 1 - # non json form for humans - luCommand( - target, - 'vtysh -c "show bgp ipv4 vpn"', - ".", - "None", - "Get VPN RIB (non-json)", - ) - ret = luCommand( - target, - 'vtysh -c "show bgp ipv4 vpn json"', - ".*", - "None", - "Get VPN RIB (json)", - ) - if re.search(r"^\s*$", ret): - # degenerate case: empty json means no routes - if len(wantroutes) > 0: - luResult(target, False, title, logstr) - return - luResult(target, True, title, logstr) - rib = json.loads(ret) - rds = rib["routes"]["routeDistinguishers"] - for want in wantroutes: - found = 0 - if debug: - self.log("want rd %s" % want["rd"]) - for rd in rds.keys(): - if rd != want["rd"]: - continue - if debug: - self.log("found rd %s" % rd) - table = rds[rd] - if self.routes_include_wanted(table, want, debug): - found = 1 - break - if not found: - if retry: - break - luResult(target, False, title, logstr) - return - if not found and retry: - time.sleep(wait) - continue + # non json form for humans + luCommand( + target, + 'vtysh -c "show bgp ipv4 vpn"', + ".", + "None", + "Get VPN RIB (non-json)", + ) + ret = luCommand( + target, + 'vtysh -c "show bgp ipv4 vpn json"', + ".*", + "None", + "Get VPN RIB (json)", + ) + if re.search(r"^\s*$", ret): + # degenerate case: empty json means no routes + if len(wantroutes) > 0: + luResult(target, False, title, logstr) + return luResult(target, True, title, logstr) - break + rib = json.loads(ret) + rds = rib["routes"]["routeDistinguishers"] + for want in wantroutes: + found = 0 + if debug: + self.log("want rd %s" % want["rd"]) + for rd in rds.keys(): + if rd != want["rd"]: + continue + if debug: + self.log("found rd %s" % rd) + table = rds[rd] + if self.routes_include_wanted(table, want, debug): + found = 1 + break + if not found: + luResult(target, False, title, logstr) + return + luResult(target, True, title, logstr) - def RequireUnicastRoutes( - self, target, afi, vrf, title, wantroutes, retry=0, wait=1, debug=0 - ): + def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0): logstr = "RequireUnicastRoutes %s" % str(wantroutes) vrfstr = "" if vrf != "": @@ -153,62 +130,48 @@ class BgpRib: if (afi != "ipv4") and (afi != "ipv6"): self.log("ERROR invalid afi") - retry += 1 - while retry: - retry -= 1 - cmdstr = "show bgp %s %s unicast" % (vrfstr, afi) - # non json form for humans - cmd = 'vtysh -c "%s"' % cmdstr - luCommand( - target, cmd, ".", "None", "Get %s %s RIB (non-json)" % (vrfstr, afi) - ) - cmd = 'vtysh -c "%s json"' % cmdstr - ret = luCommand( - target, cmd, ".*", "None", "Get %s %s RIB (json)" % (vrfstr, afi) - ) - if re.search(r"^\s*$", ret): - # degenerate case: empty json means no routes - if len(wantroutes) > 0: - luResult(target, False, title, logstr) - return - luResult(target, True, title, logstr) - rib = json.loads(ret) - try: - table = rib["routes"] - # KeyError: 'routes' probably means missing/bad VRF - except KeyError as err: - if vrf != "": - errstr = "-script ERROR: check if wrong vrf (%s)" % (vrf) - else: - errstr = "-script ERROR: check if vrf missing" - if retry: - time.sleep(wait) - continue - luResult(target, False, title + errstr, logstr) + cmdstr = "show bgp %s %s unicast" % (vrfstr, afi) + # non json form for humans + cmd = 'vtysh -c "%s"' % cmdstr + luCommand(target, cmd, ".", "None", "Get %s %s RIB (non-json)" % (vrfstr, afi)) + cmd = 'vtysh -c "%s json"' % cmdstr + ret = luCommand( + target, cmd, ".*", "None", "Get %s %s RIB (json)" % (vrfstr, afi) + ) + if re.search(r"^\s*$", ret): + # degenerate case: empty json means no routes + if len(wantroutes) > 0: + luResult(target, False, title, logstr) return - # if debug: - # self.log("table=%s" % table) - for want in wantroutes: - if debug: - self.log("want=%s" % want) - if not self.routes_include_wanted(table, want, debug): - if retry: - time.sleep(wait) - continue - luResult(target, False, title, logstr) - return luResult(target, True, title, logstr) - break + rib = json.loads(ret) + try: + table = rib["routes"] + # KeyError: 'routes' probably means missing/bad VRF + except KeyError as err: + if vrf != "": + errstr = "-script ERROR: check if wrong vrf (%s)" % (vrf) + else: + errstr = "-script ERROR: check if vrf missing" + luResult(target, False, title + errstr, logstr) + return + # if debug: + # self.log("table=%s" % table) + for want in wantroutes: + if debug: + self.log("want=%s" % want) + if not self.routes_include_wanted(table, want, debug): + luResult(target, False, title, logstr) + return + luResult(target, True, title, logstr) BgpRib = BgpRib() -def bgpribRequireVpnRoutes(target, title, wantroutes, retry=0, wait=1, debug=0): - BgpRib.RequireVpnRoutes(target, title, wantroutes, retry, wait, debug) +def bgpribRequireVpnRoutes(target, title, wantroutes, debug=0): + BgpRib.RequireVpnRoutes(target, title, wantroutes, debug) -def bgpribRequireUnicastRoutes( - target, afi, vrf, title, wantroutes, retry=0, wait=1, debug=0 -): - BgpRib.RequireUnicastRoutes(target, afi, vrf, title, wantroutes, retry, wait, debug) +def bgpribRequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug=0): + BgpRib.RequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug) diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 676a5704e5..8ed37d1a82 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -81,6 +81,26 @@ DEBUG_LOGS = { "debug pim packets register", "debug pim nht", ], + "pim6d": [ + "debug pimv6 events", + "debug pimv6 packets", + "debug pimv6 packet-dump send", + "debug pimv6 packet-dump receive", + "debug pimv6 trace", + "debug pimv6 trace detail", + "debug pimv6 zebra", + "debug pimv6 bsm", + "debug pimv6 packets hello", + "debug pimv6 packets joins", + "debug pimv6 packets register", + "debug pimv6 nht", + "debug pimv6 nht detail", + "debug mroute6", + "debug mroute6 detail", + "debug mld events", + "debug mld packets", + "debug mld trace", + ], "bgpd": [ "debug bgp neighbor-events", "debug bgp updates", diff --git a/tests/topotests/lib/lutil.py b/tests/topotests/lib/lutil.py index 5c1fa24a7b..62c21e9ce4 100644 --- a/tests/topotests/lib/lutil.py +++ b/tests/topotests/lib/lutil.py @@ -50,6 +50,7 @@ class lUtil: l_line = 0 l_dotall_experiment = False l_last_nl = None + l_wait_strict = 1 fout = "" fsum = "" @@ -189,7 +190,7 @@ Total %-4d %-4d %d\n\ self.log("unable to read: " + tstFile) sys.exit(1) - def command(self, target, command, regexp, op, result, returnJson, startt=None): + def command(self, target, command, regexp, op, result, returnJson, startt=None, force_result=False): global net if op == "jsoncmp_pass" or op == "jsoncmp_fail": returnJson = True @@ -292,7 +293,7 @@ Total %-4d %-4d %d\n\ 9, ) if startt != None: - if js != None or ret is not False: + if js != None or ret is not False or force_result is not False: delta = time.time() - startt self.result(target, success, "%s +%4.2f secs" % (result, delta)) elif op == "pass" or op == "fail": @@ -322,12 +323,23 @@ Total %-4d %-4d %d\n\ n = 0 startt = time.time() + if (op == "wait-strict") or ((op == "wait") and self.l_wait_strict): + strict = True + else: + strict = False + # Calculate the amount of `sleep`s we are going to peform. wait_count = int(math.ceil(wait / wait_time)) + 1 + force_result = False while wait_count > 0: n += 1 - found = self.command(target, command, regexp, op, result, returnJson, startt) + + # log a failure on last iteration if we don't get desired regexp + if strict and (wait_count == 1): + force_result = True + + found = self.command(target, command, regexp, op, result, returnJson, startt, force_result) if found is not False: break @@ -378,12 +390,14 @@ def luCommand( returnJson=False, wait_time=0.5, ): - if op != "wait": - return LUtil.command(target, command, regexp, op, result, returnJson) - else: + waitops = ["wait", "wait-strict", "wait-nostrict"] + + if op in waitops: return LUtil.wait( target, command, regexp, op, result, time, returnJson, wait_time ) + else: + return LUtil.command(target, command, regexp, op, result, returnJson) def luLast(usenl=False): @@ -454,6 +468,25 @@ def luShowFail(): if printed > 0: logger.error("See %s for details of errors" % LUtil.fout_name) +# +# Sets default wait type for luCommand(op="wait) (may be overridden by +# specifying luCommand(op="wait-strict") or luCommand(op="wait-nostrict")). +# +# "nostrict" is the historical default behavior, which is to ignore +# failures to match the specified regexp in the specified time. +# +# "strict" means that failure to match the specified regexp in the +# specified time yields an explicit, logged failure result +# +def luSetWaitType(waittype): + if waittype == "strict": + LUtil.l_wait_strict = 1 + else: + if waittype == "nostrict": + LUtil.l_wait_strict = 0 + else: + raise ValueError('waittype must be one of "strict" or "nostrict"') + # for testing if __name__ == "__main__": diff --git a/tests/topotests/lib/micronet.py b/tests/topotests/lib/micronet.py index dfa10ccb2f..ba3d59823c 100644 --- a/tests/topotests/lib/micronet.py +++ b/tests/topotests/lib/micronet.py @@ -470,7 +470,8 @@ class LinuxNamespace(Commander): nslist = [] cmd = ["/usr/bin/unshare"] - flags = "-" + flags = "" + self.a_flags = [] self.ifnetns = {} if cgroup: @@ -487,6 +488,7 @@ class LinuxNamespace(Commander): flags += "n" if pid: nslist.append("pid") + flags += "f" flags += "p" cmd.append("--mount-proc") if time: @@ -499,9 +501,17 @@ class LinuxNamespace(Commander): cmd.append("--keep-caps") if uts: nslist.append("uts") - cmd.append("--uts") + flags += "u" - cmd.append(flags) + if flags: + aflags = flags.replace("f", "") + if aflags: + self.a_flags = ["-" + x for x in aflags] + cmd.extend(["-" + x for x in flags]) + + if pid: + cmd.append(commander.get_exec_path("tini")) + cmd.append("-vvv") cmd.append("/bin/cat") # Using cat and a stdin PIPE is nice as it will exit when we do. However, we @@ -516,7 +526,8 @@ class LinuxNamespace(Commander): stdin=subprocess.PIPE, stdout=open("/dev/null", "w"), stderr=open("/dev/null", "w"), - preexec_fn=os.setsid, # detach from pgid so signals don't propogate + text=True, + start_new_session=True, # detach from pgid so signals don't propagate shell=False, ) self.p = p @@ -550,7 +561,7 @@ class LinuxNamespace(Commander): assert not nslist, "unshare never unshared!" # Set pre-command based on our namespace proc - self.base_pre_cmd = ["/usr/bin/nsenter", "-a", "-t", str(self.pid)] + self.base_pre_cmd = ["/usr/bin/nsenter", *self.a_flags, "-t", str(self.pid)] if not pid: self.base_pre_cmd.append("-F") self.set_pre_cmd(self.base_pre_cmd + ["--wd=" + self.cwd]) @@ -743,7 +754,7 @@ class SharedNamespace(Commander): An object that executes commands in an existing pid's linux namespace """ - def __init__(self, name, pid, logger=None): + def __init__(self, name, pid, aflags=("-a",), logger=None): """ Share a linux namespace. @@ -757,10 +768,11 @@ class SharedNamespace(Commander): self.pid = pid self.intfs = [] + self.a_flags = aflags # Set pre-command based on our namespace proc self.set_pre_cmd( - ["/usr/bin/nsenter", "-a", "-t", str(self.pid), "--wd=" + self.cwd] + ["/usr/bin/nsenter", *self.a_flags, "-t", str(self.pid), "--wd=" + self.cwd] ) def __str__(self): @@ -769,7 +781,9 @@ class SharedNamespace(Commander): def set_cwd(self, cwd): # Set pre-command based on our namespace proc self.logger.debug("%s: new CWD %s", self, cwd) - self.set_pre_cmd(["/usr/bin/nsenter", "-a", "-t", str(self.pid), "--wd=" + cwd]) + self.set_pre_cmd( + ["/usr/bin/nsenter", *self.a_flags, "-t", str(self.pid), "--wd=" + cwd] + ) def register_interface(self, ifname): if ifname not in self.intfs: @@ -800,7 +814,7 @@ class Bridge(SharedNamespace): self.brid = "br{}".format(self.brid_ord) name = self.brid - super(Bridge, self).__init__(name, unet.pid, logger) + super(Bridge, self).__init__(name, unet.pid, aflags=unet.a_flags, logger=logger) self.logger.debug("Bridge: Creating") diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py index 7a57af7dbf..32dda82712 100644 --- a/tests/topotests/lib/pim.py +++ b/tests/topotests/lib/pim.py @@ -1136,16 +1136,18 @@ def verify_upstream_iif( if group_addr_json[src_address]["joinState"] != "Joined": errormsg = ( "[DUT %s]: Verifying iif " - "(Inbound Interface) for (%s,%s) and" - " joinState :%s [FAILED]!! " - " Expected: %s, Found: %s" + "(Inbound Interface) and joinState " + "for (%s, %s), Expected iif: %s, " + "Found iif : %s, and Expected " + "joinState :%s , Found joinState: %s" % ( dut, src_address, grp_addr, - group_addr_json[src_address]["joinState"], in_interface, group_addr_json[src_address]["inboundInterface"], + joinState, + group_addr_json[src_address]["joinState"], ) ) return errormsg @@ -1153,16 +1155,18 @@ def verify_upstream_iif( elif group_addr_json[src_address]["joinState"] != joinState: errormsg = ( "[DUT %s]: Verifying iif " - "(Inbound Interface) for (%s,%s) and" - " joinState :%s [FAILED]!! " - " Expected: %s, Found: %s" + "(Inbound Interface) and joinState " + "for (%s, %s), Expected iif: %s, " + "Found iif : %s, and Expected " + "joinState :%s , Found joinState: %s" % ( dut, src_address, grp_addr, - group_addr_json[src_address]["joinState"], in_interface, group_addr_json[src_address]["inboundInterface"], + joinState, + group_addr_json[src_address]["joinState"], ) ) return errormsg @@ -1171,16 +1175,18 @@ def verify_upstream_iif( if group_addr_json[src_address]["regState"] != regState: errormsg = ( "[DUT %s]: Verifying iif " - "(Inbound Interface) for (%s,%s) and" - " rejstate :%s [FAILED]!! " - " Expected: %s, Found: %s" + "(Inbound Interface) and regState " + "for (%s, %s), Expected iif: %s, " + "Found iif : %s, and Expected " + "regState :%s , Found regState: %s" % ( dut, src_address, grp_addr, - group_addr_json[src_address]["regState"], in_interface, group_addr_json[src_address]["inboundInterface"], + regState, + group_addr_json[src_address]["regState"], ) ) return errormsg @@ -1212,8 +1218,8 @@ def verify_upstream_iif( ) return errormsg - logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) - return True + logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) + return True @retry(retry_timeout=12) diff --git a/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp1.py b/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp1.py index 285f0dcebc..a6f876f066 100755 --- a/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp1.py +++ b/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp1.py @@ -268,9 +268,6 @@ def test_pim6_add_delete_static_RP_p0(request): check_router_status(tgen) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Shut link b/w R1 and R3 and R1 and R4 as per testcase topology") @@ -468,9 +465,6 @@ def test_pim6_SPT_RPT_path_same_p1(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Shut link b/w R1->R3, R1->R4 and R3->R1, R3->R4 as per " "testcase topology") @@ -644,9 +638,6 @@ def test_pim6_RP_configured_as_LHR_p1(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Enable MLD on r1 interface") @@ -779,9 +770,6 @@ def test_pim6_RP_configured_as_FHR_p1(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Enable MLD on r1 interface") @@ -910,9 +898,6 @@ def test_pim6_SPT_RPT_path_different_p1(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Enable MLD on r1 interface") @@ -1083,9 +1068,6 @@ def test_pim6_send_join_on_higher_preffered_rp_p1(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Enable MLD on r1 interface") diff --git a/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp2.py b/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp2.py index 6113635783..b615b9b824 100755 --- a/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp2.py +++ b/tests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp2.py @@ -75,6 +75,7 @@ from lib.common_config import ( socat_send_mld_join, socat_send_pim6_traffic, kill_socat, + create_debug_log_config, ) from lib.pim import ( create_pim_config, @@ -272,11 +273,17 @@ def test_pim6_multiple_groups_same_RP_address_p2(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) + input_dict = { + "r1": {"debug": {"log_file": "r1_debug.log", "enable": ["pim6d"]}}, + "r2": {"debug": {"log_file": "r2_debug.log", "enable": ["pim6d"]}}, + "r3": {"debug": {"log_file": "r3_debug.log", "enable": ["pim6d"]}}, + "r4": {"debug": {"log_file": "r4_debug.log", "enable": ["pim6d"]}}, + } + + result = create_debug_log_config(tgen, input_dict) + step("Enable MLD on r1 interface") step("Enable the PIM6 on all the interfaces of r1, r2, r3 and r4 routers") step("r2: Configure r2 as RP") @@ -594,9 +601,6 @@ def test_pim6_multiple_groups_different_RP_address_p2(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Enable MLD on r1 interface") @@ -673,17 +677,21 @@ def test_pim6_multiple_groups_different_RP_address_p2(request): step("r1: Verify (*, G) upstream IIF interface") dut = "r1" - iif = TOPO["routers"]["r1"]["links"]["r2"]["interface"] - result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) - assert result is True, ASSERT_MSG.format(tc_name, result) + iif1 = TOPO["routers"]["r1"]["links"]["r2"]["interface"] + iif2 = TOPO["routers"]["r1"]["links"]["r4"]["interface"] - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, STAR, group_address_list, addr_type="ipv6" - ) - assert result is True, ASSERT_MSG.format(tc_name, result) + for _iif, _group in zip([iif1, iif2], [GROUP_ADDRESS_LIST_1, GROUP_ADDRESS_LIST_2]): + result = verify_upstream_iif(tgen, dut, _iif, STAR, _group) + assert result is True, ASSERT_MSG.format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, _iif, STAR, _group, addr_type="ipv6" + ) + assert result is True, ASSERT_MSG.format(tc_name, result) step("r1: Verify (*, G) ip mroutes") + iif = TOPO["routers"]["r1"]["links"]["r2"]["interface"] oif = TOPO["routers"]["r1"]["links"]["r0"]["interface"] result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) assert result is True, ASSERT_MSG.format(tc_name, result) @@ -1189,9 +1197,6 @@ def test_pim6_delete_RP_shut_noshut_upstream_interface_p1(request): pytest.skip(tgen.errors) step("Creating configuration from JSON") - kill_socat(tgen) - clear_pim6_mroute(tgen) - clear_pim6_interface_traffic(tgen, TOPO) reset_config_on_routers(tgen) step("Enable MLD on r1 interface") diff --git a/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py b/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py index 83ed8a6360..1f62cb24c9 100644 --- a/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py +++ b/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py @@ -151,7 +151,7 @@ def setup_module(mod): # 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") + pytest.skip("Kernel version should be >= 4.15") testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) @@ -691,10 +691,10 @@ def test_BSR_CRP_with_blackhole_address_p1(request): result = verify_rib( tgen, "ipv4", "f1", input_routes, protocol="static", expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "Route is still present \n Error {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "f1", result) ) # Use scapy to send pre-defined packet from senser to receiver @@ -740,10 +740,10 @@ def test_BSR_CRP_with_blackhole_address_p1(request): step("Verify if b1 chosen as BSR in l1") result = verify_pim_bsr(tgen, topo, "l1", BSR_IP_1, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "b1 is not chosen as BSR in l1 \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: b1 should be chosen as BSR in {} \n " + "Found: {}".format(tc_name, "l1", result) ) state_after = get_pim_interface_traffic(tgen, state_dict) @@ -788,9 +788,8 @@ def test_BSR_CRP_with_blackhole_address_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "Routes:[{}, {}] are still present \n Error {}".format( - tc_name, BSR1_ADDR, CRP, result - ) + "Expected: Routes should not be present in {} RIB \n " + "Found: {}".format(tc_name, "f1", result) ) step("Sending BSR after removing black-hole address for BSR and candidate RP") @@ -915,9 +914,8 @@ def test_new_router_fwd_p0(request): result = verify_pim_bsr(tgen, topo, "l1", bsr_ip, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "BSR data is present after no-forward bsm also \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: BSR data should not be present after no-forward bsm \n " + "Found: {}".format(tc_name, "l1", result) ) # unconfigure unicast bsm on f1-i1-eth2 @@ -1042,10 +1040,10 @@ def test_int_bsm_config_p1(request): result = verify_mroutes( tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "Mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should be cleared from mroute table\n " + "Found: {}".format(tc_name, "i1", result) ) # unconfigure bsm processing on f1 on f1-i1-eth2 @@ -1066,10 +1064,10 @@ def test_int_bsm_config_p1(request): # Verify bsr state in i1 step("Verify if b1 is not chosen as BSR in i1") result = verify_pim_bsr(tgen, topo, "i1", bsr_ip, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "b1 is chosen as BSR in i1 \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: b1 should not be chosen as BSR \n " + "Found: {}".format(tc_name, "i1", result) ) # check if mroute still not installed because of rp not available @@ -1079,7 +1077,8 @@ def test_int_bsm_config_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "mroute installed but rp not available \n Error: {}".format(tc_name, result) + "Expected: [{}]: mroute (S, G) should not be installed as RP is not available\n " + "Found: {}".format(tc_name, "i1", result) ) # configure bsm processing on i1 on f1-i1-eth2 @@ -1536,11 +1535,10 @@ def test_BSM_timeout_p0(request): result = verify_pim_grp_rp_source( tgen, topo, "f1", group, rp_source="BSR", expected=False ) - - assert ( - result is not True - ), "Testcase {} : Failed \n " "bsr has not aged out in f1 \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: bsr should be aged out \n " + "Found: {}".format(tc_name, "f1", result) ) # Verify RP mapping removed after hold timer expires @@ -1567,9 +1565,8 @@ def test_BSM_timeout_p0(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "join state is up and join timer is running in l1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) # Verify ip mroute is not installed @@ -1577,10 +1574,10 @@ def test_BSM_timeout_p0(request): result = verify_mroutes( tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be installed \n " + "Found: {}".format(tc_name, dut, result) ) step("clear BSM database before moving to next case") @@ -1717,10 +1714,10 @@ def test_iif_join_state_p0(request): result = verify_rib( tgen, "ipv4", "l1", input_dict, protocol="static", expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "Routes:{} are still present \n Error {}".format( - tc_name, rp_ip, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} BGP RIB \n " + "Found: {}".format(tc_name, "l1", result) ) # Check RP unreachable @@ -1742,10 +1739,10 @@ def test_iif_join_state_p0(request): result = verify_mroutes( tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be installed \n " + "Found: {}".format(tc_name, dut, result) ) # Add back route for RP to make it reachable diff --git a/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py b/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py index 3da311a08f..9ad9f0021c 100644 --- a/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py +++ b/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py @@ -131,7 +131,7 @@ def setup_module(mod): # 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") + pytest.skip("Kernel version should be >= 4.15") testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) @@ -455,10 +455,10 @@ def test_starg_mroute_p0(request): 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 + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be installed \n " + "Found: {}".format(tc_name, dut, result) ) # Send BSM again to configure rp @@ -802,10 +802,10 @@ def test_BSR_election_p0(request): # 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 + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: b2 should not be chosen as bsr \n " + "Found: {}".format(tc_name, "f1", result) ) # Verify if b1 is still chosen as bsr diff --git a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py index eb841d6504..531fea95b4 100755 --- a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py +++ b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py @@ -159,7 +159,7 @@ def setup_module(mod): # Required linux kernel version for this suite to run. result = required_linux_kernel_version("4.19") if result is not True: - pytest.skip("Kernel requirements are not met") + pytest.skip("Kernel version should be >= 4.19") testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) @@ -880,12 +880,11 @@ def test_verify_mroute_when_same_receiver_joining_5_diff_sources_p0(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behavior: {}".format(result)) step( "Source which is stopped got removed , other source" @@ -1100,12 +1099,11 @@ def test_verify_mroute_when_frr_is_transit_router_p2(request): result = verify_mroutes( tgen, "c1", "*", IGMP_JOIN, "c1-c2-eth1", "c1-l1-eth0", expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (*, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, "c1", result) ) - logger.info("Expected Behavior: {}".format(result)) write_test_footer(tc_name) @@ -1209,12 +1207,11 @@ def test_verify_mroute_when_RP_unreachable_p1(request): result = verify_mroutes( tgen, "f1", "*", IGMP_JOIN, "f1-r2-eth3", "f1-i8-eth2", expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (*, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, "f1", result) ) - logger.info("Expected Behavior: {}".format(result)) step("IGMP groups are present verify using 'show ip igmp group'") dut = "l1" diff --git a/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py b/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py index 2775464a54..044f378fb0 100755 --- a/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py +++ b/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py @@ -157,7 +157,7 @@ def setup_module(mod): # Required linux kernel version for this suite to run. result = required_linux_kernel_version("4.19") if result is not True: - pytest.skip("Kernel requirements are not met") + pytest.skip("Kernel version should be >= 4.19") testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) @@ -454,12 +454,11 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behavior: {}".format(result)) write_test_footer(tc_name) @@ -663,12 +662,11 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behavior: {}".format(result)) write_test_footer(tc_name) @@ -1053,8 +1051,9 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request): tgen, "l1", "Unknown", source, IGMP_JOIN_RANGE_2, expected=False ) assert result is not True, ( - "Testcase {} : Failed Error: \n " - "mroutes are still present, after waiting for 10 mins".format(tc_name) + "Testcase {} : Failed \n " + "Expected: [{}]: Upstream IIF should be unknown \n " + "Found: {}".format(tc_name, "l1", result) ) step("No shut the Source interface just after the upstream is expired" " from FRR1") @@ -1085,12 +1084,11 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behavior: {}".format(result)) write_test_footer(tc_name) @@ -1410,9 +1408,11 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed Error: \nmroutes are still present".format(tc_name) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) + ) write_test_footer(tc_name) @@ -1607,12 +1607,11 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behavior: {}".format(result)) step( "No traffic impact observed on other receivers verify using" @@ -1820,12 +1819,11 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request "f1-i8-eth2", expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are" " still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behavior: {}".format(result)) result = verify_upstream_iif( tgen, "f1", "Unknown", "10.0.5.2", _IGMP_JOIN_RANGE, joinState="NotJoined" diff --git a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py index 721b30140b..16603ae2d5 100755 --- a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py +++ b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py @@ -171,7 +171,7 @@ def setup_module(mod): # Required linux kernel version for this suite to run. result = required_linux_kernel_version("4.19") if result is not True: - pytest.skip("Kernel requirements are not met") + pytest.skip("Kernel version should be >= 4.19") testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) @@ -549,12 +549,11 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): input_traffic = {"l1": {"traffic_sent": [intf_l1_i1]}} result = verify_multicast_traffic(tgen, input_traffic, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " " Traffic is not stopped yet \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Multicast traffic should be stopped \n " + "Found: {}".format(tc_name, "l1", result) ) - logger.info("Expected Behaviour: {}".format(result)) step( "IGMP groups are remove from FRR1 node 'show ip igmp groups'" @@ -565,12 +564,11 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): result = verify_igmp_groups( tgen, dut, intf_l1_i1, IGMP_JOIN_RANGE_1, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "IGMP groups are not deleted \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: IGMP groups should be deleted \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) dut = "f1" result = verify_igmp_groups(tgen, dut, intf_f1_i8, IGMP_JOIN_RANGE_1) @@ -609,12 +607,11 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) for data in input_dict_l1: result = verify_upstream_iif( @@ -627,9 +624,9 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream entries are still present \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF {} should not be present \n " + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) - logger.info("Expected Behaviour: {}".format(result)) input_dict_f1 = [ { @@ -677,12 +674,11 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}} result = verify_multicast_traffic(tgen, input_traffic, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " " Traffic is not stopped yet \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Multicast traffic should be stopped \n " + "Found: {}".format(tc_name, "f1", result) ) - logger.info("Expected Behaviour: {}".format(result)) step( "IGMP groups are remove from FRR1 node 'show ip igmp groups'" @@ -693,12 +689,11 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): result = verify_igmp_groups( tgen, dut, intf_f1_i8, IGMP_JOIN_RANGE_1, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "IGMP groups are not deleted \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: IGMP groups should be deleted \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) step( "(*,G) and (S,G) OIL got prune state (none) from all the nodes" @@ -732,12 +727,11 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) for data in input_dict_l1: result = verify_upstream_iif( @@ -750,9 +744,9 @@ def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream entries are still present \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF {} should not be present \n " + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) - logger.info("Expected Behaviour: {}".format(result)) shutdown_bringup_interface(tgen, "f1", intf_f1_i8, True) shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True) @@ -920,12 +914,11 @@ def test_verify_oil_when_join_prune_sent_scenario_2_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) input_dict_l1_r2 = [ { @@ -984,12 +977,11 @@ def test_verify_oil_when_join_prune_sent_scenario_2_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) step("After prune is sent verify upstream got removed in FRR1 node") @@ -1004,9 +996,9 @@ def test_verify_oil_when_join_prune_sent_scenario_2_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream entries are still present \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF {} should not be present \n " + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) - logger.info("Expected Behaviour: {}".format(result)) write_test_footer(tc_name) @@ -1143,12 +1135,11 @@ def test_shut_noshut_source_interface_when_upstream_cleared_from_LHR_p1(request) result = verify_mroutes( tgen, "f1", source_i2, IGMP_JOIN_RANGE_1, intf_f1_i2, intf_f1_r2, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n mroutes are" " still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, "f1", result) ) - logger.info("Expected Behavior: {}".format(result)) step( "After waiting for (S,G) timeout from FRR1 for same" @@ -1159,9 +1150,11 @@ def test_shut_noshut_source_interface_when_upstream_cleared_from_LHR_p1(request) result = verify_upstream_iif( tgen, "l1", "Unknown", source_i2, IGMP_JOIN_RANGE_1, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed Error: \n mroutes are still present".format(tc_name) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Upstream IIF should be Unknown \n " + "Found: {}".format(tc_name, "l1", result) + ) step("No shut the Source interface just after the upstream is expired" " from FRR1") shutdown_bringup_interface(tgen, "f1", intf_f1_i2, True) @@ -1352,9 +1345,11 @@ def test_shut_noshut_receiver_interface_when_upstream_cleared_from_LHR_p1(reques result = verify_upstream_iif( tgen, "l1", "Unknown", source_i2, IGMP_JOIN_RANGE_1, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed Error: \nmroutes are still present".format(tc_name) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Upstream IIF should be Unknown \n " + "Found: {}".format(tc_name, "l1", result) + ) step("No shut the Source interface just after the upstream is expired" " from FRR1") shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True) @@ -1556,12 +1551,11 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): dut = "l1" interface = topo["routers"]["l1"]["links"]["i1"]["interface"] result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN_RANGE_1, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n Groups are not" " present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: IGMP groups should not be present \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"] intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"] @@ -1655,12 +1649,11 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): dut = "l1" interface = topo["routers"]["l1"]["links"]["i1"]["interface"] result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN_RANGE_1, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n Groups are not" " present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: IGMP groups should not be present \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) result = verify_multicast_traffic(tgen, input_traffic) assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) @@ -1777,12 +1770,11 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request): result = verify_mroutes( tgen, dut, source, IGMP_JOIN_RANGE_1, iif, oil, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n routes are still" " present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) write_test_footer(tc_name) @@ -1962,12 +1954,11 @@ def test_verify_remove_add_igmp_commands_when_pim_configured_p0(request): ) result = verify_igmp_config(tgen, input_dict_1, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "IGMP interface is not removed \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: IGMP interface should be removed \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) step("Verify that no core is observed") if tgen.routers_have_failure(): @@ -2849,12 +2840,11 @@ def test_mroute_after_removing_RP_sending_IGMP_prune_p2(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroute still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) for data in input_dict_sg: result = verify_mroutes( @@ -2886,9 +2876,9 @@ def test_mroute_after_removing_RP_sending_IGMP_prune_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "IGMP groups still present still present \n Error: {}".format(tc_name, result) + "Expected: [{}]: IGMP groups should not present \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) step( "After receiving the IGMP prune from FRR1 , verify traffic " @@ -3180,12 +3170,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroute still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) for data in input_dict_sg_i1: result = verify_mroutes( @@ -3209,12 +3198,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "upstream still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Upstream IIF interface {} should not be present\n" + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) - logger.info("Expected Behaviour: {}".format(result)) for data in input_dict_sg_i1: result = verify_upstream_iif( @@ -3234,12 +3222,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "RP iif is not updated \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: RP IIF should be updated as Unknown \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) step("Verify mroute after No shut the link from LHR to RP from RP node") @@ -3366,8 +3353,9 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream is still present after shut the link from " - "FHR to RP from RP node \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF interface {} should not be present" + " after shutting link from RP to FHR \n" + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) step(" No shut the link from FHR to RP from RP node") @@ -3383,12 +3371,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "RP iif is not updated \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: RP IIF should be updated as Unknown \n" + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) step("Verify mroute after Noshut the link from FHR to RP from RP node") @@ -3515,8 +3502,9 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream is still present after shut the link from " - "FHR to RP from FHR node \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF interface {} should not be present" + " after shutting link from FHR to RP \n" + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) step(" No shut the link from FHR to RP from FHR node") @@ -3531,12 +3519,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "RP iif is not updated \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: RP IIF should be updated as Unknown \n" + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) step("Verify mroute after No Shut the link from FHR to RP from FHR node") @@ -3966,12 +3953,10 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): expected=False, ) assert result is not True, ( - "Testcase {} : Failed \n" - " Expected Behaviour: mroutes are cleared \n Error: {}".format( - tc_name, result - ) + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) shutdown_bringup_interface(tgen, "r2", intf_r2_i3, True) @@ -4035,12 +4020,11 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n" "mroutes are cleared \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True) @@ -4110,12 +4094,11 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) shutdown_bringup_interface(tgen, "r2", intf_r2_f1, True) @@ -4178,12 +4161,11 @@ def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request): result = verify_mroutes( tgen, dut, src_address, _IGMP_JOIN_RANGE, iif, oil, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected Behaviour: {}".format(result)) shutdown_bringup_interface(tgen, "l1", intf_l1_r2, True) @@ -4380,12 +4362,11 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) step("No shut the receiver(l1) port in 1 min interval") @@ -4446,12 +4427,11 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) step("No shut the source(r2) port in 1 min interval") @@ -4518,12 +4498,11 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n" " mroutes are cleared \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) - logger.info("Expected Behaviour: {}".format(result)) write_test_footer(tc_name) diff --git a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py index d209e42a81..91ee026022 100755 --- a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py +++ b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py @@ -136,7 +136,7 @@ def setup_module(mod): # Required linux kernel version for this suite to run. result = required_linux_kernel_version("4.19") if result is not True: - pytest.skip("Kernel requirements are not met") + pytest.skip("Kernel version should be >= 4.19") testsuite_run_time = time.asctime(time.localtime(time.time())) logger.info("Testsuite start time: {}".format(testsuite_run_time)) @@ -424,9 +424,8 @@ def test_mroute_when_RP_reachable_default_route_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "mroutes(S,G) are present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) result = verify_upstream_iif( @@ -439,9 +438,8 @@ def test_mroute_when_RP_reachable_default_route_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream is present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream IIF interface {} should not be present\n " + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) for data in input_dict_starg: @@ -456,9 +454,8 @@ def test_mroute_when_RP_reachable_default_route_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "mroutes(*,G) are present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) result = verify_upstream_iif( @@ -471,9 +468,8 @@ def test_mroute_when_RP_reachable_default_route_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "upstream is present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream IIF interface {} should not be present\n " + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) step("Configure default routes on c2") @@ -499,9 +495,9 @@ def test_mroute_when_RP_reachable_default_route_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "RP info is unknown after removing static route from c2 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: RP Info should not be Unknown after removing static" + " route from c2 \n" + "Found: {}".format(tc_name, data["dut"], result) ) step("Verify (s,g) populated after adding default route ") @@ -720,10 +716,10 @@ def test_mroute_with_RP_default_route_all_nodes_p2(request): data["oil"], expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (S, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, data["dut"], result) ) result = verify_upstream_iif( @@ -734,10 +730,10 @@ def test_mroute_with_RP_default_route_all_nodes_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "upstream is still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Upstream IIF interface {} should not be present\n " + "Found: {}".format(tc_name, data["dut"], data["iif"], result) ) step("Configure default routes on all the nodes") @@ -777,9 +773,9 @@ def test_mroute_with_RP_default_route_all_nodes_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "RP info is unknown after removing static route from c2 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: RP Info should not be Unknown after removing static" + " route from c2 \n" + "Found: {}".format(tc_name, data["dut"], result) ) step("Verify (s,g) populated after adding default route ") diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py index e5182fbecf..772f0751ef 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py @@ -375,9 +375,8 @@ def test_add_delete_static_RP_p0(request): result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: igmp group present without any IGMP join \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: IGMP groups should not be present without any IGMP join\n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Verify show ip pim interface traffic without any IGMP join") @@ -445,17 +444,18 @@ def test_add_delete_static_RP_p0(request): result = verify_pim_rp_info( tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: RP info present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: RP info should not be present \n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Verify upstream IIF interface") result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream IIF interface present \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF interface {} should not be present\n " + "Found: {}".format(tc_name, dut, iif, result) ) step("r1: Verify upstream join state and join timer") @@ -464,24 +464,25 @@ def test_add_delete_static_RP_p0(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream join state is up and join timer is running \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) # 20 step("r1: Verify PIM state") result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) - assert result is not True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: PIM state should not be up \n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Verify ip mroutes") result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (*, G) should not be present \n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Verify show ip pim interface traffic without any IGMP join") @@ -638,9 +639,8 @@ def test_SPT_RPT_path_same_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -767,16 +767,16 @@ def test_not_reachable_static_RP_p0(request): result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "OIL is not same and IIF is not cleared on R1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: OIL should be same and IIF should be cleared\n " + "Found: {}".format(tc_name, dut, result) ) step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream") result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream IIF is not unknown \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF interface {} should be unknown \n " + "Found: {}".format(tc_name, dut, iif, result) ) step( @@ -788,9 +788,8 @@ def test_not_reachable_static_RP_p0(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r1: join state is joined and timer is not stopped \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step( @@ -811,11 +810,9 @@ def test_not_reachable_static_RP_p0(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: (*, G) are not cleared from mroute table \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared from mroute table\n " + "Found: {}".format(tc_name, dut, result) ) - logger.info("Expected behavior: %s", result) # Uncomment next line for debugging # tgen.mininet_cli() @@ -877,10 +874,10 @@ def test_add_RP_after_join_received_p1(request): result = verify_pim_rp_info( tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False ) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: rp-info is present \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: RP-info should not be present \n " + "Found: {}".format(tc_name, dut, result) ) step("joinTx value before join sent") @@ -905,7 +902,8 @@ def test_add_RP_after_join_received_p1(request): result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream IFF interface is present \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF interface {} should not be present \n " + "Found: {}".format(tc_name, dut, iif, result) ) step("r1: Verify upstream join state and join timer") @@ -915,25 +913,24 @@ def test_add_RP_after_join_received_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream join state is joined and timer is running \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Verify PIM state") result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: PIM state should not be up\n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Verify ip mroutes") result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (*, G) should not be present in mroute table \n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Configure static RP") @@ -1058,7 +1055,8 @@ def test_reachable_static_RP_after_join_p0(request): result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream IIF interface is present\n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream IIF interface {} should not be present \n " + "Found: {}".format(tc_name, dut, iif, result) ) step("r1 : Verify upstream join state and join timer") @@ -1067,25 +1065,24 @@ def test_reachable_static_RP_after_join_p0(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r1: upstream join state is joined and timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r1 : Verify PIM state") result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: PIM state should not be up \n " + "Found: {}".format(tc_name, dut, result) ) step("r1 : Verify ip mroutes") result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert ( - result is not True - ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: mroute (*, G) should not be present \n " + "Found: {}".format(tc_name, dut, result) ) step("r1: Make RP reachable") @@ -1329,9 +1326,8 @@ def test_send_join_on_higher_preffered_rp_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r1: rp-info is present for group 225.1.1.1 \n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: RP-info should not be present \n " + "Found: {}".format(tc_name, dut, result) ) step( diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py index dbeaa9b8f9..06f3c4110b 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py @@ -536,8 +536,9 @@ def test_RP_configured_as_LHR_1_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S, G) upstream join state is joined and join" - " timer is running \n Error: {}".format(tc_name, result) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -741,9 +742,9 @@ def test_RP_configured_as_LHR_2_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -947,9 +948,9 @@ def test_RP_configured_as_FHR_1_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1154,9 +1155,9 @@ def test_RP_configured_as_FHR_2_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1279,9 +1280,9 @@ def test_SPT_RPT_path_different_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1303,9 +1304,9 @@ def test_SPT_RPT_path_different_p1(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (S, G) ip mroutes") diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py index ef638bc964..088b54e33e 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py @@ -452,9 +452,9 @@ def test_restart_pimd_process_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -620,9 +620,9 @@ def test_multiple_groups_same_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -644,9 +644,9 @@ def test_multiple_groups_same_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (S, G) ip mroutes") @@ -765,9 +765,9 @@ def test_multiple_groups_same_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (S, G) ip mroutes") @@ -787,9 +787,9 @@ def test_multiple_groups_same_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -963,9 +963,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (S, G) ip mroutes") @@ -985,9 +985,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1053,9 +1053,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r4: Verify (S, G) ip mroutes") @@ -1073,8 +1073,11 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False ) - assert result is not True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1224,9 +1227,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (S, G) ip mroutes") @@ -1246,9 +1249,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1314,9 +1317,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r4: Verify (S, G) ip mroutes") @@ -1336,9 +1339,9 @@ def test_multiple_groups_different_RP_address_p2(request): ) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: Upstream Join State should not be Joined and " + "join timer should not run\n " + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (S, G) ip mroutes") @@ -1462,9 +1465,8 @@ def test_shutdown_primary_path_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared \n" + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (*, G) ip mroutes") @@ -1474,9 +1476,8 @@ def test_shutdown_primary_path_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared \n" + "Found: {}".format(tc_name, dut, result) ) step("r3: Verify (*, G) ip mroutes") @@ -1486,9 +1487,9 @@ def test_shutdown_primary_path_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r3: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared after shutting" + "link from R1 to R3 \n" + "Found: {}".format(tc_name, dut, result) ) step("r3: No shutdown the link from R1 to R3 from R3 node") @@ -1647,9 +1648,9 @@ def test_delete_RP_shut_noshut_upstream_interface_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared after shutting" + "link from R1 to R0 \n" + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (*, G) ip mroutes cleared") @@ -1659,9 +1660,9 @@ def test_delete_RP_shut_noshut_upstream_interface_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared after shutting" + "link from R1 to R0 \n" + "Found: {}".format(tc_name, dut, result) ) write_test_footer(tc_name) @@ -1770,9 +1771,9 @@ def test_delete_RP_shut_noshut_RP_interface_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r1: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared after shutting" + "link from R2 to R3 \n" + "Found: {}".format(tc_name, dut, result) ) step("r2: Verify (*, G) ip mroutes cleared") @@ -1782,9 +1783,9 @@ def test_delete_RP_shut_noshut_RP_interface_p1(request): result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) assert result is not True, ( "Testcase {} : Failed \n " - "r2: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( - tc_name, result - ) + "Expected: [{}]: mroute (*, G) should be cleared after shutting" + "link from R2 to R3 \n" + "Found: {}".format(tc_name, dut, result) ) write_test_footer(tc_name) diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt index 6bafbbb556..86c089ab3b 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt @@ -5,5 +5,5 @@ B>* 10.0.3.0/24 [20/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r1-eth1, XX:XX:XX -B>* 10.0.30.0/24 [20/0] is directly connected, neno (vrf neno), weight 1, XX:XX:XX +B>* 10.0.30.0/24 [20/0] is directly connected, r1-eth2 (vrf neno), weight 1, XX:XX:XX O>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt index 3ed6b1b3a1..9681d8a04e 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt @@ -7,4 +7,4 @@ B>* 10.0.4.0/24 [20/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r2-eth1, XX:XX:XX O>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX -B>* 10.0.40.0/24 [20/0] is directly connected, ray (vrf ray), weight 1, XX:XX:XX +B>* 10.0.40.0/24 [20/0] is directly connected, r2-eth2 (vrf ray), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index 4ad8441d85..ce9903ae71 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -1,9 +1,9 @@ VRF ray: B 10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX -B 10.0.2.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX -B 10.0.20.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX C>* 10.0.40.0/24 is directly connected, r2-eth2, XX:XX:XX diff --git a/tests/topotests/pim_basic/test_pim.py b/tests/topotests/pim_basic/test_pim.py index 2c1bc52d09..ca01a56636 100644 --- a/tests/topotests/pim_basic/test_pim.py +++ b/tests/topotests/pim_basic/test_pim.py @@ -125,7 +125,7 @@ def test_pim_rp_setup(): test_func = partial( topotest.router_json_cmp, r1, "show ip pim rp-info json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=15, wait=5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assertmsg = '"{}" JSON output mismatches'.format(r1.name) assert result is None, assertmsg # tgen.mininet_cli() @@ -148,13 +148,13 @@ def test_pim_send_mcast_stream(): # 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( + "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r2-eth0 > /tmp/bar".format( CWD ) ) # And from r3 -> r1 r3.run( - "{}/mcast-tx.py --ttl 5 --count 5 --interval 10 229.1.1.1 r3-eth0 > /tmp/bar".format( + "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r3-eth0 > /tmp/bar".format( CWD ) ) @@ -175,7 +175,7 @@ def test_pim_send_mcast_stream(): test_func = partial( topotest.router_json_cmp, r1, "show ip pim upstream json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=1) assert result is None, "failed to converge pim" # tgen.mininet_cli() @@ -191,7 +191,7 @@ def test_pim_rp_sees_stream(): test_func = partial( topotest.router_json_cmp, rp, "show ip pim upstream json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=1) assertmsg = '"{}" JSON output mismatches'.format(rp.name) assert result is None, assertmsg @@ -225,7 +225,7 @@ def test_pim_igmp_report(): test_func = partial( topotest.router_json_cmp, r1, "show ip pim upstream json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=1) assertmsg = '"{}" JSON output mismatches'.format(r1.name) assert result is None, assertmsg finally: diff --git a/tests/topotests/pim_igmp_vrf/test_pim_vrf.py b/tests/topotests/pim_igmp_vrf/test_pim_vrf.py index f845a4a6ee..64001deade 100755 --- a/tests/topotests/pim_igmp_vrf/test_pim_vrf.py +++ b/tests/topotests/pim_igmp_vrf/test_pim_vrf.py @@ -166,6 +166,11 @@ def setup_module(module): tgen = Topogen(build_topo, module.__name__) tgen.start_topology() + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("4.19") + if result is not True: + pytest.skip("Kernel requirements are not met") + vrf_setup_cmds = [ "ip link add name blue type vrf table 11", "ip link add name red type vrf table 12", @@ -210,11 +215,6 @@ def test_ospf_convergence(): "Test for OSPFv2 convergence" tgen = get_topogen() - # 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") diff --git a/tests/topotests/route_scale/scale_test_common.py b/tests/topotests/route_scale/scale_test_common.py index 856a2d0fa7..b9f324d561 100644 --- a/tests/topotests/route_scale/scale_test_common.py +++ b/tests/topotests/route_scale/scale_test_common.py @@ -178,7 +178,7 @@ def route_install_helper(iter): # Table of defaults, used for timeout values and 'expected' objects scale_defaults = dict( - zip(scale_keys, [None, None, 7, 30, expected_installed, expected_removed]) + zip(scale_keys, [None, None, 10, 50, expected_installed, expected_removed]) ) # List of params for each step in the test; note extra time given diff --git a/tests/topotests/zebra_netlink/test_zebra_netlink.py b/tests/topotests/zebra_netlink/test_zebra_netlink.py index ca90c5cb15..6d7b99291a 100644 --- a/tests/topotests/zebra_netlink/test_zebra_netlink.py +++ b/tests/topotests/zebra_netlink/test_zebra_netlink.py @@ -109,7 +109,7 @@ def test_zebra_netlink_batching(tgen): pfx = str(ipaddress.ip_network((i, 32))) match[pfx] = [dict(entry, prefix=pfx)] - ok = topotest.router_json_cmp_retry(r1, "show ip route json", match) + ok = topotest.router_json_cmp_retry(r1, "show ip route json", match, False, 30) assert ok, '"r1" JSON output mismatches' r1.vtysh_cmd("sharp remove routes 2.1.3.7 " + str(count)) |
