blob: 08d85057536e2051d61c19eee04b2e292bdd750a [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>',
Jon Hallbc743112018-04-18 11:09:01 -0700205 'Exception|Error',
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700206 '\*\*\*',
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... " )
Jon Hallbc743112018-04-18 11:09:01 -0700237 main.log.debug( self.handle.before + self.handle.after )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700238 return main.FALSE
Jon Hallab611372018-02-21 15:26:05 -0800239 elif i == 5:
240 main.log.error( self.name + ": " + self.handle.before + self.handle.after )
241 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700242 # Why did we hit this part?
243 main.log.error( "startNet did not return correctly" )
244 return main.FASLE
245 else: # if no handle
246 main.log.error( self.name + ": Connection failed to the host " +
247 self.user_name + "@" + self.ip_address )
248 main.log.error( self.name + ": Failed to connect to the Mininet" )
249 return main.FALSE
250 except pexpect.TIMEOUT:
251 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
252 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700253 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700254 except pexpect.EOF:
255 main.log.error( self.name + ": EOF exception found" )
256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700257 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700258 except Exception:
259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700260 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800261
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800262 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700263 try:
264 if topoType == 'tree':
265 # In tree topology, if fanout arg is not given, by default it is 2
266 if fanout is None:
267 fanout = 2
268 k = 0
269 count = 0
270 while( k <= depth - 1 ):
271 count = count + pow( fanout, k )
272 k = k + 1
273 numSwitches = count
274 while( k <= depth - 2 ):
275 # depth-2 gives you only core links and not considering
276 # edge links as seen by ONOS. If all the links including
277 # edge links are required, do depth-1
278 count = count + pow( fanout, k )
279 k = k + 1
280 numLinks = count * fanout
281 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
282 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800283
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700284 elif topoType == 'linear':
285 # In linear topology, if fanout or numHostsPerSw is not given,
286 # by default it is 1
287 if fanout is None:
288 fanout = 1
289 numSwitches = depth
290 numHostsPerSw = fanout
291 totalNumHosts = numSwitches * numHostsPerSw
292 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hallab611372018-02-21 15:26:05 -0800293 main.log.debug( "num_switches for %s(%d,%d) = %d and links=%d" %
294 ( topoType, depth, fanout, numSwitches, numLinks ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700295 topoDict = { "num_switches": int( numSwitches ),
296 "num_corelinks": int( numLinks ) }
297 return topoDict
298 except Exception:
299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700300 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400301
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700303 """
304 Calculate the number of switches and links in a topo."""
305 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700306 try:
307 argList = self.options[ 'arg1' ].split( "," )
308 topoArgList = argList[ 0 ].split( " " )
309 argList = map( int, argList[ 1: ] )
310 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700311
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700312 topoDict = self.numSwitchesNlinks( *topoArgList )
313 return topoDict
314 except Exception:
315 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700316 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400317
GlennRCf07c44a2015-09-18 13:33:46 -0700318 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800319 """
320 Verifies the reachability of the hosts using pingall command.
321 Optional parameter timeout allows you to specify how long to
322 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700323 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700324 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700325 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700326 ping
327 acceptableFailed - Set the number of acceptable failed pings for the
328 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800329 Returns:
330 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700331 otherwise main.FALSE
332 """
333 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700334 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700335 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700336 if self.handle:
337 main.log.info(
338 self.name +
339 ": Checking reachabilty to the hosts using pingall" )
340 response = ""
341 failedPings = 0
342 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700343 cmd = "pingall"
344 if protocol == "IPv6":
345 cmd = "py net.pingAll6()"
346 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700347 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700348 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700349 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700350 pexpect.EOF,
351 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700352 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700353 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700354 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700355 response += self.handle.before
356 break
357 elif i == 1:
358 response += self.handle.before + self.handle.after
359 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700360 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700361 returnValue = main.FALSE
362 if shortCircuit:
363 main.log.error( self.name +
364 ": Aborting pingall - "
365 + str( failedPings ) +
366 " pings failed" )
367 break
Jon Hall390696c2015-05-05 17:13:41 -0700368 if ( time.time() - startTime ) > timeout:
369 returnValue = main.FALSE
370 main.log.error( self.name +
371 ": Aborting pingall - " +
372 "Function took too long " )
373 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700374 elif i == 2:
375 main.log.error( self.name +
376 ": EOF exception found" )
377 main.log.error( self.name + ": " +
378 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700379 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700380 elif i == 3:
381 response += self.handle.before
382 main.log.error( self.name +
383 ": TIMEOUT exception found" )
384 main.log.error( self.name +
385 ": " +
386 str( response ) )
387 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800388 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700389 self.handle.expect( "Interrupt" )
390 self.handle.expect( "mininet>" )
391 break
392 pattern = "Results\:"
393 main.log.info( "Pingall output: " + str( response ) )
394 if re.search( pattern, response ):
395 main.log.info( self.name + ": Pingall finished with "
396 + str( failedPings ) + " failed pings" )
397 return returnValue
398 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700399 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800400 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700401 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700402 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700403 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700404 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700405 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700406 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700407 except pexpect.TIMEOUT:
408 if response:
409 main.log.info( "Pingall output: " + str( response ) )
410 main.log.error( self.name + ": pexpect.TIMEOUT found" )
411 return main.FALSE
412 except pexpect.EOF:
413 main.log.error( self.name + ": EOF exception found" )
414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700416
Jon Hall7eb38402015-01-08 17:19:54 -0800417 def fpingHost( self, **pingParams ):
418 """
419 Uses the fping package for faster pinging...
420 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700421 try:
422 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
423 command = args[ "SRC" ] + \
424 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
425 self.handle.sendline( command )
426 self.handle.expect(
427 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
428 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
429 response = self.handle.before
430 if re.search( ":\s-", response ):
431 main.log.info( self.name + ": Ping fail" )
432 return main.FALSE
433 elif re.search( ":\s\d{1,2}\.\d\d", response ):
434 main.log.info( self.name + ": Ping good!" )
435 return main.TRUE
436 main.log.info( self.name + ": Install fping on mininet machine... " )
437 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700438 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700439 except Exception:
440 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700441 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700442
Jon Hall3b489db2015-10-05 14:38:37 -0700443 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400444 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700445 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700446
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400447 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700448 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700449
450 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400451 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700452
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400453 Returns main.FALSE if one or more of hosts specified
454 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700455 wait = int( wait )
456 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400457
458 try:
459 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700460
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400461 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700462 pingResponse = "IPv4 ping across specified hosts\n"
463 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400464 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700465 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400466 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700467 pingList = hostList[ :listIndex ] + \
468 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700469
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700470 pingResponse += str( str( host ) + " -> " )
GlennRCd10d3cc2015-09-24 12:47:16 -0700471
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400472 for temp in pingList:
473 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700474 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700475 self.handle.sendline( pingCmd )
476 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400477 response = self.handle.before
478 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700479 pingResponse += str( " h" + str( temp[ 1: ] ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400480 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700481 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400482 # One of the host to host pair is unreachable
483 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700484 failedPings += 1
You Wang11f9ead2018-03-21 14:34:59 -0700485 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
GlennRCd10d3cc2015-09-24 12:47:16 -0700486 pingResponse += "\n"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700487 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700488 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700489 except pexpect.TIMEOUT:
490 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800491 response = self.handle.before
492 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700493 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800494 self.handle.expect( "Interrupt" )
495 response += self.handle.before + self.handle.after
496 self.handle.expect( "mininet>" )
497 response += self.handle.before + self.handle.after
498 main.log.debug( response )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700499 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400500 except pexpect.EOF:
501 main.log.error( self.name + ": EOF exception found" )
502 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700503 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700504 except Exception:
505 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700506 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400507
You Wangf19d9f42018-02-23 16:34:19 -0800508 def pingIpv6Hosts( self, hostList, wait=1, acceptableFailed=0 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700509 """
You Wangf19d9f42018-02-23 16:34:19 -0800510 IPv6 ping all hosts in hostList.
511
512 acceptableFailed: max number of acceptable failed pings
Hari Krishna9592fc82015-07-31 15:11:15 -0700513
Jon Hall3b489db2015-10-05 14:38:37 -0700514 Returns main.TRUE if all hosts specified can reach each other
Jon Hall3b489db2015-10-05 14:38:37 -0700515 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700516 """
517 try:
518 main.log.info( "Testing reachability between specified IPv6 hosts" )
519 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700520 wait = int( wait )
521 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700522 pingResponse = "IPv6 Pingall output:\n"
You Wangf19d9f42018-02-23 16:34:19 -0800523 failedPingsTotal = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700524 for host in hostList:
525 listIndex = hostList.index( host )
526 # List of hosts to ping other than itself
527 pingList = hostList[ :listIndex ] + \
528 hostList[ ( listIndex + 1 ): ]
529
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700530 pingResponse += str( str( host ) + " -> " )
GlennRC2cf7d952015-09-11 16:32:13 -0700531
Hari Krishna9592fc82015-07-31 15:11:15 -0700532 for temp in pingList:
533 # Current host pings all other hosts specified
You Wangf19d9f42018-02-23 16:34:19 -0800534 failedPings = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700535 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
You Wangf19d9f42018-02-23 16:34:19 -0800536 while failedPings <= acceptableFailed:
537 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
538 self.handle.sendline( pingCmd )
539 self.handle.expect( "mininet>", timeout=wait + 1 )
540 response = self.handle.before
541 if re.search( ',\s0\%\spacket\sloss', response ):
You Wangba231e72018-03-01 13:18:21 -0800542 pingResponse += " " + str( temp )
543 break
544 else:
545 failedPings += 1
546 time.sleep(1)
547 if failedPings > acceptableFailed:
548 # One of the host to host pair is unreachable
549 pingResponse += " X"
550 isReachable = main.FALSE
551 failedPingsTotal += 1
You Wang11f9ead2018-03-21 14:34:59 -0700552 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
You Wangba231e72018-03-01 13:18:21 -0800553 pingResponse += "\n"
554 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
555 return isReachable
556
557 except pexpect.TIMEOUT:
558 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800559 response = self.handle.before
560 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700561 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800562 self.handle.expect( "Interrupt" )
563 response += self.handle.before + self.handle.after
564 self.handle.expect( "mininet>" )
565 response += self.handle.before + self.handle.after
566 main.log.debug( response )
You Wangba231e72018-03-01 13:18:21 -0800567 return main.FALSE
568 except pexpect.EOF:
569 main.log.error( self.name + ": EOF exception found" )
570 main.log.error( self.name + ": " + self.handle.before )
571 main.cleanAndExit()
572 except Exception:
573 main.log.exception( self.name + ": Uncaught exception!" )
574 main.cleanAndExit()
575
576 def pingallHostsUnidirectional( self, srcList, dstList, ipv6=False, wait=1, acceptableFailed=0 ):
577 """
578 Verify ping from each host in srcList to each host in dstList
579
580 acceptableFailed: max number of acceptable failed pings
581
582 Returns main.TRUE if all src hosts can reach all dst hosts
583 Returns main.FALSE if one or more of src hosts cannot reach one or more of dst hosts
584 """
585 try:
586 main.log.info( "Verifying ping from each src host to each dst host" )
587 isReachable = main.TRUE
588 wait = int( wait )
589 cmd = " ping" + ("6" if ipv6 else "") + " -c 1 -i 1 -W " + str( wait ) + " "
590 pingResponse = "Ping output:\n"
591 failedPingsTotal = 0
592 for host in srcList:
593 pingResponse += str( str( host ) + " -> " )
594 for temp in dstList:
595 failedPings = 0
596 if ipv6:
597 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
598 else:
599 pingCmd = str( host ) + cmd + str( temp )
600 while failedPings <= acceptableFailed:
601 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
602 self.handle.sendline( pingCmd )
603 self.handle.expect( "mininet>", timeout=wait + 1 )
604 response = self.handle.before
605 if re.search( ',\s0\%\spacket\sloss', response ):
606 pingResponse += " " + str( temp )
You Wangf19d9f42018-02-23 16:34:19 -0800607 break
608 else:
609 failedPings += 1
610 time.sleep(1)
611 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700612 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800613 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700614 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800615 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700616 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800617 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700618 return isReachable
619
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700620 except pexpect.TIMEOUT:
621 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800622 response = self.handle.before
623 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700624 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800625 self.handle.expect( "Interrupt" )
626 response += self.handle.before + self.handle.after
627 self.handle.expect( "mininet>" )
628 response += self.handle.before + self.handle.after
629 main.log.debug( response )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700630 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700631 except pexpect.EOF:
632 main.log.error( self.name + ": EOF exception found" )
633 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700634 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700635 except Exception:
636 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700637 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700638
Jon Hall7eb38402015-01-08 17:19:54 -0800639 def pingHost( self, **pingParams ):
640 """
Jon Hall3b489db2015-10-05 14:38:37 -0700641 Ping from one mininet host to another
642 Currently the only supported Params: SRC, TARGET, and WAIT
643 """
644 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700645 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700646 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800647 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700648 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700649 try:
Jon Hall61282e32015-03-19 11:34:11 -0700650 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800651 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700652 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
653 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700654 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800655 main.log.error(
656 self.name +
657 ": timeout when waiting for response from mininet" )
658 main.log.error( "response: " + str( self.handle.before ) )
659 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700660 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800661 main.log.error(
662 self.name +
663 ": timeout when waiting for response from mininet" )
664 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700665 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700666 if re.search( ',\s0\%\spacket\sloss', response ):
667 main.log.info( self.name + ": no packets lost, host is reachable" )
668 return main.TRUE
669 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800670 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700671 self.name +
672 ": PACKET LOST, HOST IS NOT REACHABLE" )
673 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800674 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700677 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700678 except Exception:
679 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700680 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700681
682 def ping6pair( self, **pingParams ):
683 """
GlennRC2cf7d952015-09-11 16:32:13 -0700684 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700685 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000686 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700687 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
688 """
Jon Hall3b489db2015-10-05 14:38:37 -0700689 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700690 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700691 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530692 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700693 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700694 try:
695 main.log.info( "Sending: " + command )
696 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700697 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
698 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700699 if i == 1:
700 main.log.error(
701 self.name +
702 ": timeout when waiting for response from mininet" )
703 main.log.error( "response: " + str( self.handle.before ) )
704 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
705 if i == 1:
706 main.log.error(
707 self.name +
708 ": timeout when waiting for response from mininet" )
709 main.log.error( "response: " + str( self.handle.before ) )
710 response = self.handle.before
711 main.log.info( self.name + ": Ping Response: " + response )
712 if re.search( ',\s0\%\spacket\sloss', response ):
713 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700714 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700715 else:
alisone4121a92016-11-22 16:31:36 -0800716 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700717 self.name +
718 ": PACKET LOST, HOST IS NOT REACHABLE" )
719 return main.FALSE
Hari Krishna012a1c12015-08-25 14:23:58 -0700720 except pexpect.EOF:
721 main.log.error( self.name + ": EOF exception found" )
722 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700723 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700724 except Exception:
725 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700726 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800727
You Wangdb927a52016-02-26 11:03:28 -0800728 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
729 """
730 Description:
731 Ping a set of destination host from host CLI.
732 Logging into a Mininet host CLI is required before calling this funtion.
733 Params:
734 dstIPList is a list of destination ip addresses
735 Returns:
736 main.TRUE if the destination host is reachable
737 main.FALSE otherwise
738 """
739 isReachable = main.TRUE
740 wait = int( wait )
741 cmd = "ping"
742 if IPv6:
743 cmd = cmd + "6"
744 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
745 try:
746 for dstIP in dstIPList:
747 pingCmd = cmd + " " + dstIP
748 self.handle.sendline( pingCmd )
749 i = self.handle.expect( [ self.hostPrompt,
750 '\*\*\* Unknown command: ' + pingCmd,
751 pexpect.TIMEOUT ],
752 timeout=wait + 1 )
753 if i == 0:
754 response = self.handle.before
755 if not re.search( ',\s0\%\spacket\sloss', response ):
756 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
757 isReachable = main.FALSE
758 elif i == 1:
759 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700760 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800761 elif i == 2:
762 main.log.error( self.name + ": timeout when waiting for response" )
763 isReachable = main.FALSE
764 else:
765 main.log.error( self.name + ": unknown response: " + self.handle.before )
766 isReachable = main.FALSE
767 except pexpect.TIMEOUT:
768 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800769 response = self.handle.before
770 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700771 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800772 self.handle.expect( "Interrupt" )
773 response += self.handle.before + self.handle.after
774 self.handle.expect( "mininet>" )
775 response += self.handle.before + self.handle.after
776 main.log.debug( response )
You Wangdb927a52016-02-26 11:03:28 -0800777 isReachable = main.FALSE
778 except pexpect.EOF:
779 main.log.error( self.name + ": EOF exception found" )
780 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700781 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800782 except Exception:
783 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700784 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800785 return isReachable
786
Jon Hall7eb38402015-01-08 17:19:54 -0800787 def checkIP( self, host ):
788 """
789 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700790 try:
791 if self.handle:
792 try:
793 response = self.execute(
794 cmd=host +
795 " ifconfig",
796 prompt="mininet>",
797 timeout=10 )
798 except pexpect.EOF:
799 main.log.error( self.name + ": EOF exception found" )
800 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700801 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700802
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700803 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
804 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
805 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
806 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
807 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
808 "[0-9]|25[0-5]|[0-9]{1,2})"
809 # pattern = "inet addr:10.0.0.6"
810 if re.search( pattern, response ):
811 main.log.info( self.name + ": Host Ip configured properly" )
812 return main.TRUE
813 else:
814 main.log.error( self.name + ": Host IP not found" )
815 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700816 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700817 main.log.error( self.name + ": Connection failed to the host" )
818 except Exception:
819 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700820 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800821
Jon Hall7eb38402015-01-08 17:19:54 -0800822 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800823 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700824 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800825 response = self.execute(
826 cmd="h1 /usr/sbin/sshd -D&",
827 prompt="mininet>",
828 timeout=10 )
829 response = self.execute(
830 cmd="h4 /usr/sbin/sshd -D&",
831 prompt="mininet>",
832 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700833 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800834 vars( self )[ key ] = connectargs[ key ]
835 response = self.execute(
836 cmd="xterm h1 h4 ",
837 prompt="mininet>",
838 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800839 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800840 main.log.error( self.name + ": EOF exception found" )
841 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700842 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700843 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800844 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700845 if self.flag == 0:
846 self.flag = 1
847 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800848 else:
adminbae64d82013-08-01 10:50:15 -0700849 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800850
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700851 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700852 """
853 Moves a host from one switch to another on the fly
854 Note: The intf between host and oldSw when detached
855 using detach(), will still show up in the 'net'
856 cmd, because switch.detach() doesn't affect switch.intfs[]
857 ( which is correct behavior since the interfaces
858 haven't moved ).
859 """
860 if self.handle:
861 try:
862 # Bring link between oldSw-host down
863 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
864 "'," + "'down')"
865 print "cmd1= ", cmd
866 response = self.execute( cmd=cmd,
867 prompt="mininet>",
868 timeout=10 )
869
870 # Determine hostintf and Oldswitchintf
871 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
872 ")[0]"
873 print "cmd2= ", cmd
874 self.handle.sendline( cmd )
875 self.handle.expect( "mininet>" )
876
877 # Determine ip and mac address of the host-oldSw interface
878 cmd = "px ipaddr = hintf.IP()"
879 print "cmd3= ", cmd
880 self.handle.sendline( cmd )
881 self.handle.expect( "mininet>" )
882
883 cmd = "px macaddr = hintf.MAC()"
884 print "cmd3= ", cmd
885 self.handle.sendline( cmd )
886 self.handle.expect( "mininet>" )
887
888 # Detach interface between oldSw-host
889 cmd = "px " + oldSw + ".detach( sintf )"
890 print "cmd4= ", cmd
891 self.handle.sendline( cmd )
892 self.handle.expect( "mininet>" )
893
894 # Add link between host-newSw
895 cmd = "py net.addLink(" + host + "," + newSw + ")"
896 print "cmd5= ", cmd
897 self.handle.sendline( cmd )
898 self.handle.expect( "mininet>" )
899
900 # Determine hostintf and Newswitchintf
901 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
902 ")[0]"
903 print "cmd6= ", cmd
904 self.handle.sendline( cmd )
905 self.handle.expect( "mininet>" )
906
907 # Attach interface between newSw-host
908 cmd = "px " + newSw + ".attach( sintf )"
909 print "cmd3= ", cmd
910 self.handle.sendline( cmd )
911 self.handle.expect( "mininet>" )
912
913 # Set ipaddress of the host-newSw interface
914 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
915 print "cmd7 = ", cmd
916 self.handle.sendline( cmd )
917 self.handle.expect( "mininet>" )
918
919 # Set macaddress of the host-newSw interface
920 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
921 print "cmd8 = ", cmd
922 self.handle.sendline( cmd )
923 self.handle.expect( "mininet>" )
924
925 cmd = "net"
926 print "cmd9 = ", cmd
927 self.handle.sendline( cmd )
928 self.handle.expect( "mininet>" )
929 print "output = ", self.handle.before
930
931 # Determine ipaddress of the host-newSw interface
932 cmd = host + " ifconfig"
933 print "cmd10= ", cmd
934 self.handle.sendline( cmd )
935 self.handle.expect( "mininet>" )
936 print "ifconfig o/p = ", self.handle.before
937
938 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700939
940 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700941 main.log.error( self.name + ": TIMEOUT exception found" )
942 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700943 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700944 except pexpect.EOF:
945 main.log.error( self.name + ": EOF exception found" )
946 main.log.error( self.name + ": " + self.handle.before )
947 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700948 except Exception:
949 main.log.exception( self.name + ": Uncaught exception!" )
950 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700951
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700952 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800953 """
954 Moves a host from one switch to another on the fly
955 Note: The intf between host and oldSw when detached
956 using detach(), will still show up in the 'net'
957 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700958 ( which is correct behavior since the interfaces
959 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800960 """
961 if self.handle:
962 try:
Jon Hall439c8912016-04-15 02:22:03 -0700963 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800964 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700965 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800966 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800967 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800968 response = self.execute( cmd=cmd,
969 prompt="mininet>",
970 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700971
kelvin-onlaba1484582015-02-02 15:46:20 -0800972 # Determine hostintf and Oldswitchintf
973 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800974 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800975 print "cmd2= ", cmd
976 self.handle.sendline( cmd )
977 self.handle.expect( "mininet>" )
978
shahshreya73537862015-02-11 15:15:24 -0800979 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700980 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800981 print "cmd3= ", cmd
982 self.handle.sendline( cmd )
983 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800984
985 cmd = "px macaddr = hintf.MAC()"
986 print "cmd3= ", cmd
987 self.handle.sendline( cmd )
988 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700989
kelvin-onlaba1484582015-02-02 15:46:20 -0800990 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700991 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800992 print "cmd4= ", cmd
993 self.handle.sendline( cmd )
994 self.handle.expect( "mininet>" )
995
996 # Add link between host-newSw
997 cmd = "py net.addLink(" + host + "," + newSw + ")"
998 print "cmd5= ", cmd
999 self.handle.sendline( cmd )
1000 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001001
kelvin-onlaba1484582015-02-02 15:46:20 -08001002 # Determine hostintf and Newswitchintf
1003 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -08001004 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -08001005 print "cmd6= ", cmd
1006 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -07001007 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001008
1009 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001010 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001011 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001012 self.handle.sendline( cmd )
1013 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -08001014
1015 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001016 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001017 print "cmd7 = ", cmd
1018 self.handle.sendline( cmd )
1019 self.handle.expect( "mininet>" )
1020
1021 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001022 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -08001023 print "cmd8 = ", cmd
1024 self.handle.sendline( cmd )
1025 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001026
Jon Hall439c8912016-04-15 02:22:03 -07001027 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001028 print "cmd9 =", cmd
1029 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -07001030 print response
1031 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -07001032 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001033 print ipAddressSearch.group( 1 )
1034 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -07001035 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
1036 print "cmd10 = ", cmd
1037 self.handle.sendline( cmd )
1038 self.handle.expect( "mininet>" )
1039
kelvin-onlaba1484582015-02-02 15:46:20 -08001040 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -07001041 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001042 self.handle.sendline( cmd )
1043 self.handle.expect( "mininet>" )
1044 print "output = ", self.handle.before
1045
1046 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -08001047 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -07001048 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001049 self.handle.sendline( cmd )
1050 self.handle.expect( "mininet>" )
1051 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -07001052
kelvin-onlaba1484582015-02-02 15:46:20 -08001053 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001054 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001055 main.log.error( self.name + ": TIMEOUT exception found" )
1056 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001057 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08001058 except pexpect.EOF:
1059 main.log.error( self.name + ": EOF exception found" )
1060 main.log.error( self.name + ": " + self.handle.before )
1061 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001062 except Exception:
1063 main.log.exception( self.name + ": Uncaught exception!" )
1064 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -08001065
Jon Hall7eb38402015-01-08 17:19:54 -08001066 def changeIP( self, host, intf, newIP, newNetmask ):
1067 """
1068 Changes the ip address of a host on the fly
1069 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001070 if self.handle:
1071 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001072 cmd = host + " ifconfig " + intf + " " + \
1073 newIP + " " + 'netmask' + " " + newNetmask
1074 self.handle.sendline( cmd )
1075 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001076 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001077 main.log.info( "response = " + response )
1078 main.log.info(
1079 "Ip of host " +
1080 host +
1081 " changed to new IP " +
1082 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001083 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001084 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001085 main.log.error( self.name + ": TIMEOUT exception found" )
1086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001087 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001088 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001089 main.log.error( self.name + ": EOF exception found" )
1090 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001091 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001092 except Exception:
1093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001094 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001095
Jon Hall7eb38402015-01-08 17:19:54 -08001096 def changeDefaultGateway( self, host, newGW ):
1097 """
1098 Changes the default gateway of a host
1099 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001100 if self.handle:
1101 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001102 cmd = host + " route add default gw " + newGW
1103 self.handle.sendline( cmd )
1104 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001105 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001106 main.log.info( "response = " + response )
1107 main.log.info(
1108 "Default gateway of host " +
1109 host +
1110 " changed to " +
1111 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001112 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001113 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001114 main.log.error( self.name + ": TIMEOUT exception found" )
1115 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001116 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001117 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001118 main.log.error( self.name + ": EOF exception found" )
1119 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001120 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001121 except Exception:
1122 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001123 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001124
You Wange24d6272018-03-27 21:18:50 -07001125 def addRoute( self, host, dstIP, interface, ipv6=False ):
1126 """
1127 Add a route to host
1128 Ex: h1 route add -host 224.2.0.1 h1-eth0
1129 """
1130 if self.handle:
1131 try:
1132 cmd = str( host )
1133 if ipv6:
1134 cmd += " route -A inet6 add "
1135 else:
1136 cmd += " route add -host "
1137 cmd += str( dstIP ) + " " + str( interface )
1138 self.handle.sendline( cmd )
1139 self.handle.expect( "mininet>" )
1140 response = self.handle.before
1141 main.log.debug( "response = " + response )
1142 return main.TRUE
1143 except pexpect.TIMEOUT:
1144 main.log.error( self.name + ": TIMEOUT exception found" )
1145 main.log.error( self.name + ": " + self.handle.before )
1146 main.cleanAndExit()
1147 except pexpect.EOF:
1148 main.log.error( self.name + ": EOF exception found" )
1149 main.log.error( self.name + ": " + self.handle.before )
1150 return main.FALSE
1151 except Exception:
1152 main.log.exception( self.name + ": Uncaught exception!" )
1153 main.cleanAndExit()
1154
Jon Hall7eb38402015-01-08 17:19:54 -08001155 def addStaticMACAddress( self, host, GW, macaddr ):
1156 """
Jon Hallefbd9792015-03-05 16:11:36 -08001157 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001158 if self.handle:
1159 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001160 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1161 cmd = host + " arp -s " + GW + " " + macaddr
1162 self.handle.sendline( cmd )
1163 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001164 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001165 main.log.info( "response = " + response )
1166 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001167 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001168 GW +
1169 " changed to " +
1170 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001171 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001172 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001173 main.log.error( self.name + ": TIMEOUT exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001175 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001176 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001177 main.log.error( self.name + ": EOF exception found" )
1178 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001179 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001180 except Exception:
1181 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001182 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001183
Jon Hall7eb38402015-01-08 17:19:54 -08001184 def verifyStaticGWandMAC( self, host ):
1185 """
1186 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001187 if self.handle:
1188 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001189 # h1 arp -an
1190 cmd = host + " arp -an "
1191 self.handle.sendline( cmd )
1192 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001193 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001194 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001195 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001196 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001197 main.log.error( self.name + ": TIMEOUT exception found" )
1198 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001199 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001200 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001201 main.log.error( self.name + ": EOF exception found" )
1202 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001203 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001204 except Exception:
1205 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001206 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001207
Jon Hall7eb38402015-01-08 17:19:54 -08001208 def getMacAddress( self, host ):
1209 """
1210 Verifies the host's ip configured or not."""
1211 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001212 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001213 response = self.execute(
1214 cmd=host +
1215 " ifconfig",
1216 prompt="mininet>",
1217 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001218 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001219 main.log.error( self.name + ": EOF exception found" )
1220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001221 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001222 except Exception:
1223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001224 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001225
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001226 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 macAddressSearch = re.search( pattern, response, re.I )
1228 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001229 main.log.info(
1230 self.name +
1231 ": Mac-Address of Host " +
1232 host +
1233 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 macAddress )
1235 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001236 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001237 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001238
Jon Hall7eb38402015-01-08 17:19:54 -08001239 def getInterfaceMACAddress( self, host, interface ):
1240 """
1241 Return the IP address of the interface on the given host"""
1242 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001243 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001244 response = self.execute( cmd=host + " ifconfig " + interface,
1245 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001246 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001247 main.log.error( self.name + ": EOF exception found" )
1248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001249 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001250 except Exception:
1251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001252 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001253
1254 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 macAddressSearch = re.search( pattern, response, re.I )
1256 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001257 main.log.info( "No mac address found in %s" % response )
1258 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001260 main.log.info(
1261 "Mac-Address of " +
1262 host +
1263 ":" +
1264 interface +
1265 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 macAddress )
1267 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001268 else:
1269 main.log.error( "Connection failed to the host" )
1270
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001271 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001272 """
1273 Verifies the host's ip configured or not."""
1274 if self.handle:
1275 try:
1276 response = self.execute(
1277 cmd=host +
1278 " ifconfig",
1279 prompt="mininet>",
1280 timeout=10 )
1281 except pexpect.EOF:
1282 main.log.error( self.name + ": EOF exception found" )
1283 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001284 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001285 except Exception:
1286 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001287 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001288
sathishmad953462015-12-03 17:42:07 +05301289 pattern = ''
1290 if proto == 'IPV4':
1291 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1292 else:
Jon Hall439c8912016-04-15 02:22:03 -07001293 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001294 ipAddressSearch = re.search( pattern, response )
Jon Hall3c910162018-03-07 14:42:16 -08001295 if not ipAddressSearch:
1296 return None
Jon Hall7eb38402015-01-08 17:19:54 -08001297 main.log.info(
1298 self.name +
1299 ": IP-Address of Host " +
1300 host +
1301 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 ipAddressSearch.group( 1 ) )
1303 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001304 else:
1305 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001306
Jon Hall7eb38402015-01-08 17:19:54 -08001307 def getSwitchDPID( self, switch ):
1308 """
1309 return the datapath ID of the switch"""
1310 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001311 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001312 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001313 response = self.execute(
1314 cmd=cmd,
1315 prompt="mininet>",
1316 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001317 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001318 main.log.error( self.name + ": EOF exception found" )
1319 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001320 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001321 except Exception:
1322 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001323 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001324 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001325 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001326 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001327 main.log.info(
1328 "Couldn't find DPID for switch %s, found: %s" %
1329 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001330 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001331 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001332 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001333 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001334
Jon Hall7eb38402015-01-08 17:19:54 -08001335 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001336 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001337 self.handle.sendline( "" )
1338 self.expect( "mininet>" )
1339 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001340 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001341 response = self.execute(
1342 cmd=cmd,
1343 prompt="mininet>",
1344 timeout=10 )
1345 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001346 response = self.handle.before
1347 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001348 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001349 main.log.error( self.name + ": TIMEOUT exception found" )
1350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001351 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001352 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001355 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001356 except Exception:
1357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001358 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001359
Jon Hall7eb38402015-01-08 17:19:54 -08001360 def getInterfaces( self, node ):
1361 """
1362 return information dict about interfaces connected to the node"""
1363 if self.handle:
1364 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001365 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001366 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001367 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001368 response = self.execute(
1369 cmd=cmd,
1370 prompt="mininet>",
1371 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001372 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001373 main.log.error( self.name + ": EOF exception found" )
1374 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001375 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001376 except Exception:
1377 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001378 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001379 return response
1380 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001382
Jon Hall7eb38402015-01-08 17:19:54 -08001383 def dump( self ):
1384 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001385 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 response = self.execute(
1387 cmd='dump',
1388 prompt='mininet>',
1389 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001390 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001391 main.log.error( self.name + ": EOF exception found" )
1392 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001393 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001394 except Exception:
1395 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001396 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001397 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001398
Jon Hall7eb38402015-01-08 17:19:54 -08001399 def intfs( self ):
1400 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001401 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001402 response = self.execute(
1403 cmd='intfs',
1404 prompt='mininet>',
1405 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001406 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001407 main.log.error( self.name + ": EOF exception found" )
1408 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001409 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001410 except Exception:
1411 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001412 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001413 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001414
Jon Hall7eb38402015-01-08 17:19:54 -08001415 def net( self ):
1416 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001417 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001418 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001419 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001420 main.log.error( self.name + ": EOF exception found" )
1421 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001422 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001423 except Exception:
1424 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001425 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001426 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001427
Devin Lima7cfdbd2017-09-29 15:02:22 -07001428 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001429 main.log.info( self.name + ": List network links" )
1430 try:
1431 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001432 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001433 except pexpect.EOF:
1434 main.log.error( self.name + ": EOF exception found" )
1435 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001436 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001437 except Exception:
1438 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001439 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001440 return response
1441
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001442 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001443 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001444 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001445
kelvin-onlab7cce9382015-07-17 10:21:03 -07001446 @parm:
1447 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1448 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001449 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001450 try:
1451 for host1 in hosts:
1452 for host2 in hosts:
1453 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001454 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1455 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001456 except Exception:
1457 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001458 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001459
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001460 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001461 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001462 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1463 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001464
kelvin-onlab7cce9382015-07-17 10:21:03 -07001465 @parm:
1466 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1467 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001468 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001469 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1470 try:
1471 # Setup the mininet command
1472 cmd1 = 'iperf ' + host1 + " " + host2
1473 self.handle.sendline( cmd1 )
1474 outcome = self.handle.expect( "mininet>", timeout )
1475 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001476
kelvin-onlab7cce9382015-07-17 10:21:03 -07001477 # checks if there are results in the mininet response
1478 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001479 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001480 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001481 response = response.split( "\r\n" )
1482 response = response[ len( response )-2 ]
1483 response = response.split( ": " )
1484 response = response[ len( response )-1 ]
1485 response = response.replace( "[", "" )
1486 response = response.replace( "]", "" )
1487 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001488
kelvin-onlab7cce9382015-07-17 10:21:03 -07001489 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001490 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001491
kelvin-onlab7cce9382015-07-17 10:21:03 -07001492 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001493 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001494 if len( bandwidth ) == 2:
1495 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001496 return main.TRUE
1497 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001498 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001499 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001500 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001501 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001502 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001503 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001504 main.log.error( self.name + ": TIMEOUT exception found" )
1505 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001506 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001507 # NOTE: Send ctrl-c to make sure iperf is done
Jon Hall2c5ac942018-03-23 11:26:54 -07001508 self.handle.send( "\x03" )
Jon Hall3b489db2015-10-05 14:38:37 -07001509 self.handle.expect( "Interrupt" )
1510 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001511 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001512 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001513 main.log.error( self.name + ": EOF exception found" )
1514 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001515 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001516 except Exception:
1517 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001518 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001519
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001520 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001521 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1522 try:
1523 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001524 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001525 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001526 outcome1 = self.handle.expect( "mininet>" )
1527 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001528 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001529 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001530 response1 = self.handle.before
1531 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001532 print response1, response2
1533 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001534 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001535 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001536 return main.TRUE
1537 else:
1538 main.log.error( self.name + ": iperf test failed" )
1539 return main.FALSE
1540 except pexpect.TIMEOUT:
1541 main.log.error( self.name + ": TIMEOUT exception found" )
1542 main.log.error( self.name + " response: " + repr( self.handle.before ) )
Jon Hall2c5ac942018-03-23 11:26:54 -07001543 self.handle.send( "\x03" )
Jon Hall439c8912016-04-15 02:22:03 -07001544 self.handle.expect( "Interrupt" )
1545 self.handle.expect( "mininet>" )
1546 return main.FALSE
1547 except pexpect.EOF:
1548 main.log.error( self.name + ": EOF exception found" )
1549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001550 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001551 except Exception:
1552 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001553 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001554
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001555 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001556 '''
GlennRC61321f22015-07-16 13:36:54 -07001557 Runs the iperfudp function with a given set of hosts and specified
1558 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001559
GlennRC61321f22015-07-16 13:36:54 -07001560 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001561 bandwidth: the targeted bandwidth, in megabits ('M')
1562 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001563 try:
1564 for host1 in hosts:
1565 for host2 in hosts:
1566 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001567 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1568 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001569 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001570 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001571 return main.FALSE
1572 except Exception:
1573 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001574 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001575
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001576 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001577 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001578 Creates an iperf UDP test with a specific bandwidth.
1579 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001580
kelvin-onlab7cce9382015-07-17 10:21:03 -07001581 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001582 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1583 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001584 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001585 try:
1586 # setup the mininet command
1587 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001588 self.handle.sendline( cmd )
1589 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001590 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001591
kelvin-onlab7cce9382015-07-17 10:21:03 -07001592 # check if there are in results in the mininet response
1593 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001594 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001595 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001596 response = response.split( "\r\n" )
1597 response = response[ len( response )-2 ]
1598 response = response.split( ": " )
1599 response = response[ len( response )-1 ]
1600 response = response.replace( "[", "" )
1601 response = response.replace( "]", "" )
1602 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001603
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001604 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001605
kelvin-onlab7cce9382015-07-17 10:21:03 -07001606 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001607 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001608 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001609 # if one entry is blank then something is wrong
1610 for item in mnBandwidth:
1611 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001612 main.log.error( self.name + ": Could not parse iperf output" )
1613 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001614 return main.FALSE
1615 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001616 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001617 return main.TRUE
1618 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001619 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001620 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001621
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001622 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001623 main.log.error( self.name + ": TIMEOUT exception found" )
1624 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001625 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001626 except pexpect.EOF:
1627 main.log.error( self.name + ": EOF exception found" )
1628 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001629 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001630 except Exception:
1631 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001632 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001633
Jon Hall7eb38402015-01-08 17:19:54 -08001634 def nodes( self ):
1635 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001636 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001637 response = self.execute(
1638 cmd='nodes',
1639 prompt='mininet>',
1640 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001641 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001642 main.log.error( self.name + ": EOF exception found" )
1643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001644 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001645 except Exception:
1646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001647 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001648 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001649
Jon Hall7eb38402015-01-08 17:19:54 -08001650 def pingpair( self ):
1651 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001652 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001653 response = self.execute(
1654 cmd='pingpair',
1655 prompt='mininet>',
1656 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001657 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001658 main.log.error( self.name + ": EOF exception found" )
1659 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001660 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001661 except Exception:
1662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001663 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001664
Jon Hall7eb38402015-01-08 17:19:54 -08001665 if re.search( ',\s0\%\spacket\sloss', response ):
1666 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001667 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001668 else:
alisone4121a92016-11-22 16:31:36 -08001669 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001670 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001671
Jon Hall7eb38402015-01-08 17:19:54 -08001672 def link( self, **linkargs ):
1673 """
GlennRCed771242016-01-13 17:02:47 -08001674 Bring link( s ) between two nodes up or down
1675 """
Jon Hall6094a362014-04-11 14:46:56 -07001676 try:
GlennRCed771242016-01-13 17:02:47 -08001677 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1678 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1679 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1680 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1681
1682 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1683 cmd = "link {} {} {}".format( end1, end2, option )
1684 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001685 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001686 response = self.handle.before
1687 main.log.info( response )
Jon Hallab611372018-02-21 15:26:05 -08001688 if "not in network" in response:
1689 main.log.error( self.name + ": Could not find one of the endpoints of the link" )
1690 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08001691 return main.TRUE
1692 except pexpect.TIMEOUT:
1693 main.log.exception( self.name + ": Command timed out" )
1694 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001695 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001696 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001700 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001701
pingping-lin8244a3b2015-09-16 13:36:56 -07001702 def switch( self, **switchargs ):
1703 """
1704 start/stop a switch
1705 """
1706 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1707 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1708 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1709 command = "switch " + str( sw ) + " " + str( option )
1710 main.log.info( command )
1711 try:
1712 self.handle.sendline( command )
1713 self.handle.expect( "mininet>" )
1714 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001715 main.log.error( self.name + ": TIMEOUT exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001717 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001718 except pexpect.EOF:
1719 main.log.error( self.name + ": EOF exception found" )
1720 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001721 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001722 return main.TRUE
1723
pingping-lin5bb663b2015-09-24 11:47:50 -07001724 def node( self, nodeName, commandStr ):
1725 """
1726 Carry out a command line on a given node
1727 @parm:
1728 nodeName: the node name in Mininet testbed
1729 commandStr: the command line will be carried out on the node
1730 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1731 """
1732 command = str( nodeName ) + " " + str( commandStr )
1733 main.log.info( command )
1734
1735 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001736 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001737 if re.search( "Unknown command", response ):
1738 main.log.warn( response )
1739 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001740 if re.search( "Permission denied", response ):
1741 main.log.warn( response )
1742 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001743 except pexpect.EOF:
1744 main.log.error( self.name + ": EOF exception found" )
1745 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001746 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001747 main.log.info( " response is :" )
1748 main.log.info( response )
1749 return response
1750
Jon Hall7eb38402015-01-08 17:19:54 -08001751 def yank( self, **yankargs ):
1752 """
1753 yank a mininet switch interface to a host"""
1754 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001755 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001756 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1757 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001758 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001759 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001760 response = self.execute(
1761 cmd=command,
1762 prompt="mininet>",
1763 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001764 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001765 main.log.error( self.name + ": EOF exception found" )
1766 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001767 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001768 except Exception:
1769 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001770 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001771 return main.TRUE
1772
Jon Hall7eb38402015-01-08 17:19:54 -08001773 def plug( self, **plugargs ):
1774 """
1775 plug the yanked mininet switch interface to a switch"""
1776 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001777 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001778 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1779 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001780 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001781 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001782 response = self.execute(
1783 cmd=command,
1784 prompt="mininet>",
1785 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001786 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001787 main.log.error( self.name + ": EOF exception found" )
1788 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001789 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001790 except Exception:
1791 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001792 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001793 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001794
Jon Hall7eb38402015-01-08 17:19:54 -08001795 def dpctl( self, **dpctlargs ):
1796 """
1797 Run dpctl command on all switches."""
1798 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001799 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001800 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1801 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1802 command = "dpctl " + cmd + " " + str( cmdargs )
1803 try:
1804 response = self.execute(
1805 cmd=command,
1806 prompt="mininet>",
1807 timeout=10 )
1808 except pexpect.EOF:
1809 main.log.error( self.name + ": EOF exception found" )
1810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001811 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001812 except Exception:
1813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001814 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001815 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001816
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001818 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001819 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001820 try:
1821 fileInput = path + '/lib/Mininet/INSTALL'
1822 version = super( Mininet, self ).getVersion()
1823 pattern = 'Mininet\s\w\.\w\.\w\w*'
1824 for line in open( fileInput, 'r' ).readlines():
1825 result = re.match( pattern, line )
1826 if result:
1827 version = result.group( 0 )
1828 return version
1829 except Exception:
1830 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001831 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001832
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001834 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001835 Parameters:
1836 sw: The name of an OVS switch. Example "s1"
1837 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001838 The output of the command from the mininet cli
1839 or main.FALSE on timeout"""
1840 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001841 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001842 response = self.execute(
1843 cmd=command,
1844 prompt="mininet>",
1845 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001846 if response:
Jon Hallab611372018-02-21 15:26:05 -08001847 if "no bridge named" in response:
1848 main.log.error( self.name + ": Error in getSwController: " +
1849 self.handle.before )
1850 return main.FALSE
1851 else:
1852 return response
admin2a9548d2014-06-17 14:08:07 -07001853 else:
1854 return main.FALSE
1855 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001856 main.log.error( self.name + ": EOF exception found" )
1857 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001858 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001859 except Exception:
1860 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001861 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001862
Charles Chan029be652015-08-24 01:46:10 +08001863 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001864 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001865 Description:
1866 Assign switches to the controllers ( for ovs use only )
1867 Required:
1868 sw - Name of the switch. This can be a list or a string.
1869 ip - Ip addresses of controllers. This can be a list or a string.
1870 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001871 port - ONOS use port 6653, if no list of ports is passed, then
1872 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001873 ptcp - ptcp number, This can be a string or a list that has
1874 the same length as switch. This is optional and not required
1875 when using ovs switches.
1876 NOTE: If switches and ptcp are given in a list type they should have the
1877 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1878 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001879
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001880 Return:
1881 Returns main.TRUE if mininet correctly assigned switches to
1882 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001883 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001884 """
1885 assignResult = main.TRUE
1886 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001887 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001888 command = "sh ovs-vsctl set-controller "
1889 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001890 try:
1891 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001892 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001893 if isinstance( port, types.StringType ) or \
1894 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001895 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001896 elif isinstance( port, types.ListType ):
1897 main.log.error( self.name + ": Only one controller " +
1898 "assigned and a list of ports has" +
1899 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001900 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001901 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001902 main.log.error( self.name + ": Invalid controller port " +
1903 "number. Please specify correct " +
1904 "controller port" )
1905 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001906
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001907 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001908 if isinstance( port, types.StringType ) or \
1909 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001910 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001911 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1912 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001913 elif isinstance( port, types.ListType ):
1914 if ( len( ip ) != len( port ) ):
1915 main.log.error( self.name + ": Port list = " +
1916 str( len( port ) ) +
1917 "should be the same as controller" +
1918 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001919 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001920 else:
1921 onosIp = ""
1922 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001923 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1924 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001925 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001926 main.log.error( self.name + ": Invalid controller port " +
1927 "number. Please specify correct " +
1928 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001929 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001930 else:
1931 main.log.error( self.name + ": Invalid ip address" )
1932 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001933
1934 if isinstance( sw, types.StringType ):
1935 command += sw + " "
1936 if ptcp:
1937 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001938 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001939 elif isinstance( ptcp, types.ListType ):
1940 main.log.error( self.name + ": Only one switch is " +
1941 "being set and multiple PTCP is " +
1942 "being passed " )
1943 else:
1944 main.log.error( self.name + ": Invalid PTCP" )
1945 ptcp = ""
1946 command += onosIp
1947 commandList.append( command )
1948
1949 elif isinstance( sw, types.ListType ):
1950 if ptcp:
1951 if isinstance( ptcp, types.ListType ):
1952 if len( ptcp ) != len( sw ):
1953 main.log.error( self.name + ": PTCP length = " +
1954 str( len( ptcp ) ) +
1955 " is not the same as switch" +
1956 " length = " +
1957 str( len( sw ) ) )
1958 return main.FALSE
1959 else:
1960 for switch, ptcpNum in zip( sw, ptcp ):
1961 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001962 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001963 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001964 tempCmd += onosIp
1965 commandList.append( tempCmd )
1966 else:
1967 main.log.error( self.name + ": Invalid PTCP" )
1968 return main.FALSE
1969 else:
1970 for switch in sw:
1971 tempCmd = "sh ovs-vsctl set-controller "
1972 tempCmd += switch + " " + onosIp
1973 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001974 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001975 main.log.error( self.name + ": Invalid switch type " )
1976 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001977
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001978 for cmd in commandList:
1979 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001980 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
Jon Hallab611372018-02-21 15:26:05 -08001981 if "no bridge named" in self.handle.before:
1982 main.log.error( self.name + ": Error in assignSwController: " +
1983 self.handle.before )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001984 except pexpect.TIMEOUT:
1985 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1986 return main.FALSE
1987 except pexpect.EOF:
1988 main.log.error( self.name + ": EOF exception found" )
1989 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001990 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001991 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001992 except pexpect.EOF:
1993 main.log.error( self.name + ": EOF exception found" )
1994 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001995 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001996 except Exception:
1997 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001998 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001999
kelvin-onlabd3b64892015-01-20 13:26:24 -08002000 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002001 """
2002 Removes the controller target from sw"""
2003 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07002004 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002005 response = self.execute(
2006 cmd=command,
2007 prompt="mininet>",
2008 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08002009 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002010 main.log.error( self.name + ": EOF exception found" )
2011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002012 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002013 except Exception:
2014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002015 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002016 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002017 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07002018
kelvin-onlabd3b64892015-01-20 13:26:24 -08002019 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002020 """
Jon Hallb1290e82014-11-18 16:17:48 -05002021 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002022 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002023 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002024 NOTE: cannot currently specify what type of switch
2025 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002026 sw = name of the new switch as a string
2027 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05002028 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08002029 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002030 """
2031 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002032 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05002033 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002034 response = self.execute(
2035 cmd=command,
2036 prompt="mininet>",
2037 timeout=10 )
2038 if re.search( "already exists!", response ):
2039 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002040 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002041 elif re.search( "Error", response ):
2042 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002043 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002044 elif re.search( "usage:", response ):
2045 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002046 return main.FALSE
2047 else:
2048 return main.TRUE
2049 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002050 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07002051 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002052 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002053 except Exception:
2054 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002055 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002056
kelvin-onlabd3b64892015-01-20 13:26:24 -08002057 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002058 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002059 delete a switch from the mininet topology
2060 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002061 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002062 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002063 sw = name of the switch as a string
2064 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002065 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002066 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002067 response = self.execute(
2068 cmd=command,
2069 prompt="mininet>",
2070 timeout=10 )
2071 if re.search( "no switch named", response ):
2072 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002073 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002074 elif re.search( "Error", response ):
2075 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002076 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002077 elif re.search( "usage:", response ):
2078 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002079 return main.FALSE
2080 else:
2081 return main.TRUE
2082 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002083 main.log.error( self.name + ": EOF exception found" )
2084 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002085 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002086 except Exception:
2087 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002088 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002089
You Wangdb8cd0a2016-05-26 15:19:45 -07002090 def getSwitchRandom( self, timeout=60, nonCut=True ):
2091 """
2092 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002093 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002094 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002095 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002096 it just randomly returns one switch from all current switches in
2097 Mininet.
2098 Returns the name of the chosen switch.
2099 """
2100 import random
2101 candidateSwitches = []
2102 try:
2103 if not nonCut:
2104 switches = self.getSwitches( timeout=timeout )
2105 assert len( switches ) != 0
2106 for switchName in switches.keys():
2107 candidateSwitches.append( switchName )
2108 else:
2109 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002110 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002111 return None
2112 self.graph.update( graphDict )
2113 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002114 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002115 return None
2116 elif len( candidateSwitches ) == 0:
2117 main.log.info( self.name + ": No candidate switch for deletion" )
2118 return None
2119 else:
2120 switch = random.sample( candidateSwitches, 1 )
2121 return switch[ 0 ]
2122 except KeyError:
2123 main.log.exception( self.name + ": KeyError exception found" )
2124 return None
2125 except AssertionError:
2126 main.log.exception( self.name + ": AssertionError exception found" )
2127 return None
2128 except Exception:
2129 main.log.exception( self.name + ": Uncaught exception" )
2130 return None
2131
2132 def delSwitchRandom( self, timeout=60, nonCut=True ):
2133 """
2134 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002135 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002136 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002137 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002138 otherwise it just randomly delete one switch from all current
2139 switches in Mininet.
2140 Returns the name of the deleted switch
2141 """
2142 try:
2143 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002144 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002145 return None
2146 else:
2147 deletionResult = self.delSwitch( switch )
2148 if deletionResult:
2149 return switch
2150 else:
2151 return None
2152 except Exception:
2153 main.log.exception( self.name + ": Uncaught exception" )
2154 return None
2155
kelvin-onlabd3b64892015-01-20 13:26:24 -08002156 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002157 """
2158 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002159 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002160 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002161 NOTE: cannot currently specify what type of link
2162 required params:
2163 node1 = the string node name of the first endpoint of the link
2164 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002165 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002166 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002167 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002168 response = self.execute(
2169 cmd=command,
2170 prompt="mininet>",
2171 timeout=10 )
2172 if re.search( "doesnt exist!", response ):
2173 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002174 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002175 elif re.search( "Error", response ):
2176 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002177 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002178 elif re.search( "usage:", response ):
2179 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002180 return main.FALSE
2181 else:
2182 return main.TRUE
2183 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002184 main.log.error( self.name + ": EOF exception found" )
2185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002186 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002187 except Exception:
2188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002189 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002190
kelvin-onlabd3b64892015-01-20 13:26:24 -08002191 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002192 """
2193 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002194 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002195 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002196 required params:
2197 node1 = the string node name of the first endpoint of the link
2198 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002199 returns: main.FALSE on an error, else main.TRUE
2200 """
Jon Hallffb386d2014-11-21 13:43:38 -08002201 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002202 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002203 response = self.execute(
2204 cmd=command,
2205 prompt="mininet>",
2206 timeout=10 )
2207 if re.search( "no node named", response ):
2208 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002209 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002210 elif re.search( "Error", response ):
2211 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002212 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002213 elif re.search( "usage:", response ):
2214 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002215 return main.FALSE
2216 else:
2217 return main.TRUE
2218 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002219 main.log.error( self.name + ": EOF exception found" )
2220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002221 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002222 except Exception:
2223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002224 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002225
You Wangdb8cd0a2016-05-26 15:19:45 -07002226 def getLinkRandom( self, timeout=60, nonCut=True ):
2227 """
2228 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002229 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002230 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002231 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002232 it just randomly returns one link from all current links in
2233 Mininet.
2234 Returns the link as a list, e.g. [ 's1', 's2' ]
2235 """
2236 import random
2237 candidateLinks = []
2238 try:
2239 if not nonCut:
2240 links = self.getLinks( timeout=timeout )
2241 assert len( links ) != 0
2242 for link in links:
2243 # Exclude host-switch link
2244 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2245 continue
2246 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2247 else:
2248 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002249 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002250 return None
2251 self.graph.update( graphDict )
2252 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002253 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002254 return None
2255 elif len( candidateLinks ) == 0:
2256 main.log.info( self.name + ": No candidate link for deletion" )
2257 return None
2258 else:
2259 link = random.sample( candidateLinks, 1 )
2260 return link[ 0 ]
2261 except KeyError:
2262 main.log.exception( self.name + ": KeyError exception found" )
2263 return None
2264 except AssertionError:
2265 main.log.exception( self.name + ": AssertionError exception found" )
2266 return None
2267 except Exception:
2268 main.log.exception( self.name + ": Uncaught exception" )
2269 return None
2270
2271 def delLinkRandom( self, timeout=60, nonCut=True ):
2272 """
2273 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002274 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002275 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002276 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002277 otherwise it just randomly delete one link from all current links
2278 in Mininet.
2279 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2280 """
2281 try:
2282 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002283 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002284 return None
2285 else:
2286 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2287 if deletionResult:
2288 return link
2289 else:
2290 return None
2291 except Exception:
2292 main.log.exception( self.name + ": Uncaught exception" )
2293 return None
2294
kelvin-onlabd3b64892015-01-20 13:26:24 -08002295 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002296 """
Jon Hallb1290e82014-11-18 16:17:48 -05002297 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002298 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002299 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002300 NOTE: cannot currently specify what type of host
2301 required params:
2302 hostname = the string hostname
2303 optional key-value params
2304 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002305 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002306 """
2307 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002308 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002309 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002310 response = self.execute(
2311 cmd=command,
2312 prompt="mininet>",
2313 timeout=10 )
2314 if re.search( "already exists!", response ):
2315 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002316 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002317 elif re.search( "doesnt exists!", response ):
2318 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002319 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002320 elif re.search( "Error", response ):
2321 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002322 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002323 elif re.search( "usage:", response ):
2324 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002325 return main.FALSE
2326 else:
2327 return main.TRUE
2328 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002329 main.log.error( self.name + ": EOF exception found" )
2330 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002331 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002332 except Exception:
2333 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002334 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002335
kelvin-onlabd3b64892015-01-20 13:26:24 -08002336 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002337 """
2338 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002339 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002340 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002341 NOTE: this uses a custom mn function
2342 required params:
2343 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002344 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002345 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002346 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002347 response = self.execute(
2348 cmd=command,
2349 prompt="mininet>",
2350 timeout=10 )
2351 if re.search( "no host named", response ):
2352 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002353 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002354 elif re.search( "Error", response ):
2355 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002356 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002357 elif re.search( "usage:", response ):
2358 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002359 return main.FALSE
2360 else:
2361 return main.TRUE
2362 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002363 main.log.error( self.name + ": EOF exception found" )
2364 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002365 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002366 except Exception:
2367 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002368 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002369
Jon Hall7eb38402015-01-08 17:19:54 -08002370 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002371 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002372 Called at the end of the test to stop the mininet and
2373 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002374 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002375 try:
2376 self.handle.sendline( '' )
2377 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2378 timeout=2 )
2379 response = main.TRUE
2380 if i == 0:
2381 response = self.stopNet()
2382 elif i == 1:
2383 return main.TRUE
2384 # print "Disconnecting Mininet"
2385 if self.handle:
2386 self.handle.sendline( "exit" )
2387 self.handle.expect( "exit" )
2388 self.handle.expect( "(.*)" )
2389 else:
2390 main.log.error( "Connection failed to the host" )
2391 return response
2392 except pexpect.EOF:
2393 main.log.error( self.name + ": EOF exception found" )
2394 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002395 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002396 except Exception:
2397 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002398 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002399
Devin Lima7cfdbd2017-09-29 15:02:22 -07002400 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002401 """
Jon Hall21270ac2015-02-16 17:59:55 -08002402 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002403 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002404 main.FALSE if the pexpect handle does not exist.
2405
Jon Halld61331b2015-02-17 16:35:47 -08002406 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002407 """
Jon Halld61331b2015-02-17 16:35:47 -08002408 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002409 response = ''
2410 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002411 try:
Jon Halld80cc142015-07-06 13:36:05 -07002412 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002413 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002414 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002415 pexpect.EOF,
2416 pexpect.TIMEOUT ],
2417 timeout )
2418 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002419 main.log.info( "Exiting mininet.." )
2420 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002421 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002422 prompt=self.prompt,
2423 timeout=exitTimeout )
2424 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002425 self.handle.sendline( "sudo mn -c" )
2426 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002427
Jeremyd9e4eb12016-04-13 12:09:06 -07002428 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002429 main.log.info( " Mininet trying to exit while not " +
2430 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002431 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002432 elif i == 2:
2433 main.log.error( "Something went wrong exiting mininet" )
2434 elif i == 3: # timeout
2435 main.log.error( "Something went wrong exiting mininet " +
2436 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002437
You Wang18db8592018-04-02 13:52:03 -07002438 self.handle.sendline( "" )
2439 self.handle.expect( self.prompt )
2440 self.handle.sendline( "sudo killall -9 dhclient dhcpd zebra bgpd" )
2441
Hari Krishnab35c6d02015-03-18 11:13:51 -07002442 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002443 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002444 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002445 self.handle.sendline(
2446 "sudo kill -9 \`ps -ef | grep \"" +
2447 fileName +
2448 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002449 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002450 main.log.error( self.name + ": TIMEOUT exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002452 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002453 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002454 main.log.error( self.name + ": EOF exception found" )
2455 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002456 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002457 except Exception:
2458 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002459 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002460 else:
2461 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002462 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002463 return response
2464
YPZhang26a139e2016-04-25 14:01:55 -07002465 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002466 """
2467 Description:
2468 Sends arp message from mininet host for hosts discovery
2469 Required:
2470 host - hosts name
2471 Optional:
2472 ip - ip address that does not exist in the network so there would
2473 be no reply.
2474 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002475 if ethDevice:
2476 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002477 cmd = srcHost + " arping -c1 "
2478 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002479 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 -07002480 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002481 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002482 if output:
2483 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002484 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002485 i = self.handle.expect( [ "mininet>", "arping: " ] )
2486 if i == 0:
2487 return main.TRUE
2488 elif i == 1:
2489 response = self.handle.before + self.handle.after
2490 self.handle.expect( "mininet>" )
2491 response += self.handle.before + self.handle.after
2492 main.log.warn( "Error sending arping, output was: " +
2493 response )
2494 return main.FALSE
2495 except pexpect.TIMEOUT:
2496 main.log.error( self.name + ": TIMEOUT exception found" )
2497 main.log.warn( self.handle.before )
2498 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002499 except pexpect.EOF:
2500 main.log.error( self.name + ": EOF exception found" )
2501 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002502 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002503 except Exception:
2504 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002505 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002506
Jon Hall7eb38402015-01-08 17:19:54 -08002507 def decToHex( self, num ):
2508 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002509
Jon Hall7eb38402015-01-08 17:19:54 -08002510 def getSwitchFlowCount( self, switch ):
2511 """
2512 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002513 if self.handle:
2514 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2515 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002516 response = self.execute(
2517 cmd=cmd,
2518 prompt="mininet>",
2519 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002520 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002521 main.log.error( self.name + ": EOF exception found" )
2522 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002523 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002524 except Exception:
2525 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002526 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002527 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002528 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002529 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002530 main.log.info(
2531 "Couldn't find flows on switch %s, found: %s" %
2532 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002533 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002534 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002535 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002536 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002537
Jon Hall9ed8f372016-02-24 17:34:07 -08002538 def checkFlows( self, sw, dumpFormat=None ):
2539 if dumpFormat:
2540 command = "sh ovs-ofctl -F " + \
2541 dumpFormat + " dump-flows " + str( sw )
2542 else:
2543 command = "sh ovs-ofctl dump-flows " + str( sw )
2544 try:
2545 response = self.execute(
2546 cmd=command,
2547 prompt="mininet>",
2548 timeout=10 )
2549 return response
2550 except pexpect.EOF:
2551 main.log.error( self.name + ": EOF exception found" )
2552 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002553 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002554 except Exception:
2555 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002556 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002557
GlennRC68467eb2015-11-16 18:01:01 -08002558 def flowTableComp( self, flowTable1, flowTable2 ):
2559 # This function compares the selctors and treatments of each flow
2560 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002561 assert flowTable1, "flowTable1 is empty or None"
2562 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002563 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002564 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002565 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002566 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002567 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2568 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002569 for field in dFields:
2570 try:
2571 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002572 except KeyError:
2573 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002574 try:
2575 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002576 except KeyError:
2577 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002578 for i in range( len( flowTable1 ) ):
2579 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002580 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002581 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002582 returnValue = main.FALSE
2583 break
2584 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002585 except AssertionError:
2586 main.log.exception( "Nothing to compare" )
2587 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002588 except Exception:
2589 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002590 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002591
GlennRC528ad292015-11-12 10:38:18 -08002592 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002593 '''
GlennRC956ea742015-11-05 16:14:15 -08002594 Discription: Parses flows into json format.
2595 NOTE: this can parse any string thats separated with commas
2596 Arguments:
2597 Required:
2598 flows: a list of strings that represnt flows
2599 Optional:
2600 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2601 debug: prints out the final result
2602 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002603 '''
GlennRC528ad292015-11-12 10:38:18 -08002604 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002605 try:
2606 for flow in flowTable:
2607 jsonFlow = {}
2608 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002609 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002610 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002611 for i in range( len( parsedFlow ) ):
2612 item = parsedFlow[ i ]
2613 if item[ 0 ] == " ":
2614 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002615 # grab the selector and treatment from the parsed flow
2616 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002617 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002618 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002619 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002620 index = 0
2621 # parse the flags
2622 # NOTE: This only parses one flag
2623 flag = {}
2624 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002625 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002626 index += 1
2627 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002628 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002629 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002630 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002631 # the priority is stuck in the selecter so put it back
2632 # in the flow
Jon Hallab611372018-02-21 15:26:05 -08002633 if 'priority' in sel[0]:
2634 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002635 # parse selector
2636 criteria = []
2637 for item in sel:
2638 # this is the type of the packet e.g. "arp"
2639 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002640 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002641 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002642 field = item.split( "=" )
2643 criteria.append( { field[ 0 ]: field[ 1 ] } )
2644 selector = { "selector": { "criteria": sorted( criteria ) } }
2645 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002646 # get rid of the action part e.g. "action=output:2"
2647 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002648 treat = treat.split( "=" )
2649 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002650 # parse treatment
2651 action = []
2652 for item in treat:
Jon Hallab611372018-02-21 15:26:05 -08002653 if ":" in item:
2654 field = item.split( ":" )
2655 action.append( { field[ 0 ]: field[ 1 ] } )
2656 else:
2657 main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
2658 item ) )
You Wang91c37cf2016-05-23 09:39:42 -07002659 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002660 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002661 # parse the rest of the flow
2662 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002663 field = item.split( "=" )
2664 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002665 # add the treatment and the selector to the json flow
2666 jsonFlow.update( selector )
2667 jsonFlow.update( treatment )
2668 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002669
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002670 if debug:
2671 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002672
You Wang91c37cf2016-05-23 09:39:42 -07002673 # add the json flow to the json flow table
2674 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002675
You Wang91c37cf2016-05-23 09:39:42 -07002676 return jsonFlowTable
2677
2678 except IndexError:
2679 main.log.exception( self.name + ": IndexError found" )
2680 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002681 except pexpect.EOF:
2682 main.log.error( self.name + ": EOF exception found" )
2683 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002684 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002685 except Exception:
2686 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002687 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002688
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002689 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002690 '''
2691 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002692 Each element is a flow.
2693 Arguments:
2694 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002695 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002696 a list of switches.
2697 Optional:
2698 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2699 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002700 '''
GlennRC956ea742015-11-05 16:14:15 -08002701 try:
2702 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002703 if isinstance( sw, list ):
2704 switches.extend( sw )
2705 else:
2706 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002707
2708 flows = []
2709 for s in switches:
2710 cmd = "sh ovs-ofctl dump-flows " + s
2711
GlennRC528ad292015-11-12 10:38:18 -08002712 if "1.0" == version:
2713 cmd += " -F OpenFlow10-table_id"
2714 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002715 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002716
2717 main.log.info( "Sending: " + cmd )
2718 self.handle.sendline( cmd )
2719 self.handle.expect( "mininet>" )
2720 response = self.handle.before
2721 response = response.split( "\r\n" )
2722 # dump the first two elements and the last
2723 # the first element is the command that was sent
2724 # the second is the table header
2725 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002726 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002727 flows.extend( response )
2728
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002729 if debug:
2730 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002731
GlennRC528ad292015-11-12 10:38:18 -08002732 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002733
GlennRC956ea742015-11-05 16:14:15 -08002734 except pexpect.EOF:
2735 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002736 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002737 except Exception:
2738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002739 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002740
2741 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002742 '''
GlennRC956ea742015-11-05 16:14:15 -08002743 Discription: Checks whether the ID provided matches a flow ID in Mininet
2744 Arguments:
2745 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002746 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002747 a list of switches.
2748 flowId: the flow ID in hex format. Can also be a list of IDs
2749 Optional:
2750 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2751 debug: prints out the final result
2752 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2753 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002754 '''
GlennRC956ea742015-11-05 16:14:15 -08002755 try:
2756 main.log.info( "Getting flows from Mininet" )
2757 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002758 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002759 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002760
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002761 if debug:
2762 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002763
2764 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002765 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002766 result = False
2767 for f in flows:
2768 if flowId in f.get( 'cookie' ):
2769 result = True
2770 break
2771 # flowId is a list
2772 else:
2773 result = True
2774 # Get flow IDs from Mininet
2775 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2776 # Save the IDs that are not in Mininet
2777 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2778
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002779 if debug:
2780 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002781
2782 # Print out the IDs that are not in Mininet
2783 if absentIds:
2784 main.log.warn( "Absent ids: {}".format( absentIds ) )
2785 result = False
2786
2787 return main.TRUE if result else main.FALSE
2788
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002789 except pexpect.EOF:
2790 main.log.error( self.name + ": EOF exception found" )
2791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002792 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002793 except Exception:
2794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002795 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002796
Charles Chan029be652015-08-24 01:46:10 +08002797 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002798 """
Jon Hallefbd9792015-03-05 16:11:36 -08002799 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002800 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002801 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002802 self.handle.sendline( "" )
2803 self.handle.expect( "mininet>" )
2804 self.handle.sendline(
2805 "sh sudo tcpdump -n -i " +
2806 intf +
2807 " " +
2808 port +
2809 " -w " +
2810 filename.strip() +
2811 " &" )
2812 self.handle.sendline( "" )
2813 i = self.handle.expect( [ 'No\ssuch\device',
2814 'listening\son',
2815 pexpect.TIMEOUT,
2816 "mininet>" ],
2817 timeout=10 )
2818 main.log.warn( self.handle.before + self.handle.after )
2819 self.handle.sendline( "" )
2820 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002821 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002822 main.log.error(
2823 self.name +
2824 ": tcpdump - No such device exists. " +
2825 "tcpdump attempted on: " +
2826 intf )
admin2a9548d2014-06-17 14:08:07 -07002827 return main.FALSE
2828 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002829 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002830 return main.TRUE
2831 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002832 main.log.error(
2833 self.name +
2834 ": tcpdump command timed out! Check interface name," +
2835 " given interface was: " +
2836 intf )
admin2a9548d2014-06-17 14:08:07 -07002837 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002838 elif i == 3:
2839 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002840 return main.TRUE
2841 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002842 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002843 return main.FALSE
2844 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002845 main.log.error( self.name + ": EOF exception found" )
2846 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002847 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002848 except Exception:
2849 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002850 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002851
kelvin-onlabd3b64892015-01-20 13:26:24 -08002852 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002853 """
2854 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002855 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002856 self.handle.sendline( "sh sudo pkill tcpdump" )
2857 self.handle.expect( "mininet>" )
2858 self.handle.sendline( "" )
2859 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002860 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002861 main.log.error( self.name + ": TIMEOUT exception found" )
2862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002863 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002864 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002865 main.log.error( self.name + ": EOF exception found" )
2866 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002867 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002868 except Exception:
2869 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002870 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002871
Jon Halld80cc142015-07-06 13:36:05 -07002872 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002873 """
2874 Read ports from a Mininet switch.
2875
2876 Returns a json structure containing information about the
2877 ports of the given switch.
2878 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002879 try:
2880 response = self.getInterfaces( nodeName )
2881 # TODO: Sanity check on response. log if no such switch exists
2882 ports = []
2883 for line in response.split( "\n" ):
2884 if not line.startswith( "name=" ):
2885 continue
2886 portVars = {}
2887 for var in line.split( "," ):
2888 key, value = var.split( "=" )
2889 portVars[ key ] = value
2890 isUp = portVars.pop( 'enabled', "True" )
2891 isUp = "True" in isUp
2892 if verbose:
2893 main.log.info( "Reading switch port %s(%s)" %
2894 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2895 mac = portVars[ 'mac' ]
2896 if mac == 'None':
2897 mac = None
2898 ips = []
2899 ip = portVars[ 'ip' ]
2900 if ip == 'None':
2901 ip = None
2902 ips.append( ip )
2903 name = portVars[ 'name' ]
2904 if name == 'None':
2905 name = None
2906 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2907 if name == 'lo':
2908 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2909 else:
2910 portNo = re.search( portRe, name ).group( 'port' )
2911 ports.append( { 'of_port': portNo,
2912 'mac': str( mac ).replace( '\'', '' ),
2913 'name': name,
2914 'ips': ips,
2915 'enabled': isUp } )
2916 return ports
2917 except pexpect.EOF:
2918 main.log.error( self.name + ": EOF exception found" )
2919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002920 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002921 except Exception:
2922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002923 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002924
You Wangdb8cd0a2016-05-26 15:19:45 -07002925 def getOVSPorts( self, nodeName ):
2926 """
2927 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2928
2929 Returns a list of dictionaries containing information about each
2930 port of the given switch.
2931 """
2932 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2933 try:
2934 response = self.execute(
2935 cmd=command,
2936 prompt="mininet>",
2937 timeout=10 )
2938 ports = []
2939 if response:
2940 for line in response.split( "\n" ):
2941 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2942 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002943 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002944 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2945 result = re.search( pattern, line )
2946 if result:
2947 index = result.group( 'index' )
2948 name = result.group( 'name' )
2949 # This port number is extracted from port name
2950 port = result.group( 'port' )
2951 mac = result.group( 'mac' )
2952 ports.append( { 'index': index,
2953 'name': name,
2954 'port': port,
2955 'mac': mac } )
2956 return ports
2957 except pexpect.EOF:
2958 main.log.error( self.name + ": EOF exception found" )
2959 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002960 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002961 except Exception:
2962 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002963 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002964
Devin Lima7cfdbd2017-09-29 15:02:22 -07002965 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002966 """
2967 Read switches from Mininet.
2968
2969 Returns a dictionary whose keys are the switch names and the value is
2970 a dictionary containing information about the switch.
2971 """
Jon Halla22481b2015-07-28 17:46:01 -07002972 # NOTE: To support new Mininet switch classes, just append the new
2973 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002974
Jon Halla22481b2015-07-28 17:46:01 -07002975 # Regex patterns to parse 'dump' output
2976 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002977 # <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 -07002978 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002979 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2980 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2981 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002982 try:
2983 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2984 swRE = r"<(?P<class>" + switchClasses + r")" +\
2985 r"(?P<options>\{.*\})?\s" +\
2986 r"(?P<name>[^:]+)\:\s" +\
2987 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2988 r"\spid=(?P<pid>(\d)+)"
2989 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002990 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002991 output = {}
2992 dump = self.dump().split( "\n" )
2993 for line in dump:
2994 result = re.search( swRE, line, re.I )
2995 if result:
2996 name = result.group( 'name' )
2997 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2998 pid = result.group( 'pid' )
2999 swClass = result.group( 'class' )
3000 options = result.group( 'options' )
3001 if verbose:
3002 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
3003 ports = self.getPorts( name )
3004 output[ name ] = { "dpid": dpid,
3005 "ports": ports,
3006 "swClass": swClass,
3007 "pid": pid,
3008 "options": options }
3009 return output
3010 except pexpect.EOF:
3011 main.log.error( self.name + ": EOF exception found" )
3012 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003013 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003014 except Exception:
3015 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003016 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003017
Jon Hallab611372018-02-21 15:26:05 -08003018 def getHosts( self, verbose=False, updateTimeout=1000,
3019 hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
3020 getInterfaces=True ):
Jon Hallafa8a472015-06-12 14:02:42 -07003021 """
3022 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08003023 Optional:
3024 hostClass: it is used to match the class of the mininet host. It
3025 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07003026 Returns a dictionary whose keys are the host names and the value is
3027 a dictionary containing information about the host.
3028 """
3029 # Regex patterns to parse dump output
3030 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07003031 # <Host h1: pid=12725>
3032 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3033 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3034 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003035 # NOTE: Does not correctly match hosts with multi-links
3036 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3037 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003038 try:
You Wang53dba1e2018-02-02 17:45:44 -08003039 if not isinstance( hostClass, types.ListType ):
3040 hostClass = [ str( hostClass ) ]
3041 classRE = "(" + "|".join([c for c in hostClass]) + ")"
Jon Hallab611372018-02-21 15:26:05 -08003042 ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
3043 ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
3044 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003045 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07003046 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003047 # Get mininet dump
3048 dump = self.dump().split( "\n" )
3049 hosts = {}
3050 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08003051 result = re.search( hostRE, line )
3052 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003053 name = result.group( 'name' )
3054 interfaces = []
You Wang79f5c5b2018-03-14 11:10:44 -07003055 if getInterfaces:
3056 response = self.getInterfaces( name )
3057 # Populate interface info
3058 for line in response.split( "\n" ):
3059 if line.startswith( "name=" ):
3060 portVars = {}
3061 for var in line.split( "," ):
3062 key, value = var.split( "=" )
3063 portVars[ key ] = value
3064 isUp = portVars.pop( 'enabled', "True" )
3065 isUp = "True" in isUp
3066 if verbose:
3067 main.log.info( "Reading host port %s(%s)" %
3068 ( portVars[ 'name' ],
3069 portVars[ 'mac' ] ) )
3070 mac = portVars[ 'mac' ]
3071 if mac == 'None':
3072 mac = None
3073 ips = []
3074 ip = portVars[ 'ip' ]
3075 if ip == 'None':
3076 ip = None
3077 ips.append( ip )
3078 intfName = portVars[ 'name' ]
3079 if name == 'None':
3080 name = None
3081 interfaces.append( {
3082 "name": intfName,
3083 "ips": ips,
3084 "mac": str( mac ),
3085 "isUp": isUp } )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003086 hosts[ name ] = { "interfaces": interfaces }
3087 return hosts
3088 except pexpect.EOF:
3089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003091 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003092 except Exception:
3093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003094 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003095
Devin Lima7cfdbd2017-09-29 15:02:22 -07003096 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003097 """
3098 Gathers information about current Mininet links. These links may not
3099 be up if one of the ports is down.
3100
3101 Returns a list of dictionaries with link endpoints.
3102
3103 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003104 { 'node1': str( node1 name )
3105 'node2': str( node2 name )
3106 'port1': str( port1 of_port )
3107 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003108 Note: The port number returned is the eth#, not necessarily the of_port
3109 number. In Mininet, for OVS switch, these should be the same. For
3110 hosts, this is just the eth#.
3111 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003112 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003113 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003114 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003115
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003116 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003117 # s1-eth3<->s2-eth1 (OK OK)
3118 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003119 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3120 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3121 links = []
3122 for line in response:
3123 match = re.search( linkRE, line )
3124 if match:
3125 node1 = match.group( 'node1' )
3126 node2 = match.group( 'node2' )
3127 port1 = match.group( 'port1' )
3128 port2 = match.group( 'port2' )
3129 links.append( { 'node1': node1,
3130 'node2': node2,
3131 'port1': port1,
3132 'port2': port2 } )
3133 return links
3134
3135 except pexpect.EOF:
3136 main.log.error( self.name + ": EOF exception found" )
3137 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003138 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003139 except Exception:
3140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003141 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003142
3143 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003144 """
3145 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003146 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003147
Jon Hallafa8a472015-06-12 14:02:42 -07003148 Dependencies:
3149 1. numpy - "sudo pip install numpy"
3150 """
3151 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003152 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003153 try:
3154 mnDPIDs = []
3155 for swName, switch in switches.iteritems():
3156 mnDPIDs.append( switch[ 'dpid' ].lower() )
3157 mnDPIDs.sort()
3158 if switchesJson == "": # if rest call fails
3159 main.log.error(
3160 self.name +
3161 ".compareSwitches(): Empty JSON object given from ONOS" )
3162 return main.FALSE
3163 onos = switchesJson
3164 onosDPIDs = []
3165 for switch in onos:
3166 if switch[ 'available' ]:
3167 onosDPIDs.append(
3168 switch[ 'id' ].replace(
3169 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003170 '' ).replace(
3171 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003172 '' ).lower() )
3173 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003174
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003175 if mnDPIDs != onosDPIDs:
3176 switchResults = main.FALSE
3177 main.log.error( "Switches in MN but not in ONOS:" )
3178 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3179 main.log.error( str( list1 ) )
3180 main.log.error( "Switches in ONOS but not in MN:" )
3181 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3182 main.log.error( str( list2 ) )
3183 else: # list of dpid's match in onos and mn
3184 switchResults = main.TRUE
3185 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003186
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003187 # FIXME: this does not look for extra ports in ONOS, only checks that
3188 # ONOS has what is in MN
3189 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003190
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003191 # PORTS
3192 for name, mnSwitch in switches.iteritems():
3193 mnPorts = []
3194 onosPorts = []
3195 switchResult = main.TRUE
3196 for port in mnSwitch[ 'ports' ]:
3197 if port[ 'enabled' ]:
3198 mnPorts.append( int( port[ 'of_port' ] ) )
3199 for onosSwitch in portsJson:
3200 if onosSwitch[ 'device' ][ 'available' ]:
3201 if onosSwitch[ 'device' ][ 'id' ].replace(
3202 ':',
3203 '' ).replace(
3204 "of",
3205 '' ) == mnSwitch[ 'dpid' ]:
3206 for port in onosSwitch[ 'ports' ]:
3207 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003208 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003209 # onosPorts.append( 'local' )
3210 onosPorts.append( long( uint64( -2 ) ) )
3211 else:
3212 onosPorts.append( int( port[ 'port' ] ) )
3213 break
3214 mnPorts.sort( key=float )
3215 onosPorts.sort( key=float )
3216
3217 mnPortsLog = mnPorts
3218 onosPortsLog = onosPorts
3219 mnPorts = [ x for x in mnPorts ]
3220 onosPorts = [ x for x in onosPorts ]
3221
3222 # TODO: handle other reserved port numbers besides LOCAL
3223 # NOTE: Reserved ports
3224 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3225 # long( uint64( -2 ) )
3226 for mnPort in mnPortsLog:
3227 if mnPort in onosPorts:
3228 # don't set results to true here as this is just one of
3229 # many checks and it might override a failure
3230 mnPorts.remove( mnPort )
3231 onosPorts.remove( mnPort )
3232
3233 # NOTE: OVS reports this as down since there is no link
3234 # So ignoring these for now
3235 # TODO: Come up with a better way of handling these
3236 if 65534 in mnPorts:
3237 mnPorts.remove( 65534 )
3238 if long( uint64( -2 ) ) in onosPorts:
3239 onosPorts.remove( long( uint64( -2 ) ) )
3240 if len( mnPorts ): # the ports of this switch don't match
3241 switchResult = main.FALSE
3242 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3243 if len( onosPorts ): # the ports of this switch don't match
3244 switchResult = main.FALSE
3245 main.log.warn(
3246 "Ports in ONOS but not MN: " +
3247 str( onosPorts ) )
3248 if switchResult == main.FALSE:
3249 main.log.error(
3250 "The list of ports for switch %s(%s) does not match:" %
3251 ( name, mnSwitch[ 'dpid' ] ) )
3252 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3253 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3254 portsResults = portsResults and switchResult
3255 finalResults = finalResults and portsResults
3256 return finalResults
3257 except pexpect.EOF:
3258 main.log.error( self.name + ": EOF exception found" )
3259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003260 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003261 except Exception:
3262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003263 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003264
Jon Hallafa8a472015-06-12 14:02:42 -07003265 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003266 """
3267 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003268 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003269
Jon Hallafa8a472015-06-12 14:02:42 -07003270 """
Jon Hall7eb38402015-01-08 17:19:54 -08003271 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003272 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003273 try:
3274 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003275
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003276 mnLinks = []
3277 for l in links:
3278 try:
3279 node1 = switches[ l[ 'node1' ] ]
3280 node2 = switches[ l[ 'node2' ] ]
3281 enabled = True
3282 for port in node1[ 'ports' ]:
3283 if port[ 'of_port' ] == l[ 'port1' ]:
3284 enabled = enabled and port[ 'enabled' ]
3285 for port in node2[ 'ports' ]:
3286 if port[ 'of_port' ] == l[ 'port2' ]:
3287 enabled = enabled and port[ 'enabled' ]
3288 if enabled:
3289 mnLinks.append( l )
3290 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003291 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003292 if 2 * len( mnLinks ) == len( onos ):
3293 linkResults = main.TRUE
3294 else:
3295 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003296 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003297 "Mininet has " + str( len( mnLinks ) ) +
3298 " bidirectional links and ONOS has " +
3299 str( len( onos ) ) + " unidirectional links" )
3300
3301 # iterate through MN links and check if an ONOS link exists in
3302 # both directions
3303 for link in mnLinks:
3304 # TODO: Find a more efficient search method
3305 node1 = None
3306 port1 = None
3307 node2 = None
3308 port2 = None
3309 firstDir = main.FALSE
3310 secondDir = main.FALSE
3311 for swName, switch in switches.iteritems():
3312 if swName == link[ 'node1' ]:
3313 node1 = switch[ 'dpid' ]
3314 for port in switch[ 'ports' ]:
3315 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3316 port1 = port[ 'of_port' ]
3317 if node1 is not None and node2 is not None:
3318 break
3319 if swName == link[ 'node2' ]:
3320 node2 = switch[ 'dpid' ]
3321 for port in switch[ 'ports' ]:
3322 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3323 port2 = port[ 'of_port' ]
3324 if node1 is not None and node2 is not None:
3325 break
3326
3327 for onosLink in onos:
3328 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3329 ":", '' ).replace( "of", '' )
3330 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3331 ":", '' ).replace( "of", '' )
3332 onosPort1 = onosLink[ 'src' ][ 'port' ]
3333 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3334
3335 # check onos link from node1 to node2
3336 if str( onosNode1 ) == str( node1 ) and str(
3337 onosNode2 ) == str( node2 ):
3338 if int( onosPort1 ) == int( port1 ) and int(
3339 onosPort2 ) == int( port2 ):
3340 firstDir = main.TRUE
3341 else:
Jon Hallab611372018-02-21 15:26:05 -08003342 # The right switches, but wrong ports, could be
3343 # another link between these devices, or onos
3344 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003345 main.log.warn(
3346 'The port numbers do not match for ' +
3347 str( link ) +
3348 ' between ONOS and MN. When checking ONOS for ' +
3349 'link %s/%s -> %s/%s' %
3350 ( node1, port1, node2, port2 ) +
3351 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003352 ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
3353 '. This could be another link between these devices' +
3354 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003355
3356 # check onos link from node2 to node1
3357 elif ( str( onosNode1 ) == str( node2 ) and
3358 str( onosNode2 ) == str( node1 ) ):
3359 if ( int( onosPort1 ) == int( port2 )
3360 and int( onosPort2 ) == int( port1 ) ):
3361 secondDir = main.TRUE
3362 else:
Jon Hallab611372018-02-21 15:26:05 -08003363 # The right switches, but wrong ports, could be
3364 # another link between these devices, or onos
3365 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003366 main.log.warn(
3367 'The port numbers do not match for ' +
3368 str( link ) +
3369 ' between ONOS and MN. When checking ONOS for ' +
3370 'link %s/%s -> %s/%s' %
3371 ( node1, port1, node2, port2 ) +
3372 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003373 ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
3374 '. This could be another link between these devices' +
3375 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003376 else: # this is not the link you're looking for
3377 pass
3378 if not firstDir:
3379 main.log.error(
3380 'ONOS does not have the link %s/%s -> %s/%s' %
3381 ( node1, port1, node2, port2 ) )
3382 if not secondDir:
3383 main.log.error(
3384 'ONOS does not have the link %s/%s -> %s/%s' %
3385 ( node2, port2, node1, port1 ) )
3386 linkResults = linkResults and firstDir and secondDir
3387 return linkResults
3388 except pexpect.EOF:
3389 main.log.error( self.name + ": EOF exception found" )
3390 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003391 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003392 except Exception:
3393 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003394 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003395
Jon Hallafa8a472015-06-12 14:02:42 -07003396 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003397 """
Jon Hallafa8a472015-06-12 14:02:42 -07003398 Compare mn and onos Hosts.
3399 Since Mininet hosts are quiet, ONOS will only know of them when they
3400 speak. For this reason, we will only check that the hosts in ONOS
3401 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003402
Jon Hallafa8a472015-06-12 14:02:42 -07003403 Arguments:
3404 hostsJson: parsed json object from the onos hosts api
3405 Returns:
3406 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003407 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003408 try:
3409 hostResults = main.TRUE
3410 for onosHost in hostsJson:
3411 onosMAC = onosHost[ 'mac' ].lower()
3412 match = False
3413 for mnHost, info in hosts.iteritems():
3414 for mnIntf in info[ 'interfaces' ]:
3415 if onosMAC == mnIntf[ 'mac' ].lower():
3416 match = True
3417 for ip in mnIntf[ 'ips' ]:
3418 if ip in onosHost[ 'ipAddresses' ]:
3419 pass # all is well
3420 else:
3421 # misssing ip
3422 main.log.error( "ONOS host " +
3423 onosHost[ 'id' ] +
3424 " has a different IP(" +
3425 str( onosHost[ 'ipAddresses' ] ) +
3426 ") than the Mininet host(" +
3427 str( ip ) +
3428 ")." )
3429 output = json.dumps(
3430 onosHost,
3431 sort_keys=True,
3432 indent=4,
3433 separators=( ',', ': ' ) )
3434 main.log.info( output )
3435 hostResults = main.FALSE
3436 if not match:
3437 hostResults = main.FALSE
3438 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3439 "corresponding Mininet host." )
3440 output = json.dumps( onosHost,
3441 sort_keys=True,
3442 indent=4,
3443 separators=( ',', ': ' ) )
3444 main.log.info( output )
3445 return hostResults
3446 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003447 main.log.error( self.name + ": EOF exception found" )
3448 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003449 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003450 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003451 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003452 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003453
You Wang53dba1e2018-02-02 17:45:44 -08003454 def verifyHostIp( self, hostList=[], prefix="" ):
3455 """
3456 Description:
3457 Verify that all hosts have IP address assigned to them
3458 Optional:
3459 hostList: If specified, verifications only happen to the hosts
3460 in hostList
3461 prefix: at least one of the ip address assigned to the host
3462 needs to have the specified prefix
3463 Returns:
3464 main.TRUE if all hosts have specific IP address assigned;
3465 main.FALSE otherwise
3466 """
3467 try:
You Wang79f5c5b2018-03-14 11:10:44 -07003468 hosts = self.getHosts( getInterfaces=False )
You Wang53dba1e2018-02-02 17:45:44 -08003469 if not hostList:
3470 hostList = hosts.keys()
3471 for hostName in hosts.keys():
3472 if hostName not in hostList:
3473 continue
3474 ipList = []
3475 self.handle.sendline( str( hostName ) + " ip a" )
3476 self.handle.expect( "mininet>" )
3477 ipa = self.handle.before
3478 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3479 ipList += re.findall( ipv4Pattern, ipa )
3480 # It's tricky to make regex for IPv6 addresses and this one is simplified
3481 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})/'
3482 ipList += re.findall( ipv6Pattern, ipa )
3483 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3484 if not ipList:
3485 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3486 else:
3487 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3488 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3489 else:
3490 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3491 hostList.remove( hostName )
3492 return main.FALSE if hostList else main.TRUE
3493 except KeyError:
3494 main.log.exception( self.name + ": host data not as expected: " + hosts )
3495 return None
3496 except pexpect.EOF:
3497 main.log.error( self.name + ": EOF exception found" )
3498 main.log.error( self.name + ": " + self.handle.before )
3499 main.cleanAndExit()
3500 except Exception:
3501 main.log.exception( self.name + ": Uncaught exception" )
3502 return None
3503
Jon Hallafa8a472015-06-12 14:02:42 -07003504 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003505 """
3506 Returns a list of all hosts
3507 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003508 try:
3509 self.handle.sendline( "" )
3510 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003511
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003512 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3513 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003514
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003515 handlePy = self.handle.before
3516 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3517 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003518
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003519 self.handle.sendline( "" )
3520 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003521
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003522 hostStr = handlePy.replace( "]", "" )
3523 hostStr = hostStr.replace( "'", "" )
3524 hostStr = hostStr.replace( "[", "" )
3525 hostStr = hostStr.replace( " ", "" )
3526 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003527
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003528 return hostList
3529 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003530 main.log.error( self.name + ": TIMEOUT exception found" )
3531 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003532 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003533 except pexpect.EOF:
3534 main.log.error( self.name + ": EOF exception found" )
3535 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003536 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003537 except Exception:
3538 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003539 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003540
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003541 def getSwitch( self ):
3542 """
3543 Returns a list of all switches
3544 Again, don't ask question just use it...
3545 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003546 try:
3547 # get host list...
3548 hostList = self.getHosts()
3549 # Make host set
3550 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003551
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003552 # Getting all the nodes in mininet
3553 self.handle.sendline( "" )
3554 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003555
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003556 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3557 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003558
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003559 handlePy = self.handle.before
3560 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3561 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003562
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003563 self.handle.sendline( "" )
3564 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003565
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003566 nodesStr = handlePy.replace( "]", "" )
3567 nodesStr = nodesStr.replace( "'", "" )
3568 nodesStr = nodesStr.replace( "[", "" )
3569 nodesStr = nodesStr.replace( " ", "" )
3570 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003571
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003572 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003573 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003574 nodesSet.discard( 'c0' )
3575 nodesSet.discard( 'c1' )
3576 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003577
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003578 switchSet = nodesSet - hostSet
3579 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003580
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003581 return switchList
3582 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003583 main.log.error( self.name + ": TIMEOUT exception found" )
3584 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003585 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003586 except pexpect.EOF:
3587 main.log.error( self.name + ": EOF exception found" )
3588 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003589 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003590 except Exception:
3591 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003592 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003593
You Wangdb8cd0a2016-05-26 15:19:45 -07003594 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3595 """
3596 Return a dictionary which describes the latest Mininet topology data as a
3597 graph.
3598 An example of the dictionary:
3599 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3600 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3601 Each vertex should at least have an 'edges' attribute which describes the
3602 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003603 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003604 list of attributes.
3605 An example of the edges dictionary:
3606 'edges': { vertex2: { 'port': ..., 'weight': ... },
3607 vertex3: { 'port': ..., 'weight': ... } }
3608 If useId == True, dpid/mac will be used instead of names to identify
3609 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3610 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003611 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003612 in topology data.
3613 Note that link or switch that are brought down by 'link x x down' or 'switch
3614 x down' commands still show in the output of Mininet CLI commands such as
3615 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3616 recommended to use delLink() or delSwitch functions to simulate link/switch
3617 down, and addLink() or addSwitch to add them back.
3618 """
3619 graphDict = {}
3620 try:
3621 links = self.getLinks( timeout=timeout )
3622 portDict = {}
3623 if useId:
3624 switches = self.getSwitches()
3625 if includeHost:
3626 hosts = self.getHosts()
3627 for link in links:
3628 # FIXME: support 'includeHost' argument
3629 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3630 continue
3631 nodeName1 = link[ 'node1' ]
3632 nodeName2 = link[ 'node2' ]
3633 port1 = link[ 'port1' ]
3634 port2 = link[ 'port2' ]
3635 # Loop for two nodes
3636 for i in range( 2 ):
3637 # Get port index from OVS
3638 # The index extracted from port name may be inconsistent with ONOS
3639 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003640 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003641 portList = self.getOVSPorts( nodeName1 )
3642 if len( portList ) == 0:
3643 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3644 return None
3645 portDict[ nodeName1 ] = portList
3646 for port in portDict[ nodeName1 ]:
3647 if port[ 'port' ] == port1:
3648 portIndex = port[ 'index' ]
3649 break
3650 if portIndex == -1:
3651 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3652 return None
3653 if useId:
3654 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3655 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3656 else:
3657 node1 = nodeName1
3658 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003659 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003660 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003661 graphDict[ node1 ] = { 'edges': {},
3662 'dpid': switches[ nodeName1 ][ 'dpid' ],
3663 'name': nodeName1,
3664 'ports': switches[ nodeName1 ][ 'ports' ],
3665 'swClass': switches[ nodeName1 ][ 'swClass' ],
3666 'pid': switches[ nodeName1 ][ 'pid' ],
3667 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003668 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003669 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003670 else:
3671 # Assert node2 is not connected to any current links of node1
3672 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003673 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003674 # Swap two nodes/ports
3675 nodeName1, nodeName2 = nodeName2, nodeName1
3676 port1, port2 = port2, port1
3677 return graphDict
3678 except KeyError:
3679 main.log.exception( self.name + ": KeyError exception found" )
3680 return None
3681 except AssertionError:
3682 main.log.exception( self.name + ": AssertionError exception found" )
3683 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003684 except pexpect.EOF:
3685 main.log.error( self.name + ": EOF exception found" )
3686 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003687 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003688 except Exception:
3689 main.log.exception( self.name + ": Uncaught exception" )
3690 return None
3691
Devin Lima7cfdbd2017-09-29 15:02:22 -07003692 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003693 """
3694 updates the port address and status information for
3695 each port in mn"""
3696 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003697 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003698 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003699 self.handle.sendline( "" )
3700 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003701
Jon Hall7eb38402015-01-08 17:19:54 -08003702 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003703 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003704
Jon Hall7eb38402015-01-08 17:19:54 -08003705 self.handle.sendline( "" )
3706 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003707
Jon Hallb1290e82014-11-18 16:17:48 -05003708 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003709 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003710 main.log.error( self.name + ": TIMEOUT exception found" )
3711 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003712 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003713 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003714 main.log.error( self.name + ": EOF exception found" )
3715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003716 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003717 except Exception:
3718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003719 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003720
Jon Halld80cc142015-07-06 13:36:05 -07003721 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003722 """
3723 Add vlan tag to a host.
3724 Dependencies:
3725 This class depends on the "vlan" package
3726 $ sudo apt-get install vlan
3727 Configuration:
3728 Load the 8021q module into the kernel
3729 $sudo modprobe 8021q
3730
3731 To make this setup permanent:
3732 $ sudo su -c 'echo "8021q" >> /etc/modules'
3733 """
3734 if self.handle:
3735 try:
Jon Halld80cc142015-07-06 13:36:05 -07003736 # get the ip address of the host
3737 main.log.info( "Get the ip address of the host" )
3738 ipaddr = self.getIPAddress( host )
3739 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003740
Jon Halld80cc142015-07-06 13:36:05 -07003741 # remove IP from interface intf
3742 # Ex: h1 ifconfig h1-eth0 inet 0
3743 main.log.info( "Remove IP from interface " )
3744 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3745 self.handle.sendline( cmd2 )
3746 self.handle.expect( "mininet>" )
3747 response = self.handle.before
3748 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003749
Jon Halld80cc142015-07-06 13:36:05 -07003750 # create VLAN interface
3751 # Ex: h1 vconfig add h1-eth0 100
3752 main.log.info( "Create Vlan" )
3753 cmd3 = host + " vconfig add " + intf + " " + vlan
3754 self.handle.sendline( cmd3 )
3755 self.handle.expect( "mininet>" )
3756 response = self.handle.before
3757 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003758
Jon Halld80cc142015-07-06 13:36:05 -07003759 # assign the host's IP to the VLAN interface
3760 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3761 main.log.info( "Assign the host IP to the vlan interface" )
3762 vintf = intf + "." + vlan
3763 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3764 self.handle.sendline( cmd4 )
3765 self.handle.expect( "mininet>" )
3766 response = self.handle.before
3767 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003768
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003769 # update Mininet node variables
3770 main.log.info( "Update Mininet node variables" )
3771 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3772 self.handle.sendline( cmd5 )
3773 self.handle.expect( "mininet>" )
3774 response = self.handle.before
3775 main.log.info( "====> %s ", response )
3776
3777 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3778 self.handle.sendline( cmd6 )
3779 self.handle.expect( "mininet>" )
3780 response = self.handle.before
3781 main.log.info( "====> %s ", response )
3782
3783 return main.TRUE
3784 except pexpect.TIMEOUT:
3785 main.log.error( self.name + ": TIMEOUT exception found" )
3786 main.log.error( self.name + ": " + self.handle.before )
3787 main.cleanAndExit()
3788 except pexpect.EOF:
3789 main.log.error( self.name + ": EOF exception found" )
3790 main.log.error( self.name + ": " + self.handle.before )
3791 return main.FALSE
3792 except Exception:
3793 main.log.exception( self.name + ": Uncaught exception!" )
3794 return main.FALSE
3795
3796 def removeVLAN( self, host, intf ):
3797 """
3798 Remove vlan tag from a host.
3799 Dependencies:
3800 This class depends on the "vlan" package
3801 $ sudo apt-get install vlan
3802 Configuration:
3803 Load the 8021q module into the kernel
3804 $sudo modprobe 8021q
3805
3806 To make this setup permanent:
3807 $ sudo su -c 'echo "8021q" >> /etc/modules'
3808 """
3809 if self.handle:
3810 try:
3811 # get the ip address of the host
3812 main.log.info( "Get the ip address of the host" )
3813 ipaddr = self.getIPAddress( host )
3814
3815 # remove VLAN interface
3816 # Ex: h1 vconfig rem h1-eth0.100
3817 main.log.info( "Remove Vlan interface" )
3818 cmd2 = host + " vconfig rem " + intf
3819 self.handle.sendline( cmd2 )
3820 self.handle.expect( "mininet>" )
3821 response = self.handle.before
3822 main.log.info( "====> %s ", response )
3823
3824 # assign the host's IP to the original interface
3825 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3826 main.log.info( "Assign the host IP to the original interface" )
3827 original_intf = intf.split(".")[0]
3828 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3829 self.handle.sendline( cmd3 )
3830 self.handle.expect( "mininet>" )
3831 response = self.handle.before
3832 main.log.info( "====> %s ", response )
3833
3834 # update Mininet node variables
3835 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3836 self.handle.sendline( cmd4 )
3837 self.handle.expect( "mininet>" )
3838 response = self.handle.before
3839 main.log.info( "====> %s ", response )
3840
3841 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3842 self.handle.sendline( cmd5 )
3843 self.handle.expect( "mininet>" )
3844 response = self.handle.before
3845 main.log.info( "====> %s ", response )
3846
kaouthera3f13ca22015-05-05 15:01:41 -07003847 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003848 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003849 main.log.error( self.name + ": TIMEOUT exception found" )
3850 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003851 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003852 except pexpect.EOF:
3853 main.log.error( self.name + ": EOF exception found" )
3854 main.log.error( self.name + ": " + self.handle.before )
3855 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003856 except Exception:
3857 main.log.exception( self.name + ": Uncaught exception!" )
3858 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003859
Jon Hall892818c2015-10-20 17:58:34 -07003860 def createHostComponent( self, name ):
3861 """
3862 Creates a new mininet cli component with the same parameters as self.
3863 This new component is intended to be used to login to the hosts created
3864 by mininet.
3865
3866 Arguments:
3867 name - The string of the name of this component. The new component
3868 will be assigned to main.<name> .
3869 In addition, main.<name>.name = str( name )
3870 """
3871 try:
3872 # look to see if this component already exists
3873 getattr( main, name )
3874 except AttributeError:
3875 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003876 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3877 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003878 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003879 except pexpect.EOF:
3880 main.log.error( self.name + ": EOF exception found" )
3881 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003882 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003883 except Exception:
3884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003885 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003886 else:
3887 # namespace is not clear!
3888 main.log.error( name + " component already exists!" )
3889 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003890 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003891
3892 def removeHostComponent( self, name ):
3893 """
3894 Remove host component
3895 Arguments:
3896 name - The string of the name of the component to delete.
3897 """
3898 try:
3899 # Get host component
3900 component = getattr( main, name )
3901 except AttributeError:
3902 main.log.error( "Component " + name + " does not exist." )
3903 return
3904 try:
3905 # Disconnect from component
3906 component.disconnect()
3907 # Delete component
3908 delattr( main, name )
3909 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003910 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003911 except pexpect.EOF:
3912 main.log.error( self.name + ": EOF exception found" )
3913 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003914 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003915 except Exception:
3916 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003917 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003918
3919 def startHostCli( self, host=None ):
3920 """
3921 Use the mininet m utility to connect to the host's cli
3922 """
3923 # These are fields that can be used by scapy packets. Initialized to None
3924 self.hostIp = None
3925 self.hostMac = None
3926 try:
3927 if not host:
3928 host = self.name
3929 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003930 self.handle.sendline( "cd" )
3931 self.handle.expect( self.hostPrompt )
3932 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003933 self.handle.expect( self.hostPrompt )
3934 return main.TRUE
3935 except pexpect.TIMEOUT:
3936 main.log.exception( self.name + ": Command timed out" )
3937 return main.FALSE
3938 except pexpect.EOF:
3939 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003940 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003941 except Exception:
3942 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003943 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003944
YPZhang801d46d2016-08-08 13:26:28 -07003945 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003946 '''
3947
YPZhang801d46d2016-08-08 13:26:28 -07003948 Args:
3949 devicename: switch name
3950 intf: port name on switch
3951 status: up or down
3952
3953 Returns: boolean to show success change status
3954
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003955 '''
YPZhang801d46d2016-08-08 13:26:28 -07003956 if status == "down" or status == "up":
3957 try:
3958 cmd = devicename + " ifconfig " + intf + " " + status
3959 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003960 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003961 return main.TRUE
3962 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003963 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003964 return main.FALSE
3965 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003966 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003967 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003968 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003969 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003970 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003971 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003972 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003973 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003974 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003975 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003976 return main.FALSE
3977
3978
adminbae64d82013-08-01 10:50:15 -07003979if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003980 sys.modules[ __name__ ] = MininetCliDriver()