added flake8/black, pre-commit integration for flake8/black, and black formatting changes

This commit is contained in:
bharnden 2019-09-10 15:10:24 -07:00
parent d5055f85d3
commit 1fc8d647c3
77 changed files with 4452 additions and 1964 deletions

View file

@ -51,7 +51,9 @@ def cmd(node, exec_cmd):
tlvdata = CoreExecuteTlv.pack(ExecuteTlvs.NODE.value, node.id)
tlvdata += CoreExecuteTlv.pack(ExecuteTlvs.NUMBER.value, exec_num)
tlvdata += CoreExecuteTlv.pack(ExecuteTlvs.COMMAND.value, exec_cmd)
msg = coreapi.CoreExecMessage.pack(MessageFlags.STRING.value | MessageFlags.TEXT.value, tlvdata)
msg = coreapi.CoreExecMessage.pack(
MessageFlags.STRING.value | MessageFlags.TEXT.value, tlvdata
)
node.session.broker.handlerawmsg(msg)
exec_num += 1
@ -81,10 +83,16 @@ def main():
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=5, daemon="127.0.0.1:" + str(CORE_API_PORT))
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
parser.add_option("-d", "--daemon-server", dest="daemon", type=str,
help="daemon server IP address")
parser.add_option(
"-n", "--numnodes", dest="numnodes", type=int, help="number of nodes"
)
parser.add_option(
"-d",
"--daemon-server",
dest="daemon",
type=str,
help="daemon server IP address",
)
def usage(msg=None, err=0):
sys.stdout.write("\n")
@ -134,7 +142,9 @@ def main():
# Change to configuration state on both machines
session.set_state(EventTypes.CONFIGURATION_STATE)
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value)
tlvdata = coreapi.CoreEventTlv.pack(
EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value
)
session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))
flags = MessageFlags.ADD.value
@ -147,11 +157,15 @@ def main():
number_of_nodes = options.numnodes
print("creating %d remote nodes with addresses from %s" % (options.numnodes, prefix))
print(
"creating %d remote nodes with addresses from %s" % (options.numnodes, prefix)
)
# create remote nodes via API
for i in range(1, number_of_nodes + 1):
node = core.nodes.base.CoreNode(session=session, _id=i, name="n%d" % i, start=False)
node = core.nodes.base.CoreNode(
session=session, _id=i, name="n%d" % i, start=False
)
node.setposition(x=150 * i, y=150)
node.server = daemon
node_data = node.data(flags)
@ -165,14 +179,20 @@ def main():
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, i)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value, LinkTypes.WIRED.value)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value, 0)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4.value, prefix.addr(i))
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4_MASK.value, prefix.prefixlen)
tlvdata += coreapi.CoreLinkTlv.pack(
LinkTlvs.INTERFACE2_IP4.value, prefix.addr(i)
)
tlvdata += coreapi.CoreLinkTlv.pack(
LinkTlvs.INTERFACE2_IP4_MASK.value, prefix.prefixlen
)
msg = coreapi.CoreLinkMessage.pack(flags, tlvdata)
session.broker.handlerawmsg(msg)
# We change the daemon to Instantiation state
# We do not change the local session as it would try and build a tunnel and fail
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value)
tlvdata = coreapi.CoreEventTlv.pack(
EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value
)
msg = coreapi.CoreEventMessage.pack(0, tlvdata)
session.broker.handlerawmsg(msg)
@ -181,7 +201,9 @@ def main():
pingip = cmd(n[-1], "ip -4 -o addr show dev eth0").split()[3].split("/")[0]
print(cmd(n[1], "ping -c 5 " + pingip))
print("elapsed time: %s" % (datetime.datetime.now() - start))
print("To stop this session, use the core-cleanup script on the remote daemon server.")
print(
"To stop this session, use the core-cleanup script on the remote daemon server."
)
raw_input("press enter to exit")

View file

