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.py113
1 files changed, 101 insertions, 12 deletions
diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py
index b5fa2ea59b..e34d1cf0be 100644
--- a/tests/topotests/lib/topotest.py
+++ b/tests/topotests/lib/topotest.py
@@ -29,7 +29,6 @@ import re
import sys
import functools
import glob
-import StringIO
import subprocess
import tempfile
import platform
@@ -721,6 +720,49 @@ def ip4_route(node):
return result
+def ip4_vrf_route(node):
+ """
+ Gets a structured return of the command 'ip route show vrf {0}-cust1'.
+ It can be used in conjuction with json_cmp() to provide accurate assert explanations.
+
+ Return example:
+ {
+ '10.0.1.0/24': {
+ 'dev': 'eth0',
+ 'via': '172.16.0.1',
+ 'proto': '188',
+ },
+ '10.0.2.0/24': {
+ 'dev': 'eth1',
+ 'proto': 'kernel',
+ }
+ }
+ """
+ output = normalize_text(
+ node.run("ip route show vrf {0}-cust1".format(node.name))).splitlines()
+
+ result = {}
+ for line in output:
+ columns = line.split(" ")
+ route = result[columns[0]] = {}
+ prev = None
+ for column in columns:
+ if prev == "dev":
+ route["dev"] = column
+ if prev == "via":
+ route["via"] = column
+ if prev == "proto":
+ # translate protocol names back to numbers
+ route["proto"] = proto_name_to_number(column)
+ if prev == "metric":
+ route["metric"] = column
+ if prev == "scope":
+ route["scope"] = column
+ prev = column
+
+ return result
+
+
def ip6_route(node):
"""
Gets a structured return of the command 'ip -6 route'. It can be used in
@@ -761,6 +803,47 @@ def ip6_route(node):
return result
+def ip6_vrf_route(node):
+ """
+ Gets a structured return of the command 'ip -6 route show vrf {0}-cust1'.
+ It can be used in conjuction with json_cmp() to provide accurate assert explanations.
+
+ Return example:
+ {
+ '2001:db8:1::/64': {
+ 'dev': 'eth0',
+ 'proto': '188',
+ },
+ '2001:db8:2::/64': {
+ 'dev': 'eth1',
+ 'proto': 'kernel',
+ }
+ }
+ """
+ output = normalize_text(
+ node.run("ip -6 route show vrf {0}-cust1".format(node.name))).splitlines()
+ result = {}
+ for line in output:
+ columns = line.split(" ")
+ route = result[columns[0]] = {}
+ prev = None
+ for column in columns:
+ if prev == "dev":
+ route["dev"] = column
+ if prev == "via":
+ route["via"] = column
+ if prev == "proto":
+ # translate protocol names back to numbers
+ route["proto"] = proto_name_to_number(column)
+ if prev == "metric":
+ route["metric"] = column
+ if prev == "pref":
+ route["pref"] = column
+ prev = column
+
+ return result
+
+
def ip_rules(node):
"""
Gets a structured return of the command 'ip rule'. It can be used in
@@ -1013,12 +1096,9 @@ class Router(Node):
self.cmd("chown {0}:{0}vty /etc/{0}".format(self.routertype))
def terminate(self):
- # Delete Running Quagga or FRR Daemons
+ # Stop running FRR daemons
self.stopRouter()
- # rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype)
- # for d in StringIO.StringIO(rundaemons):
- # self.cmd('kill -7 `cat %s`' % d.rstrip())
- # self.waitOutput()
+
# Disable forwarding
set_sysctl(self, "net.ipv4.ip_forward", 0)
set_sysctl(self, "net.ipv6.conf.all.forwarding", 0)
@@ -1033,10 +1113,12 @@ class Router(Node):
if re.search(r"No such file or directory", rundaemons):
return 0
if rundaemons is not None:
- for d in StringIO.StringIO(rundaemons):
+ bet = rundaemons.split('\n')
+ for d in bet[:-1]:
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
ret.append(os.path.basename(d.rstrip().rsplit(".", 1)[0]))
+
return ret
def stopRouter(self, wait=True, assertOnError=True, minErrorVersion="5.1"):
@@ -1046,7 +1128,9 @@ class Router(Node):
if re.search(r"No such file or directory", rundaemons):
return errors
if rundaemons is not None:
- for d in StringIO.StringIO(rundaemons):
+ dmns = rundaemons.split('\n')
+ # Exclude empty string at end of list
+ for d in dmns[:-1]:
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
daemonname = os.path.basename(d.rstrip().rsplit(".", 1)[0])
@@ -1080,7 +1164,9 @@ class Router(Node):
if running:
# 2nd round of kill if daemons didn't exit
- for d in StringIO.StringIO(rundaemons):
+ dmns = rundaemons.split('\n')
+ # Exclude empty string at end of list
+ for d in dmns[:-1]:
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
logger.info(
@@ -1265,7 +1351,7 @@ class Router(Node):
zebra_path = os.path.join(self.daemondir, "zebra")
zebra_option = self.daemons_options["zebra"]
self.cmd(
- "{0} {1} --log stdout --log-level debug -d > zebra.out 2> zebra.err".format(
+ "{0} {1} --log stdout --log-level debug -s 90000000 -d > zebra.out 2> zebra.err".format(
zebra_path, zebra_option, self.logdir, self.name
)
)
@@ -1330,7 +1416,9 @@ class Router(Node):
for daemon in daemons:
if rundaemons is not None and daemon in rundaemons:
numRunning = 0
- for d in StringIO.StringIO(rundaemons):
+ dmns = rundaemons.split('\n')
+ # Exclude empty string at end of list
+ for d in dmns[:-1]:
if re.search(r"%s" % daemon, d):
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
@@ -1351,8 +1439,9 @@ class Router(Node):
self.name, daemon
),
)
+
# 2nd round of kill if daemons didn't exit
- for d in StringIO.StringIO(rundaemons):
+ for d in dmns[:-1]:
if re.search(r"%s" % daemon, d):
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(