aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/tools/test/topos/attcli.py
blob: 1945320417e1dece78450da01d37ec60c047b67f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python

"""
CLI for test with AttMplsTopo
"""

from mininet.net import Mininet
from mininet.cli import CLI
from mininet.util import quietRun
from mininet.log import setLogLevel, info, output, error
from mininet.node import RemoteController

from attmplsfast import AttMplsTopo

from subprocess import PIPE, STDOUT
from time import time
import random

class IperfCLI( CLI ):
    "CLI with iperf UDP traffic generation"

    def __init__( self, net, *args, **kwargs ):
        self.iperfs = {}
        self.bw = '12k'
        self.mn = net
        self.lastbw = {}  # last bandwidth reports
        self.start()
        quietRun( 'rm /tmp/*.iperf /tmp/*.client' )
        CLI.__init__( self, net, *args, **kwargs )

    def __del__( self ):
        "Destructor: kill *all* iperf servers and clients!"
        quietRun( 'pkill -9 iperf' )

    def start( self ):
        "Start iperf servers"
        for h in sorted( self.mn.hosts ):
            with open( '/tmp/%s.iperf' % h, 'w' ) as f:
                cmd = 'iperf -f k -i 1 -s -u'
                popen = h.popen( cmd, stdin=PIPE, stdout=f, stderr=STDOUT )
                self.iperfs[ h ] = popen

    def udpstart( self, h1, h2, bw):
        "Start up a udp iperf from h1 to h2 with bandwidth bw"
        # For udp we don't have to wait for startup
        self.udpstop( h1 )
        h1.cmdPrint( 'iperf -c', h2.IP(),
                     '-t 36000 -u -b', bw,
                     '1>/tmp/%s.client 2>&1 &' % h1 )

    def udpstop( self, h ):
        "udpstop h: Stop udp client on host h"
        h.cmdPrint( 'kill %iperf && wait %iperf' )
        h.cmdPrint( 'rm /tmp/%s.client' % h )

    def do_udp( self, line ):
        """udp h1 h2 [rate]: start a udp iperf session from h1 to h2
           rate: udp transmit rate [12k]"""
        args = line.split()
        if len( args ) not in ( 2, 3 ):
            error( 'usage: udp h1 h2 [rate]\n' )
            return
        h1, h2 = self.mn.get( *args[ :2 ] )
        bw = self.bw if len( args ) == 2 else args[ 2 ]
        self.udpstart( h1, h2, bw )

    def do_stop( self, line ):
        "stop [host | all]: Stop iperf client on host"
        if not line or line == 'all':
            hosts = self.mn.hosts
        else:
            hosts = [ self.mn.get( line ) ]
        for h in hosts:
            self.udpstop( h )

    def do_bw( self, line ):
        "bw: show last reported iperf server ingress bandwidth"
        output( "Last reported iperf UDP server input bandwidth:\n" )
        for h in self.mn.hosts:
            lastout, lasttime = self.lastbw.get( h, ( '', 0 ) )
            out = h.cmd( 'tail -1 /tmp/%s.iperf' % h )
            if '---' in out or ( out == lastout and
                                 time() - lasttime > 1.5 ):
                # Stale update - don't display
                out = '\n'
            else:
                self.lastbw[ h ] = ( out, time() )
            output( '%s:' % h, out )

    def do_rand( self, line ):
        """rand [N [bw]]: Start N random flows (default: 10)
           at the given bandwidth (default: 12k)
           Note: this may replace existing flows"""
        args = line.split()
        N = 10
        if args:
            try:
                N = int( args[ 0 ] )
            except:
                error( 'please specify an integer' )
                return
        output( 'Starting/restarting', N, 'random flows...\n' )
        bw = self.bw if len( args ) < 2 else args[ 1 ]
        servers = random.sample( self.mn.hosts, N )
        clients = []
        for server in servers:
            allclients = [ h for h in self.mn.hosts
                           if h not in clients ]
            client = random.choice( allclients )
            clients.append( client )
            self.udpstart( client, server, bw )

    def do_jobs( self, line ):
        "jobs: List iperf jobs"
        output( "Currently running jobs:\n" )
        for h in self.mn.hosts:
            output( '%s:' % h, h.cmd( 'jobs' ).strip(), '\n' )


def run( Topo=AttMplsTopo ):
    "Create network and run CLI"
    topo = Topo()
    net = Mininet( topo=topo, controller=RemoteController )
    net.start()
    info( '\n### Welcome to the custom iperf udp CLI!\n'
          '###\n'
          '### udp h1 h2 [bw]   start iperf udp from h1 to h2\n'
          '### stop h1 h2       stop iperf udp from h1 to h2\n'
          '### rand [N]         start/restart N random udp iperfs\n'
          '### bw               show last reported udp ingress bandwidth\n'
          '### jobs             list iperf jobs\n\n' )
    IperfCLI( net )
    net.stop()


if __name__ == '__main__':
    setLogLevel( 'info' )
    run()