Thomas Vachuska | 4558268 | 2015-06-30 13:47:10 -0700 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | |
| 3 | """ |
| 4 | CLI for test with AttMplsTopo |
| 5 | """ |
| 6 | |
| 7 | from mininet.net import Mininet |
| 8 | from mininet.cli import CLI |
| 9 | from mininet.util import quietRun |
| 10 | from mininet.log import setLogLevel, info, output, error |
| 11 | from mininet.node import RemoteController |
| 12 | |
| 13 | from attmplsfast import AttMplsTopo |
| 14 | |
| 15 | from subprocess import PIPE, STDOUT |
| 16 | from time import time |
| 17 | import random |
| 18 | |
| 19 | class IperfCLI( CLI ): |
| 20 | "CLI with iperf UDP traffic generation" |
| 21 | |
| 22 | def __init__( self, net, *args, **kwargs ): |
| 23 | self.iperfs = {} |
| 24 | self.bw = '12k' |
| 25 | self.mn = net |
| 26 | self.lastbw = {} # last bandwidth reports |
| 27 | self.start() |
| 28 | quietRun( 'rm /tmp/*.iperf /tmp/*.client' ) |
| 29 | CLI.__init__( self, net, *args, **kwargs ) |
| 30 | |
| 31 | def __del__( self ): |
| 32 | "Destructor: kill *all* iperf servers and clients!" |
| 33 | quietRun( 'pkill -9 iperf' ) |
| 34 | |
| 35 | def start( self ): |
| 36 | "Start iperf servers" |
| 37 | for h in sorted( self.mn.hosts ): |
| 38 | with open( '/tmp/%s.iperf' % h, 'w' ) as f: |
| 39 | cmd = 'iperf -f k -i 1 -s -u' |
| 40 | popen = h.popen( cmd, stdin=PIPE, stdout=f, stderr=STDOUT ) |
| 41 | self.iperfs[ h ] = popen |
| 42 | |
| 43 | def udpstart( self, h1, h2, bw): |
| 44 | "Start up a udp iperf from h1 to h2 with bandwidth bw" |
| 45 | # For udp we don't have to wait for startup |
| 46 | self.udpstop( h1 ) |
| 47 | h1.cmdPrint( 'iperf -c', h2.IP(), |
| 48 | '-t 36000 -u -b', bw, |
| 49 | '1>/tmp/%s.client 2>&1 &' % h1 ) |
| 50 | |
| 51 | def udpstop( self, h ): |
| 52 | "udpstop h: Stop udp client on host h" |
| 53 | h.cmdPrint( 'kill %iperf && wait %iperf' ) |
| 54 | h.cmdPrint( 'rm /tmp/%s.client' % h ) |
| 55 | |
| 56 | def do_udp( self, line ): |
| 57 | """udp h1 h2 [rate]: start a udp iperf session from h1 to h2 |
| 58 | rate: udp transmit rate [12k]""" |
| 59 | args = line.split() |
| 60 | if len( args ) not in ( 2, 3 ): |
| 61 | error( 'usage: udp h1 h2 [rate]\n' ) |
| 62 | return |
| 63 | h1, h2 = self.mn.get( *args[ :2 ] ) |
| 64 | bw = self.bw if len( args ) == 2 else args[ 2 ] |
| 65 | self.udpstart( h1, h2, bw ) |
| 66 | |
| 67 | def do_stop( self, line ): |
| 68 | "stop [host | all]: Stop iperf client on host" |
| 69 | if not line or line == 'all': |
| 70 | hosts = self.mn.hosts |
| 71 | else: |
| 72 | hosts = [ self.mn.get( line ) ] |
| 73 | for h in hosts: |
| 74 | self.udpstop( h ) |
| 75 | |
| 76 | def do_bw( self, line ): |
| 77 | "bw: show last reported iperf server ingress bandwidth" |
| 78 | output( "Last reported iperf UDP server input bandwidth:\n" ) |
| 79 | for h in self.mn.hosts: |
| 80 | lastout, lasttime = self.lastbw.get( h, ( '', 0 ) ) |
| 81 | out = h.cmd( 'tail -1 /tmp/%s.iperf' % h ) |
| 82 | if '---' in out or ( out == lastout and |
| 83 | time() - lasttime > 1.5 ): |
| 84 | # Stale update - don't display |
| 85 | out = '\n' |
| 86 | else: |
| 87 | self.lastbw[ h ] = ( out, time() ) |
| 88 | output( '%s:' % h, out ) |
| 89 | |
| 90 | def do_rand( self, line ): |
| 91 | """rand [N [bw]]: Start N random flows (default: 10) |
| 92 | at the given bandwidth (default: 12k) |
| 93 | Note: this may replace existing flows""" |
| 94 | args = line.split() |
| 95 | N = 10 |
| 96 | if args: |
| 97 | try: |
| 98 | N = int( args[ 0 ] ) |
| 99 | except: |
| 100 | error( 'please specify an integer' ) |
| 101 | return |
| 102 | output( 'Starting/restarting', N, 'random flows...\n' ) |
| 103 | bw = self.bw if len( args ) < 2 else args[ 1 ] |
| 104 | servers = random.sample( self.mn.hosts, N ) |
| 105 | clients = [] |
| 106 | for server in servers: |
| 107 | allclients = [ h for h in self.mn.hosts |
| 108 | if h not in clients ] |
| 109 | client = random.choice( allclients ) |
| 110 | clients.append( client ) |
| 111 | self.udpstart( client, server, bw ) |
| 112 | |
| 113 | def do_jobs( self, line ): |
| 114 | "jobs: List iperf jobs" |
| 115 | output( "Currently running jobs:\n" ) |
| 116 | for h in self.mn.hosts: |
| 117 | output( '%s:' % h, h.cmd( 'jobs' ).strip(), '\n' ) |
| 118 | |
| 119 | |
| 120 | def run( Topo=AttMplsTopo ): |
| 121 | "Create network and run CLI" |
| 122 | topo = Topo() |
| 123 | net = Mininet( topo=topo, controller=RemoteController ) |
| 124 | net.start() |
| 125 | info( '\n### Welcome to the custom iperf udp CLI!\n' |
| 126 | '###\n' |
| 127 | '### udp h1 h2 [bw] start iperf udp from h1 to h2\n' |
| 128 | '### stop h1 h2 stop iperf udp from h1 to h2\n' |
| 129 | '### rand [N] start/restart N random udp iperfs\n' |
| 130 | '### bw show last reported udp ingress bandwidth\n' |
| 131 | '### jobs list iperf jobs\n\n' ) |
| 132 | IperfCLI( net ) |
| 133 | net.stop() |
| 134 | |
| 135 | |
| 136 | if __name__ == '__main__': |
| 137 | setLogLevel( 'info' ) |
| 138 | run() |