blob: ca86a89b7d047dd70ac6f085224712c2ccddaa19 [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
You Wange24d6272018-03-27 21:18:50 -07001124 def addRoute( self, host, dstIP, interface, ipv6=False ):
1125 """
1126 Add a route to host
1127 Ex: h1 route add -host 224.2.0.1 h1-eth0
1128 """
1129 if self.handle:
1130 try:
1131 cmd = str( host )
1132 if ipv6:
1133 cmd += " route -A inet6 add "
1134 else:
1135 cmd += " route add -host "
1136 cmd += str( dstIP ) + " " + str( interface )
1137 self.handle.sendline( cmd )
1138 self.handle.expect( "mininet>" )
1139 response = self.handle.before
1140 main.log.debug( "response = " + response )
1141 return main.TRUE
1142 except pexpect.TIMEOUT:
1143 main.log.error( self.name + ": TIMEOUT exception found" )
1144 main.log.error( self.name + ": " + self.handle.before )
1145 main.cleanAndExit()
1146 except pexpect.EOF:
1147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
1149 return main.FALSE
1150 except Exception:
1151 main.log.exception( self.name + ": Uncaught exception!" )
1152 main.cleanAndExit()
1153
Jon Hall7eb38402015-01-08 17:19:54 -08001154 def addStaticMACAddress( self, host, GW, macaddr ):
1155 """
Jon Hallefbd9792015-03-05 16:11:36 -08001156 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001157 if self.handle:
1158 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001159 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1160 cmd = host + " arp -s " + GW + " " + macaddr
1161 self.handle.sendline( cmd )
1162 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001163 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001164 main.log.info( "response = " + response )
1165 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001166 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001167 GW +
1168 " changed to " +
1169 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001170 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001171 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001172 main.log.error( self.name + ": TIMEOUT exception found" )
1173 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001174 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001175 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001176 main.log.error( self.name + ": EOF exception found" )
1177 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001178 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001179 except Exception:
1180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001181 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001182
Jon Hall7eb38402015-01-08 17:19:54 -08001183 def verifyStaticGWandMAC( self, host ):
1184 """
1185 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001186 if self.handle:
1187 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001188 # h1 arp -an
1189 cmd = host + " arp -an "
1190 self.handle.sendline( cmd )
1191 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001192 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001193 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001194 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001195 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001196 main.log.error( self.name + ": TIMEOUT exception found" )
1197 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001198 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001199 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001200 main.log.error( self.name + ": EOF exception found" )
1201 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001202 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001203 except Exception:
1204 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001205 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001206
Jon Hall7eb38402015-01-08 17:19:54 -08001207 def getMacAddress( self, host ):
1208 """
1209 Verifies the host's ip configured or not."""
1210 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001211 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001212 response = self.execute(
1213 cmd=host +
1214 " ifconfig",
1215 prompt="mininet>",
1216 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001217 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001218 main.log.error( self.name + ": EOF exception found" )
1219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001220 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001221 except Exception:
1222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001223 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001224
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001225 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 macAddressSearch = re.search( pattern, response, re.I )
1227 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001228 main.log.info(
1229 self.name +
1230 ": Mac-Address of Host " +
1231 host +
1232 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 macAddress )
1234 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001235 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001237
Jon Hall7eb38402015-01-08 17:19:54 -08001238 def getInterfaceMACAddress( self, host, interface ):
1239 """
1240 Return the IP address of the interface on the given host"""
1241 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001242 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001243 response = self.execute( cmd=host + " ifconfig " + interface,
1244 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001245 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001246 main.log.error( self.name + ": EOF exception found" )
1247 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001248 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001249 except Exception:
1250 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001251 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001252
1253 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 macAddressSearch = re.search( pattern, response, re.I )
1255 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001256 main.log.info( "No mac address found in %s" % response )
1257 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001259 main.log.info(
1260 "Mac-Address of " +
1261 host +
1262 ":" +
1263 interface +
1264 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001265 macAddress )
1266 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001267 else:
1268 main.log.error( "Connection failed to the host" )
1269
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001270 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001271 """
1272 Verifies the host's ip configured or not."""
1273 if self.handle:
1274 try:
1275 response = self.execute(
1276 cmd=host +
1277 " ifconfig",
1278 prompt="mininet>",
1279 timeout=10 )
1280 except pexpect.EOF:
1281 main.log.error( self.name + ": EOF exception found" )
1282 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001283 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001284 except Exception:
1285 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001286 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001287
sathishmad953462015-12-03 17:42:07 +05301288 pattern = ''
1289 if proto == 'IPV4':
1290 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1291 else:
Jon Hall439c8912016-04-15 02:22:03 -07001292 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 ipAddressSearch = re.search( pattern, response )
Jon Hall3c910162018-03-07 14:42:16 -08001294 if not ipAddressSearch:
1295 return None
Jon Hall7eb38402015-01-08 17:19:54 -08001296 main.log.info(
1297 self.name +
1298 ": IP-Address of Host " +
1299 host +
1300 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 ipAddressSearch.group( 1 ) )
1302 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001303 else:
1304 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001305
Jon Hall7eb38402015-01-08 17:19:54 -08001306 def getSwitchDPID( self, switch ):
1307 """
1308 return the datapath ID of the switch"""
1309 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001310 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001311 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001312 response = self.execute(
1313 cmd=cmd,
1314 prompt="mininet>",
1315 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001316 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001317 main.log.error( self.name + ": EOF exception found" )
1318 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001319 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001320 except Exception:
1321 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001322 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001323 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001324 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001325 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001326 main.log.info(
1327 "Couldn't find DPID for switch %s, found: %s" %
1328 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001329 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001330 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001331 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001332 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001333
Jon Hall7eb38402015-01-08 17:19:54 -08001334 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001335 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001336 self.handle.sendline( "" )
1337 self.expect( "mininet>" )
1338 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001339 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001340 response = self.execute(
1341 cmd=cmd,
1342 prompt="mininet>",
1343 timeout=10 )
1344 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001345 response = self.handle.before
1346 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001347 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001348 main.log.error( self.name + ": TIMEOUT exception found" )
1349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001350 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001351 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001352 main.log.error( self.name + ": EOF exception found" )
1353 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001354 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001355 except Exception:
1356 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001357 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001358
Jon Hall7eb38402015-01-08 17:19:54 -08001359 def getInterfaces( self, node ):
1360 """
1361 return information dict about interfaces connected to the node"""
1362 if self.handle:
1363 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001364 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001365 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001366 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001367 response = self.execute(
1368 cmd=cmd,
1369 prompt="mininet>",
1370 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001371 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001372 main.log.error( self.name + ": EOF exception found" )
1373 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001374 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001375 except Exception:
1376 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001377 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001378 return response
1379 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001380 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001381
Jon Hall7eb38402015-01-08 17:19:54 -08001382 def dump( self ):
1383 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001384 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001385 response = self.execute(
1386 cmd='dump',
1387 prompt='mininet>',
1388 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001389 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001390 main.log.error( self.name + ": EOF exception found" )
1391 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001392 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001393 except Exception:
1394 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001395 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001396 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001397
Jon Hall7eb38402015-01-08 17:19:54 -08001398 def intfs( self ):
1399 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001400 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001401 response = self.execute(
1402 cmd='intfs',
1403 prompt='mininet>',
1404 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001405 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001406 main.log.error( self.name + ": EOF exception found" )
1407 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001408 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001409 except Exception:
1410 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001411 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001412 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001413
Jon Hall7eb38402015-01-08 17:19:54 -08001414 def net( self ):
1415 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001416 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001417 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001418 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001419 main.log.error( self.name + ": EOF exception found" )
1420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001421 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001422 except Exception:
1423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001424 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001425 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001426
Devin Lima7cfdbd2017-09-29 15:02:22 -07001427 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001428 main.log.info( self.name + ": List network links" )
1429 try:
1430 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001431 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001432 except pexpect.EOF:
1433 main.log.error( self.name + ": EOF exception found" )
1434 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001435 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001436 except Exception:
1437 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001438 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001439 return response
1440
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001441 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001442 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001443 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001444
kelvin-onlab7cce9382015-07-17 10:21:03 -07001445 @parm:
1446 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1447 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001448 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001449 try:
1450 for host1 in hosts:
1451 for host2 in hosts:
1452 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001453 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1454 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001455 except Exception:
1456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001457 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001458
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001459 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001460 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001461 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1462 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001463
kelvin-onlab7cce9382015-07-17 10:21:03 -07001464 @parm:
1465 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1466 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001467 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001468 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1469 try:
1470 # Setup the mininet command
1471 cmd1 = 'iperf ' + host1 + " " + host2
1472 self.handle.sendline( cmd1 )
1473 outcome = self.handle.expect( "mininet>", timeout )
1474 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001475
kelvin-onlab7cce9382015-07-17 10:21:03 -07001476 # checks if there are results in the mininet response
1477 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001478 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001479 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001480 response = response.split( "\r\n" )
1481 response = response[ len( response )-2 ]
1482 response = response.split( ": " )
1483 response = response[ len( response )-1 ]
1484 response = response.replace( "[", "" )
1485 response = response.replace( "]", "" )
1486 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001487
kelvin-onlab7cce9382015-07-17 10:21:03 -07001488 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001489 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001490
kelvin-onlab7cce9382015-07-17 10:21:03 -07001491 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001492 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001493 if len( bandwidth ) == 2:
1494 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001495 return main.TRUE
1496 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001497 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001498 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001499 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001500 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001501 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001502 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001503 main.log.error( self.name + ": TIMEOUT exception found" )
1504 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001505 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001506 # NOTE: Send ctrl-c to make sure iperf is done
Jon Hall2c5ac942018-03-23 11:26:54 -07001507 self.handle.send( "\x03" )
Jon Hall3b489db2015-10-05 14:38:37 -07001508 self.handle.expect( "Interrupt" )
1509 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001510 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001511 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001512 main.log.error( self.name + ": EOF exception found" )
1513 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001514 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001515 except Exception:
1516 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001517 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001518
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001519 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001520 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1521 try:
1522 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001523 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001524 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001525 outcome1 = self.handle.expect( "mininet>" )
1526 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001527 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001528 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001529 response1 = self.handle.before
1530 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001531 print response1, response2
1532 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001533 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001534 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001535 return main.TRUE
1536 else:
1537 main.log.error( self.name + ": iperf test failed" )
1538 return main.FALSE
1539 except pexpect.TIMEOUT:
1540 main.log.error( self.name + ": TIMEOUT exception found" )
1541 main.log.error( self.name + " response: " + repr( self.handle.before ) )
Jon Hall2c5ac942018-03-23 11:26:54 -07001542 self.handle.send( "\x03" )
Jon Hall439c8912016-04-15 02:22:03 -07001543 self.handle.expect( "Interrupt" )
1544 self.handle.expect( "mininet>" )
1545 return main.FALSE
1546 except pexpect.EOF:
1547 main.log.error( self.name + ": EOF exception found" )
1548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001549 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001550 except Exception:
1551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001552 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001553
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001554 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001555 '''
GlennRC61321f22015-07-16 13:36:54 -07001556 Runs the iperfudp function with a given set of hosts and specified
1557 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001558
GlennRC61321f22015-07-16 13:36:54 -07001559 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001560 bandwidth: the targeted bandwidth, in megabits ('M')
1561 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001562 try:
1563 for host1 in hosts:
1564 for host2 in hosts:
1565 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001566 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1567 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001568 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001569 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001570 return main.FALSE
1571 except Exception:
1572 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001573 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001574
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001575 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001576 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001577 Creates an iperf UDP test with a specific bandwidth.
1578 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001579
kelvin-onlab7cce9382015-07-17 10:21:03 -07001580 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001581 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1582 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001583 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001584 try:
1585 # setup the mininet command
1586 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001587 self.handle.sendline( cmd )
1588 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001589 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001590
kelvin-onlab7cce9382015-07-17 10:21:03 -07001591 # check if there are in results in the mininet response
1592 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001593 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001594 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001595 response = response.split( "\r\n" )
1596 response = response[ len( response )-2 ]
1597 response = response.split( ": " )
1598 response = response[ len( response )-1 ]
1599 response = response.replace( "[", "" )
1600 response = response.replace( "]", "" )
1601 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001602
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001603 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001604
kelvin-onlab7cce9382015-07-17 10:21:03 -07001605 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001606 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001607 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001608 # if one entry is blank then something is wrong
1609 for item in mnBandwidth:
1610 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001611 main.log.error( self.name + ": Could not parse iperf output" )
1612 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001613 return main.FALSE
1614 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001615 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001616 return main.TRUE
1617 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001618 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001619 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001620
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001621 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001622 main.log.error( self.name + ": TIMEOUT exception found" )
1623 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001624 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001625 except pexpect.EOF:
1626 main.log.error( self.name + ": EOF exception found" )
1627 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001628 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001629 except Exception:
1630 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001631 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001632
Jon Hall7eb38402015-01-08 17:19:54 -08001633 def nodes( self ):
1634 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001635 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001636 response = self.execute(
1637 cmd='nodes',
1638 prompt='mininet>',
1639 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001640 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001641 main.log.error( self.name + ": EOF exception found" )
1642 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001643 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001644 except Exception:
1645 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001646 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001647 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001648
Jon Hall7eb38402015-01-08 17:19:54 -08001649 def pingpair( self ):
1650 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001651 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001652 response = self.execute(
1653 cmd='pingpair',
1654 prompt='mininet>',
1655 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001656 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001657 main.log.error( self.name + ": EOF exception found" )
1658 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001659 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001660 except Exception:
1661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001662 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001663
Jon Hall7eb38402015-01-08 17:19:54 -08001664 if re.search( ',\s0\%\spacket\sloss', response ):
1665 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001666 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001667 else:
alisone4121a92016-11-22 16:31:36 -08001668 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001669 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001670
Jon Hall7eb38402015-01-08 17:19:54 -08001671 def link( self, **linkargs ):
1672 """
GlennRCed771242016-01-13 17:02:47 -08001673 Bring link( s ) between two nodes up or down
1674 """
Jon Hall6094a362014-04-11 14:46:56 -07001675 try:
GlennRCed771242016-01-13 17:02:47 -08001676 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1677 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1678 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1679 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1680
1681 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1682 cmd = "link {} {} {}".format( end1, end2, option )
1683 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001684 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001685 response = self.handle.before
1686 main.log.info( response )
Jon Hallab611372018-02-21 15:26:05 -08001687 if "not in network" in response:
1688 main.log.error( self.name + ": Could not find one of the endpoints of the link" )
1689 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08001690 return main.TRUE
1691 except pexpect.TIMEOUT:
1692 main.log.exception( self.name + ": Command timed out" )
1693 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001694 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001695 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001696 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001697 except Exception:
1698 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001699 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001700
pingping-lin8244a3b2015-09-16 13:36:56 -07001701 def switch( self, **switchargs ):
1702 """
1703 start/stop a switch
1704 """
1705 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1706 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1707 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1708 command = "switch " + str( sw ) + " " + str( option )
1709 main.log.info( command )
1710 try:
1711 self.handle.sendline( command )
1712 self.handle.expect( "mininet>" )
1713 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001714 main.log.error( self.name + ": TIMEOUT exception found" )
1715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001716 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001717 except pexpect.EOF:
1718 main.log.error( self.name + ": EOF exception found" )
1719 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001720 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001721 return main.TRUE
1722
pingping-lin5bb663b2015-09-24 11:47:50 -07001723 def node( self, nodeName, commandStr ):
1724 """
1725 Carry out a command line on a given node
1726 @parm:
1727 nodeName: the node name in Mininet testbed
1728 commandStr: the command line will be carried out on the node
1729 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1730 """
1731 command = str( nodeName ) + " " + str( commandStr )
1732 main.log.info( command )
1733
1734 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001735 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001736 if re.search( "Unknown command", response ):
1737 main.log.warn( response )
1738 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001739 if re.search( "Permission denied", response ):
1740 main.log.warn( response )
1741 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001742 except pexpect.EOF:
1743 main.log.error( self.name + ": EOF exception found" )
1744 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001745 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001746 main.log.info( " response is :" )
1747 main.log.info( response )
1748 return response
1749
Jon Hall7eb38402015-01-08 17:19:54 -08001750 def yank( self, **yankargs ):
1751 """
1752 yank a mininet switch interface to a host"""
1753 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001754 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001755 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1756 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001757 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001758 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001759 response = self.execute(
1760 cmd=command,
1761 prompt="mininet>",
1762 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001763 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001764 main.log.error( self.name + ": EOF exception found" )
1765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001766 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001767 except Exception:
1768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001769 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001770 return main.TRUE
1771
Jon Hall7eb38402015-01-08 17:19:54 -08001772 def plug( self, **plugargs ):
1773 """
1774 plug the yanked mininet switch interface to a switch"""
1775 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001776 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001777 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1778 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001779 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001780 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001781 response = self.execute(
1782 cmd=command,
1783 prompt="mininet>",
1784 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001785 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001786 main.log.error( self.name + ": EOF exception found" )
1787 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001788 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001789 except Exception:
1790 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001791 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001792 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001793
Jon Hall7eb38402015-01-08 17:19:54 -08001794 def dpctl( self, **dpctlargs ):
1795 """
1796 Run dpctl command on all switches."""
1797 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001798 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001799 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1800 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1801 command = "dpctl " + cmd + " " + str( cmdargs )
1802 try:
1803 response = self.execute(
1804 cmd=command,
1805 prompt="mininet>",
1806 timeout=10 )
1807 except pexpect.EOF:
1808 main.log.error( self.name + ": EOF exception found" )
1809 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001810 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001811 except Exception:
1812 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001813 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001814 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001815
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001817 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001818 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001819 try:
1820 fileInput = path + '/lib/Mininet/INSTALL'
1821 version = super( Mininet, self ).getVersion()
1822 pattern = 'Mininet\s\w\.\w\.\w\w*'
1823 for line in open( fileInput, 'r' ).readlines():
1824 result = re.match( pattern, line )
1825 if result:
1826 version = result.group( 0 )
1827 return version
1828 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
kelvin-onlabd3b64892015-01-20 13:26:24 -08001832 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001833 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001834 Parameters:
1835 sw: The name of an OVS switch. Example "s1"
1836 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001837 The output of the command from the mininet cli
1838 or main.FALSE on timeout"""
1839 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001840 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001841 response = self.execute(
1842 cmd=command,
1843 prompt="mininet>",
1844 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001845 if response:
Jon Hallab611372018-02-21 15:26:05 -08001846 if "no bridge named" in response:
1847 main.log.error( self.name + ": Error in getSwController: " +
1848 self.handle.before )
1849 return main.FALSE
1850 else:
1851 return response
admin2a9548d2014-06-17 14:08:07 -07001852 else:
1853 return main.FALSE
1854 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001855 main.log.error( self.name + ": EOF exception found" )
1856 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001857 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001858 except Exception:
1859 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001860 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001861
Charles Chan029be652015-08-24 01:46:10 +08001862 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001863 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001864 Description:
1865 Assign switches to the controllers ( for ovs use only )
1866 Required:
1867 sw - Name of the switch. This can be a list or a string.
1868 ip - Ip addresses of controllers. This can be a list or a string.
1869 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001870 port - ONOS use port 6653, if no list of ports is passed, then
1871 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001872 ptcp - ptcp number, This can be a string or a list that has
1873 the same length as switch. This is optional and not required
1874 when using ovs switches.
1875 NOTE: If switches and ptcp are given in a list type they should have the
1876 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1877 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001878
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001879 Return:
1880 Returns main.TRUE if mininet correctly assigned switches to
1881 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001882 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001883 """
1884 assignResult = main.TRUE
1885 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001886 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001887 command = "sh ovs-vsctl set-controller "
1888 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001889 try:
1890 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001891 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001892 if isinstance( port, types.StringType ) or \
1893 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001894 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001895 elif isinstance( port, types.ListType ):
1896 main.log.error( self.name + ": Only one controller " +
1897 "assigned and a list of ports has" +
1898 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001899 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001900 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001901 main.log.error( self.name + ": Invalid controller port " +
1902 "number. Please specify correct " +
1903 "controller port" )
1904 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001905
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001906 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001907 if isinstance( port, types.StringType ) or \
1908 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001909 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001910 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1911 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001912 elif isinstance( port, types.ListType ):
1913 if ( len( ip ) != len( port ) ):
1914 main.log.error( self.name + ": Port list = " +
1915 str( len( port ) ) +
1916 "should be the same as controller" +
1917 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001918 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001919 else:
1920 onosIp = ""
1921 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001922 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1923 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001924 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001925 main.log.error( self.name + ": Invalid controller port " +
1926 "number. Please specify correct " +
1927 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001928 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001929 else:
1930 main.log.error( self.name + ": Invalid ip address" )
1931 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001932
1933 if isinstance( sw, types.StringType ):
1934 command += sw + " "
1935 if ptcp:
1936 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001937 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001938 elif isinstance( ptcp, types.ListType ):
1939 main.log.error( self.name + ": Only one switch is " +
1940 "being set and multiple PTCP is " +
1941 "being passed " )
1942 else:
1943 main.log.error( self.name + ": Invalid PTCP" )
1944 ptcp = ""
1945 command += onosIp
1946 commandList.append( command )
1947
1948 elif isinstance( sw, types.ListType ):
1949 if ptcp:
1950 if isinstance( ptcp, types.ListType ):
1951 if len( ptcp ) != len( sw ):
1952 main.log.error( self.name + ": PTCP length = " +
1953 str( len( ptcp ) ) +
1954 " is not the same as switch" +
1955 " length = " +
1956 str( len( sw ) ) )
1957 return main.FALSE
1958 else:
1959 for switch, ptcpNum in zip( sw, ptcp ):
1960 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001961 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001962 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001963 tempCmd += onosIp
1964 commandList.append( tempCmd )
1965 else:
1966 main.log.error( self.name + ": Invalid PTCP" )
1967 return main.FALSE
1968 else:
1969 for switch in sw:
1970 tempCmd = "sh ovs-vsctl set-controller "
1971 tempCmd += switch + " " + onosIp
1972 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001973 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001974 main.log.error( self.name + ": Invalid switch type " )
1975 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001976
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001977 for cmd in commandList:
1978 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001979 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
Jon Hallab611372018-02-21 15:26:05 -08001980 if "no bridge named" in self.handle.before:
1981 main.log.error( self.name + ": Error in assignSwController: " +
1982 self.handle.before )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001983 except pexpect.TIMEOUT:
1984 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1985 return main.FALSE
1986 except pexpect.EOF:
1987 main.log.error( self.name + ": EOF exception found" )
1988 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001989 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001990 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001991 except pexpect.EOF:
1992 main.log.error( self.name + ": EOF exception found" )
1993 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001994 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001995 except Exception:
1996 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001997 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001998
kelvin-onlabd3b64892015-01-20 13:26:24 -08001999 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002000 """
2001 Removes the controller target from sw"""
2002 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07002003 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002004 response = self.execute(
2005 cmd=command,
2006 prompt="mininet>",
2007 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08002008 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002009 main.log.error( self.name + ": EOF exception found" )
2010 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002011 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002012 except Exception:
2013 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002014 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002015 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002016 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07002017
kelvin-onlabd3b64892015-01-20 13:26:24 -08002018 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002019 """
Jon Hallb1290e82014-11-18 16:17:48 -05002020 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002021 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002022 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002023 NOTE: cannot currently specify what type of switch
2024 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002025 sw = name of the new switch as a string
2026 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05002027 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08002028 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002029 """
2030 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002031 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05002032 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002033 response = self.execute(
2034 cmd=command,
2035 prompt="mininet>",
2036 timeout=10 )
2037 if re.search( "already exists!", response ):
2038 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002039 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002040 elif re.search( "Error", 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( "usage:", response ):
2044 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002045 return main.FALSE
2046 else:
2047 return main.TRUE
2048 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002049 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07002050 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002051 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002052 except Exception:
2053 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002055
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002057 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002058 delete a switch from the mininet topology
2059 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002060 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002061 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002062 sw = name of the switch as a string
2063 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002064 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002065 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002066 response = self.execute(
2067 cmd=command,
2068 prompt="mininet>",
2069 timeout=10 )
2070 if re.search( "no switch named", response ):
2071 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002072 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002073 elif re.search( "Error", response ):
2074 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002075 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002076 elif re.search( "usage:", response ):
2077 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002078 return main.FALSE
2079 else:
2080 return main.TRUE
2081 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002082 main.log.error( self.name + ": EOF exception found" )
2083 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002084 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002085 except Exception:
2086 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002087 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002088
You Wangdb8cd0a2016-05-26 15:19:45 -07002089 def getSwitchRandom( self, timeout=60, nonCut=True ):
2090 """
2091 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002092 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002093 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002094 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002095 it just randomly returns one switch from all current switches in
2096 Mininet.
2097 Returns the name of the chosen switch.
2098 """
2099 import random
2100 candidateSwitches = []
2101 try:
2102 if not nonCut:
2103 switches = self.getSwitches( timeout=timeout )
2104 assert len( switches ) != 0
2105 for switchName in switches.keys():
2106 candidateSwitches.append( switchName )
2107 else:
2108 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002109 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002110 return None
2111 self.graph.update( graphDict )
2112 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002113 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002114 return None
2115 elif len( candidateSwitches ) == 0:
2116 main.log.info( self.name + ": No candidate switch for deletion" )
2117 return None
2118 else:
2119 switch = random.sample( candidateSwitches, 1 )
2120 return switch[ 0 ]
2121 except KeyError:
2122 main.log.exception( self.name + ": KeyError exception found" )
2123 return None
2124 except AssertionError:
2125 main.log.exception( self.name + ": AssertionError exception found" )
2126 return None
2127 except Exception:
2128 main.log.exception( self.name + ": Uncaught exception" )
2129 return None
2130
2131 def delSwitchRandom( self, timeout=60, nonCut=True ):
2132 """
2133 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002134 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002135 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002136 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002137 otherwise it just randomly delete one switch from all current
2138 switches in Mininet.
2139 Returns the name of the deleted switch
2140 """
2141 try:
2142 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002143 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002144 return None
2145 else:
2146 deletionResult = self.delSwitch( switch )
2147 if deletionResult:
2148 return switch
2149 else:
2150 return None
2151 except Exception:
2152 main.log.exception( self.name + ": Uncaught exception" )
2153 return None
2154
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002156 """
2157 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002158 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002159 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002160 NOTE: cannot currently specify what type of link
2161 required params:
2162 node1 = the string node name of the first endpoint of the link
2163 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002164 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002165 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002166 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002167 response = self.execute(
2168 cmd=command,
2169 prompt="mininet>",
2170 timeout=10 )
2171 if re.search( "doesnt exist!", response ):
2172 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002173 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002174 elif re.search( "Error", response ):
2175 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002176 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002177 elif re.search( "usage:", response ):
2178 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002179 return main.FALSE
2180 else:
2181 return main.TRUE
2182 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002183 main.log.error( self.name + ": EOF exception found" )
2184 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002185 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002186 except Exception:
2187 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002188 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002189
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002191 """
2192 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002193 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002194 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002195 required params:
2196 node1 = the string node name of the first endpoint of the link
2197 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002198 returns: main.FALSE on an error, else main.TRUE
2199 """
Jon Hallffb386d2014-11-21 13:43:38 -08002200 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002201 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002202 response = self.execute(
2203 cmd=command,
2204 prompt="mininet>",
2205 timeout=10 )
2206 if re.search( "no node named", response ):
2207 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002208 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002209 elif re.search( "Error", response ):
2210 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002211 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002212 elif re.search( "usage:", response ):
2213 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002214 return main.FALSE
2215 else:
2216 return main.TRUE
2217 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002218 main.log.error( self.name + ": EOF exception found" )
2219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002220 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002221 except Exception:
2222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002223 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002224
You Wangdb8cd0a2016-05-26 15:19:45 -07002225 def getLinkRandom( self, timeout=60, nonCut=True ):
2226 """
2227 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002228 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002229 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002230 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002231 it just randomly returns one link from all current links in
2232 Mininet.
2233 Returns the link as a list, e.g. [ 's1', 's2' ]
2234 """
2235 import random
2236 candidateLinks = []
2237 try:
2238 if not nonCut:
2239 links = self.getLinks( timeout=timeout )
2240 assert len( links ) != 0
2241 for link in links:
2242 # Exclude host-switch link
2243 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2244 continue
2245 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2246 else:
2247 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002248 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002249 return None
2250 self.graph.update( graphDict )
2251 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002252 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002253 return None
2254 elif len( candidateLinks ) == 0:
2255 main.log.info( self.name + ": No candidate link for deletion" )
2256 return None
2257 else:
2258 link = random.sample( candidateLinks, 1 )
2259 return link[ 0 ]
2260 except KeyError:
2261 main.log.exception( self.name + ": KeyError exception found" )
2262 return None
2263 except AssertionError:
2264 main.log.exception( self.name + ": AssertionError exception found" )
2265 return None
2266 except Exception:
2267 main.log.exception( self.name + ": Uncaught exception" )
2268 return None
2269
2270 def delLinkRandom( self, timeout=60, nonCut=True ):
2271 """
2272 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002273 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002274 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002275 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002276 otherwise it just randomly delete one link from all current links
2277 in Mininet.
2278 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2279 """
2280 try:
2281 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002282 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002283 return None
2284 else:
2285 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2286 if deletionResult:
2287 return link
2288 else:
2289 return None
2290 except Exception:
2291 main.log.exception( self.name + ": Uncaught exception" )
2292 return None
2293
kelvin-onlabd3b64892015-01-20 13:26:24 -08002294 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002295 """
Jon Hallb1290e82014-11-18 16:17:48 -05002296 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002297 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002298 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002299 NOTE: cannot currently specify what type of host
2300 required params:
2301 hostname = the string hostname
2302 optional key-value params
2303 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002304 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002305 """
2306 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002307 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002308 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002309 response = self.execute(
2310 cmd=command,
2311 prompt="mininet>",
2312 timeout=10 )
2313 if re.search( "already exists!", response ):
2314 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002315 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002316 elif re.search( "doesnt exists!", response ):
2317 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002318 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002319 elif re.search( "Error", response ):
2320 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002321 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002322 elif re.search( "usage:", response ):
2323 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002324 return main.FALSE
2325 else:
2326 return main.TRUE
2327 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002328 main.log.error( self.name + ": EOF exception found" )
2329 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002330 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002331 except Exception:
2332 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002333 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002334
kelvin-onlabd3b64892015-01-20 13:26:24 -08002335 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002336 """
2337 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002338 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002339 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002340 NOTE: this uses a custom mn function
2341 required params:
2342 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002343 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002344 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002345 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002346 response = self.execute(
2347 cmd=command,
2348 prompt="mininet>",
2349 timeout=10 )
2350 if re.search( "no host named", response ):
2351 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002352 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002353 elif re.search( "Error", response ):
2354 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002355 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002356 elif re.search( "usage:", response ):
2357 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002358 return main.FALSE
2359 else:
2360 return main.TRUE
2361 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002362 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()
Jon Hall0819fd92014-05-23 12:08:13 -07002368
Jon Hall7eb38402015-01-08 17:19:54 -08002369 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002370 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002371 Called at the end of the test to stop the mininet and
2372 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002373 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002374 try:
2375 self.handle.sendline( '' )
2376 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2377 timeout=2 )
2378 response = main.TRUE
2379 if i == 0:
2380 response = self.stopNet()
2381 elif i == 1:
2382 return main.TRUE
2383 # print "Disconnecting Mininet"
2384 if self.handle:
2385 self.handle.sendline( "exit" )
2386 self.handle.expect( "exit" )
2387 self.handle.expect( "(.*)" )
2388 else:
2389 main.log.error( "Connection failed to the host" )
2390 return response
2391 except pexpect.EOF:
2392 main.log.error( self.name + ": EOF exception found" )
2393 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002394 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002395 except Exception:
2396 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002397 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002398
Devin Lima7cfdbd2017-09-29 15:02:22 -07002399 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002400 """
Jon Hall21270ac2015-02-16 17:59:55 -08002401 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002402 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002403 main.FALSE if the pexpect handle does not exist.
2404
Jon Halld61331b2015-02-17 16:35:47 -08002405 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002406 """
Jon Halld61331b2015-02-17 16:35:47 -08002407 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002408 response = ''
2409 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002410 try:
Jon Halld80cc142015-07-06 13:36:05 -07002411 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002412 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002413 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002414 pexpect.EOF,
2415 pexpect.TIMEOUT ],
2416 timeout )
2417 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002418 main.log.info( "Exiting mininet.." )
2419 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002420 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002421 prompt=self.prompt,
2422 timeout=exitTimeout )
2423 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002424 self.handle.sendline( "sudo mn -c" )
2425 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002426
Jeremyd9e4eb12016-04-13 12:09:06 -07002427 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002428 main.log.info( " Mininet trying to exit while not " +
2429 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002430 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002431 elif i == 2:
2432 main.log.error( "Something went wrong exiting mininet" )
2433 elif i == 3: # timeout
2434 main.log.error( "Something went wrong exiting mininet " +
2435 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002436
You Wang18db8592018-04-02 13:52:03 -07002437 self.handle.sendline( "" )
2438 self.handle.expect( self.prompt )
2439 self.handle.sendline( "sudo killall -9 dhclient dhcpd zebra bgpd" )
2440
Hari Krishnab35c6d02015-03-18 11:13:51 -07002441 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002442 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002443 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002444 self.handle.sendline(
2445 "sudo kill -9 \`ps -ef | grep \"" +
2446 fileName +
2447 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002448 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002449 main.log.error( self.name + ": TIMEOUT exception found" )
2450 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002451 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002452 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002453 main.log.error( self.name + ": EOF exception found" )
2454 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002455 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002456 except Exception:
2457 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002458 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002459 else:
2460 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002461 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002462 return response
2463
YPZhang26a139e2016-04-25 14:01:55 -07002464 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002465 """
2466 Description:
2467 Sends arp message from mininet host for hosts discovery
2468 Required:
2469 host - hosts name
2470 Optional:
2471 ip - ip address that does not exist in the network so there would
2472 be no reply.
2473 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002474 if ethDevice:
2475 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002476 cmd = srcHost + " arping -c1 "
2477 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002478 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 -07002479 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002480 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002481 if output:
2482 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002483 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002484 i = self.handle.expect( [ "mininet>", "arping: " ] )
2485 if i == 0:
2486 return main.TRUE
2487 elif i == 1:
2488 response = self.handle.before + self.handle.after
2489 self.handle.expect( "mininet>" )
2490 response += self.handle.before + self.handle.after
2491 main.log.warn( "Error sending arping, output was: " +
2492 response )
2493 return main.FALSE
2494 except pexpect.TIMEOUT:
2495 main.log.error( self.name + ": TIMEOUT exception found" )
2496 main.log.warn( self.handle.before )
2497 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002498 except pexpect.EOF:
2499 main.log.error( self.name + ": EOF exception found" )
2500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002501 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002502 except Exception:
2503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002504 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002505
Jon Hall7eb38402015-01-08 17:19:54 -08002506 def decToHex( self, num ):
2507 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002508
Jon Hall7eb38402015-01-08 17:19:54 -08002509 def getSwitchFlowCount( self, switch ):
2510 """
2511 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002512 if self.handle:
2513 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2514 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002515 response = self.execute(
2516 cmd=cmd,
2517 prompt="mininet>",
2518 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002519 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002520 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()
admin2a9548d2014-06-17 14:08:07 -07002526 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002527 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002528 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002529 main.log.info(
2530 "Couldn't find flows on switch %s, found: %s" %
2531 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002532 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002533 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002534 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002535 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002536
Jon Hall9ed8f372016-02-24 17:34:07 -08002537 def checkFlows( self, sw, dumpFormat=None ):
2538 if dumpFormat:
2539 command = "sh ovs-ofctl -F " + \
2540 dumpFormat + " dump-flows " + str( sw )
2541 else:
2542 command = "sh ovs-ofctl dump-flows " + str( sw )
2543 try:
2544 response = self.execute(
2545 cmd=command,
2546 prompt="mininet>",
2547 timeout=10 )
2548 return response
2549 except pexpect.EOF:
2550 main.log.error( self.name + ": EOF exception found" )
2551 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002552 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002553 except Exception:
2554 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002555 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002556
GlennRC68467eb2015-11-16 18:01:01 -08002557 def flowTableComp( self, flowTable1, flowTable2 ):
2558 # This function compares the selctors and treatments of each flow
2559 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002560 assert flowTable1, "flowTable1 is empty or None"
2561 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002562 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002563 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002564 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002565 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002566 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2567 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002568 for field in dFields:
2569 try:
2570 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002571 except KeyError:
2572 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002573 try:
2574 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002575 except KeyError:
2576 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002577 for i in range( len( flowTable1 ) ):
2578 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002579 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002580 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002581 returnValue = main.FALSE
2582 break
2583 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002584 except AssertionError:
2585 main.log.exception( "Nothing to compare" )
2586 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002587 except Exception:
2588 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002589 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002590
GlennRC528ad292015-11-12 10:38:18 -08002591 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002592 '''
GlennRC956ea742015-11-05 16:14:15 -08002593 Discription: Parses flows into json format.
2594 NOTE: this can parse any string thats separated with commas
2595 Arguments:
2596 Required:
2597 flows: a list of strings that represnt flows
2598 Optional:
2599 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2600 debug: prints out the final result
2601 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002602 '''
GlennRC528ad292015-11-12 10:38:18 -08002603 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002604 try:
2605 for flow in flowTable:
2606 jsonFlow = {}
2607 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002608 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002609 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002610 for i in range( len( parsedFlow ) ):
2611 item = parsedFlow[ i ]
2612 if item[ 0 ] == " ":
2613 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002614 # grab the selector and treatment from the parsed flow
2615 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002616 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002617 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002618 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002619 index = 0
2620 # parse the flags
2621 # NOTE: This only parses one flag
2622 flag = {}
2623 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002624 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002625 index += 1
2626 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002627 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002628 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002629 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002630 # the priority is stuck in the selecter so put it back
2631 # in the flow
Jon Hallab611372018-02-21 15:26:05 -08002632 if 'priority' in sel[0]:
2633 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002634 # parse selector
2635 criteria = []
2636 for item in sel:
2637 # this is the type of the packet e.g. "arp"
2638 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002639 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002640 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002641 field = item.split( "=" )
2642 criteria.append( { field[ 0 ]: field[ 1 ] } )
2643 selector = { "selector": { "criteria": sorted( criteria ) } }
2644 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002645 # get rid of the action part e.g. "action=output:2"
2646 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002647 treat = treat.split( "=" )
2648 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002649 # parse treatment
2650 action = []
2651 for item in treat:
Jon Hallab611372018-02-21 15:26:05 -08002652 if ":" in item:
2653 field = item.split( ":" )
2654 action.append( { field[ 0 ]: field[ 1 ] } )
2655 else:
2656 main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
2657 item ) )
You Wang91c37cf2016-05-23 09:39:42 -07002658 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002659 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002660 # parse the rest of the flow
2661 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002662 field = item.split( "=" )
2663 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002664 # add the treatment and the selector to the json flow
2665 jsonFlow.update( selector )
2666 jsonFlow.update( treatment )
2667 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002668
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002669 if debug:
2670 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002671
You Wang91c37cf2016-05-23 09:39:42 -07002672 # add the json flow to the json flow table
2673 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002674
You Wang91c37cf2016-05-23 09:39:42 -07002675 return jsonFlowTable
2676
2677 except IndexError:
2678 main.log.exception( self.name + ": IndexError found" )
2679 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002680 except pexpect.EOF:
2681 main.log.error( self.name + ": EOF exception found" )
2682 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002683 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002684 except Exception:
2685 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002686 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002687
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002688 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002689 '''
2690 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002691 Each element is a flow.
2692 Arguments:
2693 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002694 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002695 a list of switches.
2696 Optional:
2697 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2698 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002699 '''
GlennRC956ea742015-11-05 16:14:15 -08002700 try:
2701 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002702 if isinstance( sw, list ):
2703 switches.extend( sw )
2704 else:
2705 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002706
2707 flows = []
2708 for s in switches:
2709 cmd = "sh ovs-ofctl dump-flows " + s
2710
GlennRC528ad292015-11-12 10:38:18 -08002711 if "1.0" == version:
2712 cmd += " -F OpenFlow10-table_id"
2713 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002714 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002715
2716 main.log.info( "Sending: " + cmd )
2717 self.handle.sendline( cmd )
2718 self.handle.expect( "mininet>" )
2719 response = self.handle.before
2720 response = response.split( "\r\n" )
2721 # dump the first two elements and the last
2722 # the first element is the command that was sent
2723 # the second is the table header
2724 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002725 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002726 flows.extend( response )
2727
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 if debug:
2729 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002730
GlennRC528ad292015-11-12 10:38:18 -08002731 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002732
GlennRC956ea742015-11-05 16:14:15 -08002733 except pexpect.EOF:
2734 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002735 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002736 except Exception:
2737 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002738 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002739
2740 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002741 '''
GlennRC956ea742015-11-05 16:14:15 -08002742 Discription: Checks whether the ID provided matches a flow ID in Mininet
2743 Arguments:
2744 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002745 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002746 a list of switches.
2747 flowId: the flow ID in hex format. Can also be a list of IDs
2748 Optional:
2749 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2750 debug: prints out the final result
2751 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2752 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002753 '''
GlennRC956ea742015-11-05 16:14:15 -08002754 try:
2755 main.log.info( "Getting flows from Mininet" )
2756 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002757 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002758 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002759
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002760 if debug:
2761 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002762
2763 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002764 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002765 result = False
2766 for f in flows:
2767 if flowId in f.get( 'cookie' ):
2768 result = True
2769 break
2770 # flowId is a list
2771 else:
2772 result = True
2773 # Get flow IDs from Mininet
2774 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2775 # Save the IDs that are not in Mininet
2776 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2777
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002778 if debug:
2779 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002780
2781 # Print out the IDs that are not in Mininet
2782 if absentIds:
2783 main.log.warn( "Absent ids: {}".format( absentIds ) )
2784 result = False
2785
2786 return main.TRUE if result else main.FALSE
2787
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002788 except pexpect.EOF:
2789 main.log.error( self.name + ": EOF exception found" )
2790 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002791 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002792 except Exception:
2793 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002794 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002795
Charles Chan029be652015-08-24 01:46:10 +08002796 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002797 """
Jon Hallefbd9792015-03-05 16:11:36 -08002798 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002799 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002800 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002801 self.handle.sendline( "" )
2802 self.handle.expect( "mininet>" )
2803 self.handle.sendline(
2804 "sh sudo tcpdump -n -i " +
2805 intf +
2806 " " +
2807 port +
2808 " -w " +
2809 filename.strip() +
2810 " &" )
2811 self.handle.sendline( "" )
2812 i = self.handle.expect( [ 'No\ssuch\device',
2813 'listening\son',
2814 pexpect.TIMEOUT,
2815 "mininet>" ],
2816 timeout=10 )
2817 main.log.warn( self.handle.before + self.handle.after )
2818 self.handle.sendline( "" )
2819 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002820 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002821 main.log.error(
2822 self.name +
2823 ": tcpdump - No such device exists. " +
2824 "tcpdump attempted on: " +
2825 intf )
admin2a9548d2014-06-17 14:08:07 -07002826 return main.FALSE
2827 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002828 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002829 return main.TRUE
2830 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002831 main.log.error(
2832 self.name +
2833 ": tcpdump command timed out! Check interface name," +
2834 " given interface was: " +
2835 intf )
admin2a9548d2014-06-17 14:08:07 -07002836 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002837 elif i == 3:
2838 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002839 return main.TRUE
2840 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002841 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002842 return main.FALSE
2843 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002844 main.log.error( self.name + ": EOF exception found" )
2845 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002846 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002847 except Exception:
2848 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002849 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002850
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002852 """
2853 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002854 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002855 self.handle.sendline( "sh sudo pkill tcpdump" )
2856 self.handle.expect( "mininet>" )
2857 self.handle.sendline( "" )
2858 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002859 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002860 main.log.error( self.name + ": TIMEOUT exception found" )
2861 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002862 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002863 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002864 main.log.error( self.name + ": EOF exception found" )
2865 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002866 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002867 except Exception:
2868 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002869 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002870
Jon Halld80cc142015-07-06 13:36:05 -07002871 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002872 """
2873 Read ports from a Mininet switch.
2874
2875 Returns a json structure containing information about the
2876 ports of the given switch.
2877 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002878 try:
2879 response = self.getInterfaces( nodeName )
2880 # TODO: Sanity check on response. log if no such switch exists
2881 ports = []
2882 for line in response.split( "\n" ):
2883 if not line.startswith( "name=" ):
2884 continue
2885 portVars = {}
2886 for var in line.split( "," ):
2887 key, value = var.split( "=" )
2888 portVars[ key ] = value
2889 isUp = portVars.pop( 'enabled', "True" )
2890 isUp = "True" in isUp
2891 if verbose:
2892 main.log.info( "Reading switch port %s(%s)" %
2893 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2894 mac = portVars[ 'mac' ]
2895 if mac == 'None':
2896 mac = None
2897 ips = []
2898 ip = portVars[ 'ip' ]
2899 if ip == 'None':
2900 ip = None
2901 ips.append( ip )
2902 name = portVars[ 'name' ]
2903 if name == 'None':
2904 name = None
2905 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2906 if name == 'lo':
2907 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2908 else:
2909 portNo = re.search( portRe, name ).group( 'port' )
2910 ports.append( { 'of_port': portNo,
2911 'mac': str( mac ).replace( '\'', '' ),
2912 'name': name,
2913 'ips': ips,
2914 'enabled': isUp } )
2915 return ports
2916 except pexpect.EOF:
2917 main.log.error( self.name + ": EOF exception found" )
2918 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002919 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002920 except Exception:
2921 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002922 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002923
You Wangdb8cd0a2016-05-26 15:19:45 -07002924 def getOVSPorts( self, nodeName ):
2925 """
2926 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2927
2928 Returns a list of dictionaries containing information about each
2929 port of the given switch.
2930 """
2931 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2932 try:
2933 response = self.execute(
2934 cmd=command,
2935 prompt="mininet>",
2936 timeout=10 )
2937 ports = []
2938 if response:
2939 for line in response.split( "\n" ):
2940 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2941 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002942 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002943 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2944 result = re.search( pattern, line )
2945 if result:
2946 index = result.group( 'index' )
2947 name = result.group( 'name' )
2948 # This port number is extracted from port name
2949 port = result.group( 'port' )
2950 mac = result.group( 'mac' )
2951 ports.append( { 'index': index,
2952 'name': name,
2953 'port': port,
2954 'mac': mac } )
2955 return ports
2956 except pexpect.EOF:
2957 main.log.error( self.name + ": EOF exception found" )
2958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002959 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002960 except Exception:
2961 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002962 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002963
Devin Lima7cfdbd2017-09-29 15:02:22 -07002964 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002965 """
2966 Read switches from Mininet.
2967
2968 Returns a dictionary whose keys are the switch names and the value is
2969 a dictionary containing information about the switch.
2970 """
Jon Halla22481b2015-07-28 17:46:01 -07002971 # NOTE: To support new Mininet switch classes, just append the new
2972 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002973
Jon Halla22481b2015-07-28 17:46:01 -07002974 # Regex patterns to parse 'dump' output
2975 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002976 # <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 -07002977 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002978 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2979 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2980 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002981 try:
2982 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2983 swRE = r"<(?P<class>" + switchClasses + r")" +\
2984 r"(?P<options>\{.*\})?\s" +\
2985 r"(?P<name>[^:]+)\:\s" +\
2986 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2987 r"\spid=(?P<pid>(\d)+)"
2988 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002989 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002990 output = {}
2991 dump = self.dump().split( "\n" )
2992 for line in dump:
2993 result = re.search( swRE, line, re.I )
2994 if result:
2995 name = result.group( 'name' )
2996 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2997 pid = result.group( 'pid' )
2998 swClass = result.group( 'class' )
2999 options = result.group( 'options' )
3000 if verbose:
3001 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
3002 ports = self.getPorts( name )
3003 output[ name ] = { "dpid": dpid,
3004 "ports": ports,
3005 "swClass": swClass,
3006 "pid": pid,
3007 "options": options }
3008 return output
3009 except pexpect.EOF:
3010 main.log.error( self.name + ": EOF exception found" )
3011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003012 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003013 except Exception:
3014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003015 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003016
Jon Hallab611372018-02-21 15:26:05 -08003017 def getHosts( self, verbose=False, updateTimeout=1000,
3018 hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
3019 getInterfaces=True ):
Jon Hallafa8a472015-06-12 14:02:42 -07003020 """
3021 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08003022 Optional:
3023 hostClass: it is used to match the class of the mininet host. It
3024 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07003025 Returns a dictionary whose keys are the host names and the value is
3026 a dictionary containing information about the host.
3027 """
3028 # Regex patterns to parse dump output
3029 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07003030 # <Host h1: pid=12725>
3031 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3032 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3033 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003034 # NOTE: Does not correctly match hosts with multi-links
3035 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3036 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003037 try:
You Wang53dba1e2018-02-02 17:45:44 -08003038 if not isinstance( hostClass, types.ListType ):
3039 hostClass = [ str( hostClass ) ]
3040 classRE = "(" + "|".join([c for c in hostClass]) + ")"
Jon Hallab611372018-02-21 15:26:05 -08003041 ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
3042 ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
3043 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003044 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07003045 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003046 # Get mininet dump
3047 dump = self.dump().split( "\n" )
3048 hosts = {}
3049 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08003050 result = re.search( hostRE, line )
3051 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003052 name = result.group( 'name' )
3053 interfaces = []
You Wang79f5c5b2018-03-14 11:10:44 -07003054 if getInterfaces:
3055 response = self.getInterfaces( name )
3056 # Populate interface info
3057 for line in response.split( "\n" ):
3058 if line.startswith( "name=" ):
3059 portVars = {}
3060 for var in line.split( "," ):
3061 key, value = var.split( "=" )
3062 portVars[ key ] = value
3063 isUp = portVars.pop( 'enabled', "True" )
3064 isUp = "True" in isUp
3065 if verbose:
3066 main.log.info( "Reading host port %s(%s)" %
3067 ( portVars[ 'name' ],
3068 portVars[ 'mac' ] ) )
3069 mac = portVars[ 'mac' ]
3070 if mac == 'None':
3071 mac = None
3072 ips = []
3073 ip = portVars[ 'ip' ]
3074 if ip == 'None':
3075 ip = None
3076 ips.append( ip )
3077 intfName = portVars[ 'name' ]
3078 if name == 'None':
3079 name = None
3080 interfaces.append( {
3081 "name": intfName,
3082 "ips": ips,
3083 "mac": str( mac ),
3084 "isUp": isUp } )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003085 hosts[ name ] = { "interfaces": interfaces }
3086 return hosts
3087 except pexpect.EOF:
3088 main.log.error( self.name + ": EOF exception found" )
3089 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003090 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003091 except Exception:
3092 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003093 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003094
Devin Lima7cfdbd2017-09-29 15:02:22 -07003095 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003096 """
3097 Gathers information about current Mininet links. These links may not
3098 be up if one of the ports is down.
3099
3100 Returns a list of dictionaries with link endpoints.
3101
3102 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003103 { 'node1': str( node1 name )
3104 'node2': str( node2 name )
3105 'port1': str( port1 of_port )
3106 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003107 Note: The port number returned is the eth#, not necessarily the of_port
3108 number. In Mininet, for OVS switch, these should be the same. For
3109 hosts, this is just the eth#.
3110 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003111 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003112 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003113 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003114
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003115 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003116 # s1-eth3<->s2-eth1 (OK OK)
3117 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003118 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3119 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3120 links = []
3121 for line in response:
3122 match = re.search( linkRE, line )
3123 if match:
3124 node1 = match.group( 'node1' )
3125 node2 = match.group( 'node2' )
3126 port1 = match.group( 'port1' )
3127 port2 = match.group( 'port2' )
3128 links.append( { 'node1': node1,
3129 'node2': node2,
3130 'port1': port1,
3131 'port2': port2 } )
3132 return links
3133
3134 except pexpect.EOF:
3135 main.log.error( self.name + ": EOF exception found" )
3136 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003137 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003138 except Exception:
3139 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003140 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003141
3142 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003143 """
3144 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003145 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003146
Jon Hallafa8a472015-06-12 14:02:42 -07003147 Dependencies:
3148 1. numpy - "sudo pip install numpy"
3149 """
3150 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003151 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003152 try:
3153 mnDPIDs = []
3154 for swName, switch in switches.iteritems():
3155 mnDPIDs.append( switch[ 'dpid' ].lower() )
3156 mnDPIDs.sort()
3157 if switchesJson == "": # if rest call fails
3158 main.log.error(
3159 self.name +
3160 ".compareSwitches(): Empty JSON object given from ONOS" )
3161 return main.FALSE
3162 onos = switchesJson
3163 onosDPIDs = []
3164 for switch in onos:
3165 if switch[ 'available' ]:
3166 onosDPIDs.append(
3167 switch[ 'id' ].replace(
3168 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003169 '' ).replace(
3170 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003171 '' ).lower() )
3172 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003173
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003174 if mnDPIDs != onosDPIDs:
3175 switchResults = main.FALSE
3176 main.log.error( "Switches in MN but not in ONOS:" )
3177 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3178 main.log.error( str( list1 ) )
3179 main.log.error( "Switches in ONOS but not in MN:" )
3180 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3181 main.log.error( str( list2 ) )
3182 else: # list of dpid's match in onos and mn
3183 switchResults = main.TRUE
3184 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003185
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003186 # FIXME: this does not look for extra ports in ONOS, only checks that
3187 # ONOS has what is in MN
3188 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003189
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003190 # PORTS
3191 for name, mnSwitch in switches.iteritems():
3192 mnPorts = []
3193 onosPorts = []
3194 switchResult = main.TRUE
3195 for port in mnSwitch[ 'ports' ]:
3196 if port[ 'enabled' ]:
3197 mnPorts.append( int( port[ 'of_port' ] ) )
3198 for onosSwitch in portsJson:
3199 if onosSwitch[ 'device' ][ 'available' ]:
3200 if onosSwitch[ 'device' ][ 'id' ].replace(
3201 ':',
3202 '' ).replace(
3203 "of",
3204 '' ) == mnSwitch[ 'dpid' ]:
3205 for port in onosSwitch[ 'ports' ]:
3206 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003207 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003208 # onosPorts.append( 'local' )
3209 onosPorts.append( long( uint64( -2 ) ) )
3210 else:
3211 onosPorts.append( int( port[ 'port' ] ) )
3212 break
3213 mnPorts.sort( key=float )
3214 onosPorts.sort( key=float )
3215
3216 mnPortsLog = mnPorts
3217 onosPortsLog = onosPorts
3218 mnPorts = [ x for x in mnPorts ]
3219 onosPorts = [ x for x in onosPorts ]
3220
3221 # TODO: handle other reserved port numbers besides LOCAL
3222 # NOTE: Reserved ports
3223 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3224 # long( uint64( -2 ) )
3225 for mnPort in mnPortsLog:
3226 if mnPort in onosPorts:
3227 # don't set results to true here as this is just one of
3228 # many checks and it might override a failure
3229 mnPorts.remove( mnPort )
3230 onosPorts.remove( mnPort )
3231
3232 # NOTE: OVS reports this as down since there is no link
3233 # So ignoring these for now
3234 # TODO: Come up with a better way of handling these
3235 if 65534 in mnPorts:
3236 mnPorts.remove( 65534 )
3237 if long( uint64( -2 ) ) in onosPorts:
3238 onosPorts.remove( long( uint64( -2 ) ) )
3239 if len( mnPorts ): # the ports of this switch don't match
3240 switchResult = main.FALSE
3241 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3242 if len( onosPorts ): # the ports of this switch don't match
3243 switchResult = main.FALSE
3244 main.log.warn(
3245 "Ports in ONOS but not MN: " +
3246 str( onosPorts ) )
3247 if switchResult == main.FALSE:
3248 main.log.error(
3249 "The list of ports for switch %s(%s) does not match:" %
3250 ( name, mnSwitch[ 'dpid' ] ) )
3251 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3252 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3253 portsResults = portsResults and switchResult
3254 finalResults = finalResults and portsResults
3255 return finalResults
3256 except pexpect.EOF:
3257 main.log.error( self.name + ": EOF exception found" )
3258 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003259 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003260 except Exception:
3261 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003262 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003263
Jon Hallafa8a472015-06-12 14:02:42 -07003264 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003265 """
3266 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003267 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003268
Jon Hallafa8a472015-06-12 14:02:42 -07003269 """
Jon Hall7eb38402015-01-08 17:19:54 -08003270 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003271 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003272 try:
3273 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003274
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003275 mnLinks = []
3276 for l in links:
3277 try:
3278 node1 = switches[ l[ 'node1' ] ]
3279 node2 = switches[ l[ 'node2' ] ]
3280 enabled = True
3281 for port in node1[ 'ports' ]:
3282 if port[ 'of_port' ] == l[ 'port1' ]:
3283 enabled = enabled and port[ 'enabled' ]
3284 for port in node2[ 'ports' ]:
3285 if port[ 'of_port' ] == l[ 'port2' ]:
3286 enabled = enabled and port[ 'enabled' ]
3287 if enabled:
3288 mnLinks.append( l )
3289 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003290 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003291 if 2 * len( mnLinks ) == len( onos ):
3292 linkResults = main.TRUE
3293 else:
3294 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003295 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003296 "Mininet has " + str( len( mnLinks ) ) +
3297 " bidirectional links and ONOS has " +
3298 str( len( onos ) ) + " unidirectional links" )
3299
3300 # iterate through MN links and check if an ONOS link exists in
3301 # both directions
3302 for link in mnLinks:
3303 # TODO: Find a more efficient search method
3304 node1 = None
3305 port1 = None
3306 node2 = None
3307 port2 = None
3308 firstDir = main.FALSE
3309 secondDir = main.FALSE
3310 for swName, switch in switches.iteritems():
3311 if swName == link[ 'node1' ]:
3312 node1 = switch[ 'dpid' ]
3313 for port in switch[ 'ports' ]:
3314 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3315 port1 = port[ 'of_port' ]
3316 if node1 is not None and node2 is not None:
3317 break
3318 if swName == link[ 'node2' ]:
3319 node2 = switch[ 'dpid' ]
3320 for port in switch[ 'ports' ]:
3321 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3322 port2 = port[ 'of_port' ]
3323 if node1 is not None and node2 is not None:
3324 break
3325
3326 for onosLink in onos:
3327 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3328 ":", '' ).replace( "of", '' )
3329 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3330 ":", '' ).replace( "of", '' )
3331 onosPort1 = onosLink[ 'src' ][ 'port' ]
3332 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3333
3334 # check onos link from node1 to node2
3335 if str( onosNode1 ) == str( node1 ) and str(
3336 onosNode2 ) == str( node2 ):
3337 if int( onosPort1 ) == int( port1 ) and int(
3338 onosPort2 ) == int( port2 ):
3339 firstDir = main.TRUE
3340 else:
Jon Hallab611372018-02-21 15:26:05 -08003341 # The right switches, but wrong ports, could be
3342 # another link between these devices, or onos
3343 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003344 main.log.warn(
3345 'The port numbers do not match for ' +
3346 str( link ) +
3347 ' between ONOS and MN. When checking ONOS for ' +
3348 'link %s/%s -> %s/%s' %
3349 ( node1, port1, node2, port2 ) +
3350 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003351 ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
3352 '. This could be another link between these devices' +
3353 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003354
3355 # check onos link from node2 to node1
3356 elif ( str( onosNode1 ) == str( node2 ) and
3357 str( onosNode2 ) == str( node1 ) ):
3358 if ( int( onosPort1 ) == int( port2 )
3359 and int( onosPort2 ) == int( port1 ) ):
3360 secondDir = main.TRUE
3361 else:
Jon Hallab611372018-02-21 15:26:05 -08003362 # The right switches, but wrong ports, could be
3363 # another link between these devices, or onos
3364 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003365 main.log.warn(
3366 'The port numbers do not match for ' +
3367 str( link ) +
3368 ' between ONOS and MN. When checking ONOS for ' +
3369 'link %s/%s -> %s/%s' %
3370 ( node1, port1, node2, port2 ) +
3371 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003372 ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
3373 '. This could be another link between these devices' +
3374 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003375 else: # this is not the link you're looking for
3376 pass
3377 if not firstDir:
3378 main.log.error(
3379 'ONOS does not have the link %s/%s -> %s/%s' %
3380 ( node1, port1, node2, port2 ) )
3381 if not secondDir:
3382 main.log.error(
3383 'ONOS does not have the link %s/%s -> %s/%s' %
3384 ( node2, port2, node1, port1 ) )
3385 linkResults = linkResults and firstDir and secondDir
3386 return linkResults
3387 except pexpect.EOF:
3388 main.log.error( self.name + ": EOF exception found" )
3389 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003390 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003391 except Exception:
3392 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003393 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003394
Jon Hallafa8a472015-06-12 14:02:42 -07003395 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003396 """
Jon Hallafa8a472015-06-12 14:02:42 -07003397 Compare mn and onos Hosts.
3398 Since Mininet hosts are quiet, ONOS will only know of them when they
3399 speak. For this reason, we will only check that the hosts in ONOS
3400 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003401
Jon Hallafa8a472015-06-12 14:02:42 -07003402 Arguments:
3403 hostsJson: parsed json object from the onos hosts api
3404 Returns:
3405 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003406 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003407 try:
3408 hostResults = main.TRUE
3409 for onosHost in hostsJson:
3410 onosMAC = onosHost[ 'mac' ].lower()
3411 match = False
3412 for mnHost, info in hosts.iteritems():
3413 for mnIntf in info[ 'interfaces' ]:
3414 if onosMAC == mnIntf[ 'mac' ].lower():
3415 match = True
3416 for ip in mnIntf[ 'ips' ]:
3417 if ip in onosHost[ 'ipAddresses' ]:
3418 pass # all is well
3419 else:
3420 # misssing ip
3421 main.log.error( "ONOS host " +
3422 onosHost[ 'id' ] +
3423 " has a different IP(" +
3424 str( onosHost[ 'ipAddresses' ] ) +
3425 ") than the Mininet host(" +
3426 str( ip ) +
3427 ")." )
3428 output = json.dumps(
3429 onosHost,
3430 sort_keys=True,
3431 indent=4,
3432 separators=( ',', ': ' ) )
3433 main.log.info( output )
3434 hostResults = main.FALSE
3435 if not match:
3436 hostResults = main.FALSE
3437 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3438 "corresponding Mininet host." )
3439 output = json.dumps( onosHost,
3440 sort_keys=True,
3441 indent=4,
3442 separators=( ',', ': ' ) )
3443 main.log.info( output )
3444 return hostResults
3445 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003446 main.log.error( self.name + ": EOF exception found" )
3447 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003448 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003449 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003450 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003451 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003452
You Wang53dba1e2018-02-02 17:45:44 -08003453 def verifyHostIp( self, hostList=[], prefix="" ):
3454 """
3455 Description:
3456 Verify that all hosts have IP address assigned to them
3457 Optional:
3458 hostList: If specified, verifications only happen to the hosts
3459 in hostList
3460 prefix: at least one of the ip address assigned to the host
3461 needs to have the specified prefix
3462 Returns:
3463 main.TRUE if all hosts have specific IP address assigned;
3464 main.FALSE otherwise
3465 """
3466 try:
You Wang79f5c5b2018-03-14 11:10:44 -07003467 hosts = self.getHosts( getInterfaces=False )
You Wang53dba1e2018-02-02 17:45:44 -08003468 if not hostList:
3469 hostList = hosts.keys()
3470 for hostName in hosts.keys():
3471 if hostName not in hostList:
3472 continue
3473 ipList = []
3474 self.handle.sendline( str( hostName ) + " ip a" )
3475 self.handle.expect( "mininet>" )
3476 ipa = self.handle.before
3477 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3478 ipList += re.findall( ipv4Pattern, ipa )
3479 # It's tricky to make regex for IPv6 addresses and this one is simplified
3480 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})/'
3481 ipList += re.findall( ipv6Pattern, ipa )
3482 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3483 if not ipList:
3484 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3485 else:
3486 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3487 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3488 else:
3489 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3490 hostList.remove( hostName )
3491 return main.FALSE if hostList else main.TRUE
3492 except KeyError:
3493 main.log.exception( self.name + ": host data not as expected: " + hosts )
3494 return None
3495 except pexpect.EOF:
3496 main.log.error( self.name + ": EOF exception found" )
3497 main.log.error( self.name + ": " + self.handle.before )
3498 main.cleanAndExit()
3499 except Exception:
3500 main.log.exception( self.name + ": Uncaught exception" )
3501 return None
3502
Jon Hallafa8a472015-06-12 14:02:42 -07003503 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003504 """
3505 Returns a list of all hosts
3506 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003507 try:
3508 self.handle.sendline( "" )
3509 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003510
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003511 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3512 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003513
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003514 handlePy = self.handle.before
3515 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3516 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003517
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003518 self.handle.sendline( "" )
3519 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003520
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003521 hostStr = handlePy.replace( "]", "" )
3522 hostStr = hostStr.replace( "'", "" )
3523 hostStr = hostStr.replace( "[", "" )
3524 hostStr = hostStr.replace( " ", "" )
3525 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003526
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003527 return hostList
3528 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003529 main.log.error( self.name + ": TIMEOUT exception found" )
3530 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003531 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003532 except pexpect.EOF:
3533 main.log.error( self.name + ": EOF exception found" )
3534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003535 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003536 except Exception:
3537 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003538 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003539
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003540 def getSwitch( self ):
3541 """
3542 Returns a list of all switches
3543 Again, don't ask question just use it...
3544 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003545 try:
3546 # get host list...
3547 hostList = self.getHosts()
3548 # Make host set
3549 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003550
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003551 # Getting all the nodes in mininet
3552 self.handle.sendline( "" )
3553 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003554
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003555 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3556 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003557
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003558 handlePy = self.handle.before
3559 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3560 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003561
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003562 self.handle.sendline( "" )
3563 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003564
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003565 nodesStr = handlePy.replace( "]", "" )
3566 nodesStr = nodesStr.replace( "'", "" )
3567 nodesStr = nodesStr.replace( "[", "" )
3568 nodesStr = nodesStr.replace( " ", "" )
3569 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003570
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003571 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003572 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003573 nodesSet.discard( 'c0' )
3574 nodesSet.discard( 'c1' )
3575 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003576
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003577 switchSet = nodesSet - hostSet
3578 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003579
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003580 return switchList
3581 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003582 main.log.error( self.name + ": TIMEOUT exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003585 except pexpect.EOF:
3586 main.log.error( self.name + ": EOF exception found" )
3587 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003588 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003589 except Exception:
3590 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003591 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003592
You Wangdb8cd0a2016-05-26 15:19:45 -07003593 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3594 """
3595 Return a dictionary which describes the latest Mininet topology data as a
3596 graph.
3597 An example of the dictionary:
3598 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3599 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3600 Each vertex should at least have an 'edges' attribute which describes the
3601 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003602 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003603 list of attributes.
3604 An example of the edges dictionary:
3605 'edges': { vertex2: { 'port': ..., 'weight': ... },
3606 vertex3: { 'port': ..., 'weight': ... } }
3607 If useId == True, dpid/mac will be used instead of names to identify
3608 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3609 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003610 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003611 in topology data.
3612 Note that link or switch that are brought down by 'link x x down' or 'switch
3613 x down' commands still show in the output of Mininet CLI commands such as
3614 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3615 recommended to use delLink() or delSwitch functions to simulate link/switch
3616 down, and addLink() or addSwitch to add them back.
3617 """
3618 graphDict = {}
3619 try:
3620 links = self.getLinks( timeout=timeout )
3621 portDict = {}
3622 if useId:
3623 switches = self.getSwitches()
3624 if includeHost:
3625 hosts = self.getHosts()
3626 for link in links:
3627 # FIXME: support 'includeHost' argument
3628 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3629 continue
3630 nodeName1 = link[ 'node1' ]
3631 nodeName2 = link[ 'node2' ]
3632 port1 = link[ 'port1' ]
3633 port2 = link[ 'port2' ]
3634 # Loop for two nodes
3635 for i in range( 2 ):
3636 # Get port index from OVS
3637 # The index extracted from port name may be inconsistent with ONOS
3638 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003639 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003640 portList = self.getOVSPorts( nodeName1 )
3641 if len( portList ) == 0:
3642 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3643 return None
3644 portDict[ nodeName1 ] = portList
3645 for port in portDict[ nodeName1 ]:
3646 if port[ 'port' ] == port1:
3647 portIndex = port[ 'index' ]
3648 break
3649 if portIndex == -1:
3650 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3651 return None
3652 if useId:
3653 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3654 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3655 else:
3656 node1 = nodeName1
3657 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003658 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003659 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003660 graphDict[ node1 ] = { 'edges': {},
3661 'dpid': switches[ nodeName1 ][ 'dpid' ],
3662 'name': nodeName1,
3663 'ports': switches[ nodeName1 ][ 'ports' ],
3664 'swClass': switches[ nodeName1 ][ 'swClass' ],
3665 'pid': switches[ nodeName1 ][ 'pid' ],
3666 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003667 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003668 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003669 else:
3670 # Assert node2 is not connected to any current links of node1
3671 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003672 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003673 # Swap two nodes/ports
3674 nodeName1, nodeName2 = nodeName2, nodeName1
3675 port1, port2 = port2, port1
3676 return graphDict
3677 except KeyError:
3678 main.log.exception( self.name + ": KeyError exception found" )
3679 return None
3680 except AssertionError:
3681 main.log.exception( self.name + ": AssertionError exception found" )
3682 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003683 except pexpect.EOF:
3684 main.log.error( self.name + ": EOF exception found" )
3685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003686 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003687 except Exception:
3688 main.log.exception( self.name + ": Uncaught exception" )
3689 return None
3690
Devin Lima7cfdbd2017-09-29 15:02:22 -07003691 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003692 """
3693 updates the port address and status information for
3694 each port in mn"""
3695 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003696 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003697 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003698 self.handle.sendline( "" )
3699 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003700
Jon Hall7eb38402015-01-08 17:19:54 -08003701 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003702 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003703
Jon Hall7eb38402015-01-08 17:19:54 -08003704 self.handle.sendline( "" )
3705 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003706
Jon Hallb1290e82014-11-18 16:17:48 -05003707 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003708 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003709 main.log.error( self.name + ": TIMEOUT exception found" )
3710 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003711 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003712 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003713 main.log.error( self.name + ": EOF exception found" )
3714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003715 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003716 except Exception:
3717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003718 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003719
Jon Halld80cc142015-07-06 13:36:05 -07003720 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003721 """
3722 Add vlan tag to a host.
3723 Dependencies:
3724 This class depends on the "vlan" package
3725 $ sudo apt-get install vlan
3726 Configuration:
3727 Load the 8021q module into the kernel
3728 $sudo modprobe 8021q
3729
3730 To make this setup permanent:
3731 $ sudo su -c 'echo "8021q" >> /etc/modules'
3732 """
3733 if self.handle:
3734 try:
Jon Halld80cc142015-07-06 13:36:05 -07003735 # get the ip address of the host
3736 main.log.info( "Get the ip address of the host" )
3737 ipaddr = self.getIPAddress( host )
3738 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003739
Jon Halld80cc142015-07-06 13:36:05 -07003740 # remove IP from interface intf
3741 # Ex: h1 ifconfig h1-eth0 inet 0
3742 main.log.info( "Remove IP from interface " )
3743 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3744 self.handle.sendline( cmd2 )
3745 self.handle.expect( "mininet>" )
3746 response = self.handle.before
3747 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003748
Jon Halld80cc142015-07-06 13:36:05 -07003749 # create VLAN interface
3750 # Ex: h1 vconfig add h1-eth0 100
3751 main.log.info( "Create Vlan" )
3752 cmd3 = host + " vconfig add " + intf + " " + vlan
3753 self.handle.sendline( cmd3 )
3754 self.handle.expect( "mininet>" )
3755 response = self.handle.before
3756 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003757
Jon Halld80cc142015-07-06 13:36:05 -07003758 # assign the host's IP to the VLAN interface
3759 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3760 main.log.info( "Assign the host IP to the vlan interface" )
3761 vintf = intf + "." + vlan
3762 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3763 self.handle.sendline( cmd4 )
3764 self.handle.expect( "mininet>" )
3765 response = self.handle.before
3766 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003767
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003768 # update Mininet node variables
3769 main.log.info( "Update Mininet node variables" )
3770 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3771 self.handle.sendline( cmd5 )
3772 self.handle.expect( "mininet>" )
3773 response = self.handle.before
3774 main.log.info( "====> %s ", response )
3775
3776 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3777 self.handle.sendline( cmd6 )
3778 self.handle.expect( "mininet>" )
3779 response = self.handle.before
3780 main.log.info( "====> %s ", response )
3781
3782 return main.TRUE
3783 except pexpect.TIMEOUT:
3784 main.log.error( self.name + ": TIMEOUT exception found" )
3785 main.log.error( self.name + ": " + self.handle.before )
3786 main.cleanAndExit()
3787 except pexpect.EOF:
3788 main.log.error( self.name + ": EOF exception found" )
3789 main.log.error( self.name + ": " + self.handle.before )
3790 return main.FALSE
3791 except Exception:
3792 main.log.exception( self.name + ": Uncaught exception!" )
3793 return main.FALSE
3794
3795 def removeVLAN( self, host, intf ):
3796 """
3797 Remove vlan tag from a host.
3798 Dependencies:
3799 This class depends on the "vlan" package
3800 $ sudo apt-get install vlan
3801 Configuration:
3802 Load the 8021q module into the kernel
3803 $sudo modprobe 8021q
3804
3805 To make this setup permanent:
3806 $ sudo su -c 'echo "8021q" >> /etc/modules'
3807 """
3808 if self.handle:
3809 try:
3810 # get the ip address of the host
3811 main.log.info( "Get the ip address of the host" )
3812 ipaddr = self.getIPAddress( host )
3813
3814 # remove VLAN interface
3815 # Ex: h1 vconfig rem h1-eth0.100
3816 main.log.info( "Remove Vlan interface" )
3817 cmd2 = host + " vconfig rem " + intf
3818 self.handle.sendline( cmd2 )
3819 self.handle.expect( "mininet>" )
3820 response = self.handle.before
3821 main.log.info( "====> %s ", response )
3822
3823 # assign the host's IP to the original interface
3824 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3825 main.log.info( "Assign the host IP to the original interface" )
3826 original_intf = intf.split(".")[0]
3827 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3828 self.handle.sendline( cmd3 )
3829 self.handle.expect( "mininet>" )
3830 response = self.handle.before
3831 main.log.info( "====> %s ", response )
3832
3833 # update Mininet node variables
3834 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3835 self.handle.sendline( cmd4 )
3836 self.handle.expect( "mininet>" )
3837 response = self.handle.before
3838 main.log.info( "====> %s ", response )
3839
3840 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3841 self.handle.sendline( cmd5 )
3842 self.handle.expect( "mininet>" )
3843 response = self.handle.before
3844 main.log.info( "====> %s ", response )
3845
kaouthera3f13ca22015-05-05 15:01:41 -07003846 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003847 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003848 main.log.error( self.name + ": TIMEOUT exception found" )
3849 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003850 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003851 except pexpect.EOF:
3852 main.log.error( self.name + ": EOF exception found" )
3853 main.log.error( self.name + ": " + self.handle.before )
3854 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003855 except Exception:
3856 main.log.exception( self.name + ": Uncaught exception!" )
3857 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003858
Jon Hall892818c2015-10-20 17:58:34 -07003859 def createHostComponent( self, name ):
3860 """
3861 Creates a new mininet cli component with the same parameters as self.
3862 This new component is intended to be used to login to the hosts created
3863 by mininet.
3864
3865 Arguments:
3866 name - The string of the name of this component. The new component
3867 will be assigned to main.<name> .
3868 In addition, main.<name>.name = str( name )
3869 """
3870 try:
3871 # look to see if this component already exists
3872 getattr( main, name )
3873 except AttributeError:
3874 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003875 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3876 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003877 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003878 except pexpect.EOF:
3879 main.log.error( self.name + ": EOF exception found" )
3880 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003881 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003882 except Exception:
3883 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003884 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003885 else:
3886 # namespace is not clear!
3887 main.log.error( name + " component already exists!" )
3888 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003889 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003890
3891 def removeHostComponent( self, name ):
3892 """
3893 Remove host component
3894 Arguments:
3895 name - The string of the name of the component to delete.
3896 """
3897 try:
3898 # Get host component
3899 component = getattr( main, name )
3900 except AttributeError:
3901 main.log.error( "Component " + name + " does not exist." )
3902 return
3903 try:
3904 # Disconnect from component
3905 component.disconnect()
3906 # Delete component
3907 delattr( main, name )
3908 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003909 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003910 except pexpect.EOF:
3911 main.log.error( self.name + ": EOF exception found" )
3912 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003913 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003914 except Exception:
3915 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003916 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003917
3918 def startHostCli( self, host=None ):
3919 """
3920 Use the mininet m utility to connect to the host's cli
3921 """
3922 # These are fields that can be used by scapy packets. Initialized to None
3923 self.hostIp = None
3924 self.hostMac = None
3925 try:
3926 if not host:
3927 host = self.name
3928 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003929 self.handle.sendline( "cd" )
3930 self.handle.expect( self.hostPrompt )
3931 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003932 self.handle.expect( self.hostPrompt )
3933 return main.TRUE
3934 except pexpect.TIMEOUT:
3935 main.log.exception( self.name + ": Command timed out" )
3936 return main.FALSE
3937 except pexpect.EOF:
3938 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003939 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003940 except Exception:
3941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003942 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003943
YPZhang801d46d2016-08-08 13:26:28 -07003944 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003945 '''
3946
YPZhang801d46d2016-08-08 13:26:28 -07003947 Args:
3948 devicename: switch name
3949 intf: port name on switch
3950 status: up or down
3951
3952 Returns: boolean to show success change status
3953
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003954 '''
YPZhang801d46d2016-08-08 13:26:28 -07003955 if status == "down" or status == "up":
3956 try:
3957 cmd = devicename + " ifconfig " + intf + " " + status
3958 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003959 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003960 return main.TRUE
3961 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003962 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003963 return main.FALSE
3964 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003965 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003966 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003967 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003968 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003969 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003970 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003971 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003972 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003973 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003974 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003975 return main.FALSE
3976
3977
adminbae64d82013-08-01 10:50:15 -07003978if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003979 sys.modules[ __name__ ] = MininetCliDriver()