ec7b211c41
Moved monitor() and readline() into net.py and node.py respectively, which will hopefully be useful for monitoring large sets of hosts, as is done in udpbwtest.py. Changed iperf to use interactive command infrastructure (such as it is), which may make it more reliable. Hopefully it's a bit clearer as well, although it is slightly more complicated.
116 lines
3.5 KiB
Python
Executable File
116 lines
3.5 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
"""
|
|
Create a tree network and run udpbwtest.c on it, attempting to
|
|
saturate global bandwidth by sending constant all-to-all
|
|
udp traffic. This should be something of a stress test.
|
|
|
|
We should also make a tcp version. :D
|
|
|
|
In addition to trying to saturate global bandwidth in
|
|
various Mininet configurations, this example:
|
|
|
|
- uses a topology, TreeTopo, from mininet.topolib
|
|
- starts up a custom test program, udpbwtest, on each host
|
|
- dynamically monitors the output of a set of hosts
|
|
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
from time import time
|
|
|
|
flush = sys.stdout.flush
|
|
|
|
from mininet.log import lg
|
|
from mininet.net import init, Mininet
|
|
from mininet.node import KernelSwitch
|
|
from mininet.topolib import TreeTopo
|
|
from mininet.util import quietRun
|
|
|
|
# bwtest support
|
|
|
|
def parsebwtest( line,
|
|
r=re.compile( r'(\d+) s: in ([\d\.]+) Mbps, out ([\d\.]+) Mbps' ) ):
|
|
"Parse udpbwtest.c output, returning seconds, inbw, outbw."
|
|
match = r.match( line )
|
|
if match:
|
|
seconds, inbw, outbw = match.group( 1, 2, 3 )
|
|
return int( seconds ), float( inbw ), float( outbw )
|
|
return None, None, None
|
|
|
|
def printTotalHeader():
|
|
"Print header for bandwidth stats."
|
|
print
|
|
print "time(s)\thosts\ttotal in/out (Mbps)\tavg in/out (Mbps)"
|
|
|
|
# Annoyingly, pylint isn't smart enough to notice
|
|
# when an unused variable is an iteration tuple
|
|
# pylint: disable-msg=W0612
|
|
|
|
def printTotal( seconds=None, result=None ):
|
|
"Compute and print total bandwidth for given results set."
|
|
intotal = outtotal = 0.0
|
|
count = len( result )
|
|
for host, inbw, outbw in result:
|
|
intotal += inbw
|
|
outtotal += outbw
|
|
inavg = intotal / count if count > 0 else 0
|
|
outavg = outtotal / count if count > 0 else 0
|
|
print '%d\t%d\t%.2f/%.2f\t\t%.2f/%.2f' % ( seconds, count,
|
|
intotal, outtotal, inavg, outavg )
|
|
|
|
# pylint: enable-msg=W0612
|
|
|
|
# Pylint also isn't smart enough to understand iterator.next()
|
|
# pylint: disable-msg=E1101
|
|
|
|
def udpbwtest( net, seconds ):
|
|
"Start up and monitor udpbwtest on each of our hosts."
|
|
hosts = net.hosts
|
|
hostCount = len( hosts )
|
|
print "*** Starting udpbwtest on hosts"
|
|
for host in hosts:
|
|
ips = [ h.IP() for h in hosts if h != host ]
|
|
print host.name,
|
|
flush()
|
|
host.cmd( './udpbwtest ' + ' '.join( ips ) + ' &' )
|
|
print
|
|
results = {}
|
|
print "*** Monitoring hosts"
|
|
output = net.monitor( hosts )
|
|
quitTime = time() + seconds
|
|
while time() < quitTime:
|
|
host, line = output.next()
|
|
if host is None:
|
|
break
|
|
seconds, inbw, outbw = parsebwtest( line )
|
|
if seconds is not None:
|
|
result = results.get( seconds, [] ) + [ ( host, inbw, outbw ) ]
|
|
if len( result ) == hostCount:
|
|
printTotal( seconds, result )
|
|
results[ seconds ] = result
|
|
print "*** Stopping udpbwtest processes"
|
|
# We *really* don't want these things hanging around!
|
|
quietRun( 'killall -9 udpbwtest' )
|
|
print
|
|
print "*** Results:"
|
|
printTotalHeader()
|
|
times = sorted( results.keys() )
|
|
for t in times:
|
|
printTotal( t - times[ 0 ] , results[ t ] )
|
|
print
|
|
|
|
# pylint: enable-msg=E1101
|
|
|
|
if __name__ == '__main__':
|
|
lg.setLogLevel( 'info' )
|
|
if not os.path.exists( './udpbwtest' ):
|
|
raise Exception( 'Could not find udpbwtest in current directory.' )
|
|
init()
|
|
network = Mininet( TreeTopo( depth=2, fanout=2 ), switch=KernelSwitch )
|
|
network.start()
|
|
udpbwtest( network, seconds=10 )
|
|
network.stop()
|