Removed udpbwgraph - not ready for prime time.
This commit is contained in:
@@ -1,309 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""
|
||||
udpbwgraph: Plot network bandwidth over time
|
||||
|
||||
Bob Lantz
|
||||
3/27/10
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from Tkinter import Frame, Label, Button, Scrollbar, OptionMenu, Canvas
|
||||
from Tkinter import StringVar
|
||||
|
||||
from mininet.log import setLogLevel
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import KernelSwitch, UserSwitch, OVSKernelSwitch
|
||||
from mininet.node import Controller, NOX
|
||||
from mininet.topolib import TreeTopo
|
||||
from mininet.util import quietRun
|
||||
|
||||
# bwtest support
|
||||
|
||||
class Graph( Frame ):
|
||||
|
||||
"Graph that we can add bars to over time."
|
||||
|
||||
def __init__( self, master=None,
|
||||
bg = 'white',
|
||||
gheight=200, gwidth=500,
|
||||
barwidth=10,
|
||||
ymax=3.5,):
|
||||
|
||||
Frame.__init__( self, master )
|
||||
|
||||
self.bg = bg
|
||||
self.gheight = gheight
|
||||
self.gwidth = gwidth
|
||||
self.barwidth = barwidth
|
||||
self.ymax = float( ymax )
|
||||
self.xpos = 0
|
||||
|
||||
# Create everything
|
||||
self.title, self.graph, self.scale = self.createWidgets()
|
||||
self.updateScrollRegions()
|
||||
self.yview( 'moveto', '1.0' )
|
||||
|
||||
def createScale( self ):
|
||||
"Create a and return a new canvas with scale markers."
|
||||
height = float( self.gheight )
|
||||
width = 25
|
||||
ymax = self.ymax
|
||||
scale = Canvas( self, width=width, height=height, background=self.bg )
|
||||
fill = 'red'
|
||||
# Draw scale line
|
||||
scale.create_line( width - 1, height, width - 1, 0, fill=fill )
|
||||
# Draw ticks and numbers
|
||||
for y in range( 0, int( ymax + 1 ) ):
|
||||
ypos = height * ( 1 - float( y ) / ymax )
|
||||
scale.create_line( width, ypos, width - 10, ypos, fill=fill )
|
||||
scale.create_text( 10, ypos, text=str( y ), fill=fill )
|
||||
|
||||
return scale
|
||||
|
||||
def updateScrollRegions( self ):
|
||||
"Update graph and scale scroll regions."
|
||||
ofs = 20
|
||||
height = self.gheight + ofs
|
||||
self.graph.configure( scrollregion=( 0, -ofs,
|
||||
self.xpos * self.barwidth, height ) )
|
||||
self.scale.configure( scrollregion=( 0, -ofs, 0, height ) )
|
||||
|
||||
def yview( self, *args ):
|
||||
"Scroll both scale and graph."
|
||||
self.graph.yview( *args )
|
||||
self.scale.yview( *args )
|
||||
|
||||
def createWidgets( self ):
|
||||
"Create initial widget set."
|
||||
|
||||
# Objects
|
||||
title = Label( self, text="Bandwidth (Mb/s)", bg=self.bg )
|
||||
width = self.gwidth
|
||||
height = self.gheight
|
||||
scale = self.createScale()
|
||||
graph = Canvas( self, width=width, height=height, background=self.bg)
|
||||
xbar = Scrollbar( self, orient='horizontal', command=graph.xview )
|
||||
ybar = Scrollbar( self, orient='vertical', command=self.yview )
|
||||
graph.configure( xscrollcommand=xbar.set, yscrollcommand=ybar.set,
|
||||
scrollregion=(0, 0, width, height ) )
|
||||
scale.configure( yscrollcommand=ybar.set )
|
||||
|
||||
# Layout
|
||||
title.grid( row=0, columnspan=3, sticky='new')
|
||||
scale.grid( row=1, column=0, sticky='nsew' )
|
||||
graph.grid( row=1, column=1, sticky='nsew' )
|
||||
ybar.grid( row=1, column=2, sticky='ns' )
|
||||
xbar.grid( row=2, column=0, columnspan=2, sticky='ew' )
|
||||
self.rowconfigure( 1, weight=1 )
|
||||
self.columnconfigure( 1, weight=1 )
|
||||
return title, graph, scale
|
||||
|
||||
def addBar( self, yval ):
|
||||
"Add a new bar to our graph."
|
||||
percent = yval / self.ymax
|
||||
c = self.graph
|
||||
x0 = self.xpos * self.barwidth
|
||||
x1 = x0 + self.barwidth
|
||||
y0 = self.gheight
|
||||
y1 = ( 1 - percent ) * self.gheight
|
||||
c.create_rectangle( x0 , y0, x1, y1, fill='green' )
|
||||
self.xpos += 1
|
||||
self.updateScrollRegions()
|
||||
self.graph.xview( 'moveto', '1.0' )
|
||||
|
||||
def test( self ):
|
||||
"Add a bar for testing purposes."
|
||||
ms = 1000
|
||||
if self.xpos < 10:
|
||||
self.addBar( self.xpos / 10 * self.ymax )
|
||||
self.after( ms, self.test )
|
||||
|
||||
def setTitle( self, text ):
|
||||
"Set graph title"
|
||||
self.title.configure( text=text, font='Helvetica 9 bold' )
|
||||
|
||||
|
||||
class Controls( Frame ):
|
||||
|
||||
"Handy controls for configuring test."
|
||||
|
||||
switches = {
|
||||
'Kernel Switch': KernelSwitch,
|
||||
'User Switch': UserSwitch,
|
||||
'Open vSwitch': OVSKernelSwitch
|
||||
}
|
||||
|
||||
controllers = {
|
||||
'Reference Controller': Controller,
|
||||
'NOX': NOX
|
||||
}
|
||||
|
||||
def __init__( self, master, startFn, stopFn, quitFn ):
|
||||
|
||||
Frame.__init__( self, master )
|
||||
|
||||
# Option menus
|
||||
opts = { 'font': 'Geneva 7 bold' }
|
||||
self.switch = self.optionMenu( self.switches,
|
||||
KernelSwitch, opts )
|
||||
self.controller = self.optionMenu( self.controllers,
|
||||
Controller, opts)
|
||||
|
||||
# Spacer
|
||||
pk = { 'fill': 'x' }
|
||||
Label( self, **opts ).pack( **pk )
|
||||
|
||||
# Buttons
|
||||
self.start = Button( self, text='Start', command=startFn, **opts )
|
||||
self.stop = Button( self, text='Stop', command=stopFn, **opts )
|
||||
self.quit = Button( self, text='Quit', command=quitFn, **opts )
|
||||
for button in ( self.start, self.stop, self.quit ):
|
||||
button.pack( **pk )
|
||||
|
||||
def optionMenu( self, menuItems, initval, opts ):
|
||||
"Add a new option menu. Returns function to get value."
|
||||
var = StringVar()
|
||||
var.set( findKey( menuItems, initval ) )
|
||||
menu = OptionMenu( self, var, *menuItems )
|
||||
menu.config( **opts )
|
||||
menu.pack( fill='x' )
|
||||
return lambda: menuItems[ var.get() ]
|
||||
|
||||
def parsebwtest( line,
|
||||
r=re.compile( r'(\d+) s: in ([\d\.]+) MB/s, out ([\d\.]+) MB/s' ) ):
|
||||
"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
|
||||
|
||||
|
||||
class UdpBwTest( Frame ):
|
||||
"Test and plot UDP bandwidth over time"
|
||||
|
||||
def __init__( self, topo, master=None ):
|
||||
"Start up and monitor udpbwtest on each of our hosts."
|
||||
|
||||
Frame.__init__( self, master )
|
||||
|
||||
self.controls = Controls( self, self.start, self.stop, self.quit )
|
||||
self.graph = Graph( self )
|
||||
|
||||
# Layout
|
||||
self.controls.pack( side='left', expand=False, fill='y' )
|
||||
self.graph.pack( side='right', expand=True, fill='both' )
|
||||
self.pack( expand=True, fill='both' )
|
||||
|
||||
self.topo = topo
|
||||
self.net = None
|
||||
self.hosts = []
|
||||
self.hostCount = 0
|
||||
self.output = None
|
||||
self.results = {}
|
||||
self.running = False
|
||||
|
||||
def start( self ):
|
||||
"Start test."
|
||||
|
||||
if self.running:
|
||||
return
|
||||
|
||||
switch = self.controls.switch()
|
||||
controller = self.controls.controller()
|
||||
|
||||
self.net = Mininet( self.topo, switch=switch,
|
||||
controller=controller )
|
||||
self.hosts = self.net.hosts
|
||||
self.hostCount = len( self.hosts )
|
||||
|
||||
print "*** Starting network"
|
||||
self.net.start()
|
||||
|
||||
print "*** Starting udpbwtest on hosts"
|
||||
hosts = self.hosts
|
||||
for host in hosts:
|
||||
ips = [ h.IP() for h in hosts if h != host ]
|
||||
host.cmdPrint( './udpbwtest ' + ' '.join( ips ) + ' &' )
|
||||
|
||||
print "*** Monitoring hosts"
|
||||
self.output = self.net.monitor( hosts, timeoutms=1 )
|
||||
self.results = {}
|
||||
self.running = True
|
||||
self.updateGraph()
|
||||
|
||||
# Pylint isn't smart enough to understand iterator.next()
|
||||
# pylint: disable-msg=E1101
|
||||
|
||||
def updateGraph( self ):
|
||||
"Graph input bandwidth."
|
||||
|
||||
print "updateGraph"
|
||||
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
while True:
|
||||
host, line = self.output.next()
|
||||
if host is None or len( line ) == 0:
|
||||
break
|
||||
seconds, inbw, outbw = parsebwtest( line )
|
||||
if seconds is None:
|
||||
break
|
||||
result = self.results.get( seconds, [] ) + [
|
||||
( host, inbw, outbw ) ]
|
||||
self.results[ seconds ] = result
|
||||
if len( result ) == self.hostCount:
|
||||
# Calculate total and update graph
|
||||
# We report input bandwidth, i.e. packets that made it
|
||||
totalin = 0
|
||||
for host, inbw, outbw in result:
|
||||
totalin += inbw
|
||||
self.graph.addBar( totalin * 8.0 / 1000.0 )
|
||||
print totalin
|
||||
# Fileevent might be better, but for now we just poll every 500ms
|
||||
self.graph.after( 500, self.updateGraph )
|
||||
|
||||
def stop( self ):
|
||||
"Stop test."
|
||||
|
||||
print "*** Stopping udpbwtest processes"
|
||||
# We *really* don't want these things hanging around!
|
||||
quietRun( 'killall -9 udpbwtest' )
|
||||
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
print "*** Stopping network"
|
||||
self.running = False
|
||||
self.net.stop()
|
||||
|
||||
def quit( self ):
|
||||
"Quit app."
|
||||
self.stop()
|
||||
Frame.quit( self )
|
||||
|
||||
# pylint: enable-msg=E1101
|
||||
|
||||
# Useful utilities
|
||||
|
||||
def findKey( d, value ):
|
||||
"Find some key where d[ key ] == value."
|
||||
return [ key for key, val in d.items() if val == value ][ 0 ]
|
||||
|
||||
def assign( obj, **kwargs):
|
||||
"Set a bunch of fields in an object."
|
||||
for name, value in kwargs.items():
|
||||
setattr( obj, name, value )
|
||||
|
||||
class Object( object ):
|
||||
"Generic object you can stuff junk into."
|
||||
def __init__( self, **kwargs ):
|
||||
assign( self, **kwargs )
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
app = UdpBwTest( topo=TreeTopo( depth=2, fanout=2 ) )
|
||||
app.mainloop()
|
||||
@@ -1,199 +0,0 @@
|
||||
/* udpbwtest: a simple bandwidth test
|
||||
*
|
||||
* To test all-to-all communication, we simply open up a
|
||||
* UDP socket and repeat the following:
|
||||
*
|
||||
* 1. Send a packet to a random host if possible
|
||||
* 2. Receive a packet if possible
|
||||
* 3. Periodically report our I/O bandwidth
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <strings.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
|
||||
enum { Port=12345 };
|
||||
|
||||
/* Handy utility functions */
|
||||
|
||||
int bindAddr( int fd, long addr, u_short port ) {
|
||||
/* Easy interface to bind */
|
||||
struct sockaddr_in sa;
|
||||
bzero( &sa, sizeof( sa ) );
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = htonl( addr );
|
||||
sa.sin_port = htons( port );
|
||||
return bind( fd, ( struct sockaddr * )&sa, sizeof( sa ) );
|
||||
}
|
||||
|
||||
int udpSocket( u_short port ) {
|
||||
/* Easy interface to making a UDP socket */
|
||||
int fd = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||
if ( fd < 0 ) { return fd; }
|
||||
int err = bindAddr( fd, INADDR_ANY, port );
|
||||
if ( err < 0 ) { return err; }
|
||||
return fd;
|
||||
}
|
||||
|
||||
ssize_t sendBytes( int sock, char *outbuf, size_t bufsize,
|
||||
struct in_addr *addr, u_short port ) {
|
||||
/* Simpler sendto */
|
||||
struct sockaddr_in sa;
|
||||
int err;
|
||||
bzero( &sa, sizeof( sa ) );
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr = *addr;
|
||||
sa.sin_port = htons( port );
|
||||
err = sendto( sock, outbuf, bufsize, 0, (const struct sockaddr *) &sa,
|
||||
sizeof( sa ) );
|
||||
if ( err < 0 ) { perror( "sendto:" ); }
|
||||
return err;
|
||||
}
|
||||
|
||||
ssize_t recvBytes( int sock, char *inbuf, size_t bufsize,
|
||||
struct in_addr *addr) {
|
||||
/* Simpler recvfrom */
|
||||
struct sockaddr_in sa;
|
||||
socklen_t saLen = sizeof( sa );
|
||||
ssize_t len;
|
||||
len = recvfrom( sock, inbuf, bufsize, 0, (struct sockaddr *) &sa, &saLen );
|
||||
if ( len >= 0 ) {
|
||||
assert( saLen == sizeof( sa ) );
|
||||
*addr = sa.sin_addr;
|
||||
}
|
||||
else { perror( "recvfrom:" ); }
|
||||
return len;
|
||||
}
|
||||
|
||||
int readable( int fd ) {
|
||||
/* Poll a single file descriptor for reading */
|
||||
struct pollfd fds = { fd, POLLIN, POLLIN };
|
||||
int result = poll( &fds, 1, 0 );
|
||||
/* True if there is one readable descriptor */
|
||||
return ( result == 1 );
|
||||
}
|
||||
|
||||
int writable( int fd ) {
|
||||
/* Poll a single file descriptor for writing */
|
||||
struct pollfd fds = { fd, POLLOUT, POLLOUT };
|
||||
int result = poll( &fds, 1, 0 );
|
||||
/* True if there is one writable descriptor */
|
||||
return ( result == 1 );
|
||||
}
|
||||
|
||||
int poll1( int fd, int flags, int ms ) {
|
||||
/* Call poll on a single descriptor */
|
||||
struct pollfd fds[] = { { fd, flags, 0 } };
|
||||
return poll( fds, 1, ms );
|
||||
}
|
||||
|
||||
int waitReadable( int fd, int ms ) { return poll1( fd, POLLIN, ms ); }
|
||||
int waitWritable( int fd, int ms ) { return poll1( fd, POLLIN, ms ); }
|
||||
int waitReadableOrWritable( int fd, int ms ) {
|
||||
return poll1( fd, POLLIN | POLLOUT, ms );
|
||||
}
|
||||
|
||||
/* Timer support */
|
||||
|
||||
int alarm = 0;
|
||||
void handleAlarm( int sig) { alarm = 1; }
|
||||
|
||||
void startTimer( int seconds) {
|
||||
struct itimerval v;
|
||||
v.it_interval.tv_sec = seconds;
|
||||
v.it_interval.tv_usec = 0;
|
||||
v.it_value = v.it_interval;
|
||||
signal( SIGALRM, handleAlarm );
|
||||
setitimer( ITIMER_REAL, &v, 0 );
|
||||
}
|
||||
|
||||
void startOneSecondTimer() { startTimer( 1 ); }
|
||||
|
||||
void stopTimer() {
|
||||
struct itimerval v;
|
||||
bzero( &v, sizeof v );
|
||||
setitimer( ITIMER_REAL, &v, 0 );
|
||||
}
|
||||
|
||||
/* Actual program */
|
||||
|
||||
void bwtest( int sock, struct in_addr *hosts, int hostCount ) {
|
||||
|
||||
/* Test our bandwidth, by receiving whatever we get, and sending
|
||||
* randomly to a set of hosts */
|
||||
|
||||
char outbuf[ 1024 ];
|
||||
char inbuf[ 1024 ];
|
||||
time_t seconds = time( 0 );
|
||||
uint64_t b, bytes;
|
||||
uint64_t inbytes = 0, outbytes = 0;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < sizeof( outbuf ); i++ ) { outbuf[ i ] = i % 255; }
|
||||
|
||||
while ( 1 ) {
|
||||
size_t addr_len;
|
||||
struct in_addr addr = hosts[ random() % hostCount ];
|
||||
/* Wait until we have something to do. */
|
||||
waitReadableOrWritable( sock, 0 );
|
||||
/* Receive some bytes */
|
||||
for ( b = 0; b < 10 && readable( sock ); b += 1 ) {
|
||||
bytes = recvBytes( sock, inbuf, sizeof( inbuf ), &addr );
|
||||
inbytes += bytes;
|
||||
}
|
||||
/* Send some bytes */
|
||||
for ( b = 0; b < 10 && writable(sock); b += 1 ) {
|
||||
bytes = sendBytes( sock, outbuf, sizeof( outbuf ),
|
||||
&addr, Port );
|
||||
outbytes += bytes;
|
||||
}
|
||||
/* Periodically report bandwidth */
|
||||
if ( alarm ) {
|
||||
alarm = 0;
|
||||
seconds++;
|
||||
printf("%d s: in %.2f Mbps, out %.2f Mbps\n",
|
||||
seconds, 8.0*inbytes/1e6, 8.0*outbytes/1e6 ); fflush( stdout );
|
||||
inbytes = outbytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
|
||||
struct in_addr start, *hosts, addr;
|
||||
int count, sock, i;
|
||||
|
||||
if ( argc < 2 ) {
|
||||
fprintf( stderr, "usage: %s host...\n", argv[ 0 ] );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
count = argc - 1;
|
||||
hosts = (struct in_addr *) malloc( count * sizeof( struct in_addr ) );
|
||||
if ( hosts == NULL ) { perror( "malloc:" ); exit( 1 ); }
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
inet_aton( argv[ i + 1 ], &hosts[ i ] );
|
||||
|
||||
sock = udpSocket( Port );
|
||||
if ( sock < 0 ) { perror( "udpSocket:" ); exit( 1 ); }
|
||||
|
||||
startOneSecondTimer();
|
||||
|
||||
bwtest( sock, hosts, count ); /* Never returns for now... */
|
||||
|
||||
stopTimer();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
#!/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 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\.]+) MB/s, out ([\d\.]+) MB/s' ) ):
|
||||
"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 (MB/s)\tavg in/out (MB/s)"
|
||||
|
||||
# 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.' )
|
||||
network = Mininet( TreeTopo( depth=1, fanout=8 ), switch=KernelSwitch )
|
||||
network.start()
|
||||
udpbwtest( network, seconds=10 )
|
||||
network.stop()
|
||||
Reference in New Issue
Block a user