tests: Adding ospfv3 basic functionality test cases

1. Adding  APIs to configure and verify ospfv3.
2. Adding ospfv3 base functionality testcase.

Signed-off-by: nguggarigoud <nguggarigoud@vmware.com>
This commit is contained in:
nguggarigoud 2021-05-31 20:22:59 -07:00
parent 1dce93dabb
commit db56171c86
8 changed files with 2585 additions and 347 deletions

View File

@ -1859,7 +1859,7 @@ def create_interfaces_cfg(tgen, topo, build=False):
)
if "ospf6" in data:
interface_data += _create_interfaces_ospf_cfg(
"ospf6", c_data, data, ospf_keywords
"ospf6", c_data, data, ospf_keywords + ["area"]
)
result = create_common_configuration(

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,347 @@
{
"address_types": [
"ipv6"
],
"ipv6base": "fd00::",
"ipv6mask": 64,
"link_ip_start": {
"ipv6": "fd00::",
"v6mask": 64
},
"lo_prefix": {
"ipv6": "2001:db8:f::",
"v6mask": 128
},
"routers": {
"r0": {
"links": {
"lo": {
"ipv6": "auto",
"type": "loopback"
},
"r1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link4": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link5": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link6": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link7": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4,
"network": "point-to-point"
}
}
},
"ospf6": {
"router_id": "100.1.1.0",
"neighbors": {
"r1": {},
"r1-link1": {
"nbr": "r1"
},
"r1-link2": {
"nbr": "r1"
},
"r1-link3": {
"nbr": "r1"
},
"r1-link4": {
"nbr": "r1"
},
"r1-link5": {
"nbr": "r1"
},
"r1-link6": {
"nbr": "r1"
},
"r1-link7": {
"nbr": "r1"
},
"r2": {},
"r3": {}
}
}
},
"r1": {
"links": {
"lo": {
"ipv6": "auto",
"type": "loopback"
},
"r0": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link4": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link5": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link6": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r0-link7": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3-link0": {
"ipv6": "auto",
"description": "DummyIntftoR3"
}
},
"ospf6": {
"router_id": "100.1.1.1",
"neighbors": {
"r0": {},
"r0-link1": {
"nbr": "r0"
},
"r0-link2": {
"nbr": "r0"
},
"r0-link3": {
"nbr": "r0"
},
"r0-link4": {
"nbr": "r0"
},
"r0-link5": {
"nbr": "r0"
},
"r0-link6": {
"nbr": "r0"
},
"r0-link7": {
"nbr": "r0"
},
"r2": {},
"r3": {}
}
}
},
"r2": {
"links": {
"lo": {
"ipv6": "auto",
"type": "loopback"
},
"r0": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
}
},
"ospf6": {
"router_id": "100.1.1.2",
"neighbors": {
"r1": {},
"r0": {},
"r3": {}
}
}
},
"r3": {
"links": {
"lo": {
"ipv6": "auto",
"type": "loopback"
},
"r0": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4,
"network": "point-to-point"
}
},
"r1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1-link0": {
"ipv6": "auto",
"description": "DummyIntftoR1",
"ospf": {
"area": "0.0.0.0"
},
"ospf6": {
"area": "0.0.0.0"
}
}
},
"ospf6": {
"router_id": "100.1.1.3",
"neighbors": {
"r0": {},
"r1": {},
"r2": {}
}
}
}
}
}

View File

@ -0,0 +1,137 @@
{
"address_types": ["ipv6"],
"ipv6base": "fd00::",
"ipv6mask": 64,
"link_ip_start": {"ipv6": "fd00::", "v6mask": 64},
"lo_prefix": {"ipv6": "2001:db8:f::", "v6mask": 128},
"routers": {
"r0": {
"links": {
"r1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
}
},
"ospf6": {
"router_id": "100.1.1.0",
"neighbors": {"r1": {}, "r2": {}, "r3": {}}
}
},
"r1": {
"links": {
"r0": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
}
},
"ospf6": {
"router_id": "100.1.1.1",
"neighbors": {"r0": {}, "r2": {}, "r3": {}}
}
},
"r2": {
"links": {
"r0": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r3": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
}
},
"ospf6": {
"router_id": "100.1.1.2",
"neighbors": {"r1": {}, "r0": {}, "r3": {}}
}
},
"r3": {
"links": {
"r0": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r1": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
},
"r2": {
"ipv6": "auto",
"ospf6": {
"area": "0.0.0.0",
"hello_interval": 1,
"dead_interval": 4
}
}
},
"ospf6": {
"router_id": "100.1.1.3",
"neighbors": {"r0": {}, "r1": {}, "r2": {}}
}
}
}
}

