diff options
Diffstat (limited to 'tests/topotests/lib/topotest.py')
| -rw-r--r-- | tests/topotests/lib/topotest.py | 222 |
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 |
