mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 19:39:28 +00:00
tests: add dual stack OSPF topotest
Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
This commit is contained in:
parent
1feb577c63
commit
3076de892d
107
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.dot
Normal file
107
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.dot
Normal file
@ -0,0 +1,107 @@
|
||||
## Color coding:
|
||||
#########################
|
||||
## Main FRR: #f08080 red
|
||||
## Switches: #d0e0d0 gray
|
||||
## RIP: #19e3d9 Cyan
|
||||
## RIPng: #fcb314 dark yellow
|
||||
## OSPFv2: #32b835 Green
|
||||
## OSPFv3: #19e3d9 Cyan
|
||||
## ISIS IPv4 #fcb314 dark yellow
|
||||
## ISIS IPv6 #9a81ec purple
|
||||
## BGP IPv4 #eee3d3 beige
|
||||
## BGP IPv6 #fdff00 yellow
|
||||
##### Colors (see http://www.color-hex.com/)
|
||||
|
||||
graph ospf_topo1 {
|
||||
label="ospf dual stack";
|
||||
|
||||
# Routers
|
||||
r1 [
|
||||
label="r1\nrtr-id 1.1.1.1/32",
|
||||
shape=doubleoctagon,
|
||||
fillcolor="#f08080",
|
||||
style=filled,
|
||||
];
|
||||
r2 [
|
||||
label="r2\nrtr-id 2.2.2.2/32",
|
||||
shape=doubleoctagon,
|
||||
fillcolor="#f08080",
|
||||
style=filled,
|
||||
];
|
||||
r3 [
|
||||
label="r3\nrtr-id 3.3.3.3/32",
|
||||
shape=doubleoctagon,
|
||||
fillcolor="#f08080",
|
||||
style=filled,
|
||||
];
|
||||
r4 [
|
||||
label="r4\nrtr-id 4.4.4.4/32",
|
||||
shape=doubleoctagon,
|
||||
fillcolor="#f08080",
|
||||
style=filled,
|
||||
];
|
||||
r5 [
|
||||
label="r5\nrtr-id 5.5.5.5/32",
|
||||
shape=doubleoctagon,
|
||||
fillcolor="#f08080",
|
||||
style=filled,
|
||||
];
|
||||
|
||||
# Switches
|
||||
s1 [
|
||||
label="s1\n10.0.13.0/24\n2013:13::/64",
|
||||
shape=oval,
|
||||
fillcolor="#d0e0d0",
|
||||
style=filled,
|
||||
];
|
||||
s2 [
|
||||
label="s2\n10.0.23.0/24\n2023:23::/64",
|
||||
shape=oval,
|
||||
fillcolor="#d0e0d0",
|
||||
style=filled,
|
||||
];
|
||||
s3 [
|
||||
label="s3\n10.0.34.0/24\n2034:34::/64",
|
||||
shape=oval,
|
||||
fillcolor="#d0e0d0",
|
||||
style=filled,
|
||||
];
|
||||
s4 [
|
||||
label="s4\n10.0.24.0/24\n2024:24::/64",
|
||||
shape=oval,
|
||||
fillcolor="#d0e0d0",
|
||||
style=filled,
|
||||
];
|
||||
s5 [
|
||||
label="s5\n10.0.45.0/24\n2045:45::/64",
|
||||
shape=oval,
|
||||
fillcolor="#d0e0d0",
|
||||
style=filled,
|
||||
];
|
||||
|
||||
# Connections
|
||||
subgraph cluster1 {
|
||||
label="area 1.1.1.1"
|
||||
|
||||
r1 -- s1 [label="eth0\n.1\n::1"];
|
||||
r3 -- s1 [label="eth0\n.3\n::3"];
|
||||
r3 -- s2 [label="eth1\n.3\n::3"];
|
||||
r2 -- s2 [label="eth0\n.2\n::2"];
|
||||
}
|
||||
|
||||
subgraph cluster0 {
|
||||
label="area 0.0.0.0"
|
||||
|
||||
r3 -- s3 [label="eth2\n.3\n::3"];
|
||||
r4 -- s3 [label="eth0\n.4\n::4"];
|
||||
r2 -- s4 [label="eth1\n.2\n::2"];
|
||||
r4 -- s4 [label="eth1\n.4\n::4"];
|
||||
}
|
||||
|
||||
subgraph cluster2 {
|
||||
label="area 2.2.2.2"
|
||||
|
||||
r4 -- s5 [label="eth2\n.4\n::4"];
|
||||
r5 -- s5 [label="eth0\n.5\n::5"];
|
||||
}
|
||||
}
|
BIN
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.jpg
Normal file
BIN
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
255
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.json
Normal file
255
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.json
Normal file
@ -0,0 +1,255 @@
|
||||
{
|
||||
"ipv4base": "10.0.0.0",
|
||||
"ipv4mask": 24,
|
||||
"link_ip_start": {
|
||||
"ipv4": "10.0.0.0",
|
||||
"v4mask": 24
|
||||
},
|
||||
"lo_prefix": {
|
||||
"ipv4": "1.0.",
|
||||
"v4mask": 32
|
||||
},
|
||||
"routers": {
|
||||
"r1": {
|
||||
"links": {
|
||||
"r3": {
|
||||
"ipv4": "10.0.13.1/24",
|
||||
"ipv6": "2013:13::1/64",
|
||||
"ospf": {
|
||||
"area": "1.1.1.1",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
"ospf": {
|
||||
"router_id": "1.1.1.1",
|
||||
"neighbors": {
|
||||
"r3": {}
|
||||
}
|
||||
},
|
||||
"ospf6": {
|
||||
"router_id": "1.1.1.1",
|
||||
"neighbors": {
|
||||
"r3": {
|
||||
"area": "1.1.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"r2": {
|
||||
"links": {
|
||||
"r3": {
|
||||
"ipv4": "10.0.23.2/24",
|
||||
"ipv6": "2023:23::2/64",
|
||||
"ospf": {
|
||||
"area": "1.1.1.1",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
},
|
||||
"r4": {
|
||||
"ipv4": "10.0.24.2/24",
|
||||
"ipv6": "2034:34::2/64",
|
||||
"ospf": {
|
||||
"area": "0.0.0.0",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ospf": {
|
||||
"router_id": "2.2.2.2",
|
||||
"neighbors": {
|
||||
"r3": {},
|
||||
"r4": {}
|
||||
}
|
||||
},
|
||||
"ospf6": {
|
||||
"router_id": "2.2.2.2",
|
||||
"neighbors": {
|
||||
"r3": { "area": "1.1.1.1" },
|
||||
"r4": { "area": "0.0.0.0" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"r3": {
|
||||
"links": {
|
||||
"r1": {
|
||||
"ipv4": "10.0.13.3/24",
|
||||
"ipv6": "2013:13::3/64",
|
||||
"ospf": {
|
||||
"area": "1.1.1.1",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
},
|
||||
"r2": {
|
||||
"ipv4": "10.0.23.3/24",
|
||||
"ipv6": "2023:23::3/64",
|
||||
"ospf": {
|
||||
"area": "1.1.1.1",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
},
|
||||
"r4": {
|
||||
"ipv4": "10.0.34.3/24",
|
||||
"ipv6": "2034:34::3/64",
|
||||
"ospf": {
|
||||
"area": "0.0.0.0",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ospf": {
|
||||
"router_id": "3.3.3.3",
|
||||
"neighbors": {
|
||||
"r1": {},
|
||||
"r2": {},
|
||||
"r4": {}
|
||||
}
|
||||
},
|
||||
"ospf6": {
|
||||
"router_id": "3.3.3.3",
|
||||
"neighbors": {
|
||||
"r1": { "area": "1.1.1.1" },
|
||||
"r2": { "area": "1.1.1.1" },
|
||||
"r4": { "area": "0.0.0.0" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"r4": {
|
||||
"links": {
|
||||
"r2": {
|
||||
"ipv4": "10.0.24.4/24",
|
||||
"ipv6": "2024:24::4/64",
|
||||
"ospf": {
|
||||
"area": "0.0.0.0",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
},
|
||||
"r3": {
|
||||
"ipv4": "10.0.34.4/24",
|
||||
"ipv6": "2034:34::4/64",
|
||||
"ospf": {
|
||||
"area": "0.0.0.0",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
},
|
||||
"r5": {
|
||||
"ipv4": "10.0.45.4/24",
|
||||
"ipv6": "2045:45::4/64",
|
||||
"ospf": {
|
||||
"area": "2.2.2.2",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ospf": {
|
||||
"router_id": "4.4.4.4",
|
||||
"neighbors": {
|
||||
"r2": {},
|
||||
"r3": {},
|
||||
"r5": {}
|
||||
}
|
||||
},
|
||||
"ospf6": {
|
||||
"router_id": "4.4.4.4",
|
||||
"neighbors": {
|
||||
"r2": { "area": "0.0.0.0" },
|
||||
"r3": { "area": "0.0.0.0" },
|
||||
"r5": { "area": "2.2.2.2" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"r5": {
|
||||
"links": {
|
||||
"r4": {
|
||||
"ipv4": "10.0.45.5/24",
|
||||
"ipv6": "2045:45::5/64",
|
||||
"ospf": {
|
||||
"area": "2.2.2.2",
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
},
|
||||
"ospf6": {
|
||||
"hello_interval": 1,
|
||||
"dead_interval": 4,
|
||||
"network": "point-to-point"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ospf": {
|
||||
"router_id": "5.5.5.5",
|
||||
"neighbors": {
|
||||
"r4": {}
|
||||
}
|
||||
},
|
||||
"ospf6": {
|
||||
"router_id": "5.5.5.5",
|
||||
"neighbors": {
|
||||
"r4": { "area": "2.2.2.2" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
152
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.py
Normal file
152
tests/topotests/ospf-dual-stack/test_ospf_dual_stack.py
Normal file
@ -0,0 +1,152 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import pytest
|
||||
import json
|
||||
|
||||
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.append(os.path.join(CWD, "../"))
|
||||
sys.path.append(os.path.join(CWD, "../lib/"))
|
||||
|
||||
from mininet.topo import Topo
|
||||
from lib.topogen import Topogen, get_topogen
|
||||
|
||||
from lib.common_config import (
|
||||
start_topology,
|
||||
write_test_header,
|
||||
write_test_footer,
|
||||
reset_config_on_routers,
|
||||
stop_router,
|
||||
start_router,
|
||||
verify_rib,
|
||||
create_static_routes,
|
||||
step,
|
||||
start_router_daemons,
|
||||
shutdown_bringup_interface,
|
||||
topo_daemons,
|
||||
create_prefix_lists,
|
||||
create_interfaces_cfg,
|
||||
run_frr_cmd,
|
||||
)
|
||||
from lib.topolog import logger
|
||||
from lib.topojson import build_topo_from_json, build_config_from_json
|
||||
from lib.ospf import (
|
||||
verify_ospf_neighbor,
|
||||
verify_ospf6_neighbor,
|
||||
create_router_ospf,
|
||||
create_router_ospf6,
|
||||
verify_ospf_summary,
|
||||
redistribute_ospf,
|
||||
verify_ospf_database,
|
||||
)
|
||||
|
||||
# Global variables
|
||||
topo = None
|
||||
|
||||
# Reading the data from JSON File for topology creation
|
||||
jsonFile = "{}/test_ospf_dual_stack.json".format(CWD)
|
||||
try:
|
||||
with open(jsonFile, "r") as topoJson:
|
||||
topo = json.load(topoJson)
|
||||
except IOError:
|
||||
assert False, "Could not read file {}".format(jsonFile)
|
||||
|
||||
|
||||
class CreateTopo(Topo):
|
||||
"""Test topology builder."""
|
||||
|
||||
def build(self, *_args, **_opts):
|
||||
"""Build function."""
|
||||
tgen = get_topogen(self)
|
||||
|
||||
# Building topology from json file
|
||||
build_topo_from_json(tgen, topo)
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
"""Sets up the pytest environment."""
|
||||
global topo
|
||||
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...
|
||||
tgen = Topogen(CreateTopo, mod.__name__)
|
||||
# ... and here it calls Mininet initialization functions.
|
||||
|
||||
# get list of daemons needs to be started for this suite.
|
||||
daemons = topo_daemons(tgen, topo)
|
||||
|
||||
# Starting topology, create tmp files which are loaded to routers
|
||||
# to start daemons and then start routers
|
||||
start_topology(tgen, daemons)
|
||||
|
||||
# Creating configuration from JSON
|
||||
build_config_from_json(tgen, topo)
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
# Api call verify whether OSPF converged
|
||||
ospf_covergence_ipv4 = verify_ospf_neighbor(tgen, topo)
|
||||
assert ospf_covergence_ipv4 is True, "setup_module :Failed \n Error:" " {}".format(
|
||||
ospf_covergence_ipv4
|
||||
)
|
||||
|
||||
# Api call verify whether OSPF6 converged
|
||||
ospf_covergence_ipv6 = verify_ospf6_neighbor(tgen, topo)
|
||||
assert ospf_covergence_ipv6 is True, "setup_module :Failed \n Error:" " {}".format(
|
||||
ospf_covergence_ipv6
|
||||
)
|
||||
logger.info("Running setup_module() done")
|
||||
|
||||
|
||||
def teardown_module(mod):
|
||||
"""
|
||||
Teardown the pytest environment.
|
||||
|
||||
* `mod`: module name
|
||||
"""
|
||||
|
||||
logger.info("Running teardown_module to delete topology")
|
||||
tgen = get_topogen()
|
||||
# Stop topology and remove tmp files
|
||||
tgen.stop_topology()
|
||||
logger.info(
|
||||
"Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
|
||||
)
|
||||
logger.info("=" * 40)
|
||||
|
||||
|
||||
#
|
||||
# ##################################
|
||||
# Test cases start here.
|
||||
# ##################################
|
||||
#
|
||||
#
|
||||
def test_ospf_dual_stack(request):
|
||||
"""OSPF test dual stack."""
|
||||
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
tgen = get_topogen()
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
global topo
|
||||
|
||||
step("Bring up the base configuration as per the JSON topology")
|
||||
reset_config_on_routers(tgen)
|
||||
write_test_footer(tc_name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = ["-s"] + sys.argv[1:]
|
||||
sys.exit(pytest.main(args))
|
Loading…
Reference in New Issue
Block a user