Skip to content

Commit

Permalink
tests: add support for ospf instances with unified configs
Browse files Browse the repository at this point in the history
Signed-off-by: Jafar Al-Gharaibeh <[email protected]>
  • Loading branch information
Jafaral committed Nov 1, 2024
1 parent 66ed5c1 commit 0142a18
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 24 deletions.
13 changes: 11 additions & 2 deletions tests/topotests/lib/topogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -850,12 +850,21 @@ def load_frr_config(self, source, daemons=None):
result = self.run(grep_cmd, warn=False).strip()
if result:
self.load_config(daemon, "")
if daemonstr == "ospf":
grep_cmd = "grep -E 'router ospf ([0-9]+*)' {} | grep -o -E '([0-9]*)'".format(source_path)
result = self.run(grep_cmd, warn=False)
if result: # instances
instances = result.split("\n")
for id in instances:
if id != "":
self.load_config(daemon, "", None, id)

else:
for item in daemons:
daemon, param = item
self.load_config(daemon, "", param)

def load_config(self, daemon, source=None, param=None):
def load_config(self, daemon, source=None, param=None, instance=None):
"""Loads daemon configuration from the specified source
Possible daemon values are: TopoRouter.RD_ZEBRA, TopoRouter.RD_RIP,
TopoRouter.RD_RIPNG, TopoRouter.RD_OSPF, TopoRouter.RD_OSPF6,
Expand All @@ -873,7 +882,7 @@ def load_config(self, daemon, source=None, param=None):
"""
daemonstr = self.RD.get(daemon)
self.logger.debug('loading "{}" configuration: {}'.format(daemonstr, source))
return self.net.loadConf(daemonstr, source, param)
return self.net.loadConf(daemonstr, source, param, instance)

def check_router_running(self):
"""
Expand Down
44 changes: 29 additions & 15 deletions tests/topotests/lib/topotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,7 @@ def __init__(self, name, *posargs, **params):
"snmptrapd": 0,
"fpm_listener": 0,
}
self.daemon_instances = {"ospfd" : []}
self.daemons_options = {"zebra": ""}
self.reportCores = True
self.version = None
Expand Down Expand Up @@ -1632,7 +1633,7 @@ def checkCapability(self, daemon, param):
return False
return True

def loadConf(self, daemon, source=None, param=None):
def loadConf(self, daemon, source=None, param=None, instance=None):
"""Enabled and set config for a daemon.
Arranges for loading of daemon configuration from the specified source. Possible
Expand Down Expand Up @@ -1666,6 +1667,8 @@ def loadConf(self, daemon, source=None, param=None):
self.daemons[daemon] = 1
if param is not None:
self.daemons_options[daemon] = param
if instance is not None:
self.daemon_instances[daemon].append(instance)
conf_file = "/etc/{}/{}.conf".format(self.routertype, daemon)
if source and not os.path.exists(source):
logger.warning(
Expand Down Expand Up @@ -1903,16 +1906,21 @@ def startRouterDaemons(self, daemons=None, tgen=None):
tail_log_files = []
check_daemon_files = []

def start_daemon(daemon, extra_opts=None):
def start_daemon(daemon, extra_opts=None, instance=None):
daemon_opts = self.daemons_options.get(daemon, "")

# get pid and vty filenames and remove the files
m = re.match(r"(.* |^)-n (\d+)( ?.*|$)", daemon_opts)
dfname = daemon if not m else "{}-{}".format(daemon, m.group(2))
if instance != None:
id = "-" + instance
dfname = daemon + id
else:
id = ""
runbase = "/var/run/{}/{}".format(self.routertype, dfname)
# If this is a new system bring-up remove the pid/vty files, otherwise
# do not since apparently presence of the pidfile impacts BGP GR
self.cmd_status("rm -f {0}.pid {0}.vty".format(runbase))
self.cmd_status("rm -f {0}{1}.pid {0}{1}.vty".format(runbase, id))

def do_gdb_or_rr(gdb):
routers = gdb_routers if gdb else rr_routers
Expand All @@ -1923,7 +1931,7 @@ def do_gdb_or_rr(gdb):
and (not daemons or daemon in daemons or "all" in daemons)
)

rediropt = " > {0}.out 2> {0}.err".format(daemon)
rediropt = " > {0}.out 2> {0}.err".format(dfname)
if daemon == "fpm_listener":
binary = "/usr/lib/frr/fpm_listener"
cmdenv = ""
Expand Down Expand Up @@ -1952,7 +1960,7 @@ def do_gdb_or_rr(gdb):
if asan_abort:
cmdenv += "abort_on_error=1:"
cmdenv += "log_path={0}/{1}.asan.{2} ".format(
self.logdir, self.name, daemon
self.logdir, self.name, dfname
)