@ -38,10 +38,12 @@ def main():
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=5, slave=None)
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
parser.add_option("-s", "--slave-server", dest="slave", type=str,
help="slave server IP address")
parser.add_option(
"-n", "--numnodes", dest="numnodes", type=int, help="number of nodes"
)
parser.add_option(
"-s", "--slave-server", dest="slave", type=str, help="slave server IP address"
)
def usage(msg=None, err=0):
sys.stdout.write("\n")
@ -65,11 +67,11 @@ def main():
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1)
if 'server' in globals():
if "server" in globals():
server.addsession(session)
# distributed setup - connect to slave server
slaveport = options.slave.split(':')
slaveport = options.slave.split(":")
slave = slaveport[0]
if len(slaveport) > 1:
port = int(slaveport[1])
@ -79,15 +81,19 @@ def main():
session.broker.addserver(slave, slave, port)
session.broker.setupserver(slave)
session.set_state(EventTypes.CONFIGURATION_STATE)
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value)
tlvdata = coreapi.CoreEventTlv.pack(
EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value
)
session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))
switch = session.create_node(cls=core.nodes.network.SwitchNode, name="switch")
switch.setposition(x=80, y=50)
num_local = options.numnodes / 2
num_remote = options.numnodes / 2 + options.numnodes % 2
print("creating %d (%d local / %d remote) nodes with addresses from %s" % \
(options.numnodes, num_local, num_remote, prefix))
print(
"creating %d (%d local / %d remote) nodes with addresses from %s"
% (options.numnodes, num_local, num_remote, prefix)
)
for i in range(1, num_local + 1):
node = session.create_node(cls=core.nodes.base.CoreNode, name="n%d" % i, _id=i)
node.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
@ -100,7 +106,9 @@ def main():
# create remote nodes via API
for i in range(num_local + 1, options.numnodes + 1):
node = core.nodes.base.CoreNode(session=session, _id=i, name="n%d" % i, start=False)
node = core.nodes.base.CoreNode(
session=session, _id=i, name="n%d" % i, start=False
)
node.setposition(x=150 * i, y=150)
node.server = slave
n.append(node)
@ -114,13 +122,19 @@ def main():
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, i)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value, LinkTypes.WIRED.value)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value, 0)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4.value, prefix.addr(i))
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4_MASK.value, prefix.prefixlen)
tlvdata += coreapi.CoreLinkTlv.pack(
LinkTlvs.INTERFACE2_IP4.value, prefix.addr(i)
)
tlvdata += coreapi.CoreLinkTlv.pack(
LinkTlvs.INTERFACE2_IP4_MASK.value, prefix.prefixlen
)
msg = coreapi.CoreLinkMessage.pack(flags, tlvdata)
session.broker.handlerawmsg(msg)
session.instantiate()
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value)
tlvdata = coreapi.CoreEventTlv.pack(
EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value
)
msg = coreapi.CoreEventMessage.pack(0, tlvdata)
session.broker.handlerawmsg(msg)

View file

@ -78,27 +78,57 @@ switchlist = []
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(waittime=0.2, numnodes=0, bridges=0, retries=0,
logfile=None, services=None)
parser.set_defaults(
waittime=0.2, numnodes=0, bridges=0, retries=0, logfile=None, services=None
)
parser.add_option("-w", "--waittime", dest="waittime", type=float,
help="number of seconds to wait between node creation" \
" (default = %s)" % parser.defaults["waittime"])
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes (default = unlimited)")
parser.add_option("-b", "--bridges", dest="bridges", type=int,
help="number of nodes per bridge; 0 = one bridge " \
"(def. = %s)" % parser.defaults["bridges"])
parser.add_option("-r", "--retry", dest="retries", type=int,
help="number of retries on error (default = %s)" % \
parser.defaults["retries"])
parser.add_option("-l", "--log", dest="logfile", type=str,
help="log memory usage to this file (default = %s)" % \
parser.defaults["logfile"])
parser.add_option("-s", "--services", dest="services", type=str,
help="pipe-delimited list of services added to each "
"node (default = %s)\n(Example: zebra|OSPFv2|OSPFv3|"
"IPForward)" % parser.defaults["services"])
parser.add_option(
"-w",
"--waittime",
dest="waittime",
type=float,
help="number of seconds to wait between node creation"
" (default = %s)" % parser.defaults["waittime"],
)
parser.add_option(
"-n",
"--numnodes",
dest="numnodes",
type=int,
help="number of nodes (default = unlimited)",
)
parser.add_option(
"-b",
"--bridges",
dest="bridges",
type=int,
help="number of nodes per bridge; 0 = one bridge "
"(def. = %s)" % parser.defaults["bridges"],
)
parser.add_option(
"-r",
"--retry",
dest="retries",
type=int,
help="number of retries on error (default = %s)" % parser.defaults["retries"],
)
parser.add_option(
"-l",
"--log",
dest="logfile",
type=str,
help="log memory usage to this file (default = %s)"
% parser.defaults["logfile"],
)
parser.add_option(
"-s",
"--services",
dest="services",
type=str,
help="pipe-delimited list of services added to each "
"node (default = %s)\n(Example: zebra|OSPFv2|OSPFv3|"
"IPForward)" % parser.defaults["services"],
)
def usage(msg=None, err=0):
sys.stdout.write("\n")
@ -118,7 +148,10 @@ def main():
print("Testing how many network namespace nodes this machine can create.")
print(" - %s" % linuxversion())
mem = memfree()
print(" - %.02f GB total memory (%.02f GB swap)" % (mem["total"] / GBD, mem["stotal"] / GBD))
print(
" - %.02f GB total memory (%.02f GB swap)"
% (mem["total"] / GBD, mem["stotal"] / GBD)
)
print(" - using IPv4 network prefix %s" % prefix)
print(" - using wait time of %s" % options.waittime)
print(" - using %d nodes per bridge" % options.bridges)
@ -149,9 +182,15 @@ def main():
if 0 < options.bridges <= switch.numnetif():
switch = session.create_node(cls=core.nodes.network.SwitchNode)
switchlist.append(switch)
print("\nAdded bridge %s (%d) for node %d." % (switch.brname, len(switchlist), i))
print(
"\nAdded bridge %s (%d) for node %d."
% (switch.brname, len(switchlist), i)
)
except Exception as e:
print("At %d bridges (%d nodes) caught exception:\n%s\n" % (len(switchlist), i - 1, e))
print(
"At %d bridges (%d nodes) caught exception:\n%s\n"
% (len(switchlist), i - 1, e)
)
break
# create a node
@ -164,11 +203,11 @@ def main():
session.services.boot_services(n)
nodelist.append(n)
if i % 25 == 0:
print("\n%s nodes created " % i,)
print("\n%s nodes created " % i)
mem = memfree()
free = mem["free"] + mem["buff"] + mem["cached"]
swap = mem["stotal"] - mem["sfree"]
print("(%.02f/%.02f GB free/swap)" % (free / GBD, swap / GBD),)
print("(%.02f/%.02f GB free/swap)" % (free / GBD, swap / GBD))
if lfp:
lfp.write("%d," % i)
lfp.write("%s\n" % ",".join(str(mem[x]) for x in MEMKEYS))

