From: Jakub Urbańczyk Date: Tue, 26 May 2020 16:24:16 +0000 (+0200) Subject: topotest: add pbr test suite X-Git-Tag: base_7.5~292^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=9b7decf28e7d6e9b13b7fa6d0225b3cfa823fdfd;p=mirror%2Ffrr.git topotest: add pbr test suite Add some basic tests for installing PBR rules into the kernel. Signed-off-by: Jakub Urbańczyk --- 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/pbr-topo1/__init__.py b/tests/topotests/pbr-topo1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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/test_pbr_topo1.py b/tests/topotests/pbr-topo1/test_pbr_topo1.py index aedc9ca3fc..7de1cfa519 100755 --- a/tests/topotests/pbr-topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr-topo1/test_pbr_topo1.py @@ -201,6 +201,28 @@ def test_pbr_flap(): # 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