From d49a3b2d9558e6f56aa9aa04a20d7c8b489cd2a0 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 12 Sep 2024 11:14:42 +0200 Subject: [PATCH 1/2] tests: ospf6_ecmp_inter_area, use router_json_cmp expect_num_nexthops() errors are not understandable. Use router_json_cmp. Signed-off-by: Louis Scalbert --- .../r1/show_ipv6_routes_ospf6-1.json | 155 ++++++++++++++++++ .../r1/show_ipv6_routes_ospf6-2.json | 130 +++++++++++++++ .../r1/show_ipv6_routes_ospf6-3.json | 130 +++++++++++++++ .../test_ospf6_ecmp_inter_area.py | 74 +++++---- 4 files changed, 453 insertions(+), 36 deletions(-) create mode 100644 tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-1.json create mode 100644 tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-2.json create mode 100644 tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-3.json diff --git a/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-1.json b/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-1.json new file mode 100644 index 000000000000..ff2cf3119373 --- /dev/null +++ b/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-1.json @@ -0,0 +1,155 @@ +{ + "2001:db8:2::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:4::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + } + ] + } + ], + "2001:db8:5::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:6::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:7::/64": [ + { + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:8::/64": [ + { + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:8007::/64": [ + { + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:8008::/64": [ + { + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-2.json b/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-2.json new file mode 100644 index 000000000000..8918feb969d3 --- /dev/null +++ b/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-2.json @@ -0,0 +1,130 @@ +{ + "2001:db8:2::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:4::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + } + ] + } + ], + "2001:db8:5::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:6::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + } + ] + } + ], + "2001:db8:7::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:8::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:8007::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:8008::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-3.json b/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-3.json new file mode 100644 index 000000000000..8918feb969d3 --- /dev/null +++ b/tests/topotests/ospf6_ecmp_inter_area/r1/show_ipv6_routes_ospf6-3.json @@ -0,0 +1,130 @@ +{ + "2001:db8:2::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:3::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth1", + "active": true + } + ] + } + ], + "2001:db8:4::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + } + ] + } + ], + "2001:db8:5::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:6::/64": [ + { + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + } + ] + } + ], + "2001:db8:7::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:8::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:8007::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ], + "2001:db8:8008::/64": [ + { + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": true, + "interfaceName": "r1-eth2", + "active": true + }, + { + "fib": true, + "interfaceName": "r1-eth0", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py b/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py index adf289e2de20..854a75cd1d3f 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py +++ b/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py @@ -49,6 +49,7 @@ expected. """ +import json import os import sys from functools import partial @@ -156,6 +157,20 @@ def expect_neighbor_full(router, neighbor): expect_neighbor_full("r8", "10.254.254.5") expect_neighbor_full("r8", "10.254.254.6") + router = tgen.gears["r1"] + + json_file = "{}/{}/show_ipv6_routes_ospf6-1.json".format(CWD, router.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show ipv6 route ospf6 json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + def test_ecmp_inter_area(): "Test whether OSPFv3 ECMP nexthops are properly updated for inter-area routes after link down" @@ -163,50 +178,37 @@ def test_ecmp_inter_area(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - def num_nexthops(router): - # Careful: "show ipv6 ospf6 route json" doesn't work here. It will - # only list one route type per prefix and that might not necessarily - # be the best/selected route. "show ipv6 route ospf6 json" only - # lists selected routes, so that's more useful in this case. - routes = tgen.gears[router].vtysh_cmd("show ipv6 route ospf6 json", isjson=True) - route_prefixes_infos = sorted(routes.items()) - # Note: ri may contain one entry per routing protocol, but since - # we've explicitly requested only ospf6 above, we can count on ri[0] - # being the entry we're looking for. - return [ri[0]["internalNextHopActiveNum"] for rp, ri in route_prefixes_infos] - - def expect_num_nexthops(router, expected_num_nexthops, count): - "Wait until number of nexthops for routes matches expectation" - logger.info( - "waiting for OSPFv3 router '{}' nexthops {}".format( - router, expected_num_nexthops - ) - ) - test_func = partial(num_nexthops, router) - _, result = topotest.run_and_expect( - test_func, expected_num_nexthops, count=count, wait=3 - ) - assert ( - result == expected_num_nexthops - ), "'{}' wrong number of route nexthops".format(router) - - # Check nexthops pre link-down - # tgen.mininet_cli() - expect_num_nexthops("r1", [1, 1, 1, 1, 2, 3, 3, 3, 3], 4) + router = tgen.gears["r1"] logger.info("triggering R3-R6 link down") tgen.gears["r3"].run("ip link set r3-eth1 down") - # tgen.mininet_cli() - # Check nexthops post link-down - expect_num_nexthops("r1", [1, 1, 1, 1, 1, 2, 2, 2, 2], 8) + json_file = "{}/{}/show_ipv6_routes_ospf6-2.json".format(CWD, router.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show ipv6 route ospf6 json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg logger.info("triggering R2-R5 link down") tgen.gears["r2"].run("ip link set r2-eth1 down") - # tgen.mininet_cli() - # Check nexthops post link-down - expect_num_nexthops("r1", [1, 1, 1, 1, 1, 1, 1, 1, 1], 8) + json_file = "{}/{}/show_ipv6_routes_ospf6-3.json".format(CWD, router.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show ipv6 route ospf6 json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg def teardown_module(_mod): From a2d5ed10d466e815e1c36cb39d50d08ee45a3bbb Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 12 Sep 2024 11:50:25 +0200 Subject: [PATCH 2/2] tests: ospf6_ecmp_inter_area, remove eth3 shutdown eth3 shutdown is not applied because it is ospf6d.conf. Signed-off-by: Louis Scalbert --- tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf | 3 --- tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf | 3 --- 2 files changed, 6 deletions(-) diff --git a/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf index 9b7756e838c1..451cf2f728f8 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf @@ -13,9 +13,6 @@ interface r7-eth2 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 ! -interface r7-eth3 - shutdown -! router ospf6 ospf6 router-id 10.254.254.7 redistribute connected diff --git a/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf index 33c64979ca6f..f8d8619bc2e4 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf @@ -13,9 +13,6 @@ interface r8-eth2 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 ! -interface r8-eth3 - shutdown -! router ospf6 ospf6 router-id 10.254.254.8 redistribute connected