Revision 80be5642 examples/udpbwtest.py

View differences:

examples/udpbwtest.py
20 20
import re
21 21
import select
22 22
import sys
23
import time
23
from time import time
24 24

  
25 25
flush = sys.stdout.flush
26 26

  
27
from mininet.log import lg   
27
from mininet.log import lg
28 28
from mininet.net import init, Mininet
29
from mininet.node import Host, KernelSwitch
29
from mininet.node import KernelSwitch
30 30
from mininet.topolib import TreeTopo
31 31
from mininet.util import quietRun
32 32

  
33 33
# Some useful stuff: buffered readline and host monitoring
34 34

  
35
def readline( host, buffer ):
36
   "Read a line from a host, buffering with buffer."
37
   buffer += host.read( 1024 )
38
   if '\n' not in buffer: return None, buffer
39
   pos = buffer.find( '\n' )
40
   line = buffer[ 0 : pos ]
41
   rest = buffer[ pos + 1 :]
42
   return line, rest
35
def readline( host, buf ):
36
    "Read a line from a host, buffering with buffer."
37
    buf += host.read( 1024 )
38
    if '\n' not in buffer:
39
        return None, buffer
40
    pos = buf.find( '\n' )
41
    line = buf[ 0 : pos ]
42
    rest = buf[ pos + 1: ]
43
    return line, rest
43 44

  
44 45
def monitor( hosts, seconds ):
45
   "Monitor a set of hosts and yield their output."
46
   poller = select.poll()
47
   Node = hosts[ 0 ] # so we can call class method fdToNode
48
   buffers = {}
49
   for host in hosts:
50
      poller.register( host.stdout )
51
      buffers[ host ] = ''
52
   quitTime = time.time() + seconds
53
   while time.time() < quitTime:
54
      ready = poller.poll()
55
      for fd, event in ready: 
56
         host = Node.fdToNode( fd )
57
         line, buffers[ host ] = readline( host, buffers[ host ] )
58
         if line: yield host, line
59
   yield None, ''
46
    "Monitor a set of hosts and yield their output."
47
    poller = select.poll()
48
    Node = hosts[ 0 ] # so we can call class method fdToNode
49
    buffers = {}
50
    for host in hosts:
51
        poller.register( host.stdout )
52
        buffers[ host ] = ''
53
    quitTime = time() + seconds
54
    while time() < quitTime:
55
        ready = poller.poll()
56
        for fd, event in ready:
57
            host = Node.fdToNode( fd )
58
            if event & select.POLLIN:
59
                line, buffers[ host ] = readline( host, buffers[ host ] )
60
                if line:
61
                    yield host, line
62
    yield None, ''
60 63

  
61 64
# bwtest support
62 65

  
63 66
def parsebwtest( line,
64
   r=re.compile( r'(\d+) s: in ([\d\.]+) Mbps, out ([\d\.]+) Mbps' ) ):
65
   match = r.match( line )
66
   return match.group( 1, 2, 3 ) if match else ( None, None, None )
67
   
67
    r=re.compile( r'(\d+) s: in ([\d\.]+) Mbps, out ([\d\.]+) Mbps' ) ):
68
    "Parse udpbwtest.c output, returning seconds, inbw, outbw."
69
    match = r.match( line )
70
    if match:
71
        seconds, inbw, outbw = match.group( 1, 2, 3 )
72
        return int( seconds ), float( inbw ), float( outbw )
73
    return None, None, None
74

  
68 75
def printTotalHeader():
69
   print
70
   print "time(s)\thosts\ttotal in/out (Mbps)\tavg in/out (Mbps)"
71

  
72
def printTotal( time=None, result=None ):
73
   intotal = outtotal = 0.0
74
   count = len( result )
75
   for host, inbw, outbw in result:
76
      intotal += inbw
77
      outtotal += outbw
78
   inavg = intotal / count if count > 0 else 0
79
   outavg = outtotal / count if count > 0 else 0   
80
   print '%d\t%d\t%.2f/%.2f\t\t%.2f/%.2f' % ( time, count, intotal, outtotal,
81
      inavg, outavg )