View file

@ -19,6 +19,7 @@ from string import Template
import core.nodes.base
import core.nodes.network
from core.constants import QUAGGA_STATE_DIR
# this is the /etc/core/core.conf default
from core.emulator.session import Session
from core.nodes import ipaddress
@ -42,7 +43,9 @@ except OSError:
class ManetNode(core.nodes.base.CoreNode):
""" An Lxc namespace node configured for Quagga OSPFv3 MANET MDR
"""
conftemp = Template("""\
conftemp = Template(
"""\
interface eth0
ip address $ipaddr
ipv6 ospf6 instance-id 65
@ -59,12 +62,12 @@ router ospf6
interface eth0 area 0.0.0.0
!
ip forwarding
""")
"""
)
confdir = "/usr/local/etc/quagga"
def __init__(self, core, ipaddr, routerid=None,
_id=None, name=None, nodedir=None):
def __init__(self, core, ipaddr, routerid=None, _id=None, name=None, nodedir=None):
if routerid is None:
routerid = ipaddr.split("/")[0]
self.ipaddr = ipaddr
@ -74,8 +77,7 @@ ip forwarding
self.privatedir(QUAGGA_STATE_DIR)
def qconf(self):
return self.conftemp.substitute(ipaddr=self.ipaddr,
routerid=self.routerid)
return self.conftemp.substitute(ipaddr=self.ipaddr, routerid=self.routerid)
def config(self):
filename = os.path.join(self.confdir, "Quagga.conf")
@ -120,7 +122,11 @@ waitfile $STATEDIR/zebra.vty
waitfile $STATEDIR/ospf6d.vty
vtysh -b
""" % (QUAGGA_STATE_DIR, quagga_path, quagga_path)
""" % (
QUAGGA_STATE_DIR,
quagga_path,
quagga_path,
)
class Route(object):
@ -130,14 +136,19 @@ class Route(object):
try:
self.prefix = ipaddress.Ipv4Prefix(prefix)
except Exception as e:
raise ValueError("Invalid prefix given to Route object: %s\n%s" % (prefix, e))
raise ValueError(
"Invalid prefix given to Route object: %s\n%s" % (prefix, e)
)
self.gw = gw
self.metric = metric
def __eq__(self, other):
try:
return self.prefix == other.prefix and self.gw == other.gw and \
self.metric == other.metric
return (
self.prefix == other.prefix
and self.gw == other.gw
and self.metric == other.metric
)
except:
return False
@ -169,13 +180,13 @@ class ManetExperiment(object):
self.logbegin()
def info(self, msg):
''' Utility method for writing output to stdout. '''
""" Utility method for writing output to stdout. """
print(msg)
sys.stdout.flush()
self.log(msg)
def warn(self, msg):
''' Utility method for writing output to stderr. '''
""" Utility method for writing output to stderr. """
sys.stderr.write(msg)
sys.stderr.flush()
self.log(msg)
@ -193,8 +204,7 @@ class ManetExperiment(object):
if not self.logfp:
return
end = datetime.datetime.now()
self.log("ospfmanetmdrtest end: %s (%s)\n" % \
(end.ctime(), end - self.start))
self.log("ospfmanetmdrtest end: %s (%s)\n" % (end.ctime(), end - self.start))
self.logfp.flush()
self.logfp.close()
self.logfp = None
@ -245,7 +255,9 @@ class ManetExperiment(object):
self.net = self.session.create_node(cls=core.nodes.network.WlanNode)
for i in range(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.create_node(cls=ManetNode, ipaddr=addr, _id="%d" % i, name="n%d" % i)
tmp = self.session.create_node(
cls=ManetNode, ipaddr=addr, _id="%d" % i, name="n%d" % i
)
tmp.newnetif(self.net, [addr])
self.nodes.append(tmp)
# connect nodes with probability linkprob
@ -301,8 +313,9 @@ class ManetExperiment(object):
break
if not connected:
msg = "All routers do not form a CDS"
self.warn("XXX %s: not in CDS; neighbors: %s" % \
(n.routerid, nbrs[n.routerid]))
self.warn(
"XXX %s: not in CDS; neighbors: %s" % (n.routerid, nbrs[n.routerid])
)
if self.verbose:
self.info(msg)
@ -315,8 +328,9 @@ class ManetExperiment(object):
db = lsdbs[n.routerid]
if lsdbs[prev.routerid] != db:
msg = "LSDBs of all routers are not consistent"
self.warn("XXX LSDBs inconsistent for %s and %s" % \
(n.routerid, prev.routerid))
self.warn(
"XXX LSDBs inconsistent for %s and %s" % (n.routerid, prev.routerid)
)
i = 0
for entry in lsdbs[n.routerid].split("\n"):
preventries = lsdbs[prev.routerid].split("\n")
@ -355,6 +369,7 @@ class ManetExperiment(object):
class Cmd:
""" Helper class for running a command on a node and parsing the result. """
args = ""
def __init__(self, node, verbose=False):
@ -366,12 +381,12 @@ class Cmd:
self.verbose = verbose
def info(self, msg):
''' Utility method for writing output to stdout.'''
""" Utility method for writing output to stdout."""
print(msg)
sys.stdout.flush()
def warn(self, msg):
''' Utility method for writing output to stderr. '''
""" Utility method for writing output to stderr. """
sys.stderr.write("XXX %s:" % self.node.routerid, msg)
sys.stderr.flush()
@ -412,6 +427,7 @@ class VtyshCmd(Cmd):
class Ospf6NeighState(VtyshCmd):
""" Check a node for OSPFv3 neighbors in the full/two-way states. """
args = "show ipv6 ospf6 neighbor"
def parse(self):
@ -435,6 +451,7 @@ class Ospf6NeighState(VtyshCmd):
class Ospf6MdrLevel(VtyshCmd):
""" Retrieve the OSPFv3 MDR level for a node. """
args = "show ipv6 ospf6 mdrlevel"
def parse(self):
@ -451,6 +468,7 @@ class Ospf6MdrLevel(VtyshCmd):
class Ospf6Database(VtyshCmd):
""" Retrieve the OSPFv3 LSDB summary for a node. """
args = "show ipv6 ospf6 database"
def parse(self):
@ -469,6 +487,7 @@ class ZebraRoutes(VtyshCmd):
""" Return a list of Route objects for a node based on its zebra
routing table.
"""
args = "show ip route"
def parse(self):
@ -510,6 +529,7 @@ class KernelRoutes(Cmd):
""" Return a list of Route objects for a node based on its kernel
routing table.
"""
args = ("/sbin/ip", "route", "show")
def parse(self):
@ -547,18 +567,32 @@ def main():
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=10, linkprob=0.35, delay=20, seed=None)
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
parser.add_option("-p", "--linkprob", dest="linkprob", type=float,
help="link probabilty")
parser.add_option("-d", "--delay", dest="delay", type=float,
help="wait time before checking")
parser.add_option("-s", "--seed", dest="seed", type=int,
help="specify integer to use for random seed")
parser.add_option("-v", "--verbose", dest="verbose",
action="store_true", help="be more verbose")
parser.add_option("-l", "--logfile", dest="logfile", type=str,
help="log detailed output to the specified file")
parser.add_option(
"-n", "--numnodes", dest="numnodes", type=int, help="number of nodes"
)
parser.add_option(
"-p", "--linkprob", dest="linkprob", type=float, help="link probabilty"
)
parser.add_option(
"-d", "--delay", dest="delay", type=float, help="wait time before checking"
)
parser.add_option(
"-s",
"--seed",
dest="seed",
type=int,
help="specify integer to use for random seed",
)
parser.add_option(
"-v", "--verbose", dest="verbose", action="store_true", help="be more verbose"
)
parser.add_option(
"-l",
"--logfile",
dest="logfile",
type=str,
help="log detailed output to the specified file",
)
def usage(msg=None, err=0):
sys.stdout.write("\n")
@ -584,8 +618,10 @@ def main():
random.seed(options.seed)
me = ManetExperiment(options=options, start=datetime.datetime.now())
me.info("creating topology: numnodes = %s; linkprob = %s" % \
(options.numnodes, options.linkprob))
me.info(
"creating topology: numnodes = %s; linkprob = %s"
% (options.numnodes, options.linkprob)
)
me.topology(options.numnodes, options.linkprob)
me.info("waiting %s sec" % options.delay)

