summaryrefslogtreecommitdiff
path: root/tests/topotests/lib/topotest.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/topotests/lib/topotest.py')
-rw-r--r--tests/topotests/lib/topotest.py222
1 files changed, 117 insertions, 105 deletions
diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py
index 9d945d5262..bffb8208e7 100644
--- a/tests/topotests/lib/topotest.py
+++ b/tests/topotests/lib/topotest.py
@@ -991,14 +991,28 @@ class Router(Node):
super(Router, self).terminate()
os.system("chmod -R go+rw /tmp/topotests")
+ # Return count of running daemons
+ def countDaemons(self):
+ numRunning = 0
+ rundaemons = self.cmd("ls -1 /var/run/%s/*.pid" % self.routertype)
+ errors = ""
+ if re.search(r"No such file or directory", rundaemons):
+ return 0
+ if rundaemons is not None:
+ for d in StringIO.StringIO(rundaemons):
+ daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
+ if daemonpid.isdigit() and pid_exists(int(daemonpid)):
+ numRunning += 1
+ return numRunning
+
def stopRouter(self, wait=True, assertOnError=True, minErrorVersion="5.1"):
- # Stop Running Quagga or FRR Daemons
+ # Stop Running FRR Daemons
+ numRunning = 0
rundaemons = self.cmd("ls -1 /var/run/%s/*.pid" % self.routertype)
errors = ""
if re.search(r"No such file or directory", rundaemons):
return errors
if rundaemons is not None:
- numRunning = 0
for d in StringIO.StringIO(rundaemons):
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
@@ -1011,8 +1025,15 @@ class Router(Node):
self.waitOutput()
if pid_exists(int(daemonpid)):
numRunning += 1
+
+ if wait and numRunning > 0:
+ counter = 5
+ while counter > 0 and numRunning > 0:
+ sleep(2, "{}: waiting for daemons stopping".format(self.name))
+ numRunning = self.countDaemons()
+ counter -= 1
+
if wait and numRunning > 0:
- sleep(2, "{}: waiting for daemons stopping".format(self.name))
# 2nd round of kill if daemons didn't exit
for d in StringIO.StringIO(rundaemons):
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
@@ -1026,6 +1047,7 @@ class Router(Node):
self.cmd("kill -7 %s" % daemonpid)
self.waitOutput()
self.cmd("rm -- {}".format(d.rstrip()))
+
if wait:
errors = self.checkRouterCores(reportOnce=True)
if self.checkRouterVersion("<", minErrorVersion):
@@ -1144,135 +1166,116 @@ class Router(Node):
logger.info("BFD Test, but no bfdd compiled or installed")
return "BFD Test, but no bfdd compiled or installed"
- self.restartRouter()
- return ""
+ return self.startRouterDaemons()
+
+ def getStdErr(self, daemon):
+ return self.getLog("err", daemon)
+
+ def getStdOut(self, daemon):
+ return self.getLog("out", daemon)
+
+ def getLog(self, log, daemon):
+ return self.cmd("cat {}/{}/{}.{}".format(self.logdir, self.name, daemon, log))
+
+ def startRouterDaemons(self, daemons=None):
+ "Starts all FRR daemons for this router."
+
+ bundle_data = ''
+
+ if os.path.exists('/etc/frr/support_bundle_commands.conf'):
+ bundle_data = subprocess.check_output(
+ ["cat /etc/frr/support_bundle_commands.conf"], shell=True)
+ self.cmd(
+ "echo '{}' > /etc/frr/support_bundle_commands.conf".format(bundle_data)
+ )
- def restartRouter(self):
# Starts actual daemons without init (ie restart)
# cd to per node directory
self.cmd("cd {}/{}".format(self.logdir, self.name))
self.cmd("umask 000")
+
# Re-enable to allow for report per run
self.reportCores = True
+
+ # XXX: glue code forward ported from removed function.
if self.version == None:
self.version = self.cmd(
os.path.join(self.daemondir, "bgpd") + " -v"
).split()[2]
logger.info("{}: running version: {}".format(self.name, self.version))
+
+ # If `daemons` was specified then some upper API called us with
+ # specific daemons, otherwise just use our own configuration.
+ daemons_list = []
+ if daemons is None:
+ # Append all daemons configured.
+ for daemon in self.daemons:
+ if self.daemons[daemon] == 1:
+ daemons_list.append(daemon)
+
# Start Zebra first
- if self.daemons["zebra"] == 1:
+ if "zebra" in daemons_list:
zebra_path = os.path.join(self.daemondir, "zebra")
zebra_option = self.daemons_options["zebra"]
self.cmd(
- "{0} {1} > zebra.out 2> zebra.err &".format(
+ "{0} {1} --log stdout --log-level debug -d > zebra.out 2> zebra.err".format(
zebra_path, zebra_option, self.logdir, self.name
)
)
- self.waitOutput()
logger.debug("{}: {} zebra started".format(self, self.routertype))
- sleep(1, "{}: waiting for zebra to start".format(self.name))
+
+ # Remove `zebra` so we don't attempt to start it again.
+ while "zebra" in daemons_list:
+ daemons_list.remove("zebra")
+
# Start staticd next if required
- if self.daemons["staticd"] == 1:
+ if "staticd" in daemons_list:
staticd_path = os.path.join(self.daemondir, "staticd")
staticd_option = self.daemons_options["staticd"]
self.cmd(
- "{0} {1} > staticd.out 2> staticd.err &".format(
+ "{0} {1} --log stdout --log-level debug -d > staticd.out 2> staticd.err".format(
staticd_path, staticd_option, self.logdir, self.name
)
)
- self.waitOutput()
logger.debug("{}: {} staticd started".format(self, self.routertype))
+
+ # Remove `staticd` so we don't attempt to start it again.
+ while "staticd" in daemons_list:
+ daemons_list.remove("staticd")
+
# Fix Link-Local Addresses
# Somehow (on Mininet only), Zebra removes the IPv6 Link-Local addresses on start. Fix this
self.cmd(
"for i in `ls /sys/class/net/` ; do mac=`cat /sys/class/net/$i/address`; IFS=':'; set $mac; unset IFS; ip address add dev $i scope link fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6/64; done"
)
+
# Now start all the other daemons
- for daemon in self.daemons:
+ for daemon in daemons_list:
# Skip disabled daemons and zebra
- if self.daemons[daemon] == 0 or daemon == "zebra" or daemon == "staticd":
+ if self.daemons[daemon] == 0:
continue
+
daemon_path = os.path.join(self.daemondir, daemon)
self.cmd(
- "{0} {1} > {2}.out 2> {2}.err &".format(
+ "{0} {1} --log stdout --log-level debug -d > {2}.out 2> {2}.err".format(
daemon_path, self.daemons_options.get(daemon, ""), daemon
)
)
- self.waitOutput()
logger.debug("{}: {} {} started".format(self, self.routertype, daemon))
- def getStdErr(self, daemon):
- return self.getLog("err", daemon)
-
- def getStdOut(self, daemon):
- return self.getLog("out", daemon)
-
- def getLog(self, log, daemon):
- return self.cmd("cat {}/{}/{}.{}".format(self.logdir, self.name, daemon, log))
-
- def startRouterDaemons(self, daemons):
- # Starts actual daemons without init (ie restart)
- # cd to per node directory
- self.cmd('cd {}/{}'.format(self.logdir, self.name))
- self.cmd('umask 000')
- #Re-enable to allow for report per run
- self.reportCores = True
- rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype)
-
- for daemon in daemons:
- if daemon == 'zebra':
- # Start Zebra first
- if self.daemons['zebra'] == 1:
- zebra_path = os.path.join(self.daemondir, 'zebra')
- zebra_option = self.daemons_options['zebra']
- self.cmd('{0} {1} > zebra.out 2> zebra.err &'.format(
- zebra_path, zebra_option, self.logdir, self.name
- ))
- self.waitOutput()
- logger.debug('{}: {} zebra started'.format(self, self.routertype))
- sleep(1, '{}: waiting for zebra to start'.format(self.name))
-
- # Fix Link-Local Addresses
- # Somehow (on Mininet only), Zebra removes the IPv6 Link-Local
- # addresses on start. Fix this
- self.cmd('for i in `ls /sys/class/net/` ; do mac=`cat /sys/class/net/$i/address`; IFS=\':\'; set $mac; unset IFS; ip address add dev $i scope link fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6/64; done')
-
- if daemon == 'staticd':
- # Start staticd next if required
- if self.daemons['staticd'] == 1:
- staticd_path = os.path.join(self.daemondir, 'staticd')
- staticd_option = self.daemons_options['staticd']
- self.cmd('{0} {1} > staticd.out 2> staticd.err &'.format(
- staticd_path, staticd_option, self.logdir, self.name
- ))
- self.waitOutput()
- logger.debug('{}: {} staticd started'.format(self, self.routertype))
- sleep(1, '{}: waiting for staticd to start'.format(self.name))
-
- # Now start all the daemons
- # Skip disabled daemons and zebra
- if self.daemons[daemon] == 0 or daemon == 'zebra' or daemon == 'staticd':
- continue
- daemon_path = os.path.join(self.daemondir, daemon)
- self.cmd('{0} > {1}.out 2> {1}.err &'.format(
- daemon_path, daemon
- ))
- self.waitOutput()
- logger.debug('{}: {} {} started'.format(self, self.routertype, daemon))
- sleep(1, '{}: waiting for {} to start'.format(self.name, daemon))
-
- rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype)
-
+ # Check if daemons are running.
+ rundaemons = self.cmd("ls -1 /var/run/%s/*.pid" % self.routertype)
if re.search(r"No such file or directory", rundaemons):
return "Daemons are not running"
return ""
- def killRouterDaemons(self, daemons, wait=True, assertOnError=True,
- minErrorVersion='5.1'):
+ def killRouterDaemons(
+ self, daemons, wait=True, assertOnError=True, minErrorVersion="5.1"
+ ):
# Kill Running Quagga or FRR specific
# Daemons(user specified daemon only) using SIGKILL
- rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype)
+ rundaemons = self.cmd("ls -1 /var/run/%s/*.pid" % self.routertype)
errors = ""
daemonsNotRunning = []
if re.search(r"No such file or directory", rundaemons):
@@ -1282,45 +1285,54 @@ class Router(Node):
numRunning = 0
for d in StringIO.StringIO(rundaemons):
if re.search(r"%s" % daemon, d):
- daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip()
- if (daemonpid.isdigit() and pid_exists(int(daemonpid))):
- logger.info('{}: killing {}'.format(
- self.name,
- os.path.basename(d.rstrip().rsplit(".", 1)[0])
- ))
- self.cmd('kill -9 %s' % daemonpid)
+ daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
+ if daemonpid.isdigit() and pid_exists(int(daemonpid)):
+ logger.info(
+ "{}: killing {}".format(
+ self.name,
+ os.path.basename(d.rstrip().rsplit(".", 1)[0]),
+ )
+ )
+ self.cmd("kill -9 %s" % daemonpid)
self.waitOutput()
if pid_exists(int(daemonpid)):
numRunning += 1
if wait and numRunning > 0:
- sleep(2, '{}: waiting for {} daemon to be stopped'.\
- format(self.name, daemon))
+ sleep(
+ 2,
+ "{}: waiting for {} daemon to be stopped".format(
+ self.name, daemon
+ ),
+ )
# 2nd round of kill if daemons didn't exit
for d in StringIO.StringIO(rundaemons):
if re.search(r"%s" % daemon, d):
- daemonpid = \
- self.cmd('cat %s' % d.rstrip()).rstrip()
- if (daemonpid.isdigit() and pid_exists(
- int(daemonpid))):
- logger.info('{}: killing {}'.format(
- self.name,
- os.path.basename(d.rstrip().\
- rsplit(".", 1)[0])
- ))
- self.cmd('kill -9 %s' % daemonpid)
+ daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
+ if daemonpid.isdigit() and pid_exists(
+ int(daemonpid)
+ ):
+ logger.info(
+ "{}: killing {}".format(
+ self.name,
+ os.path.basename(
+ d.rstrip().rsplit(".", 1)[0]
+ ),
+ )
+ )
+ self.cmd("kill -9 %s" % daemonpid)
self.waitOutput()
- self.cmd('rm -- {}'.format(d.rstrip()))
+ self.cmd("rm -- {}".format(d.rstrip()))
if wait:
errors = self.checkRouterCores(reportOnce=True)
- if self.checkRouterVersion('<', minErrorVersion):
- #ignore errors in old versions
+ if self.checkRouterVersion("<", minErrorVersion):
+ # ignore errors in old versions
errors = ""
if assertOnError and len(errors) > 0:
assert "Errors found - details follow:" == 0, errors
else:
daemonsNotRunning.append(daemon)
if len(daemonsNotRunning) > 0:
- errors = errors+"Daemons are not running", daemonsNotRunning
+ errors = errors + "Daemons are not running", daemonsNotRunning
return errors