blob: 23d442d39bc9e460ebed229fad06bebbe8288952 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004Copyright 2012 Open Networking Foundation (ONF)
adminbae64d82013-08-01 10:50:15 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
Jon Hall7eb38402015-01-08 17:19:54 -080010TestON is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070014
Jon Hall7eb38402015-01-08 17:19:54 -080015TestON is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070019
Jon Hall7eb38402015-01-08 17:19:54 -080020You should have received a copy of the GNU General Public License
21along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
Jon Hallbe6dfc42015-01-12 17:37:25 -080023MininetCliDriver is the basic driver which will handle the Mininet functions
24
25Some functions rely on a modified version of Mininet. These functions
26should all be noted in the comments. To get this MN version run these commands
27from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080028 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080030 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git pull
32
Jon Hall272a4db2015-01-12 17:43:48 -080033
34 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080035changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070036import pexpect
adminbae64d82013-08-01 10:50:15 -070037import re
38import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070039import types
kelvin-onlaba4074292015-07-09 15:19:49 -070040import os
Devin Lima7cfdbd2017-09-29 15:02:22 -070041import time
Jon Hall1ccf82c2014-10-15 14:55:16 -040042from math import pow
adminbae64d82013-08-01 10:50:15 -070043from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070044from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
kelvin-onlab50907142015-04-01 13:37:45 -070047class MininetCliDriver( Emulator ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -070048
Jon Hall7eb38402015-01-08 17:19:54 -080049 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070053 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070056 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080057 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070058 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070059 # TODO: Refactor driver to use these everywhere
60 self.mnPrompt = "mininet>"
61 self.hostPrompt = "~#"
62 self.bashPrompt = "\$"
63 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070064 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070065
Jon Hall7eb38402015-01-08 17:19:54 -080066 def connect( self, **connectargs ):
67 """
68 Here the main is the TestON instance after creating
69 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080070 try:
71 for key in connectargs:
72 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070073 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080074 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070075 for key in self.options:
76 if key == "home":
77 self.home = self.options[ 'home' ]
78 break
79 if self.home is None or self.home == "":
80 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070081
82 try:
Jon Hall892818c2015-10-20 17:58:34 -070083 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070084 self.ip_address = os.getenv( str( self.ip_address ) )
85 else:
86 main.log.info( self.name +
87 ": Trying to connect to " +
88 self.ip_address )
89
90 except KeyError:
91 main.log.info( "Invalid host name," +
92 " connecting to local host instead" )
93 self.ip_address = 'localhost'
94 except Exception as inst:
95 main.log.error( "Uncaught exception: " + str( inst ) )
96
kelvin-onlaba1484582015-02-02 15:46:20 -080097 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070098 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080099 self ).connect(
100 user_name=self.user_name,
101 ip_address=self.ip_address,
102 port=None,
103 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800104
kelvin-onlaba1484582015-02-02 15:46:20 -0800105 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800106 main.log.info( "Connection successful to the host " +
107 self.user_name +
108 "@" +
109 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800110 return main.TRUE
111 else:
112 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800113 self.user_name +
114 "@" +
115 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800116 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800117 return main.FALSE
118 except pexpect.EOF:
119 main.log.error( self.name + ": EOF exception found" )
120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700121 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800122 except Exception:
123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700124 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800125
kelvin-onlab10e8d392015-06-03 13:53:45 -0700126 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800127 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700128 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000129 Starts Mininet accepts a topology(.py) file and/or an optional
kelvin-onlabf512e942015-06-08 19:42:59 -0700130 argument, to start the mininet, as a parameter.
131 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700132 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700133 Options:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000134 topoFile = file path for topology file (.py)
kelvin-onlabf512e942015-06-08 19:42:59 -0700135 args = extra option added when starting the topology from the file
136 mnCmd = Mininet command use to start topology
137 Returns:
138 main.TRUE if the mininet starts successfully, main.FALSE
139 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800140 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700141 try:
142 if self.handle:
143 # make sure old networks are cleaned up
144 main.log.info( self.name +
145 ": Clearing any residual state or processes" )
146 self.handle.sendline( "sudo mn -c" )
147 i = self.handle.expect( [ 'password\sfor\s',
148 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800149 pexpect.EOF,
150 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700151 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800152 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700153 # Sudo asking for password
154 main.log.info( self.name + ": Sending sudo password" )
155 self.handle.sendline( self.pwd )
Jon Hall173f2a02018-01-11 13:56:37 -0800156 i = self.handle.expect( [ '%s:' % self.user_name,
Devin Limdc78e202017-06-09 18:30:07 -0700157 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700158 pexpect.EOF,
159 pexpect.TIMEOUT ],
160 timeout )
161 if i == 1:
162 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700163 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700164 main.log.error( self.name + ": Connection terminated" )
165 elif i == 3: # timeout
166 main.log.error( self.name + ": Something while cleaning " +
167 "Mininet took too long... " )
168 # Craft the string to start mininet
169 cmdString = "sudo "
170 if not mnCmd:
171 if topoFile is None or topoFile == '': # If no file is given
172 main.log.info( self.name + ": building fresh Mininet" )
173 cmdString += "mn "
174 if args is None or args == '':
175 # If no args given, use args from .topo file
176 args = self.options[ 'arg1' ] +\
177 " " + self.options[ 'arg2' ] +\
178 " --mac --controller " +\
179 self.options[ 'controller' ] + " " +\
180 self.options[ 'arg3' ]
181 else: # else only use given args
182 pass
183 # TODO: allow use of topo args and method args?
184 else: # Use given topology file
185 main.log.info(
186 "Starting Mininet from topo file " +
187 topoFile )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700188 cmdString += "-E python " + topoFile + " "
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700189 if args is None:
190 args = ''
191 # TODO: allow use of args from .topo file?
192 cmdString += args
193 else:
194 main.log.info( "Starting Mininet topology using '" + mnCmd +
195 "' command" )
196 cmdString += mnCmd
197 # Send the command and check if network started
198 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700199 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700200 main.log.info( "Sending '" + cmdString + "' to " + self.name )
201 self.handle.sendline( cmdString )
Devin Lima7cfdbd2017-09-29 15:02:22 -0700202 startTime = time.time()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700203 while True:
204 i = self.handle.expect( [ 'mininet>',
205 'Exception',
206 '\*\*\*',
207 pexpect.EOF,
Jon Hallab611372018-02-21 15:26:05 -0800208 pexpect.TIMEOUT,
209 "No such file or directory"],
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700210 timeout )
211 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -0700212 main.log.info( self.name + ": Mininet built\nTime Took : " + str( time.time() - startTime ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700213 return main.TRUE
214 elif i == 1:
215 response = str( self.handle.before +
216 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700217 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700218 response += str( self.handle.before +
219 self.handle.after )
220 main.log.error(
221 self.name +
222 ": Launching Mininet failed: " + response )
223 return main.FALSE
224 elif i == 2:
225 self.handle.expect( [ "\n",
226 pexpect.EOF,
227 pexpect.TIMEOUT ],
228 timeout )
229 main.log.info( self.handle.before )
230 elif i == 3:
231 main.log.error( self.name + ": Connection timeout" )
232 return main.FALSE
233 elif i == 4: # timeout
234 main.log.error(
235 self.name +
236 ": Something took too long... " )
237 return main.FALSE
Jon Hallab611372018-02-21 15:26:05 -0800238 elif i == 5:
239 main.log.error( self.name + ": " + self.handle.before + self.handle.after )
240 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700241 # Why did we hit this part?
242 main.log.error( "startNet did not return correctly" )
243 return main.FASLE
244 else: # if no handle
245 main.log.error( self.name + ": Connection failed to the host " +
246 self.user_name + "@" + self.ip_address )
247 main.log.error( self.name + ": Failed to connect to the Mininet" )
248 return main.FALSE
249 except pexpect.TIMEOUT:
250 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
251 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700252 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700253 except pexpect.EOF:
254 main.log.error( self.name + ": EOF exception found" )
255 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700256 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700257 except Exception:
258 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700259 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800260
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800261 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700262 try:
263 if topoType == 'tree':
264 # In tree topology, if fanout arg is not given, by default it is 2
265 if fanout is None:
266 fanout = 2
267 k = 0
268 count = 0
269 while( k <= depth - 1 ):
270 count = count + pow( fanout, k )
271 k = k + 1
272 numSwitches = count
273 while( k <= depth - 2 ):
274 # depth-2 gives you only core links and not considering
275 # edge links as seen by ONOS. If all the links including
276 # edge links are required, do depth-1
277 count = count + pow( fanout, k )
278 k = k + 1
279 numLinks = count * fanout
280 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
281 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800282
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700283 elif topoType == 'linear':
284 # In linear topology, if fanout or numHostsPerSw is not given,
285 # by default it is 1
286 if fanout is None:
287 fanout = 1
288 numSwitches = depth
289 numHostsPerSw = fanout
290 totalNumHosts = numSwitches * numHostsPerSw
291 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hallab611372018-02-21 15:26:05 -0800292 main.log.debug( "num_switches for %s(%d,%d) = %d and links=%d" %
293 ( topoType, depth, fanout, numSwitches, numLinks ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700294 topoDict = { "num_switches": int( numSwitches ),
295 "num_corelinks": int( numLinks ) }
296 return topoDict
297 except Exception:
298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700299 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400300
kelvin-onlabd3b64892015-01-20 13:26:24 -0800301 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700302 """
303 Calculate the number of switches and links in a topo."""
304 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700305 try:
306 argList = self.options[ 'arg1' ].split( "," )
307 topoArgList = argList[ 0 ].split( " " )
308 argList = map( int, argList[ 1: ] )
309 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700310
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700311 topoDict = self.numSwitchesNlinks( *topoArgList )
312 return topoDict
313 except Exception:
314 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700315 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400316
GlennRCf07c44a2015-09-18 13:33:46 -0700317 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800318 """
319 Verifies the reachability of the hosts using pingall command.
320 Optional parameter timeout allows you to specify how long to
321 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700322 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700323 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700324 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700325 ping
326 acceptableFailed - Set the number of acceptable failed pings for the
327 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800328 Returns:
329 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700330 otherwise main.FALSE
331 """
332 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700333 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700334 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700335 if self.handle:
336 main.log.info(
337 self.name +
338 ": Checking reachabilty to the hosts using pingall" )
339 response = ""
340 failedPings = 0
341 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700342 cmd = "pingall"
343 if protocol == "IPv6":
344 cmd = "py net.pingAll6()"
345 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700346 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700347 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700348 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700349 pexpect.EOF,
350 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700351 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700352 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700353 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700354 response += self.handle.before
355 break
356 elif i == 1:
357 response += self.handle.before + self.handle.after
358 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700359 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700360 returnValue = main.FALSE
361 if shortCircuit:
362 main.log.error( self.name +
363 ": Aborting pingall - "
364 + str( failedPings ) +
365 " pings failed" )
366 break
Jon Hall390696c2015-05-05 17:13:41 -0700367 if ( time.time() - startTime ) > timeout:
368 returnValue = main.FALSE
369 main.log.error( self.name +
370 ": Aborting pingall - " +
371 "Function took too long " )
372 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700373 elif i == 2:
374 main.log.error( self.name +
375 ": EOF exception found" )
376 main.log.error( self.name + ": " +
377 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700378 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700379 elif i == 3:
380 response += self.handle.before
381 main.log.error( self.name +
382 ": TIMEOUT exception found" )
383 main.log.error( self.name +
384 ": " +
385 str( response ) )
386 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800387 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700388 self.handle.expect( "Interrupt" )
389 self.handle.expect( "mininet>" )
390 break
391 pattern = "Results\:"
392 main.log.info( "Pingall output: " + str( response ) )
393 if re.search( pattern, response ):
394 main.log.info( self.name + ": Pingall finished with "
395 + str( failedPings ) + " failed pings" )
396 return returnValue
397 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700398 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800399 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700400 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700401 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700402 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700403 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700404 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700405 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700406 except pexpect.TIMEOUT:
407 if response:
408 main.log.info( "Pingall output: " + str( response ) )
409 main.log.error( self.name + ": pexpect.TIMEOUT found" )
410 return main.FALSE
411 except pexpect.EOF:
412 main.log.error( self.name + ": EOF exception found" )
413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700414 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700415
Jon Hall7eb38402015-01-08 17:19:54 -0800416 def fpingHost( self, **pingParams ):
417 """
418 Uses the fping package for faster pinging...
419 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700420 try:
421 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
422 command = args[ "SRC" ] + \
423 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
424 self.handle.sendline( command )
425 self.handle.expect(
426 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
427 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
428 response = self.handle.before
429 if re.search( ":\s-", response ):
430 main.log.info( self.name + ": Ping fail" )
431 return main.FALSE
432 elif re.search( ":\s\d{1,2}\.\d\d", response ):
433 main.log.info( self.name + ": Ping good!" )
434 return main.TRUE
435 main.log.info( self.name + ": Install fping on mininet machine... " )
436 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700437 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700438 except Exception:
439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700440 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700441
Jon Hall3b489db2015-10-05 14:38:37 -0700442 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400443 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700444 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700445
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400446 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700447 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700448
449 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400450 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700451
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400452 Returns main.FALSE if one or more of hosts specified
453 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700454 wait = int( wait )
455 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400456
457 try:
458 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700459
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400460 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700461 pingResponse = "IPv4 ping across specified hosts\n"
462 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400463 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700464 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400465 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700466 pingList = hostList[ :listIndex ] + \
467 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700468
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700469 pingResponse += str( str( host ) + " -> " )
GlennRCd10d3cc2015-09-24 12:47:16 -0700470
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400471 for temp in pingList:
472 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700473 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700474 self.handle.sendline( pingCmd )
475 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400476 response = self.handle.before
477 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700478 pingResponse += str( " h" + str( temp[ 1: ] ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400479 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700480 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400481 # One of the host to host pair is unreachable
482 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700483 failedPings += 1
You Wang11f9ead2018-03-21 14:34:59 -0700484 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
GlennRCd10d3cc2015-09-24 12:47:16 -0700485 pingResponse += "\n"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700486 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700487 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700488 except pexpect.TIMEOUT:
489 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800490 response = self.handle.before
491 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700492 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800493 self.handle.expect( "Interrupt" )
494 response += self.handle.before + self.handle.after
495 self.handle.expect( "mininet>" )
496 response += self.handle.before + self.handle.after
497 main.log.debug( response )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700498 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400499 except pexpect.EOF:
500 main.log.error( self.name + ": EOF exception found" )
501 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700502 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700503 except Exception:
504 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700505 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400506
You Wangf19d9f42018-02-23 16:34:19 -0800507 def pingIpv6Hosts( self, hostList, wait=1, acceptableFailed=0 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700508 """
You Wangf19d9f42018-02-23 16:34:19 -0800509 IPv6 ping all hosts in hostList.
510
511 acceptableFailed: max number of acceptable failed pings
Hari Krishna9592fc82015-07-31 15:11:15 -0700512
Jon Hall3b489db2015-10-05 14:38:37 -0700513 Returns main.TRUE if all hosts specified can reach each other
Jon Hall3b489db2015-10-05 14:38:37 -0700514 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700515 """
516 try:
517 main.log.info( "Testing reachability between specified IPv6 hosts" )
518 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700519 wait = int( wait )
520 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700521 pingResponse = "IPv6 Pingall output:\n"
You Wangf19d9f42018-02-23 16:34:19 -0800522 failedPingsTotal = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700523 for host in hostList:
524 listIndex = hostList.index( host )
525 # List of hosts to ping other than itself
526 pingList = hostList[ :listIndex ] + \
527 hostList[ ( listIndex + 1 ): ]
528
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700529 pingResponse += str( str( host ) + " -> " )
GlennRC2cf7d952015-09-11 16:32:13 -0700530
Hari Krishna9592fc82015-07-31 15:11:15 -0700531 for temp in pingList:
532 # Current host pings all other hosts specified
You Wangf19d9f42018-02-23 16:34:19 -0800533 failedPings = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700534 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
You Wangf19d9f42018-02-23 16:34:19 -0800535 while failedPings <= acceptableFailed:
536 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
537 self.handle.sendline( pingCmd )
538 self.handle.expect( "mininet>", timeout=wait + 1 )
539 response = self.handle.before
540 if re.search( ',\s0\%\spacket\sloss', response ):
You Wangba231e72018-03-01 13:18:21 -0800541 pingResponse += " " + str( temp )
542 break
543 else:
544 failedPings += 1
545 time.sleep(1)
546 if failedPings > acceptableFailed:
547 # One of the host to host pair is unreachable
548 pingResponse += " X"
549 isReachable = main.FALSE
550 failedPingsTotal += 1
You Wang11f9ead2018-03-21 14:34:59 -0700551 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
You Wangba231e72018-03-01 13:18:21 -0800552 pingResponse += "\n"
553 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
554 return isReachable
555
556 except pexpect.TIMEOUT:
557 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800558 response = self.handle.before
559 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700560 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800561 self.handle.expect( "Interrupt" )
562 response += self.handle.before + self.handle.after
563 self.handle.expect( "mininet>" )
564 response += self.handle.before + self.handle.after
565 main.log.debug( response )
You Wangba231e72018-03-01 13:18:21 -0800566 return main.FALSE
567 except pexpect.EOF:
568 main.log.error( self.name + ": EOF exception found" )
569 main.log.error( self.name + ": " + self.handle.before )
570 main.cleanAndExit()
571 except Exception:
572 main.log.exception( self.name + ": Uncaught exception!" )
573 main.cleanAndExit()
574
575 def pingallHostsUnidirectional( self, srcList, dstList, ipv6=False, wait=1, acceptableFailed=0 ):
576 """
577 Verify ping from each host in srcList to each host in dstList
578
579 acceptableFailed: max number of acceptable failed pings
580
581 Returns main.TRUE if all src hosts can reach all dst hosts
582 Returns main.FALSE if one or more of src hosts cannot reach one or more of dst hosts
583 """
584 try:
585 main.log.info( "Verifying ping from each src host to each dst host" )
586 isReachable = main.TRUE
587 wait = int( wait )
588 cmd = " ping" + ("6" if ipv6 else "") + " -c 1 -i 1 -W " + str( wait ) + " "
589 pingResponse = "Ping output:\n"
590 failedPingsTotal = 0
591 for host in srcList:
592 pingResponse += str( str( host ) + " -> " )
593 for temp in dstList:
594 failedPings = 0
595 if ipv6:
596 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
597 else:
598 pingCmd = str( host ) + cmd + str( temp )
599 while failedPings <= acceptableFailed:
600 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
601 self.handle.sendline( pingCmd )
602 self.handle.expect( "mininet>", timeout=wait + 1 )
603 response = self.handle.before
604 if re.search( ',\s0\%\spacket\sloss', response ):
605 pingResponse += " " + str( temp )
You Wangf19d9f42018-02-23 16:34:19 -0800606 break
607 else:
608 failedPings += 1
609 time.sleep(1)
610 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700611 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800612 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700613 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800614 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700615 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800616 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700617 return isReachable
618
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700619 except pexpect.TIMEOUT:
620 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800621 response = self.handle.before
622 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700623 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800624 self.handle.expect( "Interrupt" )
625 response += self.handle.before + self.handle.after
626 self.handle.expect( "mininet>" )
627 response += self.handle.before + self.handle.after
628 main.log.debug( response )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700629 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700630 except pexpect.EOF:
631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700633 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700634 except Exception:
635 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700636 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700637
Jon Hall7eb38402015-01-08 17:19:54 -0800638 def pingHost( self, **pingParams ):
639 """
Jon Hall3b489db2015-10-05 14:38:37 -0700640 Ping from one mininet host to another
641 Currently the only supported Params: SRC, TARGET, and WAIT
642 """
643 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700644 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700645 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800646 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700647 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700648 try:
Jon Hall61282e32015-03-19 11:34:11 -0700649 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800650 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700651 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
652 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700653 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800654 main.log.error(
655 self.name +
656 ": timeout when waiting for response from mininet" )
657 main.log.error( "response: " + str( self.handle.before ) )
658 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700659 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800660 main.log.error(
661 self.name +
662 ": timeout when waiting for response from mininet" )
663 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700664 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700665 if re.search( ',\s0\%\spacket\sloss', response ):
666 main.log.info( self.name + ": no packets lost, host is reachable" )
667 return main.TRUE
668 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800669 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700670 self.name +
671 ": PACKET LOST, HOST IS NOT REACHABLE" )
672 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800673 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800674 main.log.error( self.name + ": EOF exception found" )
675 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700676 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700677 except Exception:
678 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700679 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700680
681 def ping6pair( self, **pingParams ):
682 """
GlennRC2cf7d952015-09-11 16:32:13 -0700683 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700684 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000685 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700686 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
687 """
Jon Hall3b489db2015-10-05 14:38:37 -0700688 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700689 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700690 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530691 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700692 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700693 try:
694 main.log.info( "Sending: " + command )
695 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700696 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
697 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700698 if i == 1:
699 main.log.error(
700 self.name +
701 ": timeout when waiting for response from mininet" )
702 main.log.error( "response: " + str( self.handle.before ) )
703 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
704 if i == 1:
705 main.log.error(
706 self.name +
707 ": timeout when waiting for response from mininet" )
708 main.log.error( "response: " + str( self.handle.before ) )
709 response = self.handle.before
710 main.log.info( self.name + ": Ping Response: " + response )
711 if re.search( ',\s0\%\spacket\sloss', response ):
712 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700713 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700714 else:
alisone4121a92016-11-22 16:31:36 -0800715 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700716 self.name +
717 ": PACKET LOST, HOST IS NOT REACHABLE" )
718 return main.FALSE
Hari Krishna012a1c12015-08-25 14:23:58 -0700719 except pexpect.EOF:
720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700722 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700723 except Exception:
724 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700725 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800726
You Wangdb927a52016-02-26 11:03:28 -0800727 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
728 """
729 Description:
730 Ping a set of destination host from host CLI.
731 Logging into a Mininet host CLI is required before calling this funtion.
732 Params:
733 dstIPList is a list of destination ip addresses
734 Returns:
735 main.TRUE if the destination host is reachable
736 main.FALSE otherwise
737 """
738 isReachable = main.TRUE
739 wait = int( wait )
740 cmd = "ping"
741 if IPv6:
742 cmd = cmd + "6"
743 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
744 try:
745 for dstIP in dstIPList:
746 pingCmd = cmd + " " + dstIP
747 self.handle.sendline( pingCmd )
748 i = self.handle.expect( [ self.hostPrompt,
749 '\*\*\* Unknown command: ' + pingCmd,
750 pexpect.TIMEOUT ],
751 timeout=wait + 1 )
752 if i == 0:
753 response = self.handle.before
754 if not re.search( ',\s0\%\spacket\sloss', response ):
755 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
756 isReachable = main.FALSE
757 elif i == 1:
758 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700759 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800760 elif i == 2:
761 main.log.error( self.name + ": timeout when waiting for response" )
762 isReachable = main.FALSE
763 else:
764 main.log.error( self.name + ": unknown response: " + self.handle.before )
765 isReachable = main.FALSE
766 except pexpect.TIMEOUT:
767 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800768 response = self.handle.before
769 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700770 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800771 self.handle.expect( "Interrupt" )
772 response += self.handle.before + self.handle.after
773 self.handle.expect( "mininet>" )
774 response += self.handle.before + self.handle.after
775 main.log.debug( response )
You Wangdb927a52016-02-26 11:03:28 -0800776 isReachable = main.FALSE
777 except pexpect.EOF:
778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700780 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800781 except Exception:
782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700783 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800784 return isReachable
785
Jon Hall7eb38402015-01-08 17:19:54 -0800786 def checkIP( self, host ):
787 """
788 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700789 try:
790 if self.handle:
791 try:
792 response = self.execute(
793 cmd=host +
794 " ifconfig",
795 prompt="mininet>",
796 timeout=10 )
797 except pexpect.EOF:
798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700800 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700801
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700802 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
803 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
804 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
805 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
806 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
807 "[0-9]|25[0-5]|[0-9]{1,2})"
808 # pattern = "inet addr:10.0.0.6"
809 if re.search( pattern, response ):
810 main.log.info( self.name + ": Host Ip configured properly" )
811 return main.TRUE
812 else:
813 main.log.error( self.name + ": Host IP not found" )
814 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700815 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700816 main.log.error( self.name + ": Connection failed to the host" )
817 except Exception:
818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700819 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800820
Jon Hall7eb38402015-01-08 17:19:54 -0800821 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800822 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700823 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800824 response = self.execute(
825 cmd="h1 /usr/sbin/sshd -D&",
826 prompt="mininet>",
827 timeout=10 )
828 response = self.execute(
829 cmd="h4 /usr/sbin/sshd -D&",
830 prompt="mininet>",
831 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700832 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 vars( self )[ key ] = connectargs[ key ]
834 response = self.execute(
835 cmd="xterm h1 h4 ",
836 prompt="mininet>",
837 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800838 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700841 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700842 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800843 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700844 if self.flag == 0:
845 self.flag = 1
846 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800847 else:
adminbae64d82013-08-01 10:50:15 -0700848 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800849
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700850 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700851 """
852 Moves a host from one switch to another on the fly
853 Note: The intf between host and oldSw when detached
854 using detach(), will still show up in the 'net'
855 cmd, because switch.detach() doesn't affect switch.intfs[]
856 ( which is correct behavior since the interfaces
857 haven't moved ).
858 """
859 if self.handle:
860 try:
861 # Bring link between oldSw-host down
862 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
863 "'," + "'down')"
864 print "cmd1= ", cmd
865 response = self.execute( cmd=cmd,
866 prompt="mininet>",
867 timeout=10 )
868
869 # Determine hostintf and Oldswitchintf
870 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
871 ")[0]"
872 print "cmd2= ", cmd
873 self.handle.sendline( cmd )
874 self.handle.expect( "mininet>" )
875
876 # Determine ip and mac address of the host-oldSw interface
877 cmd = "px ipaddr = hintf.IP()"
878 print "cmd3= ", cmd
879 self.handle.sendline( cmd )
880 self.handle.expect( "mininet>" )
881
882 cmd = "px macaddr = hintf.MAC()"
883 print "cmd3= ", cmd
884 self.handle.sendline( cmd )
885 self.handle.expect( "mininet>" )
886
887 # Detach interface between oldSw-host
888 cmd = "px " + oldSw + ".detach( sintf )"
889 print "cmd4= ", cmd
890 self.handle.sendline( cmd )
891 self.handle.expect( "mininet>" )
892
893 # Add link between host-newSw
894 cmd = "py net.addLink(" + host + "," + newSw + ")"
895 print "cmd5= ", cmd
896 self.handle.sendline( cmd )
897 self.handle.expect( "mininet>" )
898
899 # Determine hostintf and Newswitchintf
900 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
901 ")[0]"
902 print "cmd6= ", cmd
903 self.handle.sendline( cmd )
904 self.handle.expect( "mininet>" )
905
906 # Attach interface between newSw-host
907 cmd = "px " + newSw + ".attach( sintf )"
908 print "cmd3= ", cmd
909 self.handle.sendline( cmd )
910 self.handle.expect( "mininet>" )
911
912 # Set ipaddress of the host-newSw interface
913 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
914 print "cmd7 = ", cmd
915 self.handle.sendline( cmd )
916 self.handle.expect( "mininet>" )
917
918 # Set macaddress of the host-newSw interface
919 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
920 print "cmd8 = ", cmd
921 self.handle.sendline( cmd )
922 self.handle.expect( "mininet>" )
923
924 cmd = "net"
925 print "cmd9 = ", cmd
926 self.handle.sendline( cmd )
927 self.handle.expect( "mininet>" )
928 print "output = ", self.handle.before
929
930 # Determine ipaddress of the host-newSw interface
931 cmd = host + " ifconfig"
932 print "cmd10= ", cmd
933 self.handle.sendline( cmd )
934 self.handle.expect( "mininet>" )
935 print "ifconfig o/p = ", self.handle.before
936
937 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700938
939 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700940 main.log.error( self.name + ": TIMEOUT exception found" )
941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700942 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700943 except pexpect.EOF:
944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
946 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700947 except Exception:
948 main.log.exception( self.name + ": Uncaught exception!" )
949 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700950
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700951 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800952 """
953 Moves a host from one switch to another on the fly
954 Note: The intf between host and oldSw when detached
955 using detach(), will still show up in the 'net'
956 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700957 ( which is correct behavior since the interfaces
958 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800959 """
960 if self.handle:
961 try:
Jon Hall439c8912016-04-15 02:22:03 -0700962 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800963 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700964 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800965 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800966 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800967 response = self.execute( cmd=cmd,
968 prompt="mininet>",
969 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700970
kelvin-onlaba1484582015-02-02 15:46:20 -0800971 # Determine hostintf and Oldswitchintf
972 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800973 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800974 print "cmd2= ", cmd
975 self.handle.sendline( cmd )
976 self.handle.expect( "mininet>" )
977
shahshreya73537862015-02-11 15:15:24 -0800978 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700979 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800980 print "cmd3= ", cmd
981 self.handle.sendline( cmd )
982 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800983
984 cmd = "px macaddr = hintf.MAC()"
985 print "cmd3= ", cmd
986 self.handle.sendline( cmd )
987 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700988
kelvin-onlaba1484582015-02-02 15:46:20 -0800989 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700990 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800991 print "cmd4= ", cmd
992 self.handle.sendline( cmd )
993 self.handle.expect( "mininet>" )
994
995 # Add link between host-newSw
996 cmd = "py net.addLink(" + host + "," + newSw + ")"
997 print "cmd5= ", cmd
998 self.handle.sendline( cmd )
999 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001000
kelvin-onlaba1484582015-02-02 15:46:20 -08001001 # Determine hostintf and Newswitchintf
1002 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -08001003 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -08001004 print "cmd6= ", cmd
1005 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -07001006 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001007
1008 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001009 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001010 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001011 self.handle.sendline( cmd )
1012 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -08001013
1014 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001015 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001016 print "cmd7 = ", cmd
1017 self.handle.sendline( cmd )
1018 self.handle.expect( "mininet>" )
1019
1020 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001021 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -08001022 print "cmd8 = ", cmd
1023 self.handle.sendline( cmd )
1024 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001025
Jon Hall439c8912016-04-15 02:22:03 -07001026 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001027 print "cmd9 =", cmd
1028 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -07001029 print response
1030 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -07001031 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001032 print ipAddressSearch.group( 1 )
1033 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -07001034 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
1035 print "cmd10 = ", cmd
1036 self.handle.sendline( cmd )
1037 self.handle.expect( "mininet>" )
1038
kelvin-onlaba1484582015-02-02 15:46:20 -08001039 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -07001040 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001041 self.handle.sendline( cmd )
1042 self.handle.expect( "mininet>" )
1043 print "output = ", self.handle.before
1044
1045 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -08001046 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -07001047 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001048 self.handle.sendline( cmd )
1049 self.handle.expect( "mininet>" )
1050 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -07001051
kelvin-onlaba1484582015-02-02 15:46:20 -08001052 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001053 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001054 main.log.error( self.name + ": TIMEOUT exception found" )
1055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001056 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08001057 except pexpect.EOF:
1058 main.log.error( self.name + ": EOF exception found" )
1059 main.log.error( self.name + ": " + self.handle.before )
1060 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001061 except Exception:
1062 main.log.exception( self.name + ": Uncaught exception!" )
1063 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -08001064
Jon Hall7eb38402015-01-08 17:19:54 -08001065 def changeIP( self, host, intf, newIP, newNetmask ):
1066 """
1067 Changes the ip address of a host on the fly
1068 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001069 if self.handle:
1070 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001071 cmd = host + " ifconfig " + intf + " " + \
1072 newIP + " " + 'netmask' + " " + newNetmask
1073 self.handle.sendline( cmd )
1074 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001075 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001076 main.log.info( "response = " + response )
1077 main.log.info(
1078 "Ip of host " +
1079 host +
1080 " changed to new IP " +
1081 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001082 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001083 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001084 main.log.error( self.name + ": TIMEOUT exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001086 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001087 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001088 main.log.error( self.name + ": EOF exception found" )
1089 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001090 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001091 except Exception:
1092 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001093 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001094
Jon Hall7eb38402015-01-08 17:19:54 -08001095 def changeDefaultGateway( self, host, newGW ):
1096 """
1097 Changes the default gateway of a host
1098 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001099 if self.handle:
1100 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001101 cmd = host + " route add default gw " + newGW
1102 self.handle.sendline( cmd )
1103 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001104 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001105 main.log.info( "response = " + response )
1106 main.log.info(
1107 "Default gateway of host " +
1108 host +
1109 " changed to " +
1110 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001111 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001112 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001113 main.log.error( self.name + ": TIMEOUT exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001115 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001116 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 main.log.error( self.name + ": EOF exception found" )
1118 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001119 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001120 except Exception:
1121 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001122 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001123
Jon Hall7eb38402015-01-08 17:19:54 -08001124 def addStaticMACAddress( self, host, GW, macaddr ):
1125 """
Jon Hallefbd9792015-03-05 16:11:36 -08001126 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001127 if self.handle:
1128 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001129 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1130 cmd = host + " arp -s " + GW + " " + macaddr
1131 self.handle.sendline( cmd )
1132 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001133 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001134 main.log.info( "response = " + response )
1135 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001136 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001137 GW +
1138 " changed to " +
1139 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001140 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001141 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001142 main.log.error( self.name + ": TIMEOUT exception found" )
1143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001144 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001145 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001148 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001149 except Exception:
1150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001151 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001152
Jon Hall7eb38402015-01-08 17:19:54 -08001153 def verifyStaticGWandMAC( self, host ):
1154 """
1155 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001156 if self.handle:
1157 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001158 # h1 arp -an
1159 cmd = host + " arp -an "
1160 self.handle.sendline( cmd )
1161 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001162 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001163 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001164 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001165 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001166 main.log.error( self.name + ": TIMEOUT exception found" )
1167 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001168 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001169 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001170 main.log.error( self.name + ": EOF exception found" )
1171 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001172 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001173 except Exception:
1174 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001175 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001176
Jon Hall7eb38402015-01-08 17:19:54 -08001177 def getMacAddress( self, host ):
1178 """
1179 Verifies the host's ip configured or not."""
1180 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001181 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001182 response = self.execute(
1183 cmd=host +
1184 " ifconfig",
1185 prompt="mininet>",
1186 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001187 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001188 main.log.error( self.name + ": EOF exception found" )
1189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001190 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001191 except Exception:
1192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001193 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001194
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001195 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 macAddressSearch = re.search( pattern, response, re.I )
1197 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001198 main.log.info(
1199 self.name +
1200 ": Mac-Address of Host " +
1201 host +
1202 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 macAddress )
1204 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001205 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001206 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001207
Jon Hall7eb38402015-01-08 17:19:54 -08001208 def getInterfaceMACAddress( self, host, interface ):
1209 """
1210 Return the IP address of the interface on the given host"""
1211 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001212 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001213 response = self.execute( cmd=host + " ifconfig " + interface,
1214 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001215 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 main.log.error( self.name + ": EOF exception found" )
1217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001218 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001219 except Exception:
1220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001221 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001222
1223 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 macAddressSearch = re.search( pattern, response, re.I )
1225 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001226 main.log.info( "No mac address found in %s" % response )
1227 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001229 main.log.info(
1230 "Mac-Address of " +
1231 host +
1232 ":" +
1233 interface +
1234 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 macAddress )
1236 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001237 else:
1238 main.log.error( "Connection failed to the host" )
1239
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001240 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001241 """
1242 Verifies the host's ip configured or not."""
1243 if self.handle:
1244 try:
1245 response = self.execute(
1246 cmd=host +
1247 " ifconfig",
1248 prompt="mininet>",
1249 timeout=10 )
1250 except pexpect.EOF:
1251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001254 except Exception:
1255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001257
sathishmad953462015-12-03 17:42:07 +05301258 pattern = ''
1259 if proto == 'IPV4':
1260 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1261 else:
Jon Hall439c8912016-04-15 02:22:03 -07001262 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 ipAddressSearch = re.search( pattern, response )
Jon Hall3c910162018-03-07 14:42:16 -08001264 if not ipAddressSearch:
1265 return None
Jon Hall7eb38402015-01-08 17:19:54 -08001266 main.log.info(
1267 self.name +
1268 ": IP-Address of Host " +
1269 host +
1270 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 ipAddressSearch.group( 1 ) )
1272 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001273 else:
1274 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001275
Jon Hall7eb38402015-01-08 17:19:54 -08001276 def getSwitchDPID( self, switch ):
1277 """
1278 return the datapath ID of the switch"""
1279 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001280 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001281 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001282 response = self.execute(
1283 cmd=cmd,
1284 prompt="mininet>",
1285 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001286 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001289 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001292 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001293 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001294 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001295 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001296 main.log.info(
1297 "Couldn't find DPID for switch %s, found: %s" %
1298 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001299 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001300 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001301 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001302 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001303
Jon Hall7eb38402015-01-08 17:19:54 -08001304 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001305 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001306 self.handle.sendline( "" )
1307 self.expect( "mininet>" )
1308 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001309 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001310 response = self.execute(
1311 cmd=cmd,
1312 prompt="mininet>",
1313 timeout=10 )
1314 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001315 response = self.handle.before
1316 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001317 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001318 main.log.error( self.name + ": TIMEOUT exception found" )
1319 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001320 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001321 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001324 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001325 except Exception:
1326 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001327 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001328
Jon Hall7eb38402015-01-08 17:19:54 -08001329 def getInterfaces( self, node ):
1330 """
1331 return information dict about interfaces connected to the node"""
1332 if self.handle:
1333 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001334 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001335 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001336 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001337 response = self.execute(
1338 cmd=cmd,
1339 prompt="mininet>",
1340 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001341 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001342 main.log.error( self.name + ": EOF exception found" )
1343 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001344 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001345 except Exception:
1346 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001347 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001348 return response
1349 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001351
Jon Hall7eb38402015-01-08 17:19:54 -08001352 def dump( self ):
1353 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001354 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001355 response = self.execute(
1356 cmd='dump',
1357 prompt='mininet>',
1358 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001359 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001360 main.log.error( self.name + ": EOF exception found" )
1361 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001362 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001363 except Exception:
1364 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001365 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001366 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001367
Jon Hall7eb38402015-01-08 17:19:54 -08001368 def intfs( self ):
1369 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001370 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 response = self.execute(
1372 cmd='intfs',
1373 prompt='mininet>',
1374 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001375 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 main.log.error( self.name + ": EOF exception found" )
1377 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001378 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001379 except Exception:
1380 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001381 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001382 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001383
Jon Hall7eb38402015-01-08 17:19:54 -08001384 def net( self ):
1385 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001386 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001387 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001388 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001389 main.log.error( self.name + ": EOF exception found" )
1390 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001391 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001392 except Exception:
1393 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001394 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001395 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001396
Devin Lima7cfdbd2017-09-29 15:02:22 -07001397 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001398 main.log.info( self.name + ": List network links" )
1399 try:
1400 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001401 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001402 except pexpect.EOF:
1403 main.log.error( self.name + ": EOF exception found" )
1404 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001405 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001406 except Exception:
1407 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001408 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001409 return response
1410
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001411 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001412 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001413 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001414
kelvin-onlab7cce9382015-07-17 10:21:03 -07001415 @parm:
1416 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1417 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001418 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001419 try:
1420 for host1 in hosts:
1421 for host2 in hosts:
1422 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001423 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1424 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001425 except Exception:
1426 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001427 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001428
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001429 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001430 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001431 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1432 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001433
kelvin-onlab7cce9382015-07-17 10:21:03 -07001434 @parm:
1435 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1436 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001437 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001438 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1439 try:
1440 # Setup the mininet command
1441 cmd1 = 'iperf ' + host1 + " " + host2
1442 self.handle.sendline( cmd1 )
1443 outcome = self.handle.expect( "mininet>", timeout )
1444 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001445
kelvin-onlab7cce9382015-07-17 10:21:03 -07001446 # checks if there are results in the mininet response
1447 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001448 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001449 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001450 response = response.split( "\r\n" )
1451 response = response[ len( response )-2 ]
1452 response = response.split( ": " )
1453 response = response[ len( response )-1 ]
1454 response = response.replace( "[", "" )
1455 response = response.replace( "]", "" )
1456 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001457
kelvin-onlab7cce9382015-07-17 10:21:03 -07001458 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001459 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001460
kelvin-onlab7cce9382015-07-17 10:21:03 -07001461 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001462 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001463 if len( bandwidth ) == 2:
1464 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001465 return main.TRUE
1466 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001467 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001468 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001469 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001470 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001471 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001472 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001473 main.log.error( self.name + ": TIMEOUT exception found" )
1474 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001475 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001476 # NOTE: Send ctrl-c to make sure iperf is done
Jon Hall2c5ac942018-03-23 11:26:54 -07001477 self.handle.send( "\x03" )
Jon Hall3b489db2015-10-05 14:38:37 -07001478 self.handle.expect( "Interrupt" )
1479 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001480 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001481 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001482 main.log.error( self.name + ": EOF exception found" )
1483 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001484 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001485 except Exception:
1486 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001487 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001488
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001489 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001490 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1491 try:
1492 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001493 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001494 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001495 outcome1 = self.handle.expect( "mininet>" )
1496 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001497 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001498 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001499 response1 = self.handle.before
1500 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001501 print response1, response2
1502 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001503 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001504 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001505 return main.TRUE
1506 else:
1507 main.log.error( self.name + ": iperf test failed" )
1508 return main.FALSE
1509 except pexpect.TIMEOUT:
1510 main.log.error( self.name + ": TIMEOUT exception found" )
1511 main.log.error( self.name + " response: " + repr( self.handle.before ) )
Jon Hall2c5ac942018-03-23 11:26:54 -07001512 self.handle.send( "\x03" )
Jon Hall439c8912016-04-15 02:22:03 -07001513 self.handle.expect( "Interrupt" )
1514 self.handle.expect( "mininet>" )
1515 return main.FALSE
1516 except pexpect.EOF:
1517 main.log.error( self.name + ": EOF exception found" )
1518 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001519 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001520 except Exception:
1521 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001522 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001523
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001524 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001525 '''
GlennRC61321f22015-07-16 13:36:54 -07001526 Runs the iperfudp function with a given set of hosts and specified
1527 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001528
GlennRC61321f22015-07-16 13:36:54 -07001529 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001530 bandwidth: the targeted bandwidth, in megabits ('M')
1531 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001532 try:
1533 for host1 in hosts:
1534 for host2 in hosts:
1535 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001536 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1537 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001538 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001539 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001540 return main.FALSE
1541 except Exception:
1542 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001543 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001544
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001545 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001546 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001547 Creates an iperf UDP test with a specific bandwidth.
1548 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001549
kelvin-onlab7cce9382015-07-17 10:21:03 -07001550 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001551 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1552 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001553 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001554 try:
1555 # setup the mininet command
1556 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001557 self.handle.sendline( cmd )
1558 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001559 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001560
kelvin-onlab7cce9382015-07-17 10:21:03 -07001561 # check if there are in results in the mininet response
1562 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001563 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001564 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001565 response = response.split( "\r\n" )
1566 response = response[ len( response )-2 ]
1567 response = response.split( ": " )
1568 response = response[ len( response )-1 ]
1569 response = response.replace( "[", "" )
1570 response = response.replace( "]", "" )
1571 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001572
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001573 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001574
kelvin-onlab7cce9382015-07-17 10:21:03 -07001575 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001576 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001577 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001578 # if one entry is blank then something is wrong
1579 for item in mnBandwidth:
1580 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001581 main.log.error( self.name + ": Could not parse iperf output" )
1582 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001583 return main.FALSE
1584 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001585 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001586 return main.TRUE
1587 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001588 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001589 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001590
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001591 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001592 main.log.error( self.name + ": TIMEOUT exception found" )
1593 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001594 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001595 except pexpect.EOF:
1596 main.log.error( self.name + ": EOF exception found" )
1597 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001598 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001599 except Exception:
1600 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001601 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001602
Jon Hall7eb38402015-01-08 17:19:54 -08001603 def nodes( self ):
1604 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001605 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001606 response = self.execute(
1607 cmd='nodes',
1608 prompt='mininet>',
1609 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001610 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001611 main.log.error( self.name + ": EOF exception found" )
1612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001613 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001614 except Exception:
1615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001616 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001617 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001618
Jon Hall7eb38402015-01-08 17:19:54 -08001619 def pingpair( self ):
1620 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001621 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001622 response = self.execute(
1623 cmd='pingpair',
1624 prompt='mininet>',
1625 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001626 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001627 main.log.error( self.name + ": EOF exception found" )
1628 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001629 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001630 except Exception:
1631 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001632 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001633
Jon Hall7eb38402015-01-08 17:19:54 -08001634 if re.search( ',\s0\%\spacket\sloss', response ):
1635 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001636 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001637 else:
alisone4121a92016-11-22 16:31:36 -08001638 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001639 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001640
Jon Hall7eb38402015-01-08 17:19:54 -08001641 def link( self, **linkargs ):
1642 """
GlennRCed771242016-01-13 17:02:47 -08001643 Bring link( s ) between two nodes up or down
1644 """
Jon Hall6094a362014-04-11 14:46:56 -07001645 try:
GlennRCed771242016-01-13 17:02:47 -08001646 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1647 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1648 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1649 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1650
1651 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1652 cmd = "link {} {} {}".format( end1, end2, option )
1653 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001654 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001655 response = self.handle.before
1656 main.log.info( response )
Jon Hallab611372018-02-21 15:26:05 -08001657 if "not in network" in response:
1658 main.log.error( self.name + ": Could not find one of the endpoints of the link" )
1659 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08001660 return main.TRUE
1661 except pexpect.TIMEOUT:
1662 main.log.exception( self.name + ": Command timed out" )
1663 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001664 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001665 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001666 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001667 except Exception:
1668 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001669 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001670
pingping-lin8244a3b2015-09-16 13:36:56 -07001671 def switch( self, **switchargs ):
1672 """
1673 start/stop a switch
1674 """
1675 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1676 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1677 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1678 command = "switch " + str( sw ) + " " + str( option )
1679 main.log.info( command )
1680 try:
1681 self.handle.sendline( command )
1682 self.handle.expect( "mininet>" )
1683 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001684 main.log.error( self.name + ": TIMEOUT exception found" )
1685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001686 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001687 except pexpect.EOF:
1688 main.log.error( self.name + ": EOF exception found" )
1689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001690 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001691 return main.TRUE
1692
pingping-lin5bb663b2015-09-24 11:47:50 -07001693 def node( self, nodeName, commandStr ):
1694 """
1695 Carry out a command line on a given node
1696 @parm:
1697 nodeName: the node name in Mininet testbed
1698 commandStr: the command line will be carried out on the node
1699 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1700 """
1701 command = str( nodeName ) + " " + str( commandStr )
1702 main.log.info( command )
1703
1704 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001705 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001706 if re.search( "Unknown command", response ):
1707 main.log.warn( response )
1708 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001709 if re.search( "Permission denied", response ):
1710 main.log.warn( response )
1711 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001712 except pexpect.EOF:
1713 main.log.error( self.name + ": EOF exception found" )
1714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001715 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001716 main.log.info( " response is :" )
1717 main.log.info( response )
1718 return response
1719
Jon Hall7eb38402015-01-08 17:19:54 -08001720 def yank( self, **yankargs ):
1721 """
1722 yank a mininet switch interface to a host"""
1723 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001724 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001725 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1726 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001727 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001728 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001729 response = self.execute(
1730 cmd=command,
1731 prompt="mininet>",
1732 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001733 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001734 main.log.error( self.name + ": EOF exception found" )
1735 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001736 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001737 except Exception:
1738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001739 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001740 return main.TRUE
1741
Jon Hall7eb38402015-01-08 17:19:54 -08001742 def plug( self, **plugargs ):
1743 """
1744 plug the yanked mininet switch interface to a switch"""
1745 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001746 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001747 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1748 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001749 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001750 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001751 response = self.execute(
1752 cmd=command,
1753 prompt="mininet>",
1754 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001755 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001758 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001759 except Exception:
1760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001761 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001762 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001763
Jon Hall7eb38402015-01-08 17:19:54 -08001764 def dpctl( self, **dpctlargs ):
1765 """
1766 Run dpctl command on all switches."""
1767 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001768 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001769 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1770 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1771 command = "dpctl " + cmd + " " + str( cmdargs )
1772 try:
1773 response = self.execute(
1774 cmd=command,
1775 prompt="mininet>",
1776 timeout=10 )
1777 except pexpect.EOF:
1778 main.log.error( self.name + ": EOF exception found" )
1779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001780 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001781 except Exception:
1782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001783 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001784 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001785
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001787 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001788 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001789 try:
1790 fileInput = path + '/lib/Mininet/INSTALL'
1791 version = super( Mininet, self ).getVersion()
1792 pattern = 'Mininet\s\w\.\w\.\w\w*'
1793 for line in open( fileInput, 'r' ).readlines():
1794 result = re.match( pattern, line )
1795 if result:
1796 version = result.group( 0 )
1797 return version
1798 except Exception:
1799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001800 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001801
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001803 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001804 Parameters:
1805 sw: The name of an OVS switch. Example "s1"
1806 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001807 The output of the command from the mininet cli
1808 or main.FALSE on timeout"""
1809 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001810 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001811 response = self.execute(
1812 cmd=command,
1813 prompt="mininet>",
1814 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001815 if response:
Jon Hallab611372018-02-21 15:26:05 -08001816 if "no bridge named" in response:
1817 main.log.error( self.name + ": Error in getSwController: " +
1818 self.handle.before )
1819 return main.FALSE
1820 else:
1821 return response
admin2a9548d2014-06-17 14:08:07 -07001822 else:
1823 return main.FALSE
1824 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001825 main.log.error( self.name + ": EOF exception found" )
1826 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001827 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001828 except Exception:
1829 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001830 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001831
Charles Chan029be652015-08-24 01:46:10 +08001832 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001833 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001834 Description:
1835 Assign switches to the controllers ( for ovs use only )
1836 Required:
1837 sw - Name of the switch. This can be a list or a string.
1838 ip - Ip addresses of controllers. This can be a list or a string.
1839 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001840 port - ONOS use port 6653, if no list of ports is passed, then
1841 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001842 ptcp - ptcp number, This can be a string or a list that has
1843 the same length as switch. This is optional and not required
1844 when using ovs switches.
1845 NOTE: If switches and ptcp are given in a list type they should have the
1846 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1847 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001848
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001849 Return:
1850 Returns main.TRUE if mininet correctly assigned switches to
1851 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001852 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001853 """
1854 assignResult = main.TRUE
1855 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001856 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001857 command = "sh ovs-vsctl set-controller "
1858 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001859 try:
1860 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001861 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001862 if isinstance( port, types.StringType ) or \
1863 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001864 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001865 elif isinstance( port, types.ListType ):
1866 main.log.error( self.name + ": Only one controller " +
1867 "assigned and a list of ports has" +
1868 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001869 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001870 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001871 main.log.error( self.name + ": Invalid controller port " +
1872 "number. Please specify correct " +
1873 "controller port" )
1874 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001875
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001876 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001877 if isinstance( port, types.StringType ) or \
1878 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001879 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001880 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1881 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001882 elif isinstance( port, types.ListType ):
1883 if ( len( ip ) != len( port ) ):
1884 main.log.error( self.name + ": Port list = " +
1885 str( len( port ) ) +
1886 "should be the same as controller" +
1887 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001888 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001889 else:
1890 onosIp = ""
1891 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001892 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1893 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001894 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001895 main.log.error( self.name + ": Invalid controller port " +
1896 "number. Please specify correct " +
1897 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001898 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001899 else:
1900 main.log.error( self.name + ": Invalid ip address" )
1901 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001902
1903 if isinstance( sw, types.StringType ):
1904 command += sw + " "
1905 if ptcp:
1906 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001907 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001908 elif isinstance( ptcp, types.ListType ):
1909 main.log.error( self.name + ": Only one switch is " +
1910 "being set and multiple PTCP is " +
1911 "being passed " )
1912 else:
1913 main.log.error( self.name + ": Invalid PTCP" )
1914 ptcp = ""
1915 command += onosIp
1916 commandList.append( command )
1917
1918 elif isinstance( sw, types.ListType ):
1919 if ptcp:
1920 if isinstance( ptcp, types.ListType ):
1921 if len( ptcp ) != len( sw ):
1922 main.log.error( self.name + ": PTCP length = " +
1923 str( len( ptcp ) ) +
1924 " is not the same as switch" +
1925 " length = " +
1926 str( len( sw ) ) )
1927 return main.FALSE
1928 else:
1929 for switch, ptcpNum in zip( sw, ptcp ):
1930 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001931 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001932 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001933 tempCmd += onosIp
1934 commandList.append( tempCmd )
1935 else:
1936 main.log.error( self.name + ": Invalid PTCP" )
1937 return main.FALSE
1938 else:
1939 for switch in sw:
1940 tempCmd = "sh ovs-vsctl set-controller "
1941 tempCmd += switch + " " + onosIp
1942 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001943 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001944 main.log.error( self.name + ": Invalid switch type " )
1945 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001946
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001947 for cmd in commandList:
1948 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001949 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
Jon Hallab611372018-02-21 15:26:05 -08001950 if "no bridge named" in self.handle.before:
1951 main.log.error( self.name + ": Error in assignSwController: " +
1952 self.handle.before )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001953 except pexpect.TIMEOUT:
1954 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1955 return main.FALSE
1956 except pexpect.EOF:
1957 main.log.error( self.name + ": EOF exception found" )
1958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001959 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001960 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001961 except pexpect.EOF:
1962 main.log.error( self.name + ": EOF exception found" )
1963 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001964 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001965 except Exception:
1966 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001967 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001968
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001970 """
1971 Removes the controller target from sw"""
1972 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001973 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001974 response = self.execute(
1975 cmd=command,
1976 prompt="mininet>",
1977 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001978 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001979 main.log.error( self.name + ": EOF exception found" )
1980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001981 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001982 except Exception:
1983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001984 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001985 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001986 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001987
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001989 """
Jon Hallb1290e82014-11-18 16:17:48 -05001990 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001991 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001992 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001993 NOTE: cannot currently specify what type of switch
1994 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001995 sw = name of the new switch as a string
1996 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001997 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001998 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001999 """
2000 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002001 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05002002 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002003 response = self.execute(
2004 cmd=command,
2005 prompt="mininet>",
2006 timeout=10 )
2007 if re.search( "already exists!", response ):
2008 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002009 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002010 elif re.search( "Error", response ):
2011 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002012 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002013 elif re.search( "usage:", response ):
2014 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002015 return main.FALSE
2016 else:
2017 return main.TRUE
2018 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002019 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07002020 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002021 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002022 except Exception:
2023 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002024 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002025
kelvin-onlabd3b64892015-01-20 13:26:24 -08002026 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002027 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002028 delete a switch from the mininet topology
2029 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002030 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002031 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002032 sw = name of the switch as a string
2033 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002034 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002035 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002036 response = self.execute(
2037 cmd=command,
2038 prompt="mininet>",
2039 timeout=10 )
2040 if re.search( "no switch named", response ):
2041 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002042 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002043 elif re.search( "Error", response ):
2044 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002045 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002046 elif re.search( "usage:", response ):
2047 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002048 return main.FALSE
2049 else:
2050 return main.TRUE
2051 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002052 main.log.error( self.name + ": EOF exception found" )
2053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002055 except Exception:
2056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002058
You Wangdb8cd0a2016-05-26 15:19:45 -07002059 def getSwitchRandom( self, timeout=60, nonCut=True ):
2060 """
2061 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002062 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002063 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002064 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002065 it just randomly returns one switch from all current switches in
2066 Mininet.
2067 Returns the name of the chosen switch.
2068 """
2069 import random
2070 candidateSwitches = []
2071 try:
2072 if not nonCut:
2073 switches = self.getSwitches( timeout=timeout )
2074 assert len( switches ) != 0
2075 for switchName in switches.keys():
2076 candidateSwitches.append( switchName )
2077 else:
2078 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002079 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002080 return None
2081 self.graph.update( graphDict )
2082 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002083 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002084 return None
2085 elif len( candidateSwitches ) == 0:
2086 main.log.info( self.name + ": No candidate switch for deletion" )
2087 return None
2088 else:
2089 switch = random.sample( candidateSwitches, 1 )
2090 return switch[ 0 ]
2091 except KeyError:
2092 main.log.exception( self.name + ": KeyError exception found" )
2093 return None
2094 except AssertionError:
2095 main.log.exception( self.name + ": AssertionError exception found" )
2096 return None
2097 except Exception:
2098 main.log.exception( self.name + ": Uncaught exception" )
2099 return None
2100
2101 def delSwitchRandom( self, timeout=60, nonCut=True ):
2102 """
2103 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002104 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002105 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002106 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002107 otherwise it just randomly delete one switch from all current
2108 switches in Mininet.
2109 Returns the name of the deleted switch
2110 """
2111 try:
2112 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002113 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002114 return None
2115 else:
2116 deletionResult = self.delSwitch( switch )
2117 if deletionResult:
2118 return switch
2119 else:
2120 return None
2121 except Exception:
2122 main.log.exception( self.name + ": Uncaught exception" )
2123 return None
2124
kelvin-onlabd3b64892015-01-20 13:26:24 -08002125 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002126 """
2127 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002128 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002129 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002130 NOTE: cannot currently specify what type of link
2131 required params:
2132 node1 = the string node name of the first endpoint of the link
2133 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002134 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002135 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002136 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002137 response = self.execute(
2138 cmd=command,
2139 prompt="mininet>",
2140 timeout=10 )
2141 if re.search( "doesnt exist!", response ):
2142 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002143 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002144 elif re.search( "Error", response ):
2145 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002146 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002147 elif re.search( "usage:", response ):
2148 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002149 return main.FALSE
2150 else:
2151 return main.TRUE
2152 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002153 main.log.error( self.name + ": EOF exception found" )
2154 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002155 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002156 except Exception:
2157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002158 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002159
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002161 """
2162 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002163 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002164 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002165 required params:
2166 node1 = the string node name of the first endpoint of the link
2167 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002168 returns: main.FALSE on an error, else main.TRUE
2169 """
Jon Hallffb386d2014-11-21 13:43:38 -08002170 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002171 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002172 response = self.execute(
2173 cmd=command,
2174 prompt="mininet>",
2175 timeout=10 )
2176 if re.search( "no node named", response ):
2177 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002178 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002179 elif re.search( "Error", response ):
2180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002181 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002182 elif re.search( "usage:", response ):
2183 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002184 return main.FALSE
2185 else:
2186 return main.TRUE
2187 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002190 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002193 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002194
You Wangdb8cd0a2016-05-26 15:19:45 -07002195 def getLinkRandom( self, timeout=60, nonCut=True ):
2196 """
2197 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002198 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002199 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002200 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002201 it just randomly returns one link from all current links in
2202 Mininet.
2203 Returns the link as a list, e.g. [ 's1', 's2' ]
2204 """
2205 import random
2206 candidateLinks = []
2207 try:
2208 if not nonCut:
2209 links = self.getLinks( timeout=timeout )
2210 assert len( links ) != 0
2211 for link in links:
2212 # Exclude host-switch link
2213 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2214 continue
2215 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2216 else:
2217 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002218 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002219 return None
2220 self.graph.update( graphDict )
2221 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002222 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002223 return None
2224 elif len( candidateLinks ) == 0:
2225 main.log.info( self.name + ": No candidate link for deletion" )
2226 return None
2227 else:
2228 link = random.sample( candidateLinks, 1 )
2229 return link[ 0 ]
2230 except KeyError:
2231 main.log.exception( self.name + ": KeyError exception found" )
2232 return None
2233 except AssertionError:
2234 main.log.exception( self.name + ": AssertionError exception found" )
2235 return None
2236 except Exception:
2237 main.log.exception( self.name + ": Uncaught exception" )
2238 return None
2239
2240 def delLinkRandom( self, timeout=60, nonCut=True ):
2241 """
2242 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002243 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002244 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002245 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002246 otherwise it just randomly delete one link from all current links
2247 in Mininet.
2248 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2249 """
2250 try:
2251 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002252 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002253 return None
2254 else:
2255 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2256 if deletionResult:
2257 return link
2258 else:
2259 return None
2260 except Exception:
2261 main.log.exception( self.name + ": Uncaught exception" )
2262 return None
2263
kelvin-onlabd3b64892015-01-20 13:26:24 -08002264 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002265 """
Jon Hallb1290e82014-11-18 16:17:48 -05002266 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002267 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002268 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002269 NOTE: cannot currently specify what type of host
2270 required params:
2271 hostname = the string hostname
2272 optional key-value params
2273 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002274 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002275 """
2276 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002277 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002278 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002279 response = self.execute(
2280 cmd=command,
2281 prompt="mininet>",
2282 timeout=10 )
2283 if re.search( "already exists!", response ):
2284 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002285 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002286 elif re.search( "doesnt exists!", response ):
2287 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002288 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002289 elif re.search( "Error", response ):
2290 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002291 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002292 elif re.search( "usage:", response ):
2293 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002294 return main.FALSE
2295 else:
2296 return main.TRUE
2297 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002298 main.log.error( self.name + ": EOF exception found" )
2299 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002300 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002301 except Exception:
2302 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002303 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002304
kelvin-onlabd3b64892015-01-20 13:26:24 -08002305 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002306 """
2307 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002308 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002309 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002310 NOTE: this uses a custom mn function
2311 required params:
2312 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002313 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002314 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002315 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002316 response = self.execute(
2317 cmd=command,
2318 prompt="mininet>",
2319 timeout=10 )
2320 if re.search( "no host named", response ):
2321 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002322 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002323 elif re.search( "Error", response ):
2324 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002325 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002326 elif re.search( "usage:", response ):
2327 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002328 return main.FALSE
2329 else:
2330 return main.TRUE
2331 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002332 main.log.error( self.name + ": EOF exception found" )
2333 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002334 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002335 except Exception:
2336 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002337 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002338
Jon Hall7eb38402015-01-08 17:19:54 -08002339 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002340 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002341 Called at the end of the test to stop the mininet and
2342 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002343 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002344 try:
2345 self.handle.sendline( '' )
2346 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2347 timeout=2 )
2348 response = main.TRUE
2349 if i == 0:
2350 response = self.stopNet()
2351 elif i == 1:
2352 return main.TRUE
2353 # print "Disconnecting Mininet"
2354 if self.handle:
2355 self.handle.sendline( "exit" )
2356 self.handle.expect( "exit" )
2357 self.handle.expect( "(.*)" )
2358 else:
2359 main.log.error( "Connection failed to the host" )
2360 return response
2361 except pexpect.EOF:
2362 main.log.error( self.name + ": EOF exception found" )
2363 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002364 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002365 except Exception:
2366 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002367 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002368
Devin Lima7cfdbd2017-09-29 15:02:22 -07002369 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002370 """
Jon Hall21270ac2015-02-16 17:59:55 -08002371 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002372 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002373 main.FALSE if the pexpect handle does not exist.
2374
Jon Halld61331b2015-02-17 16:35:47 -08002375 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002376 """
Jon Halld61331b2015-02-17 16:35:47 -08002377 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002378 response = ''
2379 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002380 try:
Jon Halld80cc142015-07-06 13:36:05 -07002381 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002382 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002383 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002384 pexpect.EOF,
2385 pexpect.TIMEOUT ],
2386 timeout )
2387 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002388 main.log.info( "Exiting mininet.." )
2389 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002390 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002391 prompt=self.prompt,
2392 timeout=exitTimeout )
2393 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002394 self.handle.sendline( "sudo mn -c" )
2395 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002396
Jeremyd9e4eb12016-04-13 12:09:06 -07002397 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002398 main.log.info( " Mininet trying to exit while not " +
2399 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002400 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002401 elif i == 2:
2402 main.log.error( "Something went wrong exiting mininet" )
2403 elif i == 3: # timeout
2404 main.log.error( "Something went wrong exiting mininet " +
2405 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002406
You Wang18db8592018-04-02 13:52:03 -07002407 self.handle.sendline( "" )
2408 self.handle.expect( self.prompt )
2409 self.handle.sendline( "sudo killall -9 dhclient dhcpd zebra bgpd" )
2410
Hari Krishnab35c6d02015-03-18 11:13:51 -07002411 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002412 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002413 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002414 self.handle.sendline(
2415 "sudo kill -9 \`ps -ef | grep \"" +
2416 fileName +
2417 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002418 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002419 main.log.error( self.name + ": TIMEOUT exception found" )
2420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002421 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002422 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002423 main.log.error( self.name + ": EOF exception found" )
2424 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002425 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002426 except Exception:
2427 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002428 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002429 else:
2430 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002431 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002432 return response
2433
YPZhang26a139e2016-04-25 14:01:55 -07002434 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002435 """
2436 Description:
2437 Sends arp message from mininet host for hosts discovery
2438 Required:
2439 host - hosts name
2440 Optional:
2441 ip - ip address that does not exist in the network so there would
2442 be no reply.
2443 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002444 if ethDevice:
2445 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002446 cmd = srcHost + " arping -c1 "
2447 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002448 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
YPZhang26a139e2016-04-25 14:01:55 -07002449 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002450 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002451 if output:
2452 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002453 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002454 i = self.handle.expect( [ "mininet>", "arping: " ] )
2455 if i == 0:
2456 return main.TRUE
2457 elif i == 1:
2458 response = self.handle.before + self.handle.after
2459 self.handle.expect( "mininet>" )
2460 response += self.handle.before + self.handle.after
2461 main.log.warn( "Error sending arping, output was: " +
2462 response )
2463 return main.FALSE
2464 except pexpect.TIMEOUT:
2465 main.log.error( self.name + ": TIMEOUT exception found" )
2466 main.log.warn( self.handle.before )
2467 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002468 except pexpect.EOF:
2469 main.log.error( self.name + ": EOF exception found" )
2470 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002471 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002472 except Exception:
2473 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002474 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002475
Jon Hall7eb38402015-01-08 17:19:54 -08002476 def decToHex( self, num ):
2477 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002478
Jon Hall7eb38402015-01-08 17:19:54 -08002479 def getSwitchFlowCount( self, switch ):
2480 """
2481 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002482 if self.handle:
2483 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2484 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002485 response = self.execute(
2486 cmd=cmd,
2487 prompt="mininet>",
2488 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002489 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002490 main.log.error( self.name + ": EOF exception found" )
2491 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002492 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002493 except Exception:
2494 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002495 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002496 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002497 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002498 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002499 main.log.info(
2500 "Couldn't find flows on switch %s, found: %s" %
2501 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002502 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002503 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002504 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002505 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002506
Jon Hall9ed8f372016-02-24 17:34:07 -08002507 def checkFlows( self, sw, dumpFormat=None ):
2508 if dumpFormat:
2509 command = "sh ovs-ofctl -F " + \
2510 dumpFormat + " dump-flows " + str( sw )
2511 else:
2512 command = "sh ovs-ofctl dump-flows " + str( sw )
2513 try:
2514 response = self.execute(
2515 cmd=command,
2516 prompt="mininet>",
2517 timeout=10 )
2518 return response
2519 except pexpect.EOF:
2520 main.log.error( self.name + ": EOF exception found" )
2521 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002522 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002523 except Exception:
2524 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002525 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002526
GlennRC68467eb2015-11-16 18:01:01 -08002527 def flowTableComp( self, flowTable1, flowTable2 ):
2528 # This function compares the selctors and treatments of each flow
2529 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002530 assert flowTable1, "flowTable1 is empty or None"
2531 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002532 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002533 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002534 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002535 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002536 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2537 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002538 for field in dFields:
2539 try:
2540 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002541 except KeyError:
2542 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002543 try:
2544 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002545 except KeyError:
2546 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002547 for i in range( len( flowTable1 ) ):
2548 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002549 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002550 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002551 returnValue = main.FALSE
2552 break
2553 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002554 except AssertionError:
2555 main.log.exception( "Nothing to compare" )
2556 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002557 except Exception:
2558 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002559 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002560
GlennRC528ad292015-11-12 10:38:18 -08002561 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002562 '''
GlennRC956ea742015-11-05 16:14:15 -08002563 Discription: Parses flows into json format.
2564 NOTE: this can parse any string thats separated with commas
2565 Arguments:
2566 Required:
2567 flows: a list of strings that represnt flows
2568 Optional:
2569 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2570 debug: prints out the final result
2571 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002572 '''
GlennRC528ad292015-11-12 10:38:18 -08002573 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002574 try:
2575 for flow in flowTable:
2576 jsonFlow = {}
2577 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002578 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002579 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002580 for i in range( len( parsedFlow ) ):
2581 item = parsedFlow[ i ]
2582 if item[ 0 ] == " ":
2583 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002584 # grab the selector and treatment from the parsed flow
2585 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002586 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002587 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002588 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002589 index = 0
2590 # parse the flags
2591 # NOTE: This only parses one flag
2592 flag = {}
2593 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002594 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002595 index += 1
2596 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002597 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002598 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002599 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002600 # the priority is stuck in the selecter so put it back
2601 # in the flow
Jon Hallab611372018-02-21 15:26:05 -08002602 if 'priority' in sel[0]:
2603 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002604 # parse selector
2605 criteria = []
2606 for item in sel:
2607 # this is the type of the packet e.g. "arp"
2608 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002609 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002610 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002611 field = item.split( "=" )
2612 criteria.append( { field[ 0 ]: field[ 1 ] } )
2613 selector = { "selector": { "criteria": sorted( criteria ) } }
2614 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002615 # get rid of the action part e.g. "action=output:2"
2616 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002617 treat = treat.split( "=" )
2618 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002619 # parse treatment
2620 action = []
2621 for item in treat:
Jon Hallab611372018-02-21 15:26:05 -08002622 if ":" in item:
2623 field = item.split( ":" )
2624 action.append( { field[ 0 ]: field[ 1 ] } )
2625 else:
2626 main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
2627 item ) )
You Wang91c37cf2016-05-23 09:39:42 -07002628 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002629 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002630 # parse the rest of the flow
2631 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002632 field = item.split( "=" )
2633 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002634 # add the treatment and the selector to the json flow
2635 jsonFlow.update( selector )
2636 jsonFlow.update( treatment )
2637 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002638
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002639 if debug:
2640 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002641
You Wang91c37cf2016-05-23 09:39:42 -07002642 # add the json flow to the json flow table
2643 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002644
You Wang91c37cf2016-05-23 09:39:42 -07002645 return jsonFlowTable
2646
2647 except IndexError:
2648 main.log.exception( self.name + ": IndexError found" )
2649 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002650 except pexpect.EOF:
2651 main.log.error( self.name + ": EOF exception found" )
2652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002653 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002654 except Exception:
2655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002656 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002657
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002658 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002659 '''
2660 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002661 Each element is a flow.
2662 Arguments:
2663 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002664 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002665 a list of switches.
2666 Optional:
2667 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2668 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002669 '''
GlennRC956ea742015-11-05 16:14:15 -08002670 try:
2671 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002672 if isinstance( sw, list ):
2673 switches.extend( sw )
2674 else:
2675 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002676
2677 flows = []
2678 for s in switches:
2679 cmd = "sh ovs-ofctl dump-flows " + s
2680
GlennRC528ad292015-11-12 10:38:18 -08002681 if "1.0" == version:
2682 cmd += " -F OpenFlow10-table_id"
2683 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002684 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002685
2686 main.log.info( "Sending: " + cmd )
2687 self.handle.sendline( cmd )
2688 self.handle.expect( "mininet>" )
2689 response = self.handle.before
2690 response = response.split( "\r\n" )
2691 # dump the first two elements and the last
2692 # the first element is the command that was sent
2693 # the second is the table header
2694 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002695 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002696 flows.extend( response )
2697
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002698 if debug:
2699 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002700
GlennRC528ad292015-11-12 10:38:18 -08002701 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002702
GlennRC956ea742015-11-05 16:14:15 -08002703 except pexpect.EOF:
2704 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002705 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002706 except Exception:
2707 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002708 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002709
2710 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002711 '''
GlennRC956ea742015-11-05 16:14:15 -08002712 Discription: Checks whether the ID provided matches a flow ID in Mininet
2713 Arguments:
2714 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002715 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002716 a list of switches.
2717 flowId: the flow ID in hex format. Can also be a list of IDs
2718 Optional:
2719 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2720 debug: prints out the final result
2721 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2722 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002723 '''
GlennRC956ea742015-11-05 16:14:15 -08002724 try:
2725 main.log.info( "Getting flows from Mininet" )
2726 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002727 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002728 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002729
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 if debug:
2731 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002732
2733 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002734 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002735 result = False
2736 for f in flows:
2737 if flowId in f.get( 'cookie' ):
2738 result = True
2739 break
2740 # flowId is a list
2741 else:
2742 result = True
2743 # Get flow IDs from Mininet
2744 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2745 # Save the IDs that are not in Mininet
2746 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2747
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002748 if debug:
2749 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002750
2751 # Print out the IDs that are not in Mininet
2752 if absentIds:
2753 main.log.warn( "Absent ids: {}".format( absentIds ) )
2754 result = False
2755
2756 return main.TRUE if result else main.FALSE
2757
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002758 except pexpect.EOF:
2759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002761 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002762 except Exception:
2763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002764 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002765
Charles Chan029be652015-08-24 01:46:10 +08002766 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002767 """
Jon Hallefbd9792015-03-05 16:11:36 -08002768 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002769 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002770 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002771 self.handle.sendline( "" )
2772 self.handle.expect( "mininet>" )
2773 self.handle.sendline(
2774 "sh sudo tcpdump -n -i " +
2775 intf +
2776 " " +
2777 port +
2778 " -w " +
2779 filename.strip() +
2780 " &" )
2781 self.handle.sendline( "" )
2782 i = self.handle.expect( [ 'No\ssuch\device',
2783 'listening\son',
2784 pexpect.TIMEOUT,
2785 "mininet>" ],
2786 timeout=10 )
2787 main.log.warn( self.handle.before + self.handle.after )
2788 self.handle.sendline( "" )
2789 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002790 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002791 main.log.error(
2792 self.name +
2793 ": tcpdump - No such device exists. " +
2794 "tcpdump attempted on: " +
2795 intf )
admin2a9548d2014-06-17 14:08:07 -07002796 return main.FALSE
2797 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002798 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002799 return main.TRUE
2800 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002801 main.log.error(
2802 self.name +
2803 ": tcpdump command timed out! Check interface name," +
2804 " given interface was: " +
2805 intf )
admin2a9548d2014-06-17 14:08:07 -07002806 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002807 elif i == 3:
2808 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002809 return main.TRUE
2810 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002811 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002812 return main.FALSE
2813 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002814 main.log.error( self.name + ": EOF exception found" )
2815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002816 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002817 except Exception:
2818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002819 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002820
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002822 """
2823 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002824 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002825 self.handle.sendline( "sh sudo pkill tcpdump" )
2826 self.handle.expect( "mininet>" )
2827 self.handle.sendline( "" )
2828 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002829 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002830 main.log.error( self.name + ": TIMEOUT exception found" )
2831 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002832 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002833 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002834 main.log.error( self.name + ": EOF exception found" )
2835 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002836 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002837 except Exception:
2838 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002839 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002840
Jon Halld80cc142015-07-06 13:36:05 -07002841 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002842 """
2843 Read ports from a Mininet switch.
2844
2845 Returns a json structure containing information about the
2846 ports of the given switch.
2847 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002848 try:
2849 response = self.getInterfaces( nodeName )
2850 # TODO: Sanity check on response. log if no such switch exists
2851 ports = []
2852 for line in response.split( "\n" ):
2853 if not line.startswith( "name=" ):
2854 continue
2855 portVars = {}
2856 for var in line.split( "," ):
2857 key, value = var.split( "=" )
2858 portVars[ key ] = value
2859 isUp = portVars.pop( 'enabled', "True" )
2860 isUp = "True" in isUp
2861 if verbose:
2862 main.log.info( "Reading switch port %s(%s)" %
2863 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2864 mac = portVars[ 'mac' ]
2865 if mac == 'None':
2866 mac = None
2867 ips = []
2868 ip = portVars[ 'ip' ]
2869 if ip == 'None':
2870 ip = None
2871 ips.append( ip )
2872 name = portVars[ 'name' ]
2873 if name == 'None':
2874 name = None
2875 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2876 if name == 'lo':
2877 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2878 else:
2879 portNo = re.search( portRe, name ).group( 'port' )
2880 ports.append( { 'of_port': portNo,
2881 'mac': str( mac ).replace( '\'', '' ),
2882 'name': name,
2883 'ips': ips,
2884 'enabled': isUp } )
2885 return ports
2886 except pexpect.EOF:
2887 main.log.error( self.name + ": EOF exception found" )
2888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002889 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002890 except Exception:
2891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002892 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002893
You Wangdb8cd0a2016-05-26 15:19:45 -07002894 def getOVSPorts( self, nodeName ):
2895 """
2896 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2897
2898 Returns a list of dictionaries containing information about each
2899 port of the given switch.
2900 """
2901 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2902 try:
2903 response = self.execute(
2904 cmd=command,
2905 prompt="mininet>",
2906 timeout=10 )
2907 ports = []
2908 if response:
2909 for line in response.split( "\n" ):
2910 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2911 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002912 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002913 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2914 result = re.search( pattern, line )
2915 if result:
2916 index = result.group( 'index' )
2917 name = result.group( 'name' )
2918 # This port number is extracted from port name
2919 port = result.group( 'port' )
2920 mac = result.group( 'mac' )
2921 ports.append( { 'index': index,
2922 'name': name,
2923 'port': port,
2924 'mac': mac } )
2925 return ports
2926 except pexpect.EOF:
2927 main.log.error( self.name + ": EOF exception found" )
2928 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002929 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002930 except Exception:
2931 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002932 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002933
Devin Lima7cfdbd2017-09-29 15:02:22 -07002934 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002935 """
2936 Read switches from Mininet.
2937
2938 Returns a dictionary whose keys are the switch names and the value is
2939 a dictionary containing information about the switch.
2940 """
Jon Halla22481b2015-07-28 17:46:01 -07002941 # NOTE: To support new Mininet switch classes, just append the new
2942 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002943
Jon Halla22481b2015-07-28 17:46:01 -07002944 # Regex patterns to parse 'dump' output
2945 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002946 # <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=5238>
Jon Halld80cc142015-07-06 13:36:05 -07002947 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002948 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2949 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2950 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002951 try:
2952 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2953 swRE = r"<(?P<class>" + switchClasses + r")" +\
2954 r"(?P<options>\{.*\})?\s" +\
2955 r"(?P<name>[^:]+)\:\s" +\
2956 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2957 r"\spid=(?P<pid>(\d)+)"
2958 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002959 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002960 output = {}
2961 dump = self.dump().split( "\n" )
2962 for line in dump:
2963 result = re.search( swRE, line, re.I )
2964 if result:
2965 name = result.group( 'name' )
2966 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2967 pid = result.group( 'pid' )
2968 swClass = result.group( 'class' )
2969 options = result.group( 'options' )
2970 if verbose:
2971 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2972 ports = self.getPorts( name )
2973 output[ name ] = { "dpid": dpid,
2974 "ports": ports,
2975 "swClass": swClass,
2976 "pid": pid,
2977 "options": options }
2978 return output
2979 except pexpect.EOF:
2980 main.log.error( self.name + ": EOF exception found" )
2981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002982 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002983 except Exception:
2984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002985 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002986
Jon Hallab611372018-02-21 15:26:05 -08002987 def getHosts( self, verbose=False, updateTimeout=1000,
2988 hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
2989 getInterfaces=True ):
Jon Hallafa8a472015-06-12 14:02:42 -07002990 """
2991 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08002992 Optional:
2993 hostClass: it is used to match the class of the mininet host. It
2994 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07002995 Returns a dictionary whose keys are the host names and the value is
2996 a dictionary containing information about the host.
2997 """
2998 # Regex patterns to parse dump output
2999 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07003000 # <Host h1: pid=12725>
3001 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3002 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3003 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003004 # NOTE: Does not correctly match hosts with multi-links
3005 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3006 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003007 try:
You Wang53dba1e2018-02-02 17:45:44 -08003008 if not isinstance( hostClass, types.ListType ):
3009 hostClass = [ str( hostClass ) ]
3010 classRE = "(" + "|".join([c for c in hostClass]) + ")"
Jon Hallab611372018-02-21 15:26:05 -08003011 ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
3012 ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
3013 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003014 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07003015 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003016 # Get mininet dump
3017 dump = self.dump().split( "\n" )
3018 hosts = {}
3019 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08003020 result = re.search( hostRE, line )
3021 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003022 name = result.group( 'name' )
3023 interfaces = []
You Wang79f5c5b2018-03-14 11:10:44 -07003024 if getInterfaces:
3025 response = self.getInterfaces( name )
3026 # Populate interface info
3027 for line in response.split( "\n" ):
3028 if line.startswith( "name=" ):
3029 portVars = {}
3030 for var in line.split( "," ):
3031 key, value = var.split( "=" )
3032 portVars[ key ] = value
3033 isUp = portVars.pop( 'enabled', "True" )
3034 isUp = "True" in isUp
3035 if verbose:
3036 main.log.info( "Reading host port %s(%s)" %
3037 ( portVars[ 'name' ],
3038 portVars[ 'mac' ] ) )
3039 mac = portVars[ 'mac' ]
3040 if mac == 'None':
3041 mac = None
3042 ips = []
3043 ip = portVars[ 'ip' ]
3044 if ip == 'None':
3045 ip = None
3046 ips.append( ip )
3047 intfName = portVars[ 'name' ]
3048 if name == 'None':
3049 name = None
3050 interfaces.append( {
3051 "name": intfName,
3052 "ips": ips,
3053 "mac": str( mac ),
3054 "isUp": isUp } )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003055 hosts[ name ] = { "interfaces": interfaces }
3056 return hosts
3057 except pexpect.EOF:
3058 main.log.error( self.name + ": EOF exception found" )
3059 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003060 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003061 except Exception:
3062 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003063 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003064
Devin Lima7cfdbd2017-09-29 15:02:22 -07003065 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003066 """
3067 Gathers information about current Mininet links. These links may not
3068 be up if one of the ports is down.
3069
3070 Returns a list of dictionaries with link endpoints.
3071
3072 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003073 { 'node1': str( node1 name )
3074 'node2': str( node2 name )
3075 'port1': str( port1 of_port )
3076 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003077 Note: The port number returned is the eth#, not necessarily the of_port
3078 number. In Mininet, for OVS switch, these should be the same. For
3079 hosts, this is just the eth#.
3080 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003081 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003082 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003083 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003084
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003085 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003086 # s1-eth3<->s2-eth1 (OK OK)
3087 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003088 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3089 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3090 links = []
3091 for line in response:
3092 match = re.search( linkRE, line )
3093 if match:
3094 node1 = match.group( 'node1' )
3095 node2 = match.group( 'node2' )
3096 port1 = match.group( 'port1' )
3097 port2 = match.group( 'port2' )
3098 links.append( { 'node1': node1,
3099 'node2': node2,
3100 'port1': port1,
3101 'port2': port2 } )
3102 return links
3103
3104 except pexpect.EOF:
3105 main.log.error( self.name + ": EOF exception found" )
3106 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003107 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003108 except Exception:
3109 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003110 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003111
3112 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003113 """
3114 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003115 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003116
Jon Hallafa8a472015-06-12 14:02:42 -07003117 Dependencies:
3118 1. numpy - "sudo pip install numpy"
3119 """
3120 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003121 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003122 try:
3123 mnDPIDs = []
3124 for swName, switch in switches.iteritems():
3125 mnDPIDs.append( switch[ 'dpid' ].lower() )
3126 mnDPIDs.sort()
3127 if switchesJson == "": # if rest call fails
3128 main.log.error(
3129 self.name +
3130 ".compareSwitches(): Empty JSON object given from ONOS" )
3131 return main.FALSE
3132 onos = switchesJson
3133 onosDPIDs = []
3134 for switch in onos:
3135 if switch[ 'available' ]:
3136 onosDPIDs.append(
3137 switch[ 'id' ].replace(
3138 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003139 '' ).replace(
3140 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003141 '' ).lower() )
3142 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003143
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003144 if mnDPIDs != onosDPIDs:
3145 switchResults = main.FALSE
3146 main.log.error( "Switches in MN but not in ONOS:" )
3147 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3148 main.log.error( str( list1 ) )
3149 main.log.error( "Switches in ONOS but not in MN:" )
3150 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3151 main.log.error( str( list2 ) )
3152 else: # list of dpid's match in onos and mn
3153 switchResults = main.TRUE
3154 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003155
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003156 # FIXME: this does not look for extra ports in ONOS, only checks that
3157 # ONOS has what is in MN
3158 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003159
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003160 # PORTS
3161 for name, mnSwitch in switches.iteritems():
3162 mnPorts = []
3163 onosPorts = []
3164 switchResult = main.TRUE
3165 for port in mnSwitch[ 'ports' ]:
3166 if port[ 'enabled' ]:
3167 mnPorts.append( int( port[ 'of_port' ] ) )
3168 for onosSwitch in portsJson:
3169 if onosSwitch[ 'device' ][ 'available' ]:
3170 if onosSwitch[ 'device' ][ 'id' ].replace(
3171 ':',
3172 '' ).replace(
3173 "of",
3174 '' ) == mnSwitch[ 'dpid' ]:
3175 for port in onosSwitch[ 'ports' ]:
3176 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003177 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003178 # onosPorts.append( 'local' )
3179 onosPorts.append( long( uint64( -2 ) ) )
3180 else:
3181 onosPorts.append( int( port[ 'port' ] ) )
3182 break
3183 mnPorts.sort( key=float )
3184 onosPorts.sort( key=float )
3185
3186 mnPortsLog = mnPorts
3187 onosPortsLog = onosPorts
3188 mnPorts = [ x for x in mnPorts ]
3189 onosPorts = [ x for x in onosPorts ]
3190
3191 # TODO: handle other reserved port numbers besides LOCAL
3192 # NOTE: Reserved ports
3193 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3194 # long( uint64( -2 ) )
3195 for mnPort in mnPortsLog:
3196 if mnPort in onosPorts:
3197 # don't set results to true here as this is just one of
3198 # many checks and it might override a failure
3199 mnPorts.remove( mnPort )
3200 onosPorts.remove( mnPort )
3201
3202 # NOTE: OVS reports this as down since there is no link
3203 # So ignoring these for now
3204 # TODO: Come up with a better way of handling these
3205 if 65534 in mnPorts:
3206 mnPorts.remove( 65534 )
3207 if long( uint64( -2 ) ) in onosPorts:
3208 onosPorts.remove( long( uint64( -2 ) ) )
3209 if len( mnPorts ): # the ports of this switch don't match
3210 switchResult = main.FALSE
3211 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3212 if len( onosPorts ): # the ports of this switch don't match
3213 switchResult = main.FALSE
3214 main.log.warn(
3215 "Ports in ONOS but not MN: " +
3216 str( onosPorts ) )
3217 if switchResult == main.FALSE:
3218 main.log.error(
3219 "The list of ports for switch %s(%s) does not match:" %
3220 ( name, mnSwitch[ 'dpid' ] ) )
3221 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3222 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3223 portsResults = portsResults and switchResult
3224 finalResults = finalResults and portsResults
3225 return finalResults
3226 except pexpect.EOF:
3227 main.log.error( self.name + ": EOF exception found" )
3228 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003229 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003230 except Exception:
3231 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003232 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003233
Jon Hallafa8a472015-06-12 14:02:42 -07003234 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003235 """
3236 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003237 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003238
Jon Hallafa8a472015-06-12 14:02:42 -07003239 """
Jon Hall7eb38402015-01-08 17:19:54 -08003240 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003241 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003242 try:
3243 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003244
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003245 mnLinks = []
3246 for l in links:
3247 try:
3248 node1 = switches[ l[ 'node1' ] ]
3249 node2 = switches[ l[ 'node2' ] ]
3250 enabled = True
3251 for port in node1[ 'ports' ]:
3252 if port[ 'of_port' ] == l[ 'port1' ]:
3253 enabled = enabled and port[ 'enabled' ]
3254 for port in node2[ 'ports' ]:
3255 if port[ 'of_port' ] == l[ 'port2' ]:
3256 enabled = enabled and port[ 'enabled' ]
3257 if enabled:
3258 mnLinks.append( l )
3259 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003260 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003261 if 2 * len( mnLinks ) == len( onos ):
3262 linkResults = main.TRUE
3263 else:
3264 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003265 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003266 "Mininet has " + str( len( mnLinks ) ) +
3267 " bidirectional links and ONOS has " +
3268 str( len( onos ) ) + " unidirectional links" )
3269
3270 # iterate through MN links and check if an ONOS link exists in
3271 # both directions
3272 for link in mnLinks:
3273 # TODO: Find a more efficient search method
3274 node1 = None
3275 port1 = None
3276 node2 = None
3277 port2 = None
3278 firstDir = main.FALSE
3279 secondDir = main.FALSE
3280 for swName, switch in switches.iteritems():
3281 if swName == link[ 'node1' ]:
3282 node1 = switch[ 'dpid' ]
3283 for port in switch[ 'ports' ]:
3284 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3285 port1 = port[ 'of_port' ]
3286 if node1 is not None and node2 is not None:
3287 break
3288 if swName == link[ 'node2' ]:
3289 node2 = switch[ 'dpid' ]
3290 for port in switch[ 'ports' ]:
3291 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3292 port2 = port[ 'of_port' ]
3293 if node1 is not None and node2 is not None:
3294 break
3295
3296 for onosLink in onos:
3297 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3298 ":", '' ).replace( "of", '' )
3299 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3300 ":", '' ).replace( "of", '' )
3301 onosPort1 = onosLink[ 'src' ][ 'port' ]
3302 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3303
3304 # check onos link from node1 to node2
3305 if str( onosNode1 ) == str( node1 ) and str(
3306 onosNode2 ) == str( node2 ):
3307 if int( onosPort1 ) == int( port1 ) and int(
3308 onosPort2 ) == int( port2 ):
3309 firstDir = main.TRUE
3310 else:
Jon Hallab611372018-02-21 15:26:05 -08003311 # The right switches, but wrong ports, could be
3312 # another link between these devices, or onos
3313 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003314 main.log.warn(
3315 'The port numbers do not match for ' +
3316 str( link ) +
3317 ' between ONOS and MN. When checking ONOS for ' +
3318 'link %s/%s -> %s/%s' %
3319 ( node1, port1, node2, port2 ) +
3320 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003321 ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
3322 '. This could be another link between these devices' +
3323 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003324
3325 # check onos link from node2 to node1
3326 elif ( str( onosNode1 ) == str( node2 ) and
3327 str( onosNode2 ) == str( node1 ) ):
3328 if ( int( onosPort1 ) == int( port2 )
3329 and int( onosPort2 ) == int( port1 ) ):
3330 secondDir = main.TRUE
3331 else:
Jon Hallab611372018-02-21 15:26:05 -08003332 # The right switches, but wrong ports, could be
3333 # another link between these devices, or onos
3334 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003335 main.log.warn(
3336 'The port numbers do not match for ' +
3337 str( link ) +
3338 ' between ONOS and MN. When checking ONOS for ' +
3339 'link %s/%s -> %s/%s' %
3340 ( node1, port1, node2, port2 ) +
3341 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003342 ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
3343 '. This could be another link between these devices' +
3344 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003345 else: # this is not the link you're looking for
3346 pass
3347 if not firstDir:
3348 main.log.error(
3349 'ONOS does not have the link %s/%s -> %s/%s' %
3350 ( node1, port1, node2, port2 ) )
3351 if not secondDir:
3352 main.log.error(
3353 'ONOS does not have the link %s/%s -> %s/%s' %
3354 ( node2, port2, node1, port1 ) )
3355 linkResults = linkResults and firstDir and secondDir
3356 return linkResults
3357 except pexpect.EOF:
3358 main.log.error( self.name + ": EOF exception found" )
3359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003360 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003361 except Exception:
3362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003363 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003364
Jon Hallafa8a472015-06-12 14:02:42 -07003365 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003366 """
Jon Hallafa8a472015-06-12 14:02:42 -07003367 Compare mn and onos Hosts.
3368 Since Mininet hosts are quiet, ONOS will only know of them when they
3369 speak. For this reason, we will only check that the hosts in ONOS
3370 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003371
Jon Hallafa8a472015-06-12 14:02:42 -07003372 Arguments:
3373 hostsJson: parsed json object from the onos hosts api
3374 Returns:
3375 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003376 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003377 try:
3378 hostResults = main.TRUE
3379 for onosHost in hostsJson:
3380 onosMAC = onosHost[ 'mac' ].lower()
3381 match = False
3382 for mnHost, info in hosts.iteritems():
3383 for mnIntf in info[ 'interfaces' ]:
3384 if onosMAC == mnIntf[ 'mac' ].lower():
3385 match = True
3386 for ip in mnIntf[ 'ips' ]:
3387 if ip in onosHost[ 'ipAddresses' ]:
3388 pass # all is well
3389 else:
3390 # misssing ip
3391 main.log.error( "ONOS host " +
3392 onosHost[ 'id' ] +
3393 " has a different IP(" +
3394 str( onosHost[ 'ipAddresses' ] ) +
3395 ") than the Mininet host(" +
3396 str( ip ) +
3397 ")." )
3398 output = json.dumps(
3399 onosHost,
3400 sort_keys=True,
3401 indent=4,
3402 separators=( ',', ': ' ) )
3403 main.log.info( output )
3404 hostResults = main.FALSE
3405 if not match:
3406 hostResults = main.FALSE
3407 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3408 "corresponding Mininet host." )
3409 output = json.dumps( onosHost,
3410 sort_keys=True,
3411 indent=4,
3412 separators=( ',', ': ' ) )
3413 main.log.info( output )
3414 return hostResults
3415 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003416 main.log.error( self.name + ": EOF exception found" )
3417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003418 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003419 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003420 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003421 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003422
You Wang53dba1e2018-02-02 17:45:44 -08003423 def verifyHostIp( self, hostList=[], prefix="" ):
3424 """
3425 Description:
3426 Verify that all hosts have IP address assigned to them
3427 Optional:
3428 hostList: If specified, verifications only happen to the hosts
3429 in hostList
3430 prefix: at least one of the ip address assigned to the host
3431 needs to have the specified prefix
3432 Returns:
3433 main.TRUE if all hosts have specific IP address assigned;
3434 main.FALSE otherwise
3435 """
3436 try:
You Wang79f5c5b2018-03-14 11:10:44 -07003437 hosts = self.getHosts( getInterfaces=False )
You Wang53dba1e2018-02-02 17:45:44 -08003438 if not hostList:
3439 hostList = hosts.keys()
3440 for hostName in hosts.keys():
3441 if hostName not in hostList:
3442 continue
3443 ipList = []
3444 self.handle.sendline( str( hostName ) + " ip a" )
3445 self.handle.expect( "mininet>" )
3446 ipa = self.handle.before
3447 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3448 ipList += re.findall( ipv4Pattern, ipa )
3449 # It's tricky to make regex for IPv6 addresses and this one is simplified
3450 ipv6Pattern = r'inet6 ((?:[0-9a-fA-F]{1,4})?(?:[:0-9a-fA-F]{1,4}){1,7}(?:::)?(?:[:0-9a-fA-F]{1,4}){1,7})/'
3451 ipList += re.findall( ipv6Pattern, ipa )
3452 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3453 if not ipList:
3454 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3455 else:
3456 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3457 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3458 else:
3459 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3460 hostList.remove( hostName )
3461 return main.FALSE if hostList else main.TRUE
3462 except KeyError:
3463 main.log.exception( self.name + ": host data not as expected: " + hosts )
3464 return None
3465 except pexpect.EOF:
3466 main.log.error( self.name + ": EOF exception found" )
3467 main.log.error( self.name + ": " + self.handle.before )
3468 main.cleanAndExit()
3469 except Exception:
3470 main.log.exception( self.name + ": Uncaught exception" )
3471 return None
3472
Jon Hallafa8a472015-06-12 14:02:42 -07003473 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003474 """
3475 Returns a list of all hosts
3476 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003477 try:
3478 self.handle.sendline( "" )
3479 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003480
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003481 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3482 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003483
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003484 handlePy = self.handle.before
3485 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3486 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003487
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003488 self.handle.sendline( "" )
3489 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003490
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003491 hostStr = handlePy.replace( "]", "" )
3492 hostStr = hostStr.replace( "'", "" )
3493 hostStr = hostStr.replace( "[", "" )
3494 hostStr = hostStr.replace( " ", "" )
3495 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003496
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003497 return hostList
3498 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003499 main.log.error( self.name + ": TIMEOUT exception found" )
3500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003501 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003502 except pexpect.EOF:
3503 main.log.error( self.name + ": EOF exception found" )
3504 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003505 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003506 except Exception:
3507 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003508 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003509
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003510 def getSwitch( self ):
3511 """
3512 Returns a list of all switches
3513 Again, don't ask question just use it...
3514 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003515 try:
3516 # get host list...
3517 hostList = self.getHosts()
3518 # Make host set
3519 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003520
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003521 # Getting all the nodes in mininet
3522 self.handle.sendline( "" )
3523 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003524
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003525 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3526 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003527
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003528 handlePy = self.handle.before
3529 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3530 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003531
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003532 self.handle.sendline( "" )
3533 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003534
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003535 nodesStr = handlePy.replace( "]", "" )
3536 nodesStr = nodesStr.replace( "'", "" )
3537 nodesStr = nodesStr.replace( "[", "" )
3538 nodesStr = nodesStr.replace( " ", "" )
3539 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003540
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003541 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003542 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003543 nodesSet.discard( 'c0' )
3544 nodesSet.discard( 'c1' )
3545 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003546
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003547 switchSet = nodesSet - hostSet
3548 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003549
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003550 return switchList
3551 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003552 main.log.error( self.name + ": TIMEOUT exception found" )
3553 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003554 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003555 except pexpect.EOF:
3556 main.log.error( self.name + ": EOF exception found" )
3557 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003558 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003559 except Exception:
3560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003561 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003562
You Wangdb8cd0a2016-05-26 15:19:45 -07003563 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3564 """
3565 Return a dictionary which describes the latest Mininet topology data as a
3566 graph.
3567 An example of the dictionary:
3568 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3569 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3570 Each vertex should at least have an 'edges' attribute which describes the
3571 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003572 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003573 list of attributes.
3574 An example of the edges dictionary:
3575 'edges': { vertex2: { 'port': ..., 'weight': ... },
3576 vertex3: { 'port': ..., 'weight': ... } }
3577 If useId == True, dpid/mac will be used instead of names to identify
3578 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3579 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003580 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003581 in topology data.
3582 Note that link or switch that are brought down by 'link x x down' or 'switch
3583 x down' commands still show in the output of Mininet CLI commands such as
3584 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3585 recommended to use delLink() or delSwitch functions to simulate link/switch
3586 down, and addLink() or addSwitch to add them back.
3587 """
3588 graphDict = {}
3589 try:
3590 links = self.getLinks( timeout=timeout )
3591 portDict = {}
3592 if useId:
3593 switches = self.getSwitches()
3594 if includeHost:
3595 hosts = self.getHosts()
3596 for link in links:
3597 # FIXME: support 'includeHost' argument
3598 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3599 continue
3600 nodeName1 = link[ 'node1' ]
3601 nodeName2 = link[ 'node2' ]
3602 port1 = link[ 'port1' ]
3603 port2 = link[ 'port2' ]
3604 # Loop for two nodes
3605 for i in range( 2 ):
3606 # Get port index from OVS
3607 # The index extracted from port name may be inconsistent with ONOS
3608 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003609 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003610 portList = self.getOVSPorts( nodeName1 )
3611 if len( portList ) == 0:
3612 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3613 return None
3614 portDict[ nodeName1 ] = portList
3615 for port in portDict[ nodeName1 ]:
3616 if port[ 'port' ] == port1:
3617 portIndex = port[ 'index' ]
3618 break
3619 if portIndex == -1:
3620 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3621 return None
3622 if useId:
3623 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3624 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3625 else:
3626 node1 = nodeName1
3627 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003628 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003629 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003630 graphDict[ node1 ] = { 'edges': {},
3631 'dpid': switches[ nodeName1 ][ 'dpid' ],
3632 'name': nodeName1,
3633 'ports': switches[ nodeName1 ][ 'ports' ],
3634 'swClass': switches[ nodeName1 ][ 'swClass' ],
3635 'pid': switches[ nodeName1 ][ 'pid' ],
3636 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003637 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003638 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003639 else:
3640 # Assert node2 is not connected to any current links of node1
3641 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003642 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003643 # Swap two nodes/ports
3644 nodeName1, nodeName2 = nodeName2, nodeName1
3645 port1, port2 = port2, port1
3646 return graphDict
3647 except KeyError:
3648 main.log.exception( self.name + ": KeyError exception found" )
3649 return None
3650 except AssertionError:
3651 main.log.exception( self.name + ": AssertionError exception found" )
3652 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003653 except pexpect.EOF:
3654 main.log.error( self.name + ": EOF exception found" )
3655 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003656 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003657 except Exception:
3658 main.log.exception( self.name + ": Uncaught exception" )
3659 return None
3660
Devin Lima7cfdbd2017-09-29 15:02:22 -07003661 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003662 """
3663 updates the port address and status information for
3664 each port in mn"""
3665 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003666 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003667 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003668 self.handle.sendline( "" )
3669 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003670
Jon Hall7eb38402015-01-08 17:19:54 -08003671 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003672 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003673
Jon Hall7eb38402015-01-08 17:19:54 -08003674 self.handle.sendline( "" )
3675 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003676
Jon Hallb1290e82014-11-18 16:17:48 -05003677 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003678 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003679 main.log.error( self.name + ": TIMEOUT exception found" )
3680 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003681 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003682 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003683 main.log.error( self.name + ": EOF exception found" )
3684 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003685 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003686 except Exception:
3687 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003688 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003689
Jon Halld80cc142015-07-06 13:36:05 -07003690 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003691 """
3692 Add vlan tag to a host.
3693 Dependencies:
3694 This class depends on the "vlan" package
3695 $ sudo apt-get install vlan
3696 Configuration:
3697 Load the 8021q module into the kernel
3698 $sudo modprobe 8021q
3699
3700 To make this setup permanent:
3701 $ sudo su -c 'echo "8021q" >> /etc/modules'
3702 """
3703 if self.handle:
3704 try:
Jon Halld80cc142015-07-06 13:36:05 -07003705 # get the ip address of the host
3706 main.log.info( "Get the ip address of the host" )
3707 ipaddr = self.getIPAddress( host )
3708 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003709
Jon Halld80cc142015-07-06 13:36:05 -07003710 # remove IP from interface intf
3711 # Ex: h1 ifconfig h1-eth0 inet 0
3712 main.log.info( "Remove IP from interface " )
3713 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3714 self.handle.sendline( cmd2 )
3715 self.handle.expect( "mininet>" )
3716 response = self.handle.before
3717 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003718
Jon Halld80cc142015-07-06 13:36:05 -07003719 # create VLAN interface
3720 # Ex: h1 vconfig add h1-eth0 100
3721 main.log.info( "Create Vlan" )
3722 cmd3 = host + " vconfig add " + intf + " " + vlan
3723 self.handle.sendline( cmd3 )
3724 self.handle.expect( "mininet>" )
3725 response = self.handle.before
3726 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003727
Jon Halld80cc142015-07-06 13:36:05 -07003728 # assign the host's IP to the VLAN interface
3729 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3730 main.log.info( "Assign the host IP to the vlan interface" )
3731 vintf = intf + "." + vlan
3732 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3733 self.handle.sendline( cmd4 )
3734 self.handle.expect( "mininet>" )
3735 response = self.handle.before
3736 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003737
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003738 # update Mininet node variables
3739 main.log.info( "Update Mininet node variables" )
3740 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3741 self.handle.sendline( cmd5 )
3742 self.handle.expect( "mininet>" )
3743 response = self.handle.before
3744 main.log.info( "====> %s ", response )
3745
3746 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3747 self.handle.sendline( cmd6 )
3748 self.handle.expect( "mininet>" )
3749 response = self.handle.before
3750 main.log.info( "====> %s ", response )
3751
3752 return main.TRUE
3753 except pexpect.TIMEOUT:
3754 main.log.error( self.name + ": TIMEOUT exception found" )
3755 main.log.error( self.name + ": " + self.handle.before )
3756 main.cleanAndExit()
3757 except pexpect.EOF:
3758 main.log.error( self.name + ": EOF exception found" )
3759 main.log.error( self.name + ": " + self.handle.before )
3760 return main.FALSE
3761 except Exception:
3762 main.log.exception( self.name + ": Uncaught exception!" )
3763 return main.FALSE
3764
3765 def removeVLAN( self, host, intf ):
3766 """
3767 Remove vlan tag from a host.
3768 Dependencies:
3769 This class depends on the "vlan" package
3770 $ sudo apt-get install vlan
3771 Configuration:
3772 Load the 8021q module into the kernel
3773 $sudo modprobe 8021q
3774
3775 To make this setup permanent:
3776 $ sudo su -c 'echo "8021q" >> /etc/modules'
3777 """
3778 if self.handle:
3779 try:
3780 # get the ip address of the host
3781 main.log.info( "Get the ip address of the host" )
3782 ipaddr = self.getIPAddress( host )
3783
3784 # remove VLAN interface
3785 # Ex: h1 vconfig rem h1-eth0.100
3786 main.log.info( "Remove Vlan interface" )
3787 cmd2 = host + " vconfig rem " + intf
3788 self.handle.sendline( cmd2 )
3789 self.handle.expect( "mininet>" )
3790 response = self.handle.before
3791 main.log.info( "====> %s ", response )
3792
3793 # assign the host's IP to the original interface
3794 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3795 main.log.info( "Assign the host IP to the original interface" )
3796 original_intf = intf.split(".")[0]
3797 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3798 self.handle.sendline( cmd3 )
3799 self.handle.expect( "mininet>" )
3800 response = self.handle.before
3801 main.log.info( "====> %s ", response )
3802
3803 # update Mininet node variables
3804 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3805 self.handle.sendline( cmd4 )
3806 self.handle.expect( "mininet>" )
3807 response = self.handle.before
3808 main.log.info( "====> %s ", response )
3809
3810 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3811 self.handle.sendline( cmd5 )
3812 self.handle.expect( "mininet>" )
3813 response = self.handle.before
3814 main.log.info( "====> %s ", response )
3815
kaouthera3f13ca22015-05-05 15:01:41 -07003816 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003817 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003818 main.log.error( self.name + ": TIMEOUT exception found" )
3819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003820 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003821 except pexpect.EOF:
3822 main.log.error( self.name + ": EOF exception found" )
3823 main.log.error( self.name + ": " + self.handle.before )
3824 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003825 except Exception:
3826 main.log.exception( self.name + ": Uncaught exception!" )
3827 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003828
Jon Hall892818c2015-10-20 17:58:34 -07003829 def createHostComponent( self, name ):
3830 """
3831 Creates a new mininet cli component with the same parameters as self.
3832 This new component is intended to be used to login to the hosts created
3833 by mininet.
3834
3835 Arguments:
3836 name - The string of the name of this component. The new component
3837 will be assigned to main.<name> .
3838 In addition, main.<name>.name = str( name )
3839 """
3840 try:
3841 # look to see if this component already exists
3842 getattr( main, name )
3843 except AttributeError:
3844 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003845 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3846 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003847 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003848 except pexpect.EOF:
3849 main.log.error( self.name + ": EOF exception found" )
3850 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003851 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003852 except Exception:
3853 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003854 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003855 else:
3856 # namespace is not clear!
3857 main.log.error( name + " component already exists!" )
3858 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003859 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003860
3861 def removeHostComponent( self, name ):
3862 """
3863 Remove host component
3864 Arguments:
3865 name - The string of the name of the component to delete.
3866 """
3867 try:
3868 # Get host component
3869 component = getattr( main, name )
3870 except AttributeError:
3871 main.log.error( "Component " + name + " does not exist." )
3872 return
3873 try:
3874 # Disconnect from component
3875 component.disconnect()
3876 # Delete component
3877 delattr( main, name )
3878 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003879 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003880 except pexpect.EOF:
3881 main.log.error( self.name + ": EOF exception found" )
3882 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003883 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003884 except Exception:
3885 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003886 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003887
3888 def startHostCli( self, host=None ):
3889 """
3890 Use the mininet m utility to connect to the host's cli
3891 """
3892 # These are fields that can be used by scapy packets. Initialized to None
3893 self.hostIp = None
3894 self.hostMac = None
3895 try:
3896 if not host:
3897 host = self.name
3898 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003899 self.handle.sendline( "cd" )
3900 self.handle.expect( self.hostPrompt )
3901 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003902 self.handle.expect( self.hostPrompt )
3903 return main.TRUE
3904 except pexpect.TIMEOUT:
3905 main.log.exception( self.name + ": Command timed out" )
3906 return main.FALSE
3907 except pexpect.EOF:
3908 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003909 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003910 except Exception:
3911 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003912 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003913
YPZhang801d46d2016-08-08 13:26:28 -07003914 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003915 '''
3916
YPZhang801d46d2016-08-08 13:26:28 -07003917 Args:
3918 devicename: switch name
3919 intf: port name on switch
3920 status: up or down
3921
3922 Returns: boolean to show success change status
3923
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003924 '''
YPZhang801d46d2016-08-08 13:26:28 -07003925 if status == "down" or status == "up":
3926 try:
3927 cmd = devicename + " ifconfig " + intf + " " + status
3928 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003929 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003930 return main.TRUE
3931 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003932 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003933 return main.FALSE
3934 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003935 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003936 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003937 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003938 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003939 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003940 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003942 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003943 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003944 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003945 return main.FALSE
3946
3947
adminbae64d82013-08-01 10:50:15 -07003948if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003949 sys.modules[ __name__ ] = MininetCliDriver()