if cov_option:
Expand All @@ -1967,7 +1975,7 @@ def do_gdb_or_rr(gdb):
os.path.join(this_dir, "../../../tools/valgrind.supp")
)

valgrind_logbase = f"{self.logdir}/{self.name}.valgrind.{daemon}"
valgrind_logbase = f"{self.logdir}/{self.name}.valgrind.{dfname}"
if do_gdb_or_rr(True):
cmdenv += " exec"
cmdenv += (
Expand All @@ -1989,13 +1997,13 @@ def do_gdb_or_rr(gdb):
)

cmdopt = "{} --command-log-always ".format(daemon_opts)
cmdopt += "--log file:{}.log --log-level debug".format(daemon)
cmdopt += "--log file:{}.log --log-level debug".format(dfname)

if daemon in logd_options:
logdopt = logd_options[daemon]
if "all" in logdopt or self.name in logdopt:
tail_log_files.append(
"{}/{}/{}.log".format(self.logdir, self.name, daemon)
"{}/{}/{}.log".format(self.logdir, self.name, dfname)
)

if extra_opts:
Expand Down Expand Up @@ -2037,7 +2045,7 @@ def do_gdb_or_rr(gdb):
else:
cmd = " ".join([cmdenv, binary, cmdopt])
p = self.popen(cmd)
self.valgrind_gdb_daemons[daemon] = p
self.valgrind_gdb_daemons[dfname] = p
if p.poll() and p.returncode:
self.logger.error(
'%s: Failed to launch "%s" (%s) with perf using: %s',
Expand Down Expand Up @@ -2161,7 +2169,7 @@ def emacs_gdb_ready():
["perf record {} --".format(perf_options), binary, cmdopt]
)
p = self.popen(cmd)
self.perf_daemons[daemon] = p
self.perf_daemons[dfname] = p
if p.poll() and p.returncode:
self.logger.error(
'%s: Failed to launch "%s" (%s) with perf using: %s',
Expand All @@ -2184,7 +2192,7 @@ def emacs_gdb_ready():
]
)
p = self.popen(cmd)
self.rr_daemons[daemon] = p
self.rr_daemons[dfname] = p
if p.poll() and p.returncode:
self.logger.error(
'%s: Failed to launch "%s" (%s) with rr using: %s',
Expand All @@ -2205,7 +2213,9 @@ def emacs_gdb_ready():
):
cmdopt += " -d "
cmdopt += rediropt

self.logger.info('cmdenv "{}"'.format(cmdenv))
self.logger.info('binary "{}"'.format(binary))
self.logger.info('cmdopt "{}"'.format(cmdopt))
try:
self.cmd_raises(" ".join([cmdenv, binary, cmdopt]), warn=False)
except subprocess.CalledProcessError as error:
Expand Down Expand Up @@ -2265,7 +2275,11 @@ def emacs_gdb_ready():
for daemon in daemons_list:
if self.daemons[daemon] == 0:
continue
start_daemon(daemon)
if daemon == "ospfd" and self.daemon_instances[daemon] != None:
for id in self.daemon_instances[daemon]:
start_daemon(daemon, "--instance " + id, id)
else:
start_daemon(daemon)

# Check if daemons are running.
wait_time = 30 if (gdb_routers or gdb_daemons) else 10
Expand All @@ -2282,8 +2296,8 @@ def emacs_gdb_ready():

if check_daemon_files:
assert False, "Timeout({}) waiting for {} to appear on {}".format(
wait_time, check_daemon_files[0], self.name
)
wait_time, check_daemon_files[0], self.name
)

# Update the permissions on the log files
self.cmd("chown frr:frr -R {}/{}".format(self.logdir, self.name))
Expand Down
7 changes: 7 additions & 0 deletions tests/topotests/ospf_instance_redistribute/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
interface lo
ip address 192.168.100.1/24
!

router ospf 3
network 10.10.1.0/24 area 0.0.0.0
redistribute sharp
2 changes: 0 additions & 2 deletions tests/topotests/ospf_instance_redistribute/r1/ospfd-3.conf

This file was deleted.

2 changes: 0 additions & 2 deletions tests/topotests/ospf_instance_redistribute/r1/zebra.conf

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ def setup_module(module):

# This is a sample of configuration loading.
r1 = tgen.gears["r1"]
r1.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf"))
r1.load_config(TopoRouter.RD_OSPF, os.path.join(CWD, "r1/ospfd-3.conf"), "-n 3")
r1.load_config(TopoRouter.RD_SHARP, os.path.join(CWD, "r1/sharpd.conf"))
r1.load_frr_config(os.path.join(CWD, "r1/frr.conf"))

tgen.start_router()

Expand Down

0 comments on commit 0142a18

Please sign in to comment.