View File

@ -0,0 +1,520 @@
#!/usr/bin/python
#
# Copyright (c) 2021 by VMware, Inc. ("VMware")
# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
# ("NetDEF") in this file.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""OSPF Basic Functionality Automation."""
import os
import sys
import time
import pytest
import json
from copy import deepcopy
from ipaddress import IPv4Address
from lib.topotest import frr_unicode
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
sys.path.append(os.path.join(CWD, "../lib/"))
# pylint: disable=C0413
# Import topogen and topotest helpers
from mininet.topo import Topo
from lib.topogen import Topogen, get_topogen
import ipaddress
# Import topoJson from lib, to create topology and initial configuration
from lib.common_config import (
start_topology,
write_test_header,
write_test_footer,
reset_config_on_routers,
verify_rib,
create_static_routes,
step,
create_route_maps,
shutdown_bringup_interface,
create_interfaces_cfg,
topo_daemons,
get_frr_ipv6_linklocal,
)
from lib.topolog import logger
from lib.topojson import build_topo_from_json, build_config_from_json
from lib.ospf import (
verify_ospf6_neighbor,
config_ospf_interface,
clear_ospf,
verify_ospf6_rib,
create_router_ospf,
verify_ospf6_interface,
verify_ospf6_database,
config_ospf6_interface,
)
from ipaddress import IPv6Address
# Global variables
topo = None
# Reading the data from JSON File for topology creation
jsonFile = "{}/ospfv3_ecmp.json".format(CWD)
try:
with open(jsonFile, "r") as topoJson:
topo = json.load(topoJson)
except IOError:
assert False, "Could not read file {}".format(jsonFile)
NETWORK = {
"ipv4": [
"11.0.20.1/32",
"11.0.20.2/32",
"11.0.20.3/32",
"11.0.20.4/32",
"11.0.20.5/32",
],
"ipv6": ["2::1/128", "2::2/128", "2::3/128", "2::4/128", "2::5/128"],
}
"""
TOPOLOGY :
Please view in a fixed-width font such as Courier.
+---+ A1 +---+
+R1 +------------+R2 |
+-+-+- +--++
| -- -- |
| -- A0 -- |
A0| ---- |
| ---- | A2
| -- -- |
| -- -- |
+-+-+- +-+-+
+R0 +-------------+R3 |
+---+ A3 +---+
TESTCASES :
1. Verify OSPF ECMP with max path configured as 8 (ECMPconfigured at FRR level)
2. Verify OSPF ECMP with max path configured as 2 (Edge having 2 uplink ports)
"""
class CreateTopo(Topo):
"""
Test topology builder.
* `Topo`: Topology object
"""
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
* `mod`: module name
"""
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 deamons 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)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
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 toplogy and Remove tmp files
tgen.stop_topology()
logger.info(
"Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
)
logger.info("=" * 40)
def red_static(dut, config=True):
"""Local def for Redstribute static routes inside ospf."""
global topo
tgen = get_topogen()
if config:
ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "static"}]}}}
else:
ospf_red = {
dut: {
"ospf6": {"redistribute": [{"redist_type": "static", "delete": True}]}
}
}
result = create_router_ospf(tgen, topo, ospf_red)
assert result is True, "Testcase : Failed \n Error: {}".format(result)
def red_connected(dut, config=True):
"""Local def for Redstribute connected routes inside ospf."""
global topo
tgen = get_topogen()
if config:
ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "connected"}]}}}
else:
ospf_red = {
dut: {
"ospf6": {
"redistribute": [{"redist_type": "connected", "del_action": True}]
}
}
}
result = create_router_ospf(tgen, topo, ospf_red)
assert result is True, "Testcase: Failed \n Error: {}".format(result)
def get_llip(onrouter, intf):
"""
API to get the link local ipv6 address of a perticular interface
Parameters
----------
* `fromnode`: Source node
* `tonode` : interface for which link local ip needs to be returned.
Usage
-----
result = get_llip('r1', 'r2-link0')
Returns
-------
1) link local ipv6 address from the interface.
2) errormsg - when link local ip not found.
"""
tgen = get_topogen()
intf = topo["routers"][onrouter]["links"][intf]["interface"]
llip = get_frr_ipv6_linklocal(tgen, onrouter, intf)
if llip:
logger.info("llip ipv6 address to be set as NH is %s", llip)
return llip
return None
def get_glipv6(onrouter, intf):
"""
API to get the global ipv6 address of a perticular interface
Parameters
----------
* `onrouter`: Source node
* `intf` : interface for which link local ip needs to be returned.
Usage
-----
result = get_glipv6('r1', 'r2-link0')
Returns
-------
1) global ipv6 address from the interface.
2) errormsg - when link local ip not found.
"""
glipv6 = (topo["routers"][onrouter]["links"][intf]["ipv6"]).split("/")[0]
if glipv6:
logger.info("Global ipv6 address to be set as NH is %s", glipv6)
return glipv6
return None
# ##################################
# Test cases start here.
# ##################################
def test_ospfv3_ecmp_tc16_p0(request):
"""
Verify OSPF ECMP.
Verify OSPF ECMP with max path configured as 8 (ECMP
configured at FRR level)
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
global topo
step("Bring up the base config as per the topology")
step("Configure 8 interfaces between R1 and R2 and enable ospf in area 0.")
reset_config_on_routers(tgen)
step("Verify that OSPF is up with 8 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
step("Configure a static route in R0 and redistribute in OSPF.")
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 5,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r0"
red_static(dut)
llip = get_llip("r0", "r1-link1")
assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Verify that route in R2 in stalled with 8 next hops.")
nh = []
for item in range(1, 7):
nh.append(llip)
llip = get_llip("r0", "r1")
assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
nh2 = llip
nh.append(nh2)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("shut no shut all the interfaces on the remote router - R2")
dut = "r1"
for intfr in range(1, 7):
intf = topo["routers"]["r1"]["links"]["r0-link{}".format(intfr)]["interface"]
shutdown_bringup_interface(tgen, dut, intf, False)
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route present in OSPF RIB. Error: {}".format(
tc_name, result
)
protocol = "ospf"
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route present in RIB. Error: {}".format(tc_name, result)
for intfr in range(1, 7):
intf = topo["routers"]["r1"]["links"]["r0-link{}".format(intfr)]["interface"]
shutdown_bringup_interface(tgen, dut, intf, True)
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("shut no shut on all the interfaces on DUT (r1)")
for intfr in range(1, 7):
intf = topo["routers"]["r1"]["links"]["r0-link{}".format(intfr)]["interface"]
shutdown_bringup_interface(tgen, dut, intf, False)
for intfr in range(1, 7):
intf = topo["routers"]["r1"]["links"]["r0-link{}".format(intfr)]["interface"]
shutdown_bringup_interface(tgen, dut, intf, True)
step(
"Verify that all the neighbours are up and routes are installed"
" with 8 next hop in ospf and ip route tables on R1."
)
step("Verify that OSPF is up with 8 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
write_test_footer(tc_name)
def test_ospfv3_ecmp_tc17_p0(request):
"""
Verify OSPF ECMP.
Verify OSPF ECMP with max path configured as 2 (Edge having 2 uplink ports)
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
global topo
step("Bring up the base config as per the topology")
step("Configure 2 interfaces between R1 and R2 & enable ospf in area 0.")
reset_config_on_routers(tgen)
step("Verify that OSPF is up with 2 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
step("Configure a static route in R0 and redistribute in OSPF.")
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 5,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r0"
red_static(dut)
step("Verify that route in R2 in stalled with 2 next hops.")
llip = get_llip("r0", "r1-link1")
assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
nh1 = llip
llip = get_llip("r0", "r1")
assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
nh2 = llip
nh = [nh1, nh2]
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Configure ECMP value as 1.")
max_path = {"r1": {"ospf6": {"maximum-paths": 1}}}
result = create_router_ospf(tgen, topo, max_path)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r1"
max_path = {"r1": {"ospf6": {"maximum-paths": 2}}}
result = create_router_ospf(tgen, topo, max_path)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Configure cost on R0 as 100")
r0_ospf_cost = {"r0": {"links": {"r1": {"ospf6": {"cost": 100}}}}}
result = config_ospf6_interface(tgen, topo, r0_ospf_cost)
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
write_test_footer(tc_name)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))

View File

@ -0,0 +1,872 @@
#!/usr/bin/python
#
# Copyright (c) 2021 by VMware, Inc. ("VMware")
# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
# ("NetDEF") in this file.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""OSPF Basic Functionality Automation."""
import os
import sys
import time
import pytest
import json
from copy import deepcopy
from ipaddress import IPv4Address
from lib.topotest import frr_unicode
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
sys.path.append(os.path.join(CWD, "../lib/"))
# pylint: disable=C0413
# Import topogen and topotest helpers
from mininet.topo import Topo
from lib.topogen import Topogen, get_topogen
import ipaddress
# Import topoJson from lib, to create topology and initial configuration
from lib.common_config import (
start_topology,
write_test_header,
write_test_footer,
reset_config_on_routers,
create_prefix_lists,
verify_rib,
create_static_routes,
step,
create_route_maps,
verify_prefix_lists,
get_frr_ipv6_linklocal,
topo_daemons,
)
from lib.topolog import logger
from lib.topojson import build_topo_from_json, build_config_from_json
from lib.ospf import (
verify_ospf6_neighbor,
config_ospf_interface,
clear_ospf,
verify_ospf6_rib,
create_router_ospf,
verify_ospf6_interface,
verify_ospf6_database,
config_ospf6_interface,
)
from ipaddress import IPv6Address
# Global variables
topo = None
# Reading the data from JSON File for topology creation
jsonFile = "{}/ospfv3_routemaps.json".format(CWD)
try:
with open(jsonFile, "r") as topoJson:
topo = json.load(topoJson)
except IOError:
assert False, "Could not read file {}".format(jsonFile)
NETWORK = {
"ipv4": [
"11.0.20.1/32",
"11.0.20.2/32",
"11.0.20.3/32",
"11.0.20.4/32",
"11.0.20.5/32",
],
"ipv6": ["2::1/128", "2::2/128", "2::3/128", "2::4/128", "2::5/128"],
}
routerids = ["100.1.1.0", "100.1.1.1", "100.1.1.2", "100.1.1.3"]
"""
TOPOOLOGY =
Please view in a fixed-width font such as Courier.
+---+ A1 +---+
+R1 +------------+R2 |
+-+-+- +--++
| -- -- |
| -- A0 -- |
A0| ---- |
| ---- | A2
| -- -- |
| -- -- |
+-+-+- +-+-+
+R0 +-------------+R3 |
+---+ A3 +---+
TESTCASES =
2. Verify OSPF route map support functionality when route map is not
configured at system level but configured in OSPF
4. Verify OSPF route map support functionality
when route map actions are toggled.
5. Verify OSPF route map support functionality with multiple sequence
numbers in a single route-map for different match/set clauses.
6. Verify OSPF route map support functionality when we add/remove route-maps
with multiple set clauses and without any match statement.(Set only)
7. Verify OSPF route map support functionality when we
add/remove route-maps with multiple match clauses and without
any set statement.(Match only)
8. Verify OSPF route map applied to ospf redistribution with ipv6 prefix list
"""
class CreateTopo(Topo):
"""
Test topology builder.
* `Topo`: Topology object
"""
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
* `mod`: module name
"""
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 deamons 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)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
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 toplogy 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_ospfv3_routemaps_functionality_tc20_p0(request):
"""
OSPF route map support functionality.
Verify OSPF route map support functionality when route map is not
configured at system level but configured in OSPF
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
global topo
step("Bring up the base config as per the topology")
reset_config_on_routers(tgen)
step("Create static routes(10.0.20.1/32 and 10.0.20.2/32) in R0")
# Create Static routes
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 5,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Redistribute to ospf using route map ( non existent route map)")
ospf_red_r1 = {
"r0": {
"ospf6": {
"redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
}
}
}
result = create_router_ospf(tgen, topo, ospf_red_r1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step(
"Verify that routes are not allowed in OSPF even tough no "
"matching routing map is configured."
)
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
step(
"configure the route map with the same name that is used "
"in the ospf with deny rule."
)
# Create route map
routemaps = {"r0": {"route_maps": {"rmap_ipv6": [{"action": "deny"}]}}}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("verify that now route map is activated & routes are denied in OSPF.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
# Create route map
routemaps = {"r0": {"route_maps": {"rmap_ipv6": [{"action": "deny"}]}}}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("verify that now route map is activated & routes are denied in OSPF.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
step("Delete the route map.")
# Create route map
routemaps = {
"r0": {"route_maps": {"rmap_ipv6": [{"action": "deny", "delete": True}]}}
}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step(
"Verify that routes are allowed in OSPF even tough "
"no matching routing map is configured."
)
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
write_test_footer(tc_name)
def test_ospfv3_routemaps_functionality_tc25_p0(request):
"""
OSPF route map support functionality.
Verify OSPF route map support functionality
when route map actions are toggled.
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
global topo
step("Bring up the base config as per the topology")
reset_config_on_routers(tgen)
step(
"Create static routes(10.0.20.1/32) in R1 and redistribute "
"to OSPF using route map."
)
# Create Static routes
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 5,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
ospf_red_r0 = {
"r0": {
"ospf6": {
"redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
}
}
}
result = create_router_ospf(tgen, topo, ospf_red_r0)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Configure route map with permit rule")
# Create route map
routemaps = {"r0": {"route_maps": {"rmap_ipv6": [{"action": "permit"}]}}}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Verify that route is advertised to R1.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Configure route map with deny rule")
# Create route map
routemaps = {
"r0": {"route_maps": {"rmap_ipv6": [{"seq_id": 10, "action": "deny"}]}}
}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
step("Verify that route is not advertised to R1.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
write_test_footer(tc_name)
def test_ospfv3_routemaps_functionality_tc22_p0(request):
"""
OSPF Route map - Multiple sequence numbers.
Verify OSPF route map support functionality with multiple sequence
numbers in a single route-map for different match/set clauses.
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
global topo
step("Bring up the base config as per the topology")
reset_config_on_routers(tgen)
step(
"Configure route map with seq number 10 to with ip prefix"
" permitting route 10.0.20.1/32 in R1"
)
step(
"Configure route map with seq number 20 to with ip prefix"
" permitting route 10.0.20.2/32 in R1"
)
# Create route map
input_dict_3 = {
"r0": {
"route_maps": {
"rmap_ipv6": [
{
"action": "permit",
"seq_id": "10",
"match": {"ipv6": {"prefix_lists": "pf_list_1_ipv6"}},
},
{
"action": "permit",
"seq_id": "20",
"match": {"ipv6": {"prefix_lists": "pf_list_2_ipv4"}},
},
]
}
}
}
result = create_route_maps(tgen, input_dict_3)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
# Create ip prefix list
input_dict_2 = {
"r0": {
"prefix_lists": {
"ipv4": {
"pf_list_1_ipv6": [
{"seqid": 10, "network": NETWORK["ipv6"][0], "action": "permit"}
]
}
}
}
}
result = create_prefix_lists(tgen, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
# Create ip prefix list
input_dict_2 = {
"r0": {
"prefix_lists": {
"ipv4": {
"pf_list_2_ipv4": [
{"seqid": 10, "network": NETWORK["ipv6"][1], "action": "permit"}
]
}
}
}
}
result = create_prefix_lists(tgen, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Configure static routes 10.0.20.1/32 and 10.0.20.2 in R1")
# Create Static routes
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 5,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Configure redistribute static route with route map.")
ospf_red_r0 = {
"r0": {
"ospf6": {
"redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
}
}
}
result = create_router_ospf(tgen, topo, ospf_red_r0)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 2,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Verify that both routes are learned in R1 and R2")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r2"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Change route map with seq number 20 to deny.")
# Create route map
input_dict_3 = {
"r0": {
"route_maps": {
"rmap_ipv6": [
{
"action": "deny",
"seq_id": "20",
"match": {"ipv6": {"prefix_lists": "pf_list_2_ipv4"}},
}
]
}
}
}
result = create_route_maps(tgen, input_dict_3)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step(
"Verify the route 10.0.20.2/32 is withdrawn and not present "
"in the routing table of R0 and R1."
)
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv6"][1], "next_hop": "Null0"}]}
}
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
dut = "r2"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
tc_name, result
)
write_test_footer(tc_name)
def test_ospfv3_routemaps_functionality_tc24_p0(request):
"""
OSPF Route map - Multiple set clauses.
Verify OSPF route map support functionality when we
add/remove route-maps with multiple match clauses and without
any set statement.(Match only)
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
global topo
step("Bring up the base config as per the topology")
reset_config_on_routers(tgen)
step(
"Create static routes(10.0.20.1/32) in R1 and redistribute to "
"OSPF using route map."
)
# Create Static routes
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][0],
"no_of_ip": 1,
"next_hop": "Null0",
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
ospf_red_r0 = {
"r0": {
"ospf6": {
"redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
}
}
}
result = create_router_ospf(tgen, topo, ospf_red_r0)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
# Create ip prefix list
pfx_list = {
"r0": {
"prefix_lists": {
"ipv6": {
"pf_list_1_ipv6": [
{"seqid": 10, "network": "any", "action": "permit"}
]
}
}
}
}
result = create_prefix_lists(tgen, pfx_list)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("verify that prefix-list is created in R0.")
result = verify_prefix_lists(tgen, pfx_list)
assert (
result is not True
), "Testcase {} : Failed \n Prefix list not " "present. Error: {}".format(
tc_name, result
)
# Create route map
routemaps = {
"r0": {
"route_maps": {
"rmap_ipv6": [
{
"action": "permit",
"match": {"ipv6": {"prefix_lists": "pf_list_1_ipv6"}},
}
]
}
}
}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Verify that metric falls back to original metric for ospf routes.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step(
"Create static routes(10.0.20.1/32) in R1 and redistribute to "
"OSPF using route map."
)
# Create Static routes
input_dict = {
"r0": {
"static_routes": [
{
"network": NETWORK["ipv6"][1],
"no_of_ip": 1,
"next_hop": "Null0",
"tag": 1000,
}
]
}
}
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
# Create ip prefix list
pfx_list = {
"r0": {
"prefix_lists": {
"ipv6": {
"pf_list_1_ipv6": [
{"seqid": 10, "network": "any", "action": "permit"}
]
}
}
}
}
result = create_prefix_lists(tgen, pfx_list)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("verify that prefix-list is created in R0.")
result = verify_prefix_lists(tgen, pfx_list)
assert (
result is not True
), "Testcase {} : Failed \n Prefix list not " "present. Error: {}".format(
tc_name, result
)
# Create route map
routemaps = {
"r0": {
"route_maps": {
"rmap_ipv6": [{"action": "permit", "match": {"ipv6": {"tag": "1000"}}}]
}
}
}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Verify that metric falls back to original metric for ospf routes.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Delete the match clause with tag in route map")
# Create route map
routemaps = {
"r0": {
"route_maps": {
"rmap_ipv6": [
{
"action": "permit",
"match": {"ipv6": {"tag": "1000", "delete": True}},
}
]
}
}
}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Verify that metric falls back to original metric for ospf routes.")
dut = "r1"
protocol = "ospf"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Delete the match clause with metric in route map.")
# Create route map
routemaps = {
"r0": {
"route_maps": {
"rmap_ipv6": [
{
"action": "permit",
"match": {"ipv6": {"prefix_lists": "pf_list_1_ipv6"}},
}
]
}
}
}
result = create_route_maps(tgen, routemaps)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
write_test_footer(tc_name)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))

View File

@ -281,6 +281,233 @@ def red_connected(dut, config=True):
# ##################################
# Test cases start here.
# ##################################
def test_ospfv3_redistribution_tc5_p0(request):
"""Test OSPF intra area route calculations."""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
global topo
step("Bring up the base config.")
reset_config_on_routers(tgen)
step("Verify that OSPF neighbors are FULL.")
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
step("verify intra area route is calculated for r0-r3 interface ip in R1")
ip = topo["routers"]["r0"]["links"]["r3"]["ipv6"]
ip_net = str(ipaddress.ip_interface(u"{}".format(ip)).network)
llip = get_llip("r0", "r1")
assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, llip)
nh = llip
input_dict = {
"r1": {"static_routes": [{"network": ip_net, "no_of_ip": 1, "routeType": "N"}]}
}
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Delete the ip address on newly configured loopback of R0")
topo1 = {
"r0": {
"links": {
"r3": {
"ipv6": topo["routers"]["r0"]["links"]["r3"]["ipv6"],
"interface": topo["routers"]["r0"]["links"]["r3"]["interface"],
"delete": True,
}
}
}
}
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route present in RIB. Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route present in RIB. Error: {}".format(tc_name, result)
step("Add back the deleted ip address on newly configured interface of R0")
topo1 = {
"r0": {
"links": {
"r3": {
"ipv6": topo["routers"]["r0"]["links"]["r3"]["ipv6"],
"interface": topo["routers"]["r0"]["links"]["r3"]["interface"],
}
}
}
}
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Shut no shut interface on R0")
dut = "r0"
intf = topo["routers"]["r0"]["links"]["r3"]["interface"]
shutdown_bringup_interface(tgen, dut, intf, False)
step("un shut the OSPF interface on R0")
dut = "r0"
shutdown_bringup_interface(tgen, dut, intf, True)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
write_test_footer(tc_name)
def test_ospfv3_redistribution_tc6_p0(request):
"""Test OSPF inter area route calculations."""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
global topo
step("Bring up the base config.")
reset_config_on_routers(tgen)
step("Verify that OSPF neighbors are FULL.")
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
)
step("verify intra area route is calculated for r0-r3 interface ip in R1")
ip = topo["routers"]["r0"]["links"]["r3"]["ipv6"]
ip_net = str(ipaddress.ip_interface(u"{}".format(ip)).network)
llip = get_llip("r0", "r1")
assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, llip)
nh = llip
input_dict = {
"r1": {"static_routes": [{"network": ip_net, "no_of_ip": 1, "routeType": "N"}]}
}
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Delete the ip address on newly configured loopback of R0")
topo1 = {
"r0": {
"links": {
"r3": {
"ipv6": topo["routers"]["r0"]["links"]["r3"]["ipv6"],
"interface": topo["routers"]["r0"]["links"]["r3"]["interface"],
"delete": True,
}
}
}
}
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n Route present in RIB. Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(
tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh, expected=False
)
assert (
result is not True
), "Testcase {} : Failed \n Route present in RIB. Error: {}".format(tc_name, result)
step("Add back the deleted ip address on newly configured interface of R0")
topo1 = {
"r0": {
"links": {
"r3": {
"ipv6": topo["routers"]["r0"]["links"]["r3"]["ipv6"],
"interface": topo["routers"]["r0"]["links"]["r3"]["interface"],
}
}
}
}
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Shut no shut interface on R0")
dut = "r0"
intf = topo["routers"]["r0"]["links"]["r3"]["interface"]
shutdown_bringup_interface(tgen, dut, intf, False)
step("Verify that intraroute calculated for R1 intf on R0 is deleted.")
dut = "r1"
step("un shut the OSPF interface on R0")
dut = "r0"
shutdown_bringup_interface(tgen, dut, intf, True)
dut = "r1"
result = verify_ospf6_rib(tgen, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
protocol = "ospf"
result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, next_hop=nh)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
write_test_footer(tc_name)
def test_ospfv3_cost_tc52_p0(request):
"""OSPF Cost - verifying ospf interface cost functionality"""
tc_name = request.node.name
@ -368,7 +595,6 @@ def test_ospfv3_cost_tc52_p0(request):
write_test_footer(tc_name)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))

View File

@ -54,7 +54,7 @@ from lib.common_config import (
create_route_maps,
shutdown_bringup_interface,
create_interfaces_cfg,
topo_daemons,
topo_daemons
)
from lib.topolog import logger
from lib.topojson import build_topo_from_json, build_config_from_json