Merge pull request #8295 from opensourcerouting/ospf6-topo-stabilize

topotest: stabilize OSPFv3 topology
This commit is contained in:
Mark Stapp 2021-04-06 09:48:45 -04:00 committed by GitHub
commit 1832ff8b49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 113 additions and 94 deletions

View File

@ -1,9 +0,0 @@
!
router ospf6
router-id 10.0.255.1
redistribute kernel
redistribute connected
redistribute static
interface r1-eth0 area 0.0.0.0
interface r1-eth1 area 0.0.0.0
!

View File

@ -1,9 +0,0 @@
!
router ospf6
router-id 10.0.255.2
redistribute kernel
redistribute connected
redistribute static
interface r2-eth0 area 0.0.0.0
interface r2-eth1 area 0.0.0.0
!

View File

@ -1,10 +0,0 @@
!
router ospf6
router-id 10.0.255.3
redistribute kernel
redistribute connected
redistribute static
interface r3-eth0 area 0.0.0.0
interface r3-eth1 area 0.0.0.0
interface r3-eth2 area 0.0.0.1
!

View File

@ -1,9 +0,0 @@
!
router ospf6
router-id 10.0.255.4
redistribute kernel
redistribute connected
redistribute static
interface r4-eth0 area 0.0.0.1
interface r4-eth1 area 0.0.0.1
!

View File

