diff options
Diffstat (limited to 'tests')
27 files changed, 762 insertions, 285 deletions
diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py b/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py index ebd6075b52..459af486ff 100644 --- a/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py +++ b/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py @@ -102,12 +102,12 @@ def test_bgp_as_wide_bgp_identifier(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, tgen.gears["r1"]) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=260, wait=0.5) assert result is None, 'Failed to converge: "{}"'.format(tgen.gears["r1"]) test_func = functools.partial(_bgp_failed, tgen.gears["r3"]) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=260, wait=0.5) assert result is None, 'Bad BGP Identifier notification not sent: "{}"'.format( tgen.gears["r3"] diff --git a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py index 18e36311ad..5c2af2b30b 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py +++ b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py @@ -121,7 +121,7 @@ def test_ebgp_requires_policy(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, "r2") - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=65, wait=2) assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(tgen.gears["r2"]) test_func = functools.partial(_bgp_has_routes, "r2") @@ -129,7 +129,7 @@ def test_ebgp_requires_policy(): assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(tgen.gears["r2"]) test_func = functools.partial(_bgp_converge, "r4") - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=65, wait=2) assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(tgen.gears["r4"]) test_func = functools.partial(_bgp_has_routes, "r4") @@ -137,7 +137,7 @@ def test_ebgp_requires_policy(): assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(tgen.gears["r4"]) test_func = functools.partial(_bgp_converge, "r6") - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=65, wait=2) assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(tgen.gears["r6"]) test_func = functools.partial(_bgp_has_routes, "r6") diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 69c807f300..2ba0c68c2f 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -868,7 +868,7 @@ def verify_router_id(tgen, topo, input_dict): return True -@retry(attempts=20, wait=2, return_is_str=True) +@retry(attempts=44, wait=3, return_is_str=True) def verify_bgp_convergence(tgen, topo, dut=None): """ API will verify if BGP is converged with in the given time frame. diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index 414dc17874..efd5b90685 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -658,7 +658,7 @@ class TopoRouter(TopoGear): Possible daemon values are: TopoRouter.RD_ZEBRA, TopoRouter.RD_RIP, TopoRouter.RD_RIPNG, TopoRouter.RD_OSPF, TopoRouter.RD_OSPF6, TopoRouter.RD_ISIS, TopoRouter.RD_BGP, TopoRouter.RD_LDP, - TopoRouter.RD_PIM. + TopoRouter.RD_PIM, TopoRouter.RD_PBR. """ daemonstr = self.RD.get(daemon) self.logger.info('loading "{}" configuration: {}'.format(daemonstr, source)) @@ -1064,6 +1064,7 @@ def diagnose_env_linux(): "isisd", "pimd", "ldpd", + "pbrd" ]: path = os.path.join(frrdir, fname) if not os.path.isfile(path): @@ -1121,6 +1122,7 @@ def diagnose_env_linux(): "ripngd", "isisd", "pimd", + "pbrd" ]: path = os.path.join(quaggadir, fname) if not os.path.isfile(path): diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 6262082193..9d945d5262 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -727,6 +727,57 @@ def ip6_route(node): return result +def ip_rules(node): + """ + Gets a structured return of the command 'ip rule'. It can be used in + conjuction with json_cmp() to provide accurate assert explanations. + + Return example: + [ + { + "pref": "0" + "from": "all" + }, + { + "pref": "32766" + "from": "all" + }, + { + "to": "3.4.5.0/24", + "iif": "r1-eth2", + "pref": "304", + "from": "1.2.0.0/16", + "proto": "zebra" + } + ] + """ + output = normalize_text(node.run("ip rule")).splitlines() + result = [] + for line in output: + columns = line.split(" ") + + route = {} + # remove last character, since it is ':' + pref = columns[0][:-1] + route["pref"] = pref + prev = None + for column in columns: + if prev == "from": + route["from"] = column + if prev == "to": + route["to"] = column + if prev == "proto": + route["proto"] = column + if prev == "iif": + route["iif"] = column + if prev == "fwmark": + route["fwmark"] = column + prev = column + + result.append(route) + return result + + def sleep(amount, reason=None): """ Sleep wrapper that registers in the log the amount of sleep diff --git a/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json index 4ffca6f940..0416bd6ce2 100644 --- a/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json +++ b/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json @@ -15,9 +15,18 @@ "prefix":"10.0.255.2\/32", "sid":200, "inputLabel":20200, - "outputLabel":"pop", - "interface":"r1-eth0", - "nexthop":"10.0.1.2" + "prefixRoute":[ + { + "outputLabel":3, + "interface":"r1-eth0", + "nexthop":"10.0.0.2" + }, + { + "outputLabel":3, + "interface":"r1-eth1", + "nexthop":"10.0.1.2" + } + ] } ] }, @@ -36,9 +45,18 @@ "prefix":"10.0.255.4\/32", "sid":400, "inputLabel":20400, - "outputLabel":"8400", - "interface":"r1-eth0", - "nexthop":"10.0.1.2" + "prefixRoute":[ + { + "outputLabel":8400, + "interface":"r1-eth0", + "nexthop":"10.0.0.2" + }, + { + "outputLabel":8400, + "interface":"r1-eth1", + "nexthop":"10.0.1.2" + } + ] } ] }, @@ -47,19 +65,24 @@ "srgbSize":10000, "srgbLabel":10000, "algorithms":[ - { - "0":"SPF" - } ], - "nodeMsd":8, "extendedPrefix":[ { "prefix":"10.0.255.3\/32", "sid":300, "inputLabel":20300, - "outputLabel":"8300", - "interface":"r1-eth0", - "nexthop":"10.0.1.2" + "prefixRoute":[ + { + "outputLabel":8300, + "interface":"r1-eth0", + "nexthop":"10.0.0.2" + }, + { + "outputLabel":8300, + "interface":"r1-eth1", + "nexthop":"10.0.1.2" + } + ] } ] }, @@ -78,26 +101,46 @@ "prefix":"10.0.255.1\/32", "sid":100, "inputLabel":20100, - "outputLabel":"pop", - "interface":"lo", - "nexthop":"10.0.255.1" + "prefixRoute":[ + { + "outputLabel":3, + "interface":"lo", + "nexthop":"10.0.255.1" + } + ] } ], "extendedLink":[ { - "prefix":"10.0.1.1\/32", - "sid":50001, - "inputLabel":50001, - "outputLabel":"pop", + "prefix":"10.0.0.1\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r1-eth0", + "nexthop":"10.0.0.2" + }, + { + "prefix":"10.0.0.1\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, "interface":"r1-eth0", + "nexthop":"10.0.0.2" + }, + { + "prefix":"10.0.1.1\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r1-eth1", "nexthop":"10.0.1.2" }, { "prefix":"10.0.1.1\/32", - "sid":50000, - "inputLabel":50000, - "outputLabel":"pop", - "interface":"r1-eth0", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r1-eth1", "nexthop":"10.0.1.2" } ] diff --git a/tests/topotests/ospf-sr-topo1/r1/ospfd.conf b/tests/topotests/ospf-sr-topo1/r1/ospfd.conf index e8593d1a1a..292d4e6367 100644 --- a/tests/topotests/ospf-sr-topo1/r1/ospfd.conf +++ b/tests/topotests/ospf-sr-topo1/r1/ospfd.conf @@ -3,6 +3,11 @@ interface lo ip ospf area 0.0.0.0 ! interface r1-eth0 + ip ospf network point-to-point + ip ospf area 0.0.0.0 +! +interface r1-eth1 + ip ospf network point-to-point ip ospf area 0.0.0.0 ! router ospf diff --git a/tests/topotests/ospf-sr-topo1/r1/zebra.conf b/tests/topotests/ospf-sr-topo1/r1/zebra.conf index f1fcc7dd3b..faf71db25c 100644 --- a/tests/topotests/ospf-sr-topo1/r1/zebra.conf +++ b/tests/topotests/ospf-sr-topo1/r1/zebra.conf @@ -3,6 +3,9 @@ interface lo ip address 10.0.255.1/32 ! interface r1-eth0 + ip address 10.0.0.1/24 +! +interface r1-eth1 ip address 10.0.1.1/24 ! ip forwarding diff --git a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json index 6b1fe76b6e..5ae2399e5c 100644 --- a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json +++ b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json @@ -1,5 +1,5 @@ -{ - "20100":{ +[ + { "inLabel":20100, "installed":true, "nexthops":[ @@ -7,12 +7,11 @@ "type":"SR (OSPF)", "outLabel":3, "distance":150, - "installed":true, - "nexthop":"10.0.255.1" + "installed":true } ] }, - "20200":{ + { "inLabel":20200, "installed":true, "nexthops":[ @@ -22,10 +21,17 @@ "distance":150, "installed":true, "nexthop":"10.0.1.2" + }, + { + "type":"SR (OSPF)", + "outLabel":3, + "distance":150, + "installed":true, + "nexthop":"10.0.0.2" } ] }, - "20300":{ + { "inLabel":20300, "installed":true, "nexthops":[ @@ -35,10 +41,17 @@ "distance":150, "installed":true, "nexthop":"10.0.1.2" + }, + { + "type":"SR (OSPF)", + "outLabel":8300, + "distance":150, + "installed":true, + "nexthop":"10.0.0.2" } ] }, - "20400":{ + { "inLabel":20400, "installed":true, "nexthops":[ @@ -48,11 +61,44 @@ "distance":150, "installed":true, "nexthop":"10.0.1.2" + }, + { + "type":"SR (OSPF)", + "outLabel":8400, + "distance":150, + "installed":true, + "nexthop":"10.0.0.2" + } + ] + }, + { + "inLabel":"*", + "installed":true, + "nexthops":[ + { + "type":"SR (OSPF)", + "outLabel":3, + "distance":150, + "installed":true, + "nexthop":"10.0.0.2" + } + ] + }, + { + "inLabel":"*", + "installed":true, + "nexthops":[ + { + "type":"SR (OSPF)", + "outLabel":3, + "distance":150, + "installed":true, + "nexthop":"10.0.0.2" } ] }, - "50000":{ - "inLabel":50000, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -64,8 +110,8 @@ } ] }, - "50001":{ - "inLabel":50001, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -77,4 +123,4 @@ } ] } -} +] diff --git a/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json index 2548299cc7..eb202b82cd 100644 --- a/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json +++ b/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json @@ -15,59 +15,79 @@ "prefix":"10.0.255.2\/32", "sid":200, "inputLabel":0, - "outputLabel":"0", - "interface":"lo", - "nexthop":"10.0.255.2" + "prefixRoute":[ + { + "outputLabel":0, + "interface":"lo", + "nexthop":"10.0.255.2" + } + ] } ], "extendedLink":[ { "prefix":"10.0.4.2\/32", - "sid":50001, - "inputLabel":50001, - "outputLabel":"pop", - "interface":"r2-eth2", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth3", "nexthop":"10.0.4.1" }, { "prefix":"10.0.4.2\/32", - "sid":50000, - "inputLabel":50000, - "outputLabel":"pop", - "interface":"r2-eth2", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth3", "nexthop":"10.0.4.1" }, { - "prefix":"10.0.3.2\/32", - "sid":50003, - "inputLabel":50003, - "outputLabel":"pop", - "interface":"r2-eth1", - "nexthop":"10.0.3.1" + "prefix":"10.0.0.2\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth0", + "nexthop":"10.0.0.1" }, { - "prefix":"10.0.3.2\/32", - "sid":50002, - "inputLabel":50002, - "outputLabel":"pop", - "interface":"r2-eth1", - "nexthop":"10.0.3.1" + "prefix":"10.0.0.2\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth0", + "nexthop":"10.0.0.1" }, { "prefix":"10.0.1.2\/32", - "sid":50005, - "inputLabel":50005, - "outputLabel":"pop", - "interface":"r2-eth0", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth1", "nexthop":"10.0.1.1" }, { "prefix":"10.0.1.2\/32", - "sid":50004, - "inputLabel":50004, - "outputLabel":"pop", - "interface":"r2-eth0", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth1", "nexthop":"10.0.1.1" + }, + { + "prefix":"10.0.3.2\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth2", + "nexthop":"10.0.3.1" + }, + { + "prefix":"10.0.3.2\/32", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, + "interface":"r2-eth2", + "nexthop":"10.0.3.1" } ] }, @@ -76,19 +96,19 @@ "srgbSize":10000, "srgbLabel":10000, "algorithms":[ - { - "0":"SPF" - } ], - "nodeMsd":12, "extendedPrefix":[ { "prefix":"10.0.255.4\/32", "sid":400, "inputLabel":8400, - "outputLabel":"10400", - "interface":"r2-eth2", - "nexthop":"10.0.4.1" + "prefixRoute":[ + { + "outputLabel":10400, + "interface":"r2-eth3", + "nexthop":"10.0.4.1" + } + ] } ] }, @@ -97,19 +117,19 @@ "srgbSize":10000, "srgbLabel":10000, "algorithms":[ - { - "0":"SPF" - } ], - "nodeMsd":8, "extendedPrefix":[ { "prefix":"10.0.255.3\/32", "sid":300, "inputLabel":8300, - "outputLabel":"pop", - "interface":"r2-eth1", - "nexthop":"10.0.3.1" + "prefixRoute":[ + { + "outputLabel":3, + "interface":"r2-eth2", + "nexthop":"10.0.3.1" + } + ] } ] }, @@ -118,19 +138,24 @@ "srgbSize":10000, "srgbLabel":20000, "algorithms":[ - { - "0":"SPF" - } ], - "nodeMsd":16, "extendedPrefix":[ { "prefix":"10.0.255.1\/32", "sid":100, "inputLabel":8100, - "outputLabel":"20100", - "interface":"r2-eth0", - "nexthop":"10.0.1.1" + "prefixRoute":[ + { + "outputLabel":20100, + "interface":"r2-eth0", + "nexthop":"10.0.0.1" + }, + { + "outputLabel":20100, + "interface":"r2-eth1", + "nexthop":"10.0.1.1" + } + ] } ] } diff --git a/tests/topotests/ospf-sr-topo1/r2/ospfd.conf b/tests/topotests/ospf-sr-topo1/r2/ospfd.conf index 4d6146aaa7..b8c7b999e8 100644 --- a/tests/topotests/ospf-sr-topo1/r2/ospfd.conf +++ b/tests/topotests/ospf-sr-topo1/r2/ospfd.conf @@ -5,6 +5,7 @@ interface lo ip ospf area 0.0.0.0 ! interface r2-eth0 + ip ospf network point-to-point ip ospf area 0.0.0.0 ! interface r2-eth1 @@ -12,6 +13,9 @@ interface r2-eth1 ip ospf area 0.0.0.0 ! interface r2-eth2 + ip ospf area 0.0.0.0 +! +interface r2-eth3 ip ospf network point-to-point ip ospf area 0.0.0.0 ! diff --git a/tests/topotests/ospf-sr-topo1/r2/zebra.conf b/tests/topotests/ospf-sr-topo1/r2/zebra.conf index f89548d8c5..ba1d833f50 100644 --- a/tests/topotests/ospf-sr-topo1/r2/zebra.conf +++ b/tests/topotests/ospf-sr-topo1/r2/zebra.conf @@ -3,12 +3,15 @@ interface lo ip address 10.0.255.2/32 ! interface r2-eth0 - ip address 10.0.1.2/24 + ip address 10.0.0.2/24 ! interface r2-eth1 - ip address 10.0.3.2/24 + ip address 10.0.1.2/24 ! interface r2-eth2 + ip address 10.0.3.2/24 +! +interface r2-eth3 ip address 10.0.4.2/24 ! ip forwarding diff --git a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json index 79965d280a..aedcc5b8f8 100644 --- a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json +++ b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json @@ -1,5 +1,5 @@ -{ - "8100":{ +[ + { "inLabel":8100, "installed":true, "nexthops":[ @@ -9,10 +9,17 @@ "distance":150, "installed":true, "nexthop":"10.0.1.1" + }, + { + "type":"SR (OSPF)", + "outLabel":20100, + "distance":150, + "installed":true, + "nexthop":"10.0.0.1" } ] }, - "8300":{ + { "inLabel":8300, "installed":true, "nexthops":[ @@ -25,7 +32,7 @@ } ] }, - "8400":{ + { "inLabel":8400, "installed":true, "nexthops":[ @@ -38,8 +45,8 @@ } ] }, - "50000":{ - "inLabel":50000, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -51,8 +58,8 @@ } ] }, - "50001":{ - "inLabel":50001, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -64,8 +71,8 @@ } ] }, - "50002":{ - "inLabel":50002, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -73,12 +80,12 @@ "outLabel":3, "distance":150, "installed":true, - "nexthop":"10.0.3.1" + "nexthop":"10.0.0.1" } ] }, - "50003":{ - "inLabel":50003, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -86,12 +93,12 @@ "outLabel":3, "distance":150, "installed":true, - "nexthop":"10.0.3.1" + "nexthop":"10.0.0.1" } ] }, - "50004":{ - "inLabel":50004, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -103,8 +110,8 @@ } ] }, - "50005":{ - "inLabel":50005, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -115,5 +122,31 @@ "nexthop":"10.0.1.1" } ] + }, + { + "inLabel":"*", + "installed":true, + "nexthops":[ + { + "type":"SR (OSPF)", + "outLabel":3, + "distance":150, + "installed":true, + "nexthop":"10.0.3.1" + } + ] + }, + { + "inLabel":"*", + "installed":true, + "nexthops":[ + { + "type":"SR (OSPF)", + "outLabel":3, + "distance":150, + "installed":true, + "nexthop":"10.0.3.1" + } + ] } -} +] diff --git a/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json index 4b618cc7ad..b36fe674ad 100644 --- a/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json +++ b/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json @@ -15,9 +15,13 @@ "prefix":"10.0.255.2\/32", "sid":200, "inputLabel":10200, - "outputLabel":"pop", - "interface":"r3-eth0", - "nexthop":"10.0.3.2" + "prefixRoute":[ + { + "outputLabel":3, + "interface":"r3-eth0", + "nexthop":"10.0.3.2" + } + ] } ] }, @@ -36,9 +40,13 @@ "prefix":"10.0.255.4\/32", "sid":400, "inputLabel":10400, - "outputLabel":"8400", - "interface":"r3-eth0", - "nexthop":"10.0.3.2" + "prefixRoute":[ + { + "outputLabel":8400, + "interface":"r3-eth0", + "nexthop":"10.0.3.2" + } + ] } ] }, @@ -57,25 +65,29 @@ "prefix":"10.0.255.3\/32", "sid":300, "inputLabel":0, - "outputLabel":"0", - "interface":"lo", - "nexthop":"10.0.255.3" + "prefixRoute":[ + { + "outputLabel":0, + "interface":"lo", + "nexthop":"10.0.255.3" + } + ] } ], "extendedLink":[ { "prefix":"10.0.3.1\/32", - "sid":50001, - "inputLabel":50001, - "outputLabel":"pop", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, "interface":"r3-eth0", "nexthop":"10.0.3.2" }, { "prefix":"10.0.3.1\/32", - "sid":50000, - "inputLabel":50000, - "outputLabel":"pop", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, "interface":"r3-eth0", "nexthop":"10.0.3.2" } @@ -96,9 +108,13 @@ "prefix":"10.0.255.1\/32", "sid":100, "inputLabel":10100, - "outputLabel":"8100", - "interface":"r3-eth0", - "nexthop":"10.0.3.2" + "prefixRoute":[ + { + "outputLabel":8100, + "interface":"r3-eth0", + "nexthop":"10.0.3.2" + } + ] } ] } diff --git a/tests/topotests/ospf-sr-topo1/r3/ospfd.conf b/tests/topotests/ospf-sr-topo1/r3/ospfd.conf index 5aaa14fac4..cf274bed2e 100644 --- a/tests/topotests/ospf-sr-topo1/r3/ospfd.conf +++ b/tests/topotests/ospf-sr-topo1/r3/ospfd.conf @@ -3,7 +3,6 @@ interface lo ip ospf area 0.0.0.0 ! interface r3-eth0 - ip ospf network point-to-point ip ospf area 0.0.0.0 ! ! diff --git a/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json index ceb2f7a0e5..71e8366137 100644 --- a/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json +++ b/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json @@ -1,5 +1,5 @@ -{ - "10100":{ +[ + { "inLabel":10100, "installed":true, "nexthops":[ @@ -12,7 +12,7 @@ } ] }, - "10200":{ + { "inLabel":10200, "installed":true, "nexthops":[ @@ -25,7 +25,7 @@ } ] }, - "10400":{ + { "inLabel":10400, "installed":true, "nexthops":[ @@ -38,8 +38,8 @@ } ] }, - "50000":{ - "inLabel":50000, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -51,8 +51,8 @@ } ] }, - "50001":{ - "inLabel":50001, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -64,4 +64,4 @@ } ] } -} +] diff --git a/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json index 098e87dc25..d92ec91c72 100644 --- a/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json +++ b/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json @@ -6,18 +6,19 @@ "srgbSize":20000, "srgbLabel":8000, "algorithms":[ - { - "0":"SPF" - } ], "extendedPrefix":[ { "prefix":"10.0.255.2\/32", "sid":200, "inputLabel":10200, - "outputLabel":"pop", - "interface":"r4-eth0", - "nexthop":"10.0.4.2" + "prefixRoute":[ + { + "outputLabel":3, + "interface":"r4-eth0", + "nexthop":"10.0.4.2" + } + ] } ] }, @@ -36,25 +37,29 @@ "prefix":"10.0.255.4\/32", "sid":400, "inputLabel":10400, - "outputLabel":"pop", - "interface":"lo", - "nexthop":"10.0.255.4" + "prefixRoute":[ + { + "outputLabel":3, + "interface":"lo", + "nexthop":"10.0.255.4" + } + ] } ], "extendedLink":[ { "prefix":"10.0.4.1\/32", - "sid":50001, - "inputLabel":50001, - "outputLabel":"pop", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, "interface":"r4-eth0", "nexthop":"10.0.4.2" }, { "prefix":"10.0.4.1\/32", - "sid":50000, - "inputLabel":50000, - "outputLabel":"pop", + "sid":"*", + "inputLabel":"*", + "outputLabel":3, "interface":"r4-eth0", "nexthop":"10.0.4.2" } @@ -65,19 +70,19 @@ "srgbSize":10000, "srgbLabel":10000, "algorithms":[ - { - "0":"SPF" - } ], - "nodeMsd":8, "extendedPrefix":[ { "prefix":"10.0.255.3\/32", "sid":300, "inputLabel":10300, - "outputLabel":"8300", - "interface":"r4-eth0", - "nexthop":"10.0.4.2" + "prefixRoute":[ + { + "outputLabel":8300, + "interface":"r4-eth0", + "nexthop":"10.0.4.2" + } + ] } ] }, @@ -86,19 +91,19 @@ "srgbSize":10000, "srgbLabel":20000, "algorithms":[ - { - "0":"SPF" - } ], - "nodeMsd":16, "extendedPrefix":[ { "prefix":"10.0.255.1\/32", "sid":100, "inputLabel":10100, - "outputLabel":"8100", - "interface":"r4-eth0", - "nexthop":"10.0.4.2" + "prefixRoute":[ + { + "outputLabel":8100, + "interface":"r4-eth0", + "nexthop":"10.0.4.2" + } + ] } ] } diff --git a/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json index d7f54b224d..b5767e1d7d 100644 --- a/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json +++ b/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json @@ -1,5 +1,5 @@ -{ - "10100":{ +[ + { "inLabel":10100, "installed":true, "nexthops":[ @@ -12,7 +12,7 @@ } ] }, - "10200":{ + { "inLabel":10200, "installed":true, "nexthops":[ @@ -25,7 +25,7 @@ } ] }, - "10300":{ + { "inLabel":10300, "installed":true, "nexthops":[ @@ -38,7 +38,7 @@ } ] }, - "10400":{ + { "inLabel":10400, "installed":true, "nexthops":[ @@ -46,13 +46,12 @@ "type":"SR (OSPF)", "outLabel":3, "distance":150, - "installed":true, - "nexthop":"10.0.255.4" + "installed":true } ] }, - "50000":{ - "inLabel":50000, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -64,8 +63,8 @@ } ] }, - "50001":{ - "inLabel":50001, + { + "inLabel":"*", "installed":true, "nexthops":[ { @@ -77,4 +76,4 @@ } ] } -} +] diff --git a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py index 92cebfe0b6..6792c56b3b 100755 --- a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py +++ b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py @@ -27,7 +27,9 @@ test_ospf_sr_topo1.py: Test the FRR OSPF routing daemon with Segment Routing. """ import os +import re import sys +import json from functools import partial # Save the Current Working Directory to find configuration files. @@ -62,20 +64,23 @@ class OspfSrTopo(Topo): for routern in range(1, 5): tgen.add_router("r{}".format(routern)) - # Interconect router 1 and 2 - switch = tgen.add_switch("s1") - switch.add_link(tgen.gears["r1"]) - switch.add_link(tgen.gears["r2"]) + # Interconect router 1 and 2 with 2 links + switch = tgen.add_switch('s1') + switch.add_link(tgen.gears['r1']) + switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch('s2') + switch.add_link(tgen.gears['r1']) + switch.add_link(tgen.gears['r2']) # Interconect router 3 and 2 - switch = tgen.add_switch("s2") - switch.add_link(tgen.gears["r3"]) - switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch('s3') + switch.add_link(tgen.gears['r3']) + switch.add_link(tgen.gears['r2']) # Interconect router 4 and 2 - switch = tgen.add_switch("s3") - switch.add_link(tgen.gears["r4"]) - switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch('s4') + switch.add_link(tgen.gears['r4']) + switch.add_link(tgen.gears['r2']) def setup_module(mod): @@ -99,19 +104,6 @@ def setup_module(mod): # Initialize all routers. tgen.start_router() - # Verify that version, MPLS and Segment Routing are OK - for router in router_list.values(): - # Check for Version - if router.has_version("<", "4"): - tgen.set_error("Unsupported FRR version") - break - # Check that Segment Routing is available - output = tgen.gears[router.name].vtysh_cmd( - "show ip ospf database segment-routing json" - ) - if output.find("Unknown") != -1: - tgen.set_error("Segment Routing is not available") - def teardown_module(mod): "Teardown the pytest environment" @@ -122,31 +114,6 @@ def teardown_module(mod): logger.info("\n\n---- OSPF Segment Routing tests End ----\n") -# Shared test function to validate expected output. -def compare_ospf_srdb(rname, expected): - """ - Calls 'show ip ospf database segment-routing json' for router `rname` - and compare the obtained result with the expected output. - """ - tgen = get_topogen() - current = tgen.gears[rname].vtysh_cmd("show ip ospf database segment-routing json") - return topotest.difflines( - current, expected, title1="Current output", title2="Expected output" - ) - - -def compare_mpls_table(rname, expected): - """ - Calls 'show mpls table json' for router `rname` and compare the obtained - result with the expected output. - """ - tgen = get_topogen() - current = tgen.gears[rname].vtysh_cmd("show mpls table json") - return topotest.difflines( - current, expected, title1="Current output", title2="Expected output" - ) - - def test_ospf_sr(): "Test OSPF daemon Segment Routing" tgen = get_topogen() @@ -162,12 +129,15 @@ def test_ospf_sr(): # Load expected results from the command reffile = os.path.join(CWD, "{}/ospf_srdb.json".format(router)) - expected = open(reffile).read() + expected = json.loads(open(reffile).read()) # Run test function until we get an result. Wait at most 60 seconds. - test_func = partial(compare_ospf_srdb, router, expected) - result, diff = topotest.run_and_expect(test_func, "", count=25, wait=3) - assert result, ("OSPF did not start Segment Routing on {}:\n{}").format( + rt = tgen.gears[router] + test_func = partial( + topotest.router_json_cmp, rt, 'show ip ospf database segment-routing json', expected + ) + rv, diff = topotest.run_and_expect(test_func, None, count=25, wait=3) + assert rv, "OSPF did not start Segment Routing on {}:\n{}".format( router, diff ) @@ -180,6 +150,33 @@ def test_ospf_kernel_route(): logger.info("--- test OSPF Segment Routing MPLS tables ---") + def show_mpls_table_json_cmp(rt, expected): + """ + Reformat MPLS table output to use a list of labels instead of dict. + + Original: + { + "X": { + inLabel: "X", + # ... + } + } + + List format: + [ + { + inLabel: "X", + } + ] + """ + out = rt.vtysh_cmd('show mpls table json', isjson=True) + + outlist = [] + for key in out.keys(): + outlist.append(out[key]) + + return topotest.json_cmp(outlist, expected) + for rnum in range(1, 5): router = "r{}".format(rnum) @@ -187,12 +184,13 @@ def test_ospf_kernel_route(): # Load expected results from the command reffile = os.path.join(CWD, "{}/zebra_mpls.json".format(router)) - expected = open(reffile).read() + expected = json.loads(open(reffile).read()) # Run test function until we get an result. Wait at most 60 seconds. - test_func = partial(compare_mpls_table, router, expected) - result, diff = topotest.run_and_expect(test_func, "", count=25, wait=3) - assert result, ("OSPF did not properly instal MPLS table on {}:\n{}").format( + rt = tgen.gears[router] + test_func = partial(show_mpls_table_json_cmp, rt, expected) + rv, diff = topotest.run_and_expect(test_func, None, count=25, wait=3) + assert rv, "OSPF did not properly instal MPLS table on {}:\n{}".format( router, diff ) diff --git a/tests/topotests/pbr-topo1/__init__.py b/tests/topotests/pbr-topo1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/pbr-topo1/__init__.py diff --git a/tests/topotests/pbr-topo1/r1/linux-rules.json b/tests/topotests/pbr-topo1/r1/linux-rules.json new file mode 100644 index 0000000000..5af4363418 --- /dev/null +++ b/tests/topotests/pbr-topo1/r1/linux-rules.json @@ -0,0 +1,19 @@ +[ + { + "iif": "r1-eth1", + "pref": "304", + "from": "4.5.6.7" + }, + { + "to": "3.4.5.0/24", + "iif": "r1-eth2", + "pref": "304", + "from": "1.2.0.0/16" + }, + { + "to": "9.9.9.9", + "iif": "r1-eth1", + "pref": "309", + "from": "all" + } +] diff --git a/tests/topotests/pbr-topo1/r1/pbr-interface.json b/tests/topotests/pbr-topo1/r1/pbr-interface.json index 452b24dcd7..e28d9fb149 100644 --- a/tests/topotests/pbr-topo1/r1/pbr-interface.json +++ b/tests/topotests/pbr-topo1/r1/pbr-interface.json @@ -8,5 +8,20 @@ "name":"r1-eth2", "policy":"DONNA", "valid":true + }, + { + "name":"r1-eth3", + "policy":"AKIHABARA", + "valid":true + }, + { + "name":"r1-eth4", + "policy":"ASAKUSA", + "valid":true + }, + { + "name":"r1-noexist", + "policy":"NOEXIST", + "valid":false } ] diff --git a/tests/topotests/pbr-topo1/r1/pbr-map.json b/tests/topotests/pbr-topo1/r1/pbr-map.json index 6b9eaa9ceb..f0738dc540 100644 --- a/tests/topotests/pbr-topo1/r1/pbr-map.json +++ b/tests/topotests/pbr-topo1/r1/pbr-map.json @@ -1,21 +1,92 @@ [ { - "name":"DONNA", - "valid":true, + "name":"AKIHABARA", + "valid":false, "policies":[ { - "id":3, "sequenceNumber":5, - "ruleNumber":304, "vrfUnchanged":false, "installed":true, "installedReason":"Valid", + "nexthopGroup": { + "name":"C", + "installed":true, + "installedInternally":1 + }, + "matchDst":"192.168.4.0\/24" + }, + { + "sequenceNumber":10, + "vrfUnchanged":false, + "installed":true, + "installedReason":"Invalid Src or Dst", "nexthopGroup":{ - "tableId":10002, "name":"C", "installed":true, "installedInternally":1 + } + }, + { + "sequenceNumber":15, + "vrfUnchanged":false, + "installed":false, + "installedReason":"No Nexthops" + } + ] + }, + { + "name":"ASAKUSA", + "valid":true, + "policies":[ + { + "sequenceNumber":5, + "vrfUnchanged":false, + "installed":true, + "installedReason":"Valid", + "matchDst":"c0ff:ee::\/64", + "nexthopGroup":{ + "name":"D", + "installed":true, + "installedInternally":1 + } + }, + { + "sequenceNumber":10, + "vrfUnchanged":false, + "installed":true, + "installedReason":"Valid", + "nexthopGroup":{ + "name":"ASAKUSA10", + "installed":true, + "installedInternally":1 }, + "matchDst":"dead:beef::\/64", + "matchMark":314159 + } + ] + }, + { + "name":"DONNA", + "valid":false, + "policies":[ + { + "sequenceNumber":5, + "vrfUnchanged":false, + "installed":false, + "installedReason":"Invalid NH-group", + "nexthopGroup":{ + "name":"B", + "installed":false, + "installedInternally":0 + }, + "matchSrc":"1.2.0.0\/16", + "matchDst":"3.4.5.0\/24" + }, + { + "sequenceNumber":10, + "vrfUnchanged":true, + "installed":false, + "installedReason":"Valid", "matchSrc":"1.2.0.0\/16", "matchDst":"3.4.5.0\/24" } @@ -26,14 +97,11 @@ "valid":true, "policies":[ { - "id":1, "sequenceNumber":5, - "ruleNumber":304, "vrfUnchanged":false, "installed":true, "installedReason":"Valid", "nexthopGroup":{ - "tableId":10003, "name":"EVA5", "installed":true, "installedInternally":1 @@ -41,14 +109,12 @@ "matchSrc":"4.5.6.7\/32" }, { - "id":2, "sequenceNumber":10, "ruleNumber":309, "vrfUnchanged":false, "installed":true, "installedReason":"Valid", "nexthopGroup":{ - "tableId":10000, "name":"A", "installed":true, "installedInternally":1 diff --git a/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json b/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json index ff85438ad5..540ea28158 100644 --- a/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json +++ b/tests/topotests/pbr-topo1/r1/pbr-nexthop-groups.json @@ -1,6 +1,16 @@ [ { - "id":10000, + "name":"ASAKUSA10", + "valid":true, + "installed":true, + "nexthops":[ + { + "nexthop":"c0ff:ee::1", + "valid":true + } + ] + }, + { "name":"A", "valid":true, "installed":true, @@ -20,19 +30,47 @@ ] }, { - "id":10002, + "name":"D", + "valid":true, + "installed":true, + "nexthops":[ + { + "nexthop":"c0ff:ee::3", + "valid":true + }, + { + "nexthop":"c0ff:ee::2", + "valid":true + }, + { + "nexthop":"c0ff:ee::1", + "valid":true + } + ] + }, + { "name":"C", "valid":true, "installed":true, "nexthops":[ { - "nexthop":"192.168.1.44", + "nexthop":"192.168.4.3", + "targetVrf":"vrf-chiyoda", + "valid":true + }, + { + "nexthop":"192.168.4.2", + "targetVrf":"vrf-chiyoda", + "valid":true + }, + { + "nexthop":"192.168.4.1", + "targetVrf":"vrf-chiyoda", "valid":true } ] }, { - "id":10001, "name":"B", "valid":false, "installed":false, @@ -44,7 +82,6 @@ ] }, { - "id":10003, "name":"EVA5", "valid":true, "installed":true, diff --git a/tests/topotests/pbr-topo1/r1/pbrd.conf b/tests/topotests/pbr-topo1/r1/pbrd.conf index 234683f307..4a126151b0 100644 --- a/tests/topotests/pbr-topo1/r1/pbrd.conf +++ b/tests/topotests/pbr-topo1/r1/pbrd.conf @@ -1,8 +1,16 @@ +debug pbr +# Valid table range +pbr table range 10000 50000 +# Try to set invalid bounds +pbr table range 10000 10001 +pbr table range 50000 10000 +# Reset table range +no pbr table range +! nexthop-group A nexthop 192.168.1.2 nexthop 192.168.2.2 nexthop 192.168.3.2 - nexhtop 192.168.4.2 ! # This one is bogus and should # never work @@ -10,7 +18,14 @@ nexthop-group B nexthop 192.168.50.1 ! nexthop-group C - nexthop 192.168.1.44 + nexthop 192.168.4.1 nexthop-vrf vrf-chiyoda + nexthop 192.168.4.2 nexthop-vrf vrf-chiyoda + nexthop 192.168.4.3 nexthop-vrf vrf-chiyoda +! +nexthop-group D + nexthop c0ff:ee::1 + nexthop c0ff:ee::2 + nexthop c0ff:ee::3 ! pbr-map EVA seq 5 match src-ip 4.5.6.7/32 @@ -23,11 +38,50 @@ pbr-map EVA seq 10 pbr-map DONNA seq 5 match dst-ip 3.4.5.0/24 match src-ip 1.2.0.0/16 - set nexthop-group C -! - + set nexthop-group B +! +pbr-map DONNA seq 10 + match dst-ip 3.4.5.0/24 + match src-ip 1.2.0.0/16 + set vrf unchanged +! +pbr-map AKIHABARA seq 5 + no set vrf unchanged + match dst-ip 192.168.4.0/24 + set nexthop-group C +! +pbr-map AKIHABARA seq 10 + match dst-ip 192.168.4.0/24 + no match dst-ip 192.168.4.0/24 + set nexthop-group C +! +pbr-map AKIHABARA seq 15 + set vrf noexist-vrf + match dst-ip 192.168.4.0/24 + set nexthop-group C + no set nexthop-group C +! +pbr-map ASAKUSA seq 5 + match dst-ip c0ff:ee::/64 + set nexthop-group D +! +pbr-map ASAKUSA seq 10 + match dst-ip dead:beef::/64 + match mark 314159 + set nexthop c0ff:ee::1 +! +# Interface policies int r1-eth1 pbr-policy EVA ! int r1-eth2 pbr-policy DONNA +! +int r1-eth3 + pbr-policy AKIHABARA +! +int r1-eth4 + pbr-policy ASAKUSA +! +int r1-noexist + pbr-policy NOEXIST diff --git a/tests/topotests/pbr-topo1/r1/zebra.conf b/tests/topotests/pbr-topo1/r1/zebra.conf index f29b146a62..2ec947c275 100644 --- a/tests/topotests/pbr-topo1/r1/zebra.conf +++ b/tests/topotests/pbr-topo1/r1/zebra.conf @@ -7,5 +7,8 @@ int r1-eth1 int r1-eth2 ip address 192.168.3.1/24 -int r1-eth3 +int r1-eth3 vrf vrf-chiyoda ip address 192.168.4.1/24 + +int r1-eth4 + ipv6 address c0ff:ee::/64 diff --git a/tests/topotests/pbr-topo1/test_pbr_topo1.py b/tests/topotests/pbr-topo1/test_pbr_topo1.py index 2853165d45..7de1cfa519 100755 --- a/tests/topotests/pbr-topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr-topo1/test_pbr_topo1.py @@ -42,6 +42,7 @@ sys.path.append(os.path.join(CWD, "../")) from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger +from lib.common_config import shutdown_bringup_interface # Required to instantiate the topology builder class. from mininet.topo import Topo @@ -61,26 +62,14 @@ class NetworkTopo(Topo): tgen = get_topogen(self) + # Populate routers for routern in range(1, 2): tgen.add_router("r{}".format(routern)) - # On main router - # First switch is for a dummy interface (for local network) - switch = tgen.add_switch("sw1") - switch.add_link(tgen.gears["r1"]) - - # Switches for PBR - # switch 2 switch is for connection to PBR router - switch = tgen.add_switch("sw2") - switch.add_link(tgen.gears["r1"]) - - # switch 4 is stub on remote PBR router - switch = tgen.add_switch("sw4") - switch.add_link(tgen.gears["r1"]) - - # switch 3 is between PBR routers - switch = tgen.add_switch("sw3") - switch.add_link(tgen.gears["r1"]) + # Populate switches + for switchn in range(1, 6): + switch = tgen.add_switch("sw{}".format(switchn)) + switch.add_link(tgen.gears["r1"]) ##################################################### @@ -95,9 +84,13 @@ def setup_module(module): tgen = Topogen(NetworkTopo, module.__name__) tgen.start_topology() - # This is a sample of configuration loading. router_list = tgen.routers() for rname, router in router_list.iteritems(): + # Install vrf into the kernel and slave eth3 + router.run("ip link add vrf-chiyoda type vrf table 1000") + router.run("ip link set dev {}-eth3 master vrf-chiyoda".format(rname)) + router.run("ip link set vrf-chiyoda up") + router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -106,7 +99,7 @@ def setup_module(module): ) tgen.start_router() - #gen.mininet_cli() + def teardown_module(_mod): "Teardown the pytest environment" @@ -141,19 +134,19 @@ def test_pbr_data(): router_list = tgen.routers().values() for router in router_list: intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name) - logger.info(intf_file) + # Read expected result from file expected = json.loads(open(intf_file).read()) # Actual output from router actual = router.vtysh_cmd("show pbr interface json", isjson=True) - assertmsg = '"show pbr interface" mismatches on {}'.format(router.name) assert topotest.json_cmp(actual, expected) is None, assertmsg map_file = "{}/{}/pbr-map.json".format(CWD, router.name) logger.info(map_file) + # Read expected result from file expected = json.loads(open(map_file).read()) @@ -164,7 +157,8 @@ def test_pbr_data(): assert topotest.json_cmp(actual, expected) is None, assertmsg nexthop_file = "{}/{}/pbr-nexthop-groups.json".format(CWD, router.name) - + logger.info(nexthop_file) + # Read expected result from file expected = json.loads(open(nexthop_file).read()) @@ -174,7 +168,64 @@ def test_pbr_data(): assertmsg = '"show pbr nexthop-groups" mismatches on {}'.format(router.name) assert topotest.json_cmp(actual, expected) is None, assertmsg + +def test_pbr_flap(): + "Test PBR interface flapping" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Verify PBR Status + logger.info("Flapping PBR Interfaces") + + router_list = tgen.routers().values() + for router in router_list: + # Flap interface to see if route-map properties are intact + # Shutdown interface + + for i in range(5): + intf = "r1-eth{}".format(i) + + # Down and back again + shutdown_bringup_interface(tgen, router.name, intf, False) + shutdown_bringup_interface(tgen, router.name, intf, True) + + intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name) + logger.info(intf_file) + + # Read expected result from file + expected = json.loads(open(intf_file).read()) + + # Actual output from router + actual = router.vtysh_cmd("show pbr interface json", isjson=True) + assertmsg = '"show pbr interface" mismatches on {}'.format(router.name) + + assert topotest.json_cmp(actual, expected) is None, assertmsg + + +def test_rule_linux_installation(): + "Ensure that rule is installed in the kernel" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking for installed PBR rules in OS") + + router_list = tgen.routers().values() + for router in router_list: + rules_file = "{}/{}/linux-rules.json".format(CWD, router.name) + + actual = topotest.ip_rules(router) + expected = json.loads(open(rules_file).read()) + + assertmsg = "Router {} OS rules mismatch".format(router.name) + assert topotest.json_cmp(actual, expected) is None, assertmsg + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) - |
