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