@ -93,8 +93,6 @@ def setup_module(mod):
tgen.start_topology()
ospf6_config = "ospf6d.conf"
if tgen.gears["r1"].has_version("<", "4.0"):
ospf6_config = "ospf6d.conf-pre-v4"
router_list = tgen.routers()
for rname, router in router_list.items():
@ -118,6 +116,78 @@ def teardown_module(mod):
tgen.stop_topology()
def test_wait_protocol_convergence():
"Wait for OSPFv2/OSPFv3 to converge"
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("waiting for protocols to converge")
def expect_ospfv2_neighbor_full(router, neighbor):
"Wait until OSPFv2 convergence."
logger.info("waiting OSPFv2 router '{}'".format(router))
def run_command_and_expect():
"""
Function that runs command and expect the following outcomes:
* Full/DR
* Full/DROther
* Full/Backup
"""
result = tgen.gears[router].vtysh_cmd('show ip ospf neighbor json',
isjson=True)
if topotest.json_cmp(result, {"neighbors": {neighbor: [
{"state": "Full/DR"}]}}) is None:
return None
if topotest.json_cmp(result, {"neighbors": {neighbor: [
{"state": "Full/DROther"}]}}) is None:
return None
return topotest.json_cmp(result, {"neighbors": {neighbor: [
{"state": "Full/Backup"}]}})
_, result = topotest.run_and_expect(run_command_and_expect, None,
count=130, wait=1)
assertmsg = '"{}" convergence failure'.format(router)
assert result is None, assertmsg
def expect_ospfv3_neighbor_full(router, neighbor):
"Wait until OSPFv3 convergence."
logger.info("waiting OSPFv3 router '{}'".format(router))
test_func = partial(
topotest.router_json_cmp,
tgen.gears[router],
"show ipv6 ospf6 neighbor json",
{"neighbors": [{"neighborId": neighbor, "state": "Full"}]},
)
_, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
assertmsg = '"{}" convergence failure'.format(router)
assert result is None, assertmsg
# Wait for OSPFv2 convergence
expect_ospfv2_neighbor_full("r1", "10.0.255.2")
expect_ospfv2_neighbor_full("r1", "10.0.255.3")
expect_ospfv2_neighbor_full("r2", "10.0.255.1")
expect_ospfv2_neighbor_full("r2", "10.0.255.3")
expect_ospfv2_neighbor_full("r3", "10.0.255.1")
expect_ospfv2_neighbor_full("r3", "10.0.255.2")
expect_ospfv2_neighbor_full("r3", "10.0.255.4")
expect_ospfv2_neighbor_full("r4", "10.0.255.3")
# Wait for OSPFv3 convergence
expect_ospfv3_neighbor_full("r1", "10.0.255.2")
expect_ospfv3_neighbor_full("r1", "10.0.255.3")
expect_ospfv3_neighbor_full("r2", "10.0.255.1")
expect_ospfv3_neighbor_full("r2", "10.0.255.3")
expect_ospfv3_neighbor_full("r3", "10.0.255.1")
expect_ospfv3_neighbor_full("r3", "10.0.255.2")
expect_ospfv3_neighbor_full("r3", "10.0.255.4")
expect_ospfv3_neighbor_full("r4", "10.0.255.3")
def compare_show_ipv6_ospf6(rname, expected):
"""
Calls 'show ipv6 ospf6 route' for router `rname` and compare the obtained

View File

@ -11,9 +11,13 @@ debug ospf6 flooding
!
interface r1-stubnet
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
interface r1-sw5
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
router ospf6
ospf6 router-id 10.0.0.1

View File

@ -11,9 +11,13 @@ debug ospf6 flooding
!
interface r2-stubnet
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
interface r2-sw5
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
router ospf6
ospf6 router-id 10.0.0.2

View File

@ -11,12 +11,18 @@ debug ospf6 flooding
!
interface r3-stubnet
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
interface r3-sw5
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
interface r3-sw6
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
router ospf6
ospf6 router-id 10.0.0.3

View File

@ -11,9 +11,13 @@ debug ospf6 flooding
!
interface r4-stubnet
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
interface r4-sw6
ipv6 ospf6 network broadcast
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 10
!
router ospf6
ospf6 router-id 10.0.0.4

View File

@ -185,70 +185,38 @@ def teardown_module(mod):
tgen.stop_topology()
def test_ospf6_converged():
def test_wait_protocol_convergence():
"Wait for OSPFv3 to converge"
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
# For debugging, uncomment the next line
# tgen.mininet_cli()
logger.info("waiting for protocols to converge")
# Wait for OSPF6 to converge (All Neighbors in either Full or TwoWay State)
logger.info("Waiting for OSPF6 convergence")
def expect_neighbor_full(router, neighbor):
"Wait until OSPFv3 convergence."
logger.info("waiting OSPFv3 router '{}'".format(router))
test_func = partial(
topotest.router_json_cmp,
tgen.gears[router],
"show ipv6 ospf6 neighbor json",
{"neighbors": [{"neighborId": neighbor, "state": "Full"}]},
)
_, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
assertmsg = '"{}" convergence failure'.format(router)
assert result is None, assertmsg
# Set up for regex
pat1 = re.compile("^[0-9]")
pat2 = re.compile("Full")
expect_neighbor_full("r1", "10.0.0.2")
expect_neighbor_full("r1", "10.0.0.3")
timeout = 60
while timeout > 0:
logger.info("Timeout in %s: " % timeout),
sys.stdout.flush()
expect_neighbor_full("r2", "10.0.0.1")
expect_neighbor_full("r2", "10.0.0.3")
# Look for any node not yet converged
for router, rnode in tgen.routers().items():
resStr = rnode.vtysh_cmd("show ipv6 ospf neigh")
expect_neighbor_full("r3", "10.0.0.1")
expect_neighbor_full("r3", "10.0.0.2")
expect_neighbor_full("r3", "10.0.0.4")
isConverged = False
for line in resStr.splitlines():
res1 = pat1.match(line)
if res1:
isConverged = True
res2 = pat2.search(line)
if res2 == None:
isConverged = False
break
if isConverged == False:
logger.info("Waiting for {}".format(router))
sys.stdout.flush()
break
if isConverged:
logger.info("Done")
break
else:
sleep(5)
timeout -= 5
if timeout == 0:
# Bail out with error if a router fails to converge
ospfStatus = rnode.vtysh_cmd("show ipv6 ospf neigh")
assert False, "OSPFv6 did not converge:\n{}".format(ospfStatus)
logger.info("OSPFv3 converged.")
# For debugging, uncomment the next line
# tgen.mininet_cli()
# Make sure that all daemons are still running
if tgen.routers_have_failure():
assert tgen.errors == "", tgen.errors
expect_neighbor_full("r4", "10.0.0.3")
def compare_show_ipv6(rname, expected):