82
   
76
    "Print header for bandwidth stats."
77
    print
78
    print "time(s)\thosts\ttotal in/out (Mbps)\tavg in/out (Mbps)"
79

  
80
# Annoyingly, pylint isn't smart enough to notice
81
# when an unused variable is an iteration tuple
82
# pylint: disable-msg=W0612
83

  
84
def printTotal( seconds=None, result=None ):
85
    "Compute and print total bandwidth for given results set."
86
    intotal = outtotal = 0.0
87
    count = len( result )
88
    for host, inbw, outbw in result:
89
        intotal += inbw
90
        outtotal += outbw
91
    inavg = intotal / count if count > 0 else 0
92
    outavg = outtotal / count if count > 0 else 0
93
    print '%d\t%d\t%.2f/%.2f\t\t%.2f/%.2f' % ( seconds, count,
94
        intotal, outtotal, inavg, outavg )
95

  
96
# pylint: enable-msg=W0612
97

  
98
# Pylint also isn't smart enough to understand iterator.next()
99
# pylint: disable-msg=E1101
100

  
83 101
def udpbwtest( net, seconds ):
84
   "Start up and monitor udpbwtest on each of our hosts."
85
   hosts, switches = net.hosts, net.switches
86
   hostCount = len( hosts )
87
   print "*** Starting udpbwtest on hosts"
88
   for host in hosts: 
89
      ips = [ h.IP() for h in hosts if h != host ]
90
      print host.name, ; flush()
91
      host.cmd( './udpbwtest ' + ' '.join( ips ) + ' &' )
92
   print
93
   results = {}
94
   print "*** Monitoring hosts"
95
   output = monitor( hosts, seconds )
96
   while True:
97
      host, line = output.next()
98
      if host is None: break
99
      time, inbw, outbw = parsebwtest( line )
100
      if time is not None:
101
         time, inbw, outbw = int( time ), float( inbw ), float( outbw )
102
         result = results.get( time, [] ) + [ ( host, inbw, outbw ) ]
103
         if len( result ) == hostCount: printTotal( time, result )
104
         results[ time ] = result
105
   print "*** Stopping udpbwtest processes"
106
   # We *really* don't want these things hanging around!
107
   quietRun( 'killall -9 udpbwtest' )
108
   print 
109
   print "*** Results:"
110
   printTotalHeader()
111
   times = sorted( results.keys() )
112
   for time in times:
113
      printTotal( time - times[ 0 ] , results[ time ] )
114
   print 
115
     
102
    "Start up and monitor udpbwtest on each of our hosts."
103
    hosts = net.hosts
104
    hostCount = len( hosts )
105
    print "*** Starting udpbwtest on hosts"
106
    for host in hosts:
107
        ips = [ h.IP() for h in hosts if h != host ]
108
        print host.name,
109
        flush()
110
        host.cmd( './udpbwtest ' + ' '.join( ips ) + ' &' )
111
    print
112
    results = {}
113
    print "*** Monitoring hosts"
114
    output = monitor( hosts, seconds )
115
    while True:
116
        host, line = output.next()
117
        if host is None:
118
            break
119
        seconds, inbw, outbw = parsebwtest( line )
120
        if seconds is not None:
121
            result = results.get( seconds, [] ) + [ ( host, inbw, outbw ) ]
122
            if len( result ) == hostCount:
123
                printTotal( seconds, result )
124
            results[ seconds ] = result
125
    print "*** Stopping udpbwtest processes"
126
    # We *really* don't want these things hanging around!
127
    quietRun( 'killall -9 udpbwtest' )
128
    print
129
    print "*** Results:"
130
    printTotalHeader()
131
    times = sorted( results.keys() )
132
    for t in times:
133
        printTotal( t - t[ 0 ] , results[ t ] )
134
    print
135

  
136
# pylint: enable-msg=E1101
137

  
116 138
if __name__ == '__main__':
117 139
    lg.setLogLevel( 'info' )
118 140
    if not os.path.exists( './udpbwtest' ):

Also available in: Unified diff