summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/topotests/bfd_topo3/r3/bfd-static-down.json12
-rw-r--r--tests/topotests/bfd_topo3/r3/bfd-static.json13
-rw-r--r--tests/topotests/bfd_topo3/r3/staticd.conf1
-rw-r--r--tests/topotests/bfd_topo3/r4/bfd-peers.json48
-rw-r--r--tests/topotests/bfd_topo3/r4/bgpd.conf1
-rw-r--r--tests/topotests/bfd_topo3/r4/staticd.conf2
-rw-r--r--tests/topotests/bfd_topo3/r4/zebra.conf4
-rw-r--r--tests/topotests/bfd_topo3/r5/bfd-peers.json23
-rw-r--r--tests/topotests/bfd_topo3/r5/bfdd.conf11
-rw-r--r--tests/topotests/bfd_topo3/r5/staticd.conf2
-rw-r--r--tests/topotests/bfd_topo3/r5/zebra.conf10
-rw-r--r--tests/topotests/bfd_topo3/r6/bfd-peers.json46
-rw-r--r--tests/topotests/bfd_topo3/r6/bfd-static-down.json19
-rw-r--r--tests/topotests/bfd_topo3/r6/bfd-static.json19
-rw-r--r--tests/topotests/bfd_topo3/r6/bfdd.conf11
-rw-r--r--tests/topotests/bfd_topo3/r6/staticd.conf5
-rw-r--r--tests/topotests/bfd_topo3/r6/zebra.conf10
-rw-r--r--tests/topotests/bfd_topo3/test_bfd_topo3.dot22
-rw-r--r--tests/topotests/bfd_topo3/test_bfd_topo3.jpgbin34705 -> 42789 bytes
-rw-r--r--tests/topotests/bfd_topo3/test_bfd_topo3.py90
-rw-r--r--tests/topotests/bgp_accept_own/pe1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_accept_own/pe1/zebra.conf3
-rw-r--r--tests/topotests/bgp_accept_own/test_bgp_accept_own.py47
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py14
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf48
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf6
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf11
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py21
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py50
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py77
-rw-r--r--tests/topotests/bgp_path_attribute_discard/__init__.py0
-rw-r--r--tests/topotests/bgp_path_attribute_discard/exabgp.env53
-rw-r--r--tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg24
-rw-r--r--tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf6
-rw-r--r--tests/topotests/bgp_path_attribute_discard/r1/zebra.conf4
-rw-r--r--tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py159
-rw-r--r--tests/topotests/bgp_sender_as_path_loop_detection/r1/bgpd.conf23
-rw-r--r--tests/topotests/bgp_sender_as_path_loop_detection/r1/zebra.conf1
-rw-r--r--tests/topotests/bgp_sender_as_path_loop_detection/r2/bgpd.conf15
-rw-r--r--tests/topotests/bgp_sender_as_path_loop_detection/r3/bgpd.conf6
-rw-r--r--tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py48
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/bgpd.conf0
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/staticd.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/c31/zebra.conf6
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/bgpd.conf0
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/staticd.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/c32/zebra.conf6
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/bgpd.conf15
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/staticd.conf3
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r1/zebra.conf9
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/bgpd.conf10
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/staticd.conf3
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r2/zebra.conf2
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/bgpd.conf52
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/staticd.conf6
-rw-r--r--tests/topotests/bgp_srv6l3vpn_over_ipv6/r3/zebra.conf29
-rwxr-xr-xtests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py46
-rw-r--r--tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json2
-rw-r--r--tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json2
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py407
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py932
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py932
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py1909
-rw-r--r--tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf6
-rw-r--r--tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf6
-rw-r--r--tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py234
-rw-r--r--tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py27
-rw-r--r--tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py72
-rw-r--r--tests/topotests/lib/bgprib.py193
-rw-r--r--tests/topotests/lib/common_config.py20
-rw-r--r--tests/topotests/lib/lutil.py45
-rw-r--r--tests/topotests/lib/micronet.py32
-rw-r--r--tests/topotests/lib/pim.py34
-rwxr-xr-xtests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp1.py18
-rwxr-xr-xtests/topotests/multicast_pim6_static_rp_topo1/test_multicast_pim6_static_rp2.py39
-rw-r--r--tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py85
-rw-r--r--tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py18
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py29
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py60
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py277
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py50
-rwxr-xr-xtests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py120
-rwxr-xr-xtests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py35
-rwxr-xr-xtests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py119
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt4
-rw-r--r--tests/topotests/pim_basic/test_pim.py12
-rwxr-xr-xtests/topotests/pim_igmp_vrf/test_pim_vrf.py10
-rw-r--r--tests/topotests/route_scale/scale_test_common.py2
-rw-r--r--tests/topotests/zebra_netlink/test_zebra_netlink.py2
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
index 6b532560bf..f100eae712 100644
--- a/tests/topotests/bfd_topo3/test_bfd_topo3.jpg
+++ b/tests/topotests/bfd_topo3/test_bfd_topo3.jpg
Binary files differ
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))