Committed by
Gerrit Code Review
Enhancing ONOS mininet topology approach to remove boilerplate and simplify testing and demos.
Change-Id: Id8ab2bfa74254560714f4c27a9342693d1dc9788
Showing
5 changed files
with
114 additions
and
44 deletions
... | @@ -34,13 +34,7 @@ | ... | @@ -34,13 +34,7 @@ |
34 | <step name="Wait-For-Mininet" requires="Start-Mininet" | 34 | <step name="Wait-For-Mininet" requires="Start-Mininet" |
35 | exec="onos-mininet wait 10"/> | 35 | exec="onos-mininet wait 10"/> |
36 | 36 | ||
37 | - <step name="Show-Network" requires="Wait-For-Mininet" | 37 | + <step name="Check-Summary" requires="~Wait-For-Mininet" |
38 | - exec="onos-mininet sendAndExpect net --expect ."/> | ||
39 | - | ||
40 | - <step name="Discover-Hosts" requires="Show-Network" | ||
41 | - exec="onos-mininet sendAndExpect py [ h.cmd('arping -U -c 1 ' + h.IP()) for h in net.hosts ] --expect ."/> | ||
42 | - | ||
43 | - <step name="Check-Summary" requires="Discover-Hosts" | ||
44 | exec="onos-check-summary ${OC1} [0-9]* 25 140 25"/> | 38 | exec="onos-check-summary ${OC1} [0-9]* 25 140 25"/> |
45 | 39 | ||
46 | <step name="Balance-Masters" requires="~Check-Summary" if="${OC2}" | 40 | <step name="Balance-Masters" requires="~Check-Summary" if="${OC2}" | ... | ... |
1 | #!/usr/bin/python | 1 | #!/usr/bin/python |
2 | 2 | ||
3 | -import sys | 3 | +from onosnet import run |
4 | - | ||
5 | -from mininet.net import Mininet | ||
6 | -from mininet.cli import CLI | ||
7 | -from mininet.log import setLogLevel | ||
8 | -from mininet.node import RemoteController | ||
9 | -from mininet.link import TCLink | ||
10 | - | ||
11 | from attmpls import AttMplsTopo | 4 | from attmpls import AttMplsTopo |
12 | 5 | ||
13 | -setLogLevel( 'info' ) | 6 | +run( AttMplsTopo() ) |
14 | - | ||
15 | -def pingloop( net ): | ||
16 | - setLogLevel( 'error' ) | ||
17 | - try: | ||
18 | - while True: | ||
19 | - net.ping() | ||
20 | - finally: | ||
21 | - setLogLevel( 'info' ) | ||
22 | - | ||
23 | -def run(controllers=[ '127.0.0.1' ]): | ||
24 | - Mininet.pingloop = pingloop | ||
25 | - net = Mininet( topo=AttMplsTopo(), link=TCLink, build=False, autoSetMacs=True ) | ||
26 | - ctrl_count = 0 | ||
27 | - for controllerIP in controllers: | ||
28 | - net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) | ||
29 | - ctrl_count = ctrl_count + 1 | ||
30 | - net.build() | ||
31 | - net.start() | ||
32 | - CLI( net ) | ||
33 | - net.stop() | ||
34 | - | ||
35 | -if __name__ == '__main__': | ||
36 | - if len( sys.argv ) > 1: | ||
37 | - controllers = sys.argv[ 1: ] | ||
38 | - else: | ||
39 | - print 'Usage: att-onos.py <c0 IP> <c1 IP> ...' | ||
40 | - exit( 1 ) | ||
41 | - run( controllers ) | ... | ... |
... | @@ -175,3 +175,7 @@ class AttMplsTopo( Topo ): | ... | @@ -175,3 +175,7 @@ class AttMplsTopo( Topo ): |
175 | self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms') | 175 | self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms') |
176 | 176 | ||
177 | topos = { 'att': ( lambda: AttMplsTopo() ) } | 177 | topos = { 'att': ( lambda: AttMplsTopo() ) } |
178 | + | ||
179 | +if __name__ == '__main__': | ||
180 | + from onosnet import run | ||
181 | + run( AttMplsTopo() ) | ... | ... |
tools/test/topos/onosnet.py
0 → 100644
1 | +#!/usr/bin/python | ||
2 | + | ||
3 | +import sys | ||
4 | +from threading import Thread | ||
5 | + | ||
6 | +from mininet.net import Mininet | ||
7 | +from mininet.log import setLogLevel | ||
8 | +from mininet.node import RemoteController | ||
9 | +from mininet.log import info, debug | ||
10 | +from mininet.util import quietRun | ||
11 | +from mininet.link import TCLink | ||
12 | +from mininet.cli import CLI | ||
13 | + | ||
14 | +class ONOSMininet( Mininet ): | ||
15 | + | ||
16 | + @classmethod | ||
17 | + def setup( cls ): | ||
18 | + cls.useArping = True if quietRun( 'which arping' ) else False | ||
19 | + | ||
20 | + def __init__( self, controllers=[], gratuitousArp=True, build=True, *args, **kwargs ): | ||
21 | + """Create Mininet object for ONOS. | ||
22 | + controllers: List of controller IP addresses | ||
23 | + gratuitousArp: Send an ARP from each host to aid controller's host discovery""" | ||
24 | + # discarding provided controller (if any), | ||
25 | + # using list of remote controller IPs instead | ||
26 | + kwargs[ 'controller' ] = None | ||
27 | + | ||
28 | + # delay building for a second | ||
29 | + kwargs[ 'build' ] = False | ||
30 | + | ||
31 | + Mininet.__init__(self, *args, **kwargs ) | ||
32 | + | ||
33 | + self.gratArp = gratuitousArp | ||
34 | + self.useArping = ONOSMininet.useArping | ||
35 | + | ||
36 | + info ( '*** Adding controllers\n' ) | ||
37 | + ctrl_count = 0 | ||
38 | + for controllerIP in controllers: | ||
39 | + self.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) | ||
40 | + info( ' c%d (%s)\n' % ( ctrl_count, controllerIP ) ) | ||
41 | + ctrl_count = ctrl_count + 1 | ||
42 | + | ||
43 | + if self.topo and build: | ||
44 | + self.build() | ||
45 | + | ||
46 | + def start( self ): | ||
47 | + Mininet.start( self ) | ||
48 | + if self.gratArp: | ||
49 | + self.waitConnected() | ||
50 | + info ( '*** Sending a gratuitious ARP from each host\n' ) | ||
51 | + self.gratuitousArp() | ||
52 | + | ||
53 | + | ||
54 | + def gratuitousArp( self ): | ||
55 | + "Send an ARP from each host to aid controller's host discovery; fallback to ping if necessary" | ||
56 | + if self.useArping: | ||
57 | + for host in self.hosts: | ||
58 | + info( '%s ' % host.name ) | ||
59 | + debug( host.cmd( 'arping -U -c 1 ' + host.IP() ) ) | ||
60 | + info ( '\n' ) | ||
61 | + else: | ||
62 | + info( '\nWARNING: arping is not found, using ping instead.\n' | ||
63 | + 'For higher performance, install arping: sudo apt-get install iputils-arping\n\n' ) | ||
64 | + | ||
65 | + threads = [ self.threadPing(s, d) for (s, d) in zip( self.hosts, self.hosts[1:] + self.hosts[0:1] ) ] | ||
66 | + for t in threads: | ||
67 | + t.join() | ||
68 | + info ( '\n' ) | ||
69 | + | ||
70 | + def threadPing( self, src, dst ): | ||
71 | + "Ping from src to dst in a thread" | ||
72 | + def p(): | ||
73 | + src.cmd( 'ping -w 0.1 -W 0.1 -c1 ' + dst.IP() ) | ||
74 | + t = Thread( target=p ) | ||
75 | + info ( '%s ' % src.name ) | ||
76 | + t.start() | ||
77 | + return t | ||
78 | + | ||
79 | + def pingloop( self ): | ||
80 | + "Loop forever pinging the full mesh of hosts" | ||
81 | + setLogLevel( 'error' ) | ||
82 | + try: | ||
83 | + while True: | ||
84 | + self.ping() | ||
85 | + finally: | ||
86 | + setLogLevel( 'info' ) | ||
87 | + | ||
88 | +# Initialize ONOSMininet the first time that the class is loaded | ||
89 | +ONOSMininet.setup() | ||
90 | + | ||
91 | +def run( topo, controllers=None, link=TCLink, autoSetMacs=True ): | ||
92 | + if not controllers and len( sys.argv ) > 1: | ||
93 | + controllers = sys.argv[ 1: ] | ||
94 | + else: | ||
95 | + print 'Need to provide a topology and list of controllers' | ||
96 | + exit( 1 ) | ||
97 | + | ||
98 | + setLogLevel( 'info' ) | ||
99 | + | ||
100 | + net = ONOSMininet( topo=topo, controllers=controllers, link=link, autoSetMacs=autoSetMacs ) | ||
101 | + net.start() | ||
102 | + CLI( net ) | ||
103 | + net.stop() |
... | @@ -81,3 +81,7 @@ class UkTopo( Topo ): | ... | @@ -81,3 +81,7 @@ class UkTopo( Topo ): |
81 | self.addLink( YORK, NRWICH, bw=10, delay='1.0ms') | 81 | self.addLink( YORK, NRWICH, bw=10, delay='1.0ms') |
82 | 82 | ||
83 | topos = { 'uk': ( lambda: UkTopo() ) } | 83 | topos = { 'uk': ( lambda: UkTopo() ) } |
84 | + | ||
85 | +if __name__ == '__main__': | ||
86 | + from onosnet import run | ||
87 | + run( UkTopo() ) | ... | ... |
-
Please register or login to post a comment