View file

@ -80,7 +80,7 @@ def getcputimes(line):
# assume columns are:
# cpu# user nice sys idle iowait irq softirq steal guest (man 5 proc)
items = line.split()
(user, nice, sys, idle) = map(lambda (x): int(x), items[1:5])
(user, nice, sys, idle) = map(lambda x: int(x), items[1:5])
return [user, nice, sys, idle]
@ -97,8 +97,10 @@ def calculatecpu(timesa, timesb):
# end move these to core.misc.utils
class Cmd(object):
""" Helper class for running a command on a node and parsing the result. """
args = ""
def __init__(self, node, verbose=False):
@ -149,6 +151,7 @@ class Cmd(object):
class ClientServerCmd(Cmd):
""" Helper class for running a command on a node and parsing the result. """
args = ""
client_args = ""
@ -171,8 +174,9 @@ class ClientServerCmd(Cmd):
def client_open(self):
""" Exceute call to client_node.popen(). """
self.client_id, self.client_stdin, self.client_out, self.client_err = \
self.client_node.client.popen(self.client_args)
self.client_id, self.client_stdin, self.client_out, self.client_err = self.client_node.client.popen(
self.client_args
)
def parse(self):
""" This method is overloaded by child classes and should return some
@ -195,7 +199,7 @@ class PingCmd(Cmd):
""" Test latency using ping.
"""
def __init__(self, node, verbose=False, addr=None, count=50, interval=0.1, ):
def __init__(self, node, verbose=False, addr=None, count=50, interval=0.1):
Cmd.__init__(self, node, verbose)
self.addr = addr
self.count = count
@ -205,14 +209,20 @@ class PingCmd(Cmd):
def run(self):
if self.verbose:
self.info("%s initial test ping (max 1 second)..." % self.node.name)
(status, result) = self.node.cmd_output(["ping", "-q", "-c", "1", "-w", "1", self.addr])
(status, result) = self.node.cmd_output(
["ping", "-q", "-c", "1", "-w", "1", self.addr]
)
if status != 0:
self.warn("initial ping from %s to %s failed! result:\n%s" %
(self.node.name, self.addr, result))
self.warn(
"initial ping from %s to %s failed! result:\n%s"
% (self.node.name, self.addr, result)
)
return 0.0, 0.0
if self.verbose:
self.info("%s pinging %s (%d seconds)..." %
(self.node.name, self.addr, self.count * self.interval))
self.info(
"%s pinging %s (%d seconds)..."
% (self.node.name, self.addr, self.count * self.interval)
)
return Cmd.run(self)
def parse(self):
@ -245,8 +255,10 @@ class IperfCmd(ClientServerCmd):
def run(self):
if self.verbose:
self.info("Launching the iperf server on %s..." % self.node.name)
self.info("Running the iperf client on %s (%s seconds)..." % \
(self.client_node.name, self.time))
self.info(
"Running the iperf client on %s (%s seconds)..."
% (self.client_node.name, self.time)
)
return ClientServerCmd.run(self)
def parse(self):
@ -263,19 +275,26 @@ class MgenCmd(ClientServerCmd):
""" Run a test traffic flow using an MGEN sender and receiver.
"""
def __init__(self, node, client_node, verbose=False, addr=None, time=10,
rate=512):
def __init__(self, node, client_node, verbose=False, addr=None, time=10, rate=512):
ClientServerCmd.__init__(self, node, client_node, verbose)
self.addr = addr
self.time = time
self.args = ["mgen", "event", "listen udp 5000", "output",
"/var/log/mgen.log"]
self.args = ["mgen", "event", "listen udp 5000", "output", "/var/log/mgen.log"]
self.rate = rate
sendevent = "ON 1 UDP DST %s/5000 PERIODIC [%s]" % \
(addr, self.mgenrate(self.rate))
sendevent = "ON 1 UDP DST %s/5000 PERIODIC [%s]" % (
addr,
self.mgenrate(self.rate),
)
stopevent = "%s OFF 1" % time
self.client_args = ["mgen", "event", sendevent, "event", stopevent,
"output", "/var/log/mgen.log"]
self.client_args = [
"mgen",
"event",
sendevent,
"event",
stopevent,
"output",
"/var/log/mgen.log",
]
@staticmethod
def mgenrate(kbps):
@ -291,8 +310,10 @@ class MgenCmd(ClientServerCmd):
def run(self):
if self.verbose:
self.info("Launching the MGEN receiver on %s..." % self.node.name)
self.info("Running the MGEN sender on %s (%s seconds)..." % \
(self.client_node.name, self.time))
self.info(
"Running the MGEN sender on %s (%s seconds)..."
% (self.client_node.name, self.time)
)
return ClientServerCmd.run(self)
def cleanup(self):
@ -328,8 +349,7 @@ class MgenCmd(ClientServerCmd):
else:
loss = 0
if self.verbose:
self.info("Receiver log shows %d of %d packets lost" % \
(numlost, lastseq))
self.info("Receiver log shows %d of %d packets lost" % (numlost, lastseq))
return loss
@ -381,8 +401,7 @@ class Experiment(object):
if not self.logfp:
return
end = datetime.datetime.now()
self.log("%s end: %s (%s)\n" % \
(sys.argv[0], end.ctime(), end - self.start))
self.log("%s end: %s (%s)\n" % (sys.argv[0], end.ctime(), end - self.start))
self.logfp.flush()
self.logfp.close()
self.logfp = None
@ -411,11 +430,15 @@ class Experiment(object):
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
self.session = Session(1)
# emulated network
self.net = self.session.create_node(cls=core.nodes.network.WlanNode, name="wlan1")
self.net = self.session.create_node(
cls=core.nodes.network.WlanNode, name="wlan1"
)
prev = None
for i in range(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.create_node(cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i)
tmp = self.session.create_node(
cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i
)
tmp.newnetif(self.net, [addr])
self.nodes.append(tmp)
self.session.services.add_services(tmp, "router", "IPForward")
@ -438,12 +461,16 @@ class Experiment(object):
self.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
self.session.location.refscale = 150.0
self.session.emane.loadmodels()
self.net = self.session.create_node(cls=EmaneNode, _id=numnodes + 1, name="wlan1")
self.net = self.session.create_node(
cls=EmaneNode, _id=numnodes + 1, name="wlan1"
)
self.net.verbose = verbose
# self.session.emane.addobj(self.net)
for i in range(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.create_node(cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i)
tmp = self.session.create_node(
cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i
)
# tmp.setposition(i * 20, 50, None)
tmp.setposition(50, 50, None)
tmp.newnetif(self.net, [addr])
@ -518,8 +545,9 @@ class Experiment(object):
dev = "lo"
else:
dev = self.session.obj("ctrlnet").brname
service = EventService(eventchannel=("224.1.2.8", 45703, dev),
otachannel=None)
service = EventService(
eventchannel=("224.1.2.8", 45703, dev), otachannel=None
)
old = False
for i in range(1, numnodes + 1):
@ -529,9 +557,13 @@ class Experiment(object):
if txnem > 0:
if old:
e.set(0, txnem, 10.0, 10.0)
service.publish(emaneeventpathloss.EVENT_ID,
emaneeventservice.PLATFORMID_ANY, rxnem,
emaneeventservice.COMPONENTID_ANY, e.export())
service.publish(
emaneeventpathloss.EVENT_ID,
emaneeventservice.PLATFORMID_ANY,
rxnem,
emaneeventservice.COMPONENTID_ANY,
e.export(),
)
else:
e = PathlossEvent()
e.append(txnem, forward=10.0, reverse=10.0)
@ -542,9 +574,13 @@ class Experiment(object):
continue
if old:
e.set(0, txnem, 10.0, 10.0)
service.publish(emaneeventpathloss.EVENT_ID,
emaneeventservice.PLATFORMID_ANY, rxnem,
emaneeventservice.COMPONENTID_ANY, e.export())
service.publish(
emaneeventpathloss.EVENT_ID,
emaneeventservice.PLATFORMID_ANY,
rxnem,
emaneeventservice.COMPONENTID_ANY,
e.export(),
)
else:
e = PathlossEvent()
e.append(txnem, forward=10.0, reverse=10.0)
@ -567,12 +603,16 @@ class Experiment(object):
duration = self.opt.duration
rate = self.opt.rate
if len(title) > 0:
self.info("----- running %s tests (duration=%s, rate=%s) -----" % \
(title, duration, rate))
self.info(
"----- running %s tests (duration=%s, rate=%s) -----"
% (title, duration, rate)
)
(latency, mdev, throughput, cpu, loss) = (0, 0, 0, 0, 0)
self.info("number of runs: ping=%d, iperf=%d, mgen=%d" % \
(self.numping, self.numiperf, self.nummgen))
self.info(
"number of runs: ping=%d, iperf=%d, mgen=%d"
% (self.numping, self.numiperf, self.nummgen)
)
if self.numping > 0:
(latency, mdev) = self.pingtest(count=self.numping)
@ -595,8 +635,8 @@ class Experiment(object):
for i in range(1, self.nummgen + 1):
(cpu, loss) = self.cputest(time=duration, rate=rate)
if self.nummgen > 1:
cpus += cpu,
losses += loss,
cpus += (cpu,)
losses += (loss,)
if self.nummgen > 1:
cpu = sum(cpus) / len(cpus)
loss = sum(losses) / len(losses)
@ -608,8 +648,13 @@ class Experiment(object):
def pingtest(self, count=50):
""" Ping through a chain of nodes and report the average latency.
"""
p = PingCmd(node=self.firstnode, verbose=self.verbose,
addr=self.lastaddr, count=count, interval=0.1).run()
p = PingCmd(
node=self.firstnode,
verbose=self.verbose,
addr=self.lastaddr,
count=count,
interval=0.1,
).run()
(latency, mdev) = p
self.info("latency (ms): %.03f, %.03f" % (latency, mdev))
return p
@ -618,8 +663,13 @@ class Experiment(object):
""" Run iperf through a chain of nodes and report the maximum
throughput.
"""
bps = IperfCmd(node=self.lastnode, client_node=self.firstnode,
verbose=False, addr=self.lastaddr, time=time).run()
bps = IperfCmd(
node=self.lastnode,
client_node=self.firstnode,
verbose=False,
addr=self.lastaddr,
time=time,
).run()
self.info("throughput (bps): %s" % bps)
return bps
@ -628,19 +678,26 @@ class Experiment(object):
percent of lost packets. Rate is in kbps.
"""
if self.verbose:
self.info("%s initial test ping (max 1 second)..." % \
self.firstnode.name)
(status, result) = self.firstnode.cmd_output(["ping", "-q", "-c", "1",
"-w", "1", self.lastaddr])
self.info("%s initial test ping (max 1 second)..." % self.firstnode.name)
(status, result) = self.firstnode.cmd_output(
["ping", "-q", "-c", "1", "-w", "1", self.lastaddr]
)
if status != 0:
self.warn("initial ping from %s to %s failed! result:\n%s" % \
(self.firstnode.name, self.lastaddr, result))
self.warn(
"initial ping from %s to %s failed! result:\n%s"
% (self.firstnode.name, self.lastaddr, result)
)
return 0.0, 0.0
lines = readstat()
cpustart = getcputimes(lines[0])
loss = MgenCmd(node=self.lastnode, client_node=self.firstnode,
verbose=False, addr=self.lastaddr,
time=time, rate=rate).run()
loss = MgenCmd(
node=self.lastnode,
client_node=self.firstnode,
verbose=False,
addr=self.lastaddr,
time=time,
rate=rate,
).run()
lines = readstat()
cpuend = getcputimes(lines[0])
percent = calculatecpu(cpustart, cpuend)
@ -653,28 +710,59 @@ def main():
"""
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=10, delay=3, duration=10, rate=512,
verbose=False,
numping=50, numiperf=1, nummgen=1)
parser.set_defaults(
numnodes=10,
delay=3,
duration=10,
rate=512,
verbose=False,
numping=50,
numiperf=1,
nummgen=1,
)
parser.add_option("-d", "--delay", dest="delay", type=float,
help="wait time before testing")
parser.add_option("-l", "--logfile", dest="logfile", type=str,
help="log detailed output to the specified file")
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
parser.add_option("-r", "--rate", dest="rate", type=float,
help="kbps rate to use for MGEN CPU tests")
parser.add_option("--numping", dest="numping", type=int,
help="number of ping latency test runs")
parser.add_option("--numiperf", dest="numiperf", type=int,
help="number of iperf throughput test runs")
parser.add_option("--nummgen", dest="nummgen", type=int,
help="number of MGEN CPU tests runs")
parser.add_option("-t", "--time", dest="duration", type=int,
help="duration in seconds of throughput and CPU tests")
parser.add_option("-v", "--verbose", dest="verbose",
action="store_true", help="be more verbose")
parser.add_option(
"-d", "--delay", dest="delay", type=float, help="wait time before testing"
)
parser.add_option(
"-l",
"--logfile",
dest="logfile",
type=str,
help="log detailed output to the specified file",
)
parser.add_option(
"-n", "--numnodes", dest="numnodes", type=int, help="number of nodes"
)
parser.add_option(
"-r",
"--rate",
dest="rate",
type=float,
help="kbps rate to use for MGEN CPU tests",
)
parser.add_option(
"--numping", dest="numping", type=int, help="number of ping latency test runs"
)
parser.add_option(
"--numiperf",
dest="numiperf",
type=int,
help="number of iperf throughput test runs",
)
parser.add_option(
"--nummgen", dest="nummgen", type=int, help="number of MGEN CPU tests runs"
)
parser.add_option(
"-t",
"--time",
dest="duration",
type=int,
help="duration in seconds of throughput and CPU tests",
)
parser.add_option(
"-v", "--verbose", dest="verbose", action="store_true", help="be more verbose"
)
def usage(msg=None, err=0):
sys.stdout.write("\n")
@ -735,7 +823,12 @@ def main():
# EMANE bypass model
exp.info("setting up EMANE tests 1/2 with bypass model")
exp.createemanesession(numnodes=opt.numnodes, verbose=opt.verbose, cls=EmaneBypassModel, values=None)
exp.createemanesession(
numnodes=opt.numnodes,
verbose=opt.verbose,
cls=EmaneBypassModel,
values=None,
)
exp.setnodes()
exp.info("waiting %s sec (node/route bring-up)" % opt.delay)
time.sleep(opt.delay)
@ -757,7 +850,12 @@ def main():
rfpipevals[rfpnames.index("defaultconnectivitymode")] = "1"
else:
rfpipevals[rfpnames.index("propagationmodel")] = "2ray"
exp.createemanesession(numnodes=opt.numnodes, verbose=opt.verbose, cls=EmaneRfPipeModel, values=rfpipevals)
exp.createemanesession(
numnodes=opt.numnodes,
verbose=opt.verbose,
cls=EmaneRfPipeModel,
values=rfpipevals,
)
exp.setnodes()
exp.info("waiting %s sec (node/route bring-up)" % opt.delay)
time.sleep(opt.delay)
@ -777,8 +875,12 @@ def main():
rfpipevals[rfpnames.index("defaultconnectivitymode")] = "1"
else:
rfpipevals[rfpnames.index("propagationmodel")] = "2ray"
exp.createemanesession(numnodes=opt.numnodes, verbose=opt.verbose,
cls=EmaneRfPipeModel, values=rfpipevals)
exp.createemanesession(
numnodes=opt.numnodes,
verbose=opt.verbose,
cls=EmaneRfPipeModel,
values=rfpipevals,
)
exp.setnodes()
exp.info("waiting %s sec (node/route bring-up)" % opt.delay)
time.sleep(opt.delay)
@ -796,8 +898,12 @@ def main():
rfpipevals[rfpnames.index("defaultconnectivitymode")] = "0"
else:
rfpipevals[rfpnames.index("propagationmodel")] = "precomputed"
exp.createemanesession(numnodes=opt.numnodes, verbose=opt.verbose,
cls=EmaneRfPipeModel, values=rfpipevals)
exp.createemanesession(
numnodes=opt.numnodes,
verbose=opt.verbose,
cls=EmaneRfPipeModel,
values=rfpipevals,
)
exp.setnodes()
exp.info("waiting %s sec (node/route bring-up)" % opt.delay)
time.sleep(opt.delay)
@ -815,8 +921,12 @@ def main():
rfpipevals[rfpnames.index("delay")] = "200"
rfpipevals[rfpnames.index("pathlossmode")] = "pathloss"
rfpipevals[rfpnames.index("defaultconnectivitymode")] = "0"
exp.createemanesession(numnodes=opt.numnodes, verbose=opt.verbose,
cls=EmaneRfPipeModel, values=rfpipevals)
exp.createemanesession(
numnodes=opt.numnodes,
verbose=opt.verbose,
cls=EmaneRfPipeModel,
values=rfpipevals,
)
exp.setnodes()
exp.info("waiting %s sec (node/route bring-up)" % opt.delay)
time.sleep(opt.delay)
@ -827,14 +937,18 @@ def main():
exp.reset()
# summary of results in CSV format
exp.info("----- summary of results (%s nodes, rate=%s, duration=%s) -----" \
% (opt.numnodes, opt.rate, opt.duration))
exp.info(
"----- summary of results (%s nodes, rate=%s, duration=%s) -----"
% (opt.numnodes, opt.rate, opt.duration)
)
exp.info("netname:latency,mdev,throughput,cpu,loss")
for test in sorted(results.keys()):
(latency, mdev, throughput, cpu, loss) = results[test]
exp.info("%s:%.03f,%.03f,%d,%.02f,%.02f" % \
(test, latency, mdev, throughput, cpu, loss))
exp.info(
"%s:%.03f,%.03f,%d,%.02f,%.02f"
% (test, latency, mdev, throughput, cpu, loss)
)
exp.logend()
return exp