blob: 3f7e6dd293128a79e2516e6a05ee82f15b33fed8 [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
You Wang5da39c82018-04-26 22:55:08 -0700596 dstIP = self.getIPAddress( temp, proto='IPV6' if ipv6 else 'IPV4' )
597 assert dstIP, "Not able to get IP address of host {}".format( temp )
598 pingCmd = str( host ) + cmd + str( dstIP )
You Wangba231e72018-03-01 13:18:21 -0800599 while failedPings <= acceptableFailed:
600 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
601 self.handle.sendline( pingCmd )
602 self.handle.expect( "mininet>", timeout=wait + 1 )
603 response = self.handle.before
604 if re.search( ',\s0\%\spacket\sloss', response ):
605 pingResponse += " " + str( temp )
You Wangf19d9f42018-02-23 16:34:19 -0800606 break
607 else:
608 failedPings += 1
609 time.sleep(1)
610 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700611 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800612 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700613 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800614 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700615 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800616 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700617 return isReachable
You Wang5da39c82018-04-26 22:55:08 -0700618 except AssertionError:
619 main.log.exception( "" )
620 return main.FALSE
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700621 except pexpect.TIMEOUT:
622 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800623 response = self.handle.before
624 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700625 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800626 self.handle.expect( "Interrupt" )
627 response += self.handle.before + self.handle.after
628 self.handle.expect( "mininet>" )
629 response += self.handle.before + self.handle.after
630 main.log.debug( response )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700631 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700632 except pexpect.EOF:
633 main.log.error( self.name + ": EOF exception found" )
634 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700635 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700636 except Exception:
637 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700638 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700639
Jon Hall7eb38402015-01-08 17:19:54 -0800640 def pingHost( self, **pingParams ):
641 """
Jon Hall3b489db2015-10-05 14:38:37 -0700642 Ping from one mininet host to another
643 Currently the only supported Params: SRC, TARGET, and WAIT
644 """
645 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700646 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700647 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800648 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700649 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700650 try:
Jon Hall61282e32015-03-19 11:34:11 -0700651 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800652 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700653 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
654 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700655 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800656 main.log.error(
657 self.name +
658 ": timeout when waiting for response from mininet" )
659 main.log.error( "response: " + str( self.handle.before ) )
660 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700661 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800662 main.log.error(
663 self.name +
664 ": timeout when waiting for response from mininet" )
665 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700666 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700667 if re.search( ',\s0\%\spacket\sloss', response ):
668 main.log.info( self.name + ": no packets lost, host is reachable" )
669 return main.TRUE
670 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800671 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700672 self.name +
673 ": PACKET LOST, HOST IS NOT REACHABLE" )
674 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800675 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800676 main.log.error( self.name + ": EOF exception found" )
677 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700679 except Exception:
680 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700681 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700682
683 def ping6pair( self, **pingParams ):
684 """
GlennRC2cf7d952015-09-11 16:32:13 -0700685 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700686 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000687 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700688 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
689 """
Jon Hall3b489db2015-10-05 14:38:37 -0700690 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700691 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700692 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530693 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700694 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700695 try:
696 main.log.info( "Sending: " + command )
697 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700698 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
699 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700700 if i == 1:
701 main.log.error(
702 self.name +
703 ": timeout when waiting for response from mininet" )
704 main.log.error( "response: " + str( self.handle.before ) )
705 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
706 if i == 1:
707 main.log.error(
708 self.name +
709 ": timeout when waiting for response from mininet" )
710 main.log.error( "response: " + str( self.handle.before ) )
711 response = self.handle.before
712 main.log.info( self.name + ": Ping Response: " + response )
713 if re.search( ',\s0\%\spacket\sloss', response ):
714 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700715 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700716 else:
alisone4121a92016-11-22 16:31:36 -0800717 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700718 self.name +
719 ": PACKET LOST, HOST IS NOT REACHABLE" )
720 return main.FALSE
Hari Krishna012a1c12015-08-25 14:23:58 -0700721 except pexpect.EOF:
722 main.log.error( self.name + ": EOF exception found" )
723 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700724 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700725 except Exception:
726 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700727 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800728
You Wangdb927a52016-02-26 11:03:28 -0800729 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
730 """
731 Description:
732 Ping a set of destination host from host CLI.
733 Logging into a Mininet host CLI is required before calling this funtion.
734 Params:
735 dstIPList is a list of destination ip addresses
736 Returns:
737 main.TRUE if the destination host is reachable
738 main.FALSE otherwise
739 """
740 isReachable = main.TRUE
741 wait = int( wait )
742 cmd = "ping"
743 if IPv6:
744 cmd = cmd + "6"
745 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
746 try:
747 for dstIP in dstIPList:
748 pingCmd = cmd + " " + dstIP
749 self.handle.sendline( pingCmd )
750 i = self.handle.expect( [ self.hostPrompt,
751 '\*\*\* Unknown command: ' + pingCmd,
752 pexpect.TIMEOUT ],
753 timeout=wait + 1 )
You Wang5da39c82018-04-26 22:55:08 -0700754 # For some reason we need to send something
755 # Otherwise ping results won't be read by handle
756 self.handle.sendline( "" )
757 self.handle.expect( self.hostPrompt )
You Wangdb927a52016-02-26 11:03:28 -0800758 if i == 0:
759 response = self.handle.before
760 if not re.search( ',\s0\%\spacket\sloss', response ):
761 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
762 isReachable = main.FALSE
763 elif i == 1:
764 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700765 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800766 elif i == 2:
767 main.log.error( self.name + ": timeout when waiting for response" )
768 isReachable = main.FALSE
769 else:
770 main.log.error( self.name + ": unknown response: " + self.handle.before )
771 isReachable = main.FALSE
772 except pexpect.TIMEOUT:
773 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800774 response = self.handle.before
775 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700776 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800777 self.handle.expect( "Interrupt" )
778 response += self.handle.before + self.handle.after
779 self.handle.expect( "mininet>" )
780 response += self.handle.before + self.handle.after
781 main.log.debug( response )
You Wangdb927a52016-02-26 11:03:28 -0800782 isReachable = main.FALSE
783 except pexpect.EOF:
784 main.log.error( self.name + ": EOF exception found" )
785 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700786 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800787 except Exception:
788 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700789 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800790 return isReachable
791
Jon Hall7eb38402015-01-08 17:19:54 -0800792 def checkIP( self, host ):
793 """
794 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700795 try:
796 if self.handle:
797 try:
798 response = self.execute(
799 cmd=host +
800 " ifconfig",
801 prompt="mininet>",
802 timeout=10 )
803 except pexpect.EOF:
804 main.log.error( self.name + ": EOF exception found" )
805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700806 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700807
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700808 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
809 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
810 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
811 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
812 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
813 "[0-9]|25[0-5]|[0-9]{1,2})"
814 # pattern = "inet addr:10.0.0.6"
815 if re.search( pattern, response ):
816 main.log.info( self.name + ": Host Ip configured properly" )
817 return main.TRUE
818 else:
819 main.log.error( self.name + ": Host IP not found" )
820 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700821 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700822 main.log.error( self.name + ": Connection failed to the host" )
823 except Exception:
824 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700825 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800826
Jon Hall7eb38402015-01-08 17:19:54 -0800827 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800828 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700829 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800830 response = self.execute(
831 cmd="h1 /usr/sbin/sshd -D&",
832 prompt="mininet>",
833 timeout=10 )
834 response = self.execute(
835 cmd="h4 /usr/sbin/sshd -D&",
836 prompt="mininet>",
837 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700838 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800839 vars( self )[ key ] = connectargs[ key ]
840 response = self.execute(
841 cmd="xterm h1 h4 ",
842 prompt="mininet>",
843 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800844 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800845 main.log.error( self.name + ": EOF exception found" )
846 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700847 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700848 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800849 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700850 if self.flag == 0:
851 self.flag = 1
852 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800853 else:
adminbae64d82013-08-01 10:50:15 -0700854 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800855
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700856 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700857 """
858 Moves a host from one switch to another on the fly
859 Note: The intf between host and oldSw when detached
860 using detach(), will still show up in the 'net'
861 cmd, because switch.detach() doesn't affect switch.intfs[]
862 ( which is correct behavior since the interfaces
863 haven't moved ).
864 """
865 if self.handle:
866 try:
867 # Bring link between oldSw-host down
868 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
869 "'," + "'down')"
870 print "cmd1= ", cmd
871 response = self.execute( cmd=cmd,
872 prompt="mininet>",
873 timeout=10 )
874
875 # Determine hostintf and Oldswitchintf
876 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
877 ")[0]"
878 print "cmd2= ", cmd
879 self.handle.sendline( cmd )
880 self.handle.expect( "mininet>" )
881
882 # Determine ip and mac address of the host-oldSw interface
883 cmd = "px ipaddr = hintf.IP()"
884 print "cmd3= ", cmd
885 self.handle.sendline( cmd )
886 self.handle.expect( "mininet>" )
887
888 cmd = "px macaddr = hintf.MAC()"
889 print "cmd3= ", cmd
890 self.handle.sendline( cmd )
891 self.handle.expect( "mininet>" )
892
893 # Detach interface between oldSw-host
894 cmd = "px " + oldSw + ".detach( sintf )"
895 print "cmd4= ", cmd
896 self.handle.sendline( cmd )
897 self.handle.expect( "mininet>" )
898
899 # Add link between host-newSw
900 cmd = "py net.addLink(" + host + "," + newSw + ")"
901 print "cmd5= ", cmd
902 self.handle.sendline( cmd )
903 self.handle.expect( "mininet>" )
904
905 # Determine hostintf and Newswitchintf
906 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
907 ")[0]"
908 print "cmd6= ", cmd
909 self.handle.sendline( cmd )
910 self.handle.expect( "mininet>" )
911
912 # Attach interface between newSw-host
913 cmd = "px " + newSw + ".attach( sintf )"
914 print "cmd3= ", cmd
915 self.handle.sendline( cmd )
916 self.handle.expect( "mininet>" )
917
918 # Set ipaddress of the host-newSw interface
919 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
920 print "cmd7 = ", cmd
921 self.handle.sendline( cmd )
922 self.handle.expect( "mininet>" )
923
924 # Set macaddress of the host-newSw interface
925 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
926 print "cmd8 = ", cmd
927 self.handle.sendline( cmd )
928 self.handle.expect( "mininet>" )
929
930 cmd = "net"
931 print "cmd9 = ", cmd
932 self.handle.sendline( cmd )
933 self.handle.expect( "mininet>" )
934 print "output = ", self.handle.before
935
936 # Determine ipaddress of the host-newSw interface
937 cmd = host + " ifconfig"
938 print "cmd10= ", cmd
939 self.handle.sendline( cmd )
940 self.handle.expect( "mininet>" )
941 print "ifconfig o/p = ", self.handle.before
942
943 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700944
945 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700946 main.log.error( self.name + ": TIMEOUT exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700949 except pexpect.EOF:
950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
952 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700953 except Exception:
954 main.log.exception( self.name + ": Uncaught exception!" )
955 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700956
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700957 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800958 """
959 Moves a host from one switch to another on the fly
960 Note: The intf between host and oldSw when detached
961 using detach(), will still show up in the 'net'
962 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700963 ( which is correct behavior since the interfaces
964 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800965 """
966 if self.handle:
967 try:
Jon Hall439c8912016-04-15 02:22:03 -0700968 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800969 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700970 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800971 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800972 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800973 response = self.execute( cmd=cmd,
974 prompt="mininet>",
975 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700976
kelvin-onlaba1484582015-02-02 15:46:20 -0800977 # Determine hostintf and Oldswitchintf
978 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800979 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800980 print "cmd2= ", cmd
981 self.handle.sendline( cmd )
982 self.handle.expect( "mininet>" )
983
shahshreya73537862015-02-11 15:15:24 -0800984 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700985 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800986 print "cmd3= ", cmd
987 self.handle.sendline( cmd )
988 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800989
990 cmd = "px macaddr = hintf.MAC()"
991 print "cmd3= ", cmd
992 self.handle.sendline( cmd )
993 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700994
kelvin-onlaba1484582015-02-02 15:46:20 -0800995 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700996 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800997 print "cmd4= ", cmd
998 self.handle.sendline( cmd )
999 self.handle.expect( "mininet>" )
1000
1001 # Add link between host-newSw
1002 cmd = "py net.addLink(" + host + "," + newSw + ")"
1003 print "cmd5= ", cmd
1004 self.handle.sendline( cmd )
1005 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001006
kelvin-onlaba1484582015-02-02 15:46:20 -08001007 # Determine hostintf and Newswitchintf
1008 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -08001009 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -08001010 print "cmd6= ", cmd
1011 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -07001012 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001013
1014 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001015 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001016 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001017 self.handle.sendline( cmd )
1018 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -08001019
1020 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001021 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001022 print "cmd7 = ", cmd
1023 self.handle.sendline( cmd )
1024 self.handle.expect( "mininet>" )
1025
1026 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001027 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -08001028 print "cmd8 = ", cmd
1029 self.handle.sendline( cmd )
1030 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001031
Jon Hall439c8912016-04-15 02:22:03 -07001032 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001033 print "cmd9 =", cmd
1034 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -07001035 print response
1036 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -07001037 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001038 print ipAddressSearch.group( 1 )
1039 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -07001040 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
1041 print "cmd10 = ", cmd
1042 self.handle.sendline( cmd )
1043 self.handle.expect( "mininet>" )
1044
kelvin-onlaba1484582015-02-02 15:46:20 -08001045 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -07001046 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001047 self.handle.sendline( cmd )
1048 self.handle.expect( "mininet>" )
1049 print "output = ", self.handle.before
1050
1051 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -08001052 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -07001053 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001054 self.handle.sendline( cmd )
1055 self.handle.expect( "mininet>" )
1056 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -07001057
kelvin-onlaba1484582015-02-02 15:46:20 -08001058 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001059 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001060 main.log.error( self.name + ": TIMEOUT exception found" )
1061 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001062 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08001063 except pexpect.EOF:
1064 main.log.error( self.name + ": EOF exception found" )
1065 main.log.error( self.name + ": " + self.handle.before )
1066 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001067 except Exception:
1068 main.log.exception( self.name + ": Uncaught exception!" )
1069 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -08001070
Jon Hall7eb38402015-01-08 17:19:54 -08001071 def changeIP( self, host, intf, newIP, newNetmask ):
1072 """
1073 Changes the ip address of a host on the fly
1074 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001075 if self.handle:
1076 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001077 cmd = host + " ifconfig " + intf + " " + \
1078 newIP + " " + 'netmask' + " " + newNetmask
1079 self.handle.sendline( cmd )
1080 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001081 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001082 main.log.info( "response = " + response )
1083 main.log.info(
1084 "Ip of host " +
1085 host +
1086 " changed to new IP " +
1087 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001088 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001089 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001090 main.log.error( self.name + ": TIMEOUT exception found" )
1091 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001092 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001093 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001094 main.log.error( self.name + ": EOF exception found" )
1095 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001096 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001097 except Exception:
1098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001099 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001100
Jon Hall7eb38402015-01-08 17:19:54 -08001101 def changeDefaultGateway( self, host, newGW ):
1102 """
1103 Changes the default gateway of a host
1104 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001105 if self.handle:
1106 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001107 cmd = host + " route add default gw " + newGW
1108 self.handle.sendline( cmd )
1109 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001110 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001111 main.log.info( "response = " + response )
1112 main.log.info(
1113 "Default gateway of host " +
1114 host +
1115 " changed to " +
1116 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001117 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001118 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001119 main.log.error( self.name + ": TIMEOUT exception found" )
1120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001121 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001122 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001123 main.log.error( self.name + ": EOF exception found" )
1124 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001125 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001126 except Exception:
1127 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001128 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001129
You Wange24d6272018-03-27 21:18:50 -07001130 def addRoute( self, host, dstIP, interface, ipv6=False ):
1131 """
1132 Add a route to host
1133 Ex: h1 route add -host 224.2.0.1 h1-eth0
1134 """
1135 if self.handle:
1136 try:
1137 cmd = str( host )
1138 if ipv6:
1139 cmd += " route -A inet6 add "
1140 else:
1141 cmd += " route add -host "
1142 cmd += str( dstIP ) + " " + str( interface )
1143 self.handle.sendline( cmd )
1144 self.handle.expect( "mininet>" )
1145 response = self.handle.before
1146 main.log.debug( "response = " + response )
1147 return main.TRUE
1148 except pexpect.TIMEOUT:
1149 main.log.error( self.name + ": TIMEOUT exception found" )
1150 main.log.error( self.name + ": " + self.handle.before )
1151 main.cleanAndExit()
1152 except pexpect.EOF:
1153 main.log.error( self.name + ": EOF exception found" )
1154 main.log.error( self.name + ": " + self.handle.before )
1155 return main.FALSE
1156 except Exception:
1157 main.log.exception( self.name + ": Uncaught exception!" )
1158 main.cleanAndExit()
1159
Jon Hall7eb38402015-01-08 17:19:54 -08001160 def addStaticMACAddress( self, host, GW, macaddr ):
1161 """
Jon Hallefbd9792015-03-05 16:11:36 -08001162 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001163 if self.handle:
1164 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001165 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1166 cmd = host + " arp -s " + GW + " " + macaddr
1167 self.handle.sendline( cmd )
1168 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001169 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001170 main.log.info( "response = " + response )
1171 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001172 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001173 GW +
1174 " changed to " +
1175 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001176 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001177 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001178 main.log.error( self.name + ": TIMEOUT exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001180 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001181 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001182 main.log.error( self.name + ": EOF exception found" )
1183 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001184 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001185 except Exception:
1186 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001187 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001188
Jon Hall7eb38402015-01-08 17:19:54 -08001189 def verifyStaticGWandMAC( self, host ):
1190 """
1191 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001192 if self.handle:
1193 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001194 # h1 arp -an
1195 cmd = host + " arp -an "
1196 self.handle.sendline( cmd )
1197 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001198 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001199 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001200 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001201 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001202 main.log.error( self.name + ": TIMEOUT exception found" )
1203 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001204 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001205 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001206 main.log.error( self.name + ": EOF exception found" )
1207 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001208 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001209 except Exception:
1210 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001211 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001212
Jon Hall7eb38402015-01-08 17:19:54 -08001213 def getMacAddress( self, host ):
1214 """
1215 Verifies the host's ip configured or not."""
1216 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001217 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001218 response = self.execute(
1219 cmd=host +
1220 " ifconfig",
1221 prompt="mininet>",
1222 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001223 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001226 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001227 except Exception:
1228 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001229 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001230
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001231 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 macAddressSearch = re.search( pattern, response, re.I )
1233 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001234 main.log.info(
1235 self.name +
1236 ": Mac-Address of Host " +
1237 host +
1238 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 macAddress )
1240 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001241 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001242 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001243
Jon Hall7eb38402015-01-08 17:19:54 -08001244 def getInterfaceMACAddress( self, host, interface ):
1245 """
1246 Return the IP address of the interface on the given host"""
1247 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001248 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 response = self.execute( cmd=host + " ifconfig " + interface,
1250 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001251 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001252 main.log.error( self.name + ": EOF exception found" )
1253 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001254 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001255 except Exception:
1256 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001257 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001258
1259 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 macAddressSearch = re.search( pattern, response, re.I )
1261 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001262 main.log.info( "No mac address found in %s" % response )
1263 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001265 main.log.info(
1266 "Mac-Address of " +
1267 host +
1268 ":" +
1269 interface +
1270 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 macAddress )
1272 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001273 else:
1274 main.log.error( "Connection failed to the host" )
1275
You Wang5da39c82018-04-26 22:55:08 -07001276 def getIPAddress( self, host, proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001277 """
1278 Verifies the host's ip configured or not."""
1279 if self.handle:
1280 try:
1281 response = self.execute(
1282 cmd=host +
1283 " ifconfig",
1284 prompt="mininet>",
1285 timeout=10 )
1286 except pexpect.EOF:
1287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001289 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001292 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001293
sathishmad953462015-12-03 17:42:07 +05301294 pattern = ''
1295 if proto == 'IPV4':
You Wang5da39c82018-04-26 22:55:08 -07001296 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)\s\sBcast"
sathishmad953462015-12-03 17:42:07 +05301297 else:
Jon Hall439c8912016-04-15 02:22:03 -07001298 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 ipAddressSearch = re.search( pattern, response )
Jon Hall3c910162018-03-07 14:42:16 -08001300 if not ipAddressSearch:
1301 return None
Jon Hall7eb38402015-01-08 17:19:54 -08001302 main.log.info(
1303 self.name +
1304 ": IP-Address of Host " +
1305 host +
1306 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 ipAddressSearch.group( 1 ) )
1308 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001309 else:
1310 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001311
Jon Hall7eb38402015-01-08 17:19:54 -08001312 def getSwitchDPID( self, switch ):
1313 """
1314 return the datapath ID of the switch"""
1315 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001316 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001317 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001318 response = self.execute(
1319 cmd=cmd,
1320 prompt="mininet>",
1321 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001322 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001323 main.log.error( self.name + ": EOF exception found" )
1324 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001325 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001326 except Exception:
1327 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001328 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001329 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001330 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001331 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001332 main.log.info(
1333 "Couldn't find DPID for switch %s, found: %s" %
1334 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001335 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001336 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001337 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001338 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001339
Jon Hall7eb38402015-01-08 17:19:54 -08001340 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001341 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001342 self.handle.sendline( "" )
1343 self.expect( "mininet>" )
1344 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001345 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001346 response = self.execute(
1347 cmd=cmd,
1348 prompt="mininet>",
1349 timeout=10 )
1350 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001351 response = self.handle.before
1352 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001353 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001354 main.log.error( self.name + ": TIMEOUT exception found" )
1355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001356 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001357 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001358 main.log.error( self.name + ": EOF exception found" )
1359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001360 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001361 except Exception:
1362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001363 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001364
Jon Hall7eb38402015-01-08 17:19:54 -08001365 def getInterfaces( self, node ):
1366 """
1367 return information dict about interfaces connected to the node"""
1368 if self.handle:
1369 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001370 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001371 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001372 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001373 response = self.execute(
1374 cmd=cmd,
1375 prompt="mininet>",
1376 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001377 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001378 main.log.error( self.name + ": EOF exception found" )
1379 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001380 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001381 except Exception:
1382 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001383 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001384 return response
1385 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001387
Jon Hall7eb38402015-01-08 17:19:54 -08001388 def dump( self ):
1389 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001390 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001391 response = self.execute(
1392 cmd='dump',
1393 prompt='mininet>',
1394 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001395 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001396 main.log.error( self.name + ": EOF exception found" )
1397 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001398 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001399 except Exception:
1400 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001401 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001402 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001403
Jon Hall7eb38402015-01-08 17:19:54 -08001404 def intfs( self ):
1405 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001406 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001407 response = self.execute(
1408 cmd='intfs',
1409 prompt='mininet>',
1410 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001411 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001412 main.log.error( self.name + ": EOF exception found" )
1413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001414 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001415 except Exception:
1416 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001417 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001418 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001419
Jon Hall7eb38402015-01-08 17:19:54 -08001420 def net( self ):
1421 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001422 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001423 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001424 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001425 main.log.error( self.name + ": EOF exception found" )
1426 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001427 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001428 except Exception:
1429 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001430 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001431 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001432
Devin Lima7cfdbd2017-09-29 15:02:22 -07001433 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001434 main.log.info( self.name + ": List network links" )
1435 try:
1436 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001437 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001438 except pexpect.EOF:
1439 main.log.error( self.name + ": EOF exception found" )
1440 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001441 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001442 except Exception:
1443 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001444 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001445 return response
1446
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001447 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001448 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001449 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001450
kelvin-onlab7cce9382015-07-17 10:21:03 -07001451 @parm:
1452 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1453 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001454 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001455 try:
1456 for host1 in hosts:
1457 for host2 in hosts:
1458 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001459 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1460 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001461 except Exception:
1462 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001463 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001464
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001465 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001466 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001467 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1468 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001469
kelvin-onlab7cce9382015-07-17 10:21:03 -07001470 @parm:
1471 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1472 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001473 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001474 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1475 try:
1476 # Setup the mininet command
1477 cmd1 = 'iperf ' + host1 + " " + host2
1478 self.handle.sendline( cmd1 )
1479 outcome = self.handle.expect( "mininet>", timeout )
1480 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001481
kelvin-onlab7cce9382015-07-17 10:21:03 -07001482 # checks if there are results in the mininet response
1483 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001484 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001485 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001486 response = response.split( "\r\n" )
1487 response = response[ len( response )-2 ]
1488 response = response.split( ": " )
1489 response = response[ len( response )-1 ]
1490 response = response.replace( "[", "" )
1491 response = response.replace( "]", "" )
1492 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001493
kelvin-onlab7cce9382015-07-17 10:21:03 -07001494 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001495 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001496
kelvin-onlab7cce9382015-07-17 10:21:03 -07001497 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001498 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001499 if len( bandwidth ) == 2:
1500 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001501 return main.TRUE
1502 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001503 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001504 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001505 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001506 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001507 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001508 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001509 main.log.error( self.name + ": TIMEOUT exception found" )
1510 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001511 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001512 # NOTE: Send ctrl-c to make sure iperf is done
Jon Hall2c5ac942018-03-23 11:26:54 -07001513 self.handle.send( "\x03" )
Jon Hall3b489db2015-10-05 14:38:37 -07001514 self.handle.expect( "Interrupt" )
1515 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001516 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001517 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001518 main.log.error( self.name + ": EOF exception found" )
1519 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001520 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001521 except Exception:
1522 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001523 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001524
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001525 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001526 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1527 try:
1528 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001529 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001530 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001531 outcome1 = self.handle.expect( "mininet>" )
1532 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001533 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001534 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001535 response1 = self.handle.before
1536 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001537 print response1, response2
1538 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001539 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001540 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001541 return main.TRUE
1542 else:
1543 main.log.error( self.name + ": iperf test failed" )
1544 return main.FALSE
1545 except pexpect.TIMEOUT:
1546 main.log.error( self.name + ": TIMEOUT exception found" )
1547 main.log.error( self.name + " response: " + repr( self.handle.before ) )
Jon Hall2c5ac942018-03-23 11:26:54 -07001548 self.handle.send( "\x03" )
Jon Hall439c8912016-04-15 02:22:03 -07001549 self.handle.expect( "Interrupt" )
1550 self.handle.expect( "mininet>" )
1551 return main.FALSE
1552 except pexpect.EOF:
1553 main.log.error( self.name + ": EOF exception found" )
1554 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001555 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001556 except Exception:
1557 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001558 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001559
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001560 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001561 '''
GlennRC61321f22015-07-16 13:36:54 -07001562 Runs the iperfudp function with a given set of hosts and specified
1563 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001564
GlennRC61321f22015-07-16 13:36:54 -07001565 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001566 bandwidth: the targeted bandwidth, in megabits ('M')
1567 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001568 try:
1569 for host1 in hosts:
1570 for host2 in hosts:
1571 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001572 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1573 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001574 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001575 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001576 return main.FALSE
1577 except Exception:
1578 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001579 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001580
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001581 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001582 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001583 Creates an iperf UDP test with a specific bandwidth.
1584 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001585
kelvin-onlab7cce9382015-07-17 10:21:03 -07001586 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001587 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1588 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001589 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001590 try:
1591 # setup the mininet command
1592 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001593 self.handle.sendline( cmd )
1594 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001595 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001596
kelvin-onlab7cce9382015-07-17 10:21:03 -07001597 # check if there are in results in the mininet response
1598 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001599 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001600 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001601 response = response.split( "\r\n" )
1602 response = response[ len( response )-2 ]
1603 response = response.split( ": " )
1604 response = response[ len( response )-1 ]
1605 response = response.replace( "[", "" )
1606 response = response.replace( "]", "" )
1607 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001608
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001609 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001610
kelvin-onlab7cce9382015-07-17 10:21:03 -07001611 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001612 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001613 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001614 # if one entry is blank then something is wrong
1615 for item in mnBandwidth:
1616 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001617 main.log.error( self.name + ": Could not parse iperf output" )
1618 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001619 return main.FALSE
1620 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001621 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001622 return main.TRUE
1623 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001624 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001625 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001626
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001627 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001628 main.log.error( self.name + ": TIMEOUT exception found" )
1629 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001630 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001631 except pexpect.EOF:
1632 main.log.error( self.name + ": EOF exception found" )
1633 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001634 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001635 except Exception:
1636 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001637 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001638
Jon Hall7eb38402015-01-08 17:19:54 -08001639 def nodes( self ):
1640 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001641 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001642 response = self.execute(
1643 cmd='nodes',
1644 prompt='mininet>',
1645 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001646 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001647 main.log.error( self.name + ": EOF exception found" )
1648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001649 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001650 except Exception:
1651 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001652 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001653 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001654
Jon Hall7eb38402015-01-08 17:19:54 -08001655 def pingpair( self ):
1656 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001657 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001658 response = self.execute(
1659 cmd='pingpair',
1660 prompt='mininet>',
1661 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001662 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001663 main.log.error( self.name + ": EOF exception found" )
1664 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001665 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001666 except Exception:
1667 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001668 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001669
Jon Hall7eb38402015-01-08 17:19:54 -08001670 if re.search( ',\s0\%\spacket\sloss', response ):
1671 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001672 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001673 else:
alisone4121a92016-11-22 16:31:36 -08001674 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001675 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001676
Jon Hall7eb38402015-01-08 17:19:54 -08001677 def link( self, **linkargs ):
1678 """
GlennRCed771242016-01-13 17:02:47 -08001679 Bring link( s ) between two nodes up or down
1680 """
Jon Hall6094a362014-04-11 14:46:56 -07001681 try:
GlennRCed771242016-01-13 17:02:47 -08001682 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1683 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1684 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1685 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1686
1687 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1688 cmd = "link {} {} {}".format( end1, end2, option )
1689 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001690 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001691 response = self.handle.before
1692 main.log.info( response )
Jon Hallab611372018-02-21 15:26:05 -08001693 if "not in network" in response:
1694 main.log.error( self.name + ": Could not find one of the endpoints of the link" )
1695 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08001696 return main.TRUE
1697 except pexpect.TIMEOUT:
1698 main.log.exception( self.name + ": Command timed out" )
1699 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001700 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001701 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001702 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001703 except Exception:
1704 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001705 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001706
pingping-lin8244a3b2015-09-16 13:36:56 -07001707 def switch( self, **switchargs ):
1708 """
1709 start/stop a switch
1710 """
1711 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1712 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1713 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1714 command = "switch " + str( sw ) + " " + str( option )
1715 main.log.info( command )
1716 try:
1717 self.handle.sendline( command )
1718 self.handle.expect( "mininet>" )
1719 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001720 main.log.error( self.name + ": TIMEOUT exception found" )
1721 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001722 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001723 except pexpect.EOF:
1724 main.log.error( self.name + ": EOF exception found" )
1725 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001726 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001727 return main.TRUE
1728
pingping-lin5bb663b2015-09-24 11:47:50 -07001729 def node( self, nodeName, commandStr ):
1730 """
1731 Carry out a command line on a given node
1732 @parm:
1733 nodeName: the node name in Mininet testbed
1734 commandStr: the command line will be carried out on the node
1735 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1736 """
1737 command = str( nodeName ) + " " + str( commandStr )
1738 main.log.info( command )
1739
1740 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001741 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001742 if re.search( "Unknown command", response ):
1743 main.log.warn( response )
1744 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001745 if re.search( "Permission denied", response ):
1746 main.log.warn( response )
1747 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001748 except pexpect.EOF:
1749 main.log.error( self.name + ": EOF exception found" )
1750 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001751 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001752 main.log.info( " response is :" )
1753 main.log.info( response )
1754 return response
1755
Jon Hall7eb38402015-01-08 17:19:54 -08001756 def yank( self, **yankargs ):
1757 """
1758 yank a mininet switch interface to a host"""
1759 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001760 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001761 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1762 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001763 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001764 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001765 response = self.execute(
1766 cmd=command,
1767 prompt="mininet>",
1768 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001769 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001770 main.log.error( self.name + ": EOF exception found" )
1771 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001772 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001773 except Exception:
1774 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001775 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001776 return main.TRUE
1777
Jon Hall7eb38402015-01-08 17:19:54 -08001778 def plug( self, **plugargs ):
1779 """
1780 plug the yanked mininet switch interface to a switch"""
1781 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001782 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001783 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1784 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001785 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001786 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001787 response = self.execute(
1788 cmd=command,
1789 prompt="mininet>",
1790 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001791 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001792 main.log.error( self.name + ": EOF exception found" )
1793 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001794 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001795 except Exception:
1796 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001797 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001798 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001799
Jon Hall7eb38402015-01-08 17:19:54 -08001800 def dpctl( self, **dpctlargs ):
1801 """
1802 Run dpctl command on all switches."""
1803 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001804 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001805 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1806 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1807 command = "dpctl " + cmd + " " + str( cmdargs )
1808 try:
1809 response = self.execute(
1810 cmd=command,
1811 prompt="mininet>",
1812 timeout=10 )
1813 except pexpect.EOF:
1814 main.log.error( self.name + ": EOF exception found" )
1815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001816 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001817 except Exception:
1818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001819 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001820 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001821
kelvin-onlabd3b64892015-01-20 13:26:24 -08001822 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001823 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001824 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001825 try:
1826 fileInput = path + '/lib/Mininet/INSTALL'
1827 version = super( Mininet, self ).getVersion()
1828 pattern = 'Mininet\s\w\.\w\.\w\w*'
1829 for line in open( fileInput, 'r' ).readlines():
1830 result = re.match( pattern, line )
1831 if result:
1832 version = result.group( 0 )
1833 return version
1834 except Exception:
1835 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001836 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001837
kelvin-onlabd3b64892015-01-20 13:26:24 -08001838 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001839 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001840 Parameters:
1841 sw: The name of an OVS switch. Example "s1"
1842 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001843 The output of the command from the mininet cli
1844 or main.FALSE on timeout"""
1845 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001846 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001847 response = self.execute(
1848 cmd=command,
1849 prompt="mininet>",
1850 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001851 if response:
Jon Hallab611372018-02-21 15:26:05 -08001852 if "no bridge named" in response:
1853 main.log.error( self.name + ": Error in getSwController: " +
1854 self.handle.before )
1855 return main.FALSE
1856 else:
1857 return response
admin2a9548d2014-06-17 14:08:07 -07001858 else:
1859 return main.FALSE
1860 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001861 main.log.error( self.name + ": EOF exception found" )
1862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001863 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001864 except Exception:
1865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001866 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001867
Charles Chan029be652015-08-24 01:46:10 +08001868 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001869 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001870 Description:
1871 Assign switches to the controllers ( for ovs use only )
1872 Required:
1873 sw - Name of the switch. This can be a list or a string.
1874 ip - Ip addresses of controllers. This can be a list or a string.
1875 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001876 port - ONOS use port 6653, if no list of ports is passed, then
1877 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001878 ptcp - ptcp number, This can be a string or a list that has
1879 the same length as switch. This is optional and not required
1880 when using ovs switches.
1881 NOTE: If switches and ptcp are given in a list type they should have the
1882 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1883 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001884
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001885 Return:
1886 Returns main.TRUE if mininet correctly assigned switches to
1887 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001888 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001889 """
1890 assignResult = main.TRUE
1891 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001892 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001893 command = "sh ovs-vsctl set-controller "
1894 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001895 try:
1896 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001897 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001898 if isinstance( port, types.StringType ) or \
1899 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001900 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001901 elif isinstance( port, types.ListType ):
1902 main.log.error( self.name + ": Only one controller " +
1903 "assigned and a list of ports has" +
1904 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001905 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001906 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001907 main.log.error( self.name + ": Invalid controller port " +
1908 "number. Please specify correct " +
1909 "controller port" )
1910 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001911
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001912 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001913 if isinstance( port, types.StringType ) or \
1914 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001915 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001916 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1917 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001918 elif isinstance( port, types.ListType ):
1919 if ( len( ip ) != len( port ) ):
1920 main.log.error( self.name + ": Port list = " +
1921 str( len( port ) ) +
1922 "should be the same as controller" +
1923 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001924 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001925 else:
1926 onosIp = ""
1927 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001928 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1929 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001930 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001931 main.log.error( self.name + ": Invalid controller port " +
1932 "number. Please specify correct " +
1933 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001934 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001935 else:
1936 main.log.error( self.name + ": Invalid ip address" )
1937 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001938
1939 if isinstance( sw, types.StringType ):
1940 command += sw + " "
1941 if ptcp:
1942 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001943 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001944 elif isinstance( ptcp, types.ListType ):
1945 main.log.error( self.name + ": Only one switch is " +
1946 "being set and multiple PTCP is " +
1947 "being passed " )
1948 else:
1949 main.log.error( self.name + ": Invalid PTCP" )
1950 ptcp = ""
1951 command += onosIp
1952 commandList.append( command )
1953
1954 elif isinstance( sw, types.ListType ):
1955 if ptcp:
1956 if isinstance( ptcp, types.ListType ):
1957 if len( ptcp ) != len( sw ):
1958 main.log.error( self.name + ": PTCP length = " +
1959 str( len( ptcp ) ) +
1960 " is not the same as switch" +
1961 " length = " +
1962 str( len( sw ) ) )
1963 return main.FALSE
1964 else:
1965 for switch, ptcpNum in zip( sw, ptcp ):
1966 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001967 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001968 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001969 tempCmd += onosIp
1970 commandList.append( tempCmd )
1971 else:
1972 main.log.error( self.name + ": Invalid PTCP" )
1973 return main.FALSE
1974 else:
1975 for switch in sw:
1976 tempCmd = "sh ovs-vsctl set-controller "
1977 tempCmd += switch + " " + onosIp
1978 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001979 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001980 main.log.error( self.name + ": Invalid switch type " )
1981 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001982
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001983 for cmd in commandList:
1984 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001985 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
Jon Hallab611372018-02-21 15:26:05 -08001986 if "no bridge named" in self.handle.before:
1987 main.log.error( self.name + ": Error in assignSwController: " +
1988 self.handle.before )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001989 except pexpect.TIMEOUT:
1990 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1991 return main.FALSE
1992 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 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001997 except pexpect.EOF:
1998 main.log.error( self.name + ": EOF exception found" )
1999 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002000 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002001 except Exception:
2002 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002003 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07002004
kelvin-onlabd3b64892015-01-20 13:26:24 -08002005 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002006 """
2007 Removes the controller target from sw"""
2008 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07002009 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002010 response = self.execute(
2011 cmd=command,
2012 prompt="mininet>",
2013 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08002014 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002015 main.log.error( self.name + ": EOF exception found" )
2016 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002017 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002018 except Exception:
2019 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002020 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002021 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002022 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07002023
kelvin-onlabd3b64892015-01-20 13:26:24 -08002024 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002025 """
Jon Hallb1290e82014-11-18 16:17:48 -05002026 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002027 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002028 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002029 NOTE: cannot currently specify what type of switch
2030 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002031 sw = name of the new switch as a string
2032 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05002033 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08002034 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002035 """
2036 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002037 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05002038 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002039 response = self.execute(
2040 cmd=command,
2041 prompt="mininet>",
2042 timeout=10 )
2043 if re.search( "already exists!", response ):
2044 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002045 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002046 elif re.search( "Error", response ):
2047 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002048 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002049 elif re.search( "usage:", response ):
2050 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002051 return main.FALSE
2052 else:
2053 return main.TRUE
2054 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002055 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07002056 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002060 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002061
kelvin-onlabd3b64892015-01-20 13:26:24 -08002062 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002063 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002064 delete a switch from the mininet topology
2065 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002066 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002067 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002068 sw = name of the switch as a string
2069 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002070 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002071 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002072 response = self.execute(
2073 cmd=command,
2074 prompt="mininet>",
2075 timeout=10 )
2076 if re.search( "no switch named", response ):
2077 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002078 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002079 elif re.search( "Error", response ):
2080 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002081 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002082 elif re.search( "usage:", response ):
2083 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002084 return main.FALSE
2085 else:
2086 return main.TRUE
2087 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002088 main.log.error( self.name + ": EOF exception found" )
2089 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002090 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002091 except Exception:
2092 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002093 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002094
You Wangdb8cd0a2016-05-26 15:19:45 -07002095 def getSwitchRandom( self, timeout=60, nonCut=True ):
2096 """
2097 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002098 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002099 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002100 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002101 it just randomly returns one switch from all current switches in
2102 Mininet.
2103 Returns the name of the chosen switch.
2104 """
2105 import random
2106 candidateSwitches = []
2107 try:
2108 if not nonCut:
2109 switches = self.getSwitches( timeout=timeout )
2110 assert len( switches ) != 0
2111 for switchName in switches.keys():
2112 candidateSwitches.append( switchName )
2113 else:
2114 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002115 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002116 return None
2117 self.graph.update( graphDict )
2118 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002119 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002120 return None
2121 elif len( candidateSwitches ) == 0:
2122 main.log.info( self.name + ": No candidate switch for deletion" )
2123 return None
2124 else:
2125 switch = random.sample( candidateSwitches, 1 )
2126 return switch[ 0 ]
2127 except KeyError:
2128 main.log.exception( self.name + ": KeyError exception found" )
2129 return None
2130 except AssertionError:
2131 main.log.exception( self.name + ": AssertionError exception found" )
2132 return None
2133 except Exception:
2134 main.log.exception( self.name + ": Uncaught exception" )
2135 return None
2136
2137 def delSwitchRandom( self, timeout=60, nonCut=True ):
2138 """
2139 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002140 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002141 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002142 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002143 otherwise it just randomly delete one switch from all current
2144 switches in Mininet.
2145 Returns the name of the deleted switch
2146 """
2147 try:
2148 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002149 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002150 return None
2151 else:
2152 deletionResult = self.delSwitch( switch )
2153 if deletionResult:
2154 return switch
2155 else:
2156 return None
2157 except Exception:
2158 main.log.exception( self.name + ": Uncaught exception" )
2159 return None
2160
kelvin-onlabd3b64892015-01-20 13:26:24 -08002161 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002162 """
2163 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002164 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002165 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002166 NOTE: cannot currently specify what type of link
2167 required params:
2168 node1 = the string node name of the first endpoint of the link
2169 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002170 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002171 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002172 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002173 response = self.execute(
2174 cmd=command,
2175 prompt="mininet>",
2176 timeout=10 )
2177 if re.search( "doesnt exist!", response ):
2178 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002179 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002180 elif re.search( "Error", response ):
2181 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002182 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002183 elif re.search( "usage:", response ):
2184 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002185 return main.FALSE
2186 else:
2187 return main.TRUE
2188 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002189 main.log.error( self.name + ": EOF exception found" )
2190 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002191 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002192 except Exception:
2193 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002194 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002195
kelvin-onlabd3b64892015-01-20 13:26:24 -08002196 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002197 """
2198 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002199 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002200 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002201 required params:
2202 node1 = the string node name of the first endpoint of the link
2203 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002204 returns: main.FALSE on an error, else main.TRUE
2205 """
Jon Hallffb386d2014-11-21 13:43:38 -08002206 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002207 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002208 response = self.execute(
2209 cmd=command,
2210 prompt="mininet>",
2211 timeout=10 )
2212 if re.search( "no node named", response ):
2213 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002214 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002215 elif re.search( "Error", response ):
2216 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002217 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002218 elif re.search( "usage:", response ):
2219 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002220 return main.FALSE
2221 else:
2222 return main.TRUE
2223 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002224 main.log.error( self.name + ": EOF exception found" )
2225 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002226 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002227 except Exception:
2228 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002229 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002230
You Wangdb8cd0a2016-05-26 15:19:45 -07002231 def getLinkRandom( self, timeout=60, nonCut=True ):
2232 """
2233 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002234 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002235 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002236 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002237 it just randomly returns one link from all current links in
2238 Mininet.
2239 Returns the link as a list, e.g. [ 's1', 's2' ]
2240 """
2241 import random
2242 candidateLinks = []
2243 try:
2244 if not nonCut:
2245 links = self.getLinks( timeout=timeout )
2246 assert len( links ) != 0
2247 for link in links:
2248 # Exclude host-switch link
2249 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2250 continue
2251 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2252 else:
2253 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002254 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002255 return None
2256 self.graph.update( graphDict )
2257 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002258 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002259 return None
2260 elif len( candidateLinks ) == 0:
2261 main.log.info( self.name + ": No candidate link for deletion" )
2262 return None
2263 else:
2264 link = random.sample( candidateLinks, 1 )
2265 return link[ 0 ]
2266 except KeyError:
2267 main.log.exception( self.name + ": KeyError exception found" )
2268 return None
2269 except AssertionError:
2270 main.log.exception( self.name + ": AssertionError exception found" )
2271 return None
2272 except Exception:
2273 main.log.exception( self.name + ": Uncaught exception" )
2274 return None
2275
2276 def delLinkRandom( self, timeout=60, nonCut=True ):
2277 """
2278 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002279 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002280 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002281 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002282 otherwise it just randomly delete one link from all current links
2283 in Mininet.
2284 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2285 """
2286 try:
2287 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002288 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002289 return None
2290 else:
2291 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2292 if deletionResult:
2293 return link
2294 else:
2295 return None
2296 except Exception:
2297 main.log.exception( self.name + ": Uncaught exception" )
2298 return None
2299
kelvin-onlabd3b64892015-01-20 13:26:24 -08002300 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002301 """
Jon Hallb1290e82014-11-18 16:17:48 -05002302 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002303 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002304 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002305 NOTE: cannot currently specify what type of host
2306 required params:
2307 hostname = the string hostname
2308 optional key-value params
2309 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002310 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002311 """
2312 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002313 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002314 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002315 response = self.execute(
2316 cmd=command,
2317 prompt="mininet>",
2318 timeout=10 )
2319 if re.search( "already exists!", response ):
2320 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002321 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002322 elif re.search( "doesnt exists!", response ):
2323 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002324 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002325 elif re.search( "Error", response ):
2326 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002327 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002328 elif re.search( "usage:", response ):
2329 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002330 return main.FALSE
2331 else:
2332 return main.TRUE
2333 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002334 main.log.error( self.name + ": EOF exception found" )
2335 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002336 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002337 except Exception:
2338 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002339 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002340
kelvin-onlabd3b64892015-01-20 13:26:24 -08002341 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002342 """
2343 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002344 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002345 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002346 NOTE: this uses a custom mn function
2347 required params:
2348 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002349 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002350 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002351 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002352 response = self.execute(
2353 cmd=command,
2354 prompt="mininet>",
2355 timeout=10 )
2356 if re.search( "no host named", response ):
2357 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002358 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002359 elif re.search( "Error", response ):
2360 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002361 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002362 elif re.search( "usage:", response ):
2363 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002364 return main.FALSE
2365 else:
2366 return main.TRUE
2367 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002368 main.log.error( self.name + ": EOF exception found" )
2369 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002370 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002371 except Exception:
2372 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002373 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002374
Jon Hall7eb38402015-01-08 17:19:54 -08002375 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002376 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002377 Called at the end of the test to stop the mininet and
2378 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002379 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002380 try:
2381 self.handle.sendline( '' )
You Wangd66de192018-04-30 17:30:12 -07002382 i = self.handle.expect( [ 'mininet>', self.hostPrompt, pexpect.EOF, pexpect.TIMEOUT ],
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002383 timeout=2 )
2384 response = main.TRUE
2385 if i == 0:
2386 response = self.stopNet()
You Wangd66de192018-04-30 17:30:12 -07002387 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002388 return main.TRUE
2389 # print "Disconnecting Mininet"
2390 if self.handle:
2391 self.handle.sendline( "exit" )
2392 self.handle.expect( "exit" )
2393 self.handle.expect( "(.*)" )
2394 else:
2395 main.log.error( "Connection failed to the host" )
2396 return response
2397 except pexpect.EOF:
2398 main.log.error( self.name + ": EOF exception found" )
2399 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002400 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002401 except Exception:
2402 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002403 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002404
Devin Lima7cfdbd2017-09-29 15:02:22 -07002405 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002406 """
Jon Hall21270ac2015-02-16 17:59:55 -08002407 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002408 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002409 main.FALSE if the pexpect handle does not exist.
2410
Jon Halld61331b2015-02-17 16:35:47 -08002411 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002412 """
Jon Halld61331b2015-02-17 16:35:47 -08002413 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002414 response = ''
2415 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002416 try:
Jon Halld80cc142015-07-06 13:36:05 -07002417 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002418 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002419 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002420 pexpect.EOF,
2421 pexpect.TIMEOUT ],
2422 timeout )
2423 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002424 main.log.info( "Exiting mininet.." )
2425 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002426 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002427 prompt=self.prompt,
2428 timeout=exitTimeout )
2429 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002430 self.handle.sendline( "sudo mn -c" )
2431 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002432
Jeremyd9e4eb12016-04-13 12:09:06 -07002433 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002434 main.log.info( " Mininet trying to exit while not " +
2435 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002436 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002437 elif i == 2:
2438 main.log.error( "Something went wrong exiting mininet" )
2439 elif i == 3: # timeout
2440 main.log.error( "Something went wrong exiting mininet " +
2441 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002442
You Wang18db8592018-04-02 13:52:03 -07002443 self.handle.sendline( "" )
2444 self.handle.expect( self.prompt )
2445 self.handle.sendline( "sudo killall -9 dhclient dhcpd zebra bgpd" )
2446
Hari Krishnab35c6d02015-03-18 11:13:51 -07002447 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002448 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002449 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002450 self.handle.sendline(
2451 "sudo kill -9 \`ps -ef | grep \"" +
2452 fileName +
2453 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002454 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002455 main.log.error( self.name + ": TIMEOUT exception found" )
2456 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002457 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002458 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002459 main.log.error( self.name + ": EOF exception found" )
2460 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002461 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002462 except Exception:
2463 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002464 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002465 else:
2466 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002467 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002468 return response
2469
YPZhang26a139e2016-04-25 14:01:55 -07002470 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002471 """
2472 Description:
2473 Sends arp message from mininet host for hosts discovery
2474 Required:
2475 host - hosts name
2476 Optional:
2477 ip - ip address that does not exist in the network so there would
2478 be no reply.
2479 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002480 if ethDevice:
2481 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002482 cmd = srcHost + " arping -c1 "
2483 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002484 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 -07002485 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002486 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002487 if output:
2488 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002489 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002490 i = self.handle.expect( [ "mininet>", "arping: " ] )
2491 if i == 0:
2492 return main.TRUE
2493 elif i == 1:
2494 response = self.handle.before + self.handle.after
2495 self.handle.expect( "mininet>" )
2496 response += self.handle.before + self.handle.after
2497 main.log.warn( "Error sending arping, output was: " +
2498 response )
2499 return main.FALSE
2500 except pexpect.TIMEOUT:
2501 main.log.error( self.name + ": TIMEOUT exception found" )
2502 main.log.warn( self.handle.before )
2503 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002504 except pexpect.EOF:
2505 main.log.error( self.name + ": EOF exception found" )
2506 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002507 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002508 except Exception:
2509 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002510 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002511
Jon Hall7eb38402015-01-08 17:19:54 -08002512 def decToHex( self, num ):
2513 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002514
Jon Hall7eb38402015-01-08 17:19:54 -08002515 def getSwitchFlowCount( self, switch ):
2516 """
2517 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002518 if self.handle:
2519 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2520 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002521 response = self.execute(
2522 cmd=cmd,
2523 prompt="mininet>",
2524 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002525 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002526 main.log.error( self.name + ": EOF exception found" )
2527 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002528 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002529 except Exception:
2530 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002531 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002532 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002533 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002534 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002535 main.log.info(
2536 "Couldn't find flows on switch %s, found: %s" %
2537 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002538 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002539 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002540 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002541 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002542
Jon Hall9ed8f372016-02-24 17:34:07 -08002543 def checkFlows( self, sw, dumpFormat=None ):
2544 if dumpFormat:
2545 command = "sh ovs-ofctl -F " + \
2546 dumpFormat + " dump-flows " + str( sw )
2547 else:
2548 command = "sh ovs-ofctl dump-flows " + str( sw )
2549 try:
2550 response = self.execute(
2551 cmd=command,
2552 prompt="mininet>",
2553 timeout=10 )
2554 return response
2555 except pexpect.EOF:
2556 main.log.error( self.name + ": EOF exception found" )
2557 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002558 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002559 except Exception:
2560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002561 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002562
GlennRC68467eb2015-11-16 18:01:01 -08002563 def flowTableComp( self, flowTable1, flowTable2 ):
2564 # This function compares the selctors and treatments of each flow
2565 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002566 assert flowTable1, "flowTable1 is empty or None"
2567 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002568 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002569 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002570 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002571 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002572 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2573 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002574 for field in dFields:
2575 try:
2576 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002577 except KeyError:
2578 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002579 try:
2580 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002581 except KeyError:
2582 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002583 for i in range( len( flowTable1 ) ):
2584 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002585 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002586 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002587 returnValue = main.FALSE
2588 break
2589 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002590 except AssertionError:
2591 main.log.exception( "Nothing to compare" )
2592 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002593 except Exception:
2594 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002595 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002596
GlennRC528ad292015-11-12 10:38:18 -08002597 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002598 '''
GlennRC956ea742015-11-05 16:14:15 -08002599 Discription: Parses flows into json format.
2600 NOTE: this can parse any string thats separated with commas
2601 Arguments:
2602 Required:
2603 flows: a list of strings that represnt flows
2604 Optional:
2605 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2606 debug: prints out the final result
2607 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002608 '''
GlennRC528ad292015-11-12 10:38:18 -08002609 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002610 try:
2611 for flow in flowTable:
2612 jsonFlow = {}
2613 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002614 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002615 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002616 for i in range( len( parsedFlow ) ):
2617 item = parsedFlow[ i ]
2618 if item[ 0 ] == " ":
2619 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002620 # grab the selector and treatment from the parsed flow
2621 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002622 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002623 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002624 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002625 index = 0
2626 # parse the flags
2627 # NOTE: This only parses one flag
2628 flag = {}
2629 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002630 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002631 index += 1
2632 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002633 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002634 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002635 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002636 # the priority is stuck in the selecter so put it back
2637 # in the flow
Jon Hallab611372018-02-21 15:26:05 -08002638 if 'priority' in sel[0]:
2639 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002640 # parse selector
2641 criteria = []
2642 for item in sel:
2643 # this is the type of the packet e.g. "arp"
2644 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002645 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002646 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002647 field = item.split( "=" )
2648 criteria.append( { field[ 0 ]: field[ 1 ] } )
2649 selector = { "selector": { "criteria": sorted( criteria ) } }
2650 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002651 # get rid of the action part e.g. "action=output:2"
2652 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002653 treat = treat.split( "=" )
2654 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002655 # parse treatment
2656 action = []
2657 for item in treat:
Jon Hallab611372018-02-21 15:26:05 -08002658 if ":" in item:
2659 field = item.split( ":" )
2660 action.append( { field[ 0 ]: field[ 1 ] } )
2661 else:
2662 main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
2663 item ) )
You Wang91c37cf2016-05-23 09:39:42 -07002664 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002665 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002666 # parse the rest of the flow
2667 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002668 field = item.split( "=" )
2669 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002670 # add the treatment and the selector to the json flow
2671 jsonFlow.update( selector )
2672 jsonFlow.update( treatment )
2673 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002674
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002675 if debug:
2676 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002677
You Wang91c37cf2016-05-23 09:39:42 -07002678 # add the json flow to the json flow table
2679 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002680
You Wang91c37cf2016-05-23 09:39:42 -07002681 return jsonFlowTable
2682
2683 except IndexError:
2684 main.log.exception( self.name + ": IndexError found" )
2685 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002686 except pexpect.EOF:
2687 main.log.error( self.name + ": EOF exception found" )
2688 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002689 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002690 except Exception:
2691 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002692 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002693
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002694 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002695 '''
2696 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002697 Each element is a flow.
2698 Arguments:
2699 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002700 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002701 a list of switches.
2702 Optional:
2703 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2704 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002705 '''
GlennRC956ea742015-11-05 16:14:15 -08002706 try:
2707 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002708 if isinstance( sw, list ):
2709 switches.extend( sw )
2710 else:
2711 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002712
2713 flows = []
2714 for s in switches:
2715 cmd = "sh ovs-ofctl dump-flows " + s
2716
GlennRC528ad292015-11-12 10:38:18 -08002717 if "1.0" == version:
2718 cmd += " -F OpenFlow10-table_id"
2719 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002720 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002721
2722 main.log.info( "Sending: " + cmd )
2723 self.handle.sendline( cmd )
2724 self.handle.expect( "mininet>" )
2725 response = self.handle.before
2726 response = response.split( "\r\n" )
2727 # dump the first two elements and the last
2728 # the first element is the command that was sent
2729 # the second is the table header
2730 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002731 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002732 flows.extend( response )
2733
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002734 if debug:
2735 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002736
GlennRC528ad292015-11-12 10:38:18 -08002737 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002738
GlennRC956ea742015-11-05 16:14:15 -08002739 except pexpect.EOF:
2740 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002741 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002742 except Exception:
2743 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002744 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002745
2746 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002747 '''
GlennRC956ea742015-11-05 16:14:15 -08002748 Discription: Checks whether the ID provided matches a flow ID in Mininet
2749 Arguments:
2750 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002751 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002752 a list of switches.
2753 flowId: the flow ID in hex format. Can also be a list of IDs
2754 Optional:
2755 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2756 debug: prints out the final result
2757 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2758 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002759 '''
GlennRC956ea742015-11-05 16:14:15 -08002760 try:
2761 main.log.info( "Getting flows from Mininet" )
2762 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002763 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002764 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002765
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002766 if debug:
2767 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002768
2769 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002770 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002771 result = False
2772 for f in flows:
2773 if flowId in f.get( 'cookie' ):
2774 result = True
2775 break
2776 # flowId is a list
2777 else:
2778 result = True
2779 # Get flow IDs from Mininet
2780 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2781 # Save the IDs that are not in Mininet
2782 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2783
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002784 if debug:
2785 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002786
2787 # Print out the IDs that are not in Mininet
2788 if absentIds:
2789 main.log.warn( "Absent ids: {}".format( absentIds ) )
2790 result = False
2791
2792 return main.TRUE if result else main.FALSE
2793
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002794 except pexpect.EOF:
2795 main.log.error( self.name + ": EOF exception found" )
2796 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002797 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002798 except Exception:
2799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002800 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002801
Charles Chan029be652015-08-24 01:46:10 +08002802 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002803 """
Jon Hallefbd9792015-03-05 16:11:36 -08002804 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002805 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002806 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002807 self.handle.sendline( "" )
2808 self.handle.expect( "mininet>" )
2809 self.handle.sendline(
2810 "sh sudo tcpdump -n -i " +
2811 intf +
2812 " " +
2813 port +
2814 " -w " +
2815 filename.strip() +
2816 " &" )
2817 self.handle.sendline( "" )
2818 i = self.handle.expect( [ 'No\ssuch\device',
2819 'listening\son',
2820 pexpect.TIMEOUT,
2821 "mininet>" ],
2822 timeout=10 )
2823 main.log.warn( self.handle.before + self.handle.after )
2824 self.handle.sendline( "" )
2825 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002826 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002827 main.log.error(
2828 self.name +
2829 ": tcpdump - No such device exists. " +
2830 "tcpdump attempted on: " +
2831 intf )
admin2a9548d2014-06-17 14:08:07 -07002832 return main.FALSE
2833 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002834 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002835 return main.TRUE
2836 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002837 main.log.error(
2838 self.name +
2839 ": tcpdump command timed out! Check interface name," +
2840 " given interface was: " +
2841 intf )
admin2a9548d2014-06-17 14:08:07 -07002842 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002843 elif i == 3:
2844 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002845 return main.TRUE
2846 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002847 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002848 return main.FALSE
2849 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002850 main.log.error( self.name + ": EOF exception found" )
2851 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002852 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002853 except Exception:
2854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002855 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002856
kelvin-onlabd3b64892015-01-20 13:26:24 -08002857 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002858 """
2859 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002860 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002861 self.handle.sendline( "sh sudo pkill tcpdump" )
2862 self.handle.expect( "mininet>" )
2863 self.handle.sendline( "" )
2864 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002865 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002866 main.log.error( self.name + ": TIMEOUT exception found" )
2867 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002868 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002869 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002870 main.log.error( self.name + ": EOF exception found" )
2871 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002872 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002873 except Exception:
2874 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002875 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002876
Jon Halld80cc142015-07-06 13:36:05 -07002877 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002878 """
2879 Read ports from a Mininet switch.
2880
2881 Returns a json structure containing information about the
2882 ports of the given switch.
2883 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002884 try:
2885 response = self.getInterfaces( nodeName )
2886 # TODO: Sanity check on response. log if no such switch exists
2887 ports = []
2888 for line in response.split( "\n" ):
2889 if not line.startswith( "name=" ):
2890 continue
2891 portVars = {}
2892 for var in line.split( "," ):
2893 key, value = var.split( "=" )
2894 portVars[ key ] = value
2895 isUp = portVars.pop( 'enabled', "True" )
2896 isUp = "True" in isUp
2897 if verbose:
2898 main.log.info( "Reading switch port %s(%s)" %
2899 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2900 mac = portVars[ 'mac' ]
2901 if mac == 'None':
2902 mac = None
2903 ips = []
2904 ip = portVars[ 'ip' ]
2905 if ip == 'None':
2906 ip = None
2907 ips.append( ip )
2908 name = portVars[ 'name' ]
2909 if name == 'None':
2910 name = None
2911 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2912 if name == 'lo':
2913 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2914 else:
2915 portNo = re.search( portRe, name ).group( 'port' )
2916 ports.append( { 'of_port': portNo,
2917 'mac': str( mac ).replace( '\'', '' ),
2918 'name': name,
2919 'ips': ips,
2920 'enabled': isUp } )
2921 return ports
2922 except pexpect.EOF:
2923 main.log.error( self.name + ": EOF exception found" )
2924 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002925 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002926 except Exception:
2927 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002929
You Wangdb8cd0a2016-05-26 15:19:45 -07002930 def getOVSPorts( self, nodeName ):
2931 """
2932 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2933
2934 Returns a list of dictionaries containing information about each
2935 port of the given switch.
2936 """
2937 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2938 try:
2939 response = self.execute(
2940 cmd=command,
2941 prompt="mininet>",
2942 timeout=10 )
2943 ports = []
2944 if response:
2945 for line in response.split( "\n" ):
2946 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2947 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002948 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002949 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2950 result = re.search( pattern, line )
2951 if result:
2952 index = result.group( 'index' )
2953 name = result.group( 'name' )
2954 # This port number is extracted from port name
2955 port = result.group( 'port' )
2956 mac = result.group( 'mac' )
2957 ports.append( { 'index': index,
2958 'name': name,
2959 'port': port,
2960 'mac': mac } )
2961 return ports
2962 except pexpect.EOF:
2963 main.log.error( self.name + ": EOF exception found" )
2964 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002965 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002966 except Exception:
2967 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002968 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002969
Devin Lima7cfdbd2017-09-29 15:02:22 -07002970 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002971 """
2972 Read switches from Mininet.
2973
2974 Returns a dictionary whose keys are the switch names and the value is
2975 a dictionary containing information about the switch.
2976 """
Jon Halla22481b2015-07-28 17:46:01 -07002977 # NOTE: To support new Mininet switch classes, just append the new
2978 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002979
Jon Halla22481b2015-07-28 17:46:01 -07002980 # Regex patterns to parse 'dump' output
2981 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002982 # <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 -07002983 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002984 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2985 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2986 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002987 try:
2988 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2989 swRE = r"<(?P<class>" + switchClasses + r")" +\
2990 r"(?P<options>\{.*\})?\s" +\
2991 r"(?P<name>[^:]+)\:\s" +\
2992 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2993 r"\spid=(?P<pid>(\d)+)"
2994 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002995 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002996 output = {}
2997 dump = self.dump().split( "\n" )
2998 for line in dump:
2999 result = re.search( swRE, line, re.I )
3000 if result:
3001 name = result.group( 'name' )
3002 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
3003 pid = result.group( 'pid' )
3004 swClass = result.group( 'class' )
3005 options = result.group( 'options' )
3006 if verbose:
3007 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
3008 ports = self.getPorts( name )
3009 output[ name ] = { "dpid": dpid,
3010 "ports": ports,
3011 "swClass": swClass,
3012 "pid": pid,
3013 "options": options }
3014 return output
3015 except pexpect.EOF:
3016 main.log.error( self.name + ": EOF exception found" )
3017 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003018 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003019 except Exception:
3020 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003021 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003022
You Wangd66de192018-04-30 17:30:12 -07003023 def getHosts( self, verbose=False, update=True, updateTimeout=1000,
Jon Hallab611372018-02-21 15:26:05 -08003024 hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
3025 getInterfaces=True ):
Jon Hallafa8a472015-06-12 14:02:42 -07003026 """
3027 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08003028 Optional:
3029 hostClass: it is used to match the class of the mininet host. It
3030 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07003031 Returns a dictionary whose keys are the host names and the value is
3032 a dictionary containing information about the host.
3033 """
3034 # Regex patterns to parse dump output
3035 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07003036 # <Host h1: pid=12725>
3037 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3038 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3039 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003040 # NOTE: Does not correctly match hosts with multi-links
3041 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3042 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003043 try:
You Wang53dba1e2018-02-02 17:45:44 -08003044 if not isinstance( hostClass, types.ListType ):
3045 hostClass = [ str( hostClass ) ]
3046 classRE = "(" + "|".join([c for c in hostClass]) + ")"
Jon Hallab611372018-02-21 15:26:05 -08003047 ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
3048 ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
3049 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
You Wangd66de192018-04-30 17:30:12 -07003050 if update:
3051 # update mn port info
3052 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003053 # Get mininet dump
3054 dump = self.dump().split( "\n" )
3055 hosts = {}
3056 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08003057 result = re.search( hostRE, line )
3058 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003059 name = result.group( 'name' )
3060 interfaces = []
You Wang79f5c5b2018-03-14 11:10:44 -07003061 if getInterfaces:
3062 response = self.getInterfaces( name )
3063 # Populate interface info
3064 for line in response.split( "\n" ):
3065 if line.startswith( "name=" ):
3066 portVars = {}
3067 for var in line.split( "," ):
3068 key, value = var.split( "=" )
3069 portVars[ key ] = value
3070 isUp = portVars.pop( 'enabled', "True" )
3071 isUp = "True" in isUp
3072 if verbose:
3073 main.log.info( "Reading host port %s(%s)" %
3074 ( portVars[ 'name' ],
3075 portVars[ 'mac' ] ) )
3076 mac = portVars[ 'mac' ]
3077 if mac == 'None':
3078 mac = None
3079 ips = []
3080 ip = portVars[ 'ip' ]
3081 if ip == 'None':
3082 ip = None
3083 ips.append( ip )
3084 intfName = portVars[ 'name' ]
3085 if name == 'None':
3086 name = None
3087 interfaces.append( {
3088 "name": intfName,
3089 "ips": ips,
3090 "mac": str( mac ),
3091 "isUp": isUp } )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003092 hosts[ name ] = { "interfaces": interfaces }
3093 return hosts
3094 except pexpect.EOF:
3095 main.log.error( self.name + ": EOF exception found" )
3096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003097 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003098 except Exception:
3099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003100 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003101
Devin Lima7cfdbd2017-09-29 15:02:22 -07003102 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003103 """
3104 Gathers information about current Mininet links. These links may not
3105 be up if one of the ports is down.
3106
3107 Returns a list of dictionaries with link endpoints.
3108
3109 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003110 { 'node1': str( node1 name )
3111 'node2': str( node2 name )
3112 'port1': str( port1 of_port )
3113 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003114 Note: The port number returned is the eth#, not necessarily the of_port
3115 number. In Mininet, for OVS switch, these should be the same. For
3116 hosts, this is just the eth#.
3117 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003118 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003119 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003120 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003121
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003122 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003123 # s1-eth3<->s2-eth1 (OK OK)
3124 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003125 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3126 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3127 links = []
3128 for line in response:
3129 match = re.search( linkRE, line )
3130 if match:
3131 node1 = match.group( 'node1' )
3132 node2 = match.group( 'node2' )
3133 port1 = match.group( 'port1' )
3134 port2 = match.group( 'port2' )
3135 links.append( { 'node1': node1,
3136 'node2': node2,
3137 'port1': port1,
3138 'port2': port2 } )
3139 return links
3140
3141 except pexpect.EOF:
3142 main.log.error( self.name + ": EOF exception found" )
3143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003144 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003145 except Exception:
3146 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003147 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003148
3149 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003150 """
3151 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003152 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003153
Jon Hallafa8a472015-06-12 14:02:42 -07003154 Dependencies:
3155 1. numpy - "sudo pip install numpy"
3156 """
3157 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003158 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003159 try:
3160 mnDPIDs = []
3161 for swName, switch in switches.iteritems():
3162 mnDPIDs.append( switch[ 'dpid' ].lower() )
3163 mnDPIDs.sort()
3164 if switchesJson == "": # if rest call fails
3165 main.log.error(
3166 self.name +
3167 ".compareSwitches(): Empty JSON object given from ONOS" )
3168 return main.FALSE
3169 onos = switchesJson
3170 onosDPIDs = []
3171 for switch in onos:
3172 if switch[ 'available' ]:
3173 onosDPIDs.append(
3174 switch[ 'id' ].replace(
3175 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003176 '' ).replace(
3177 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003178 '' ).lower() )
3179 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003180
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003181 if mnDPIDs != onosDPIDs:
3182 switchResults = main.FALSE
3183 main.log.error( "Switches in MN but not in ONOS:" )
3184 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3185 main.log.error( str( list1 ) )
3186 main.log.error( "Switches in ONOS but not in MN:" )
3187 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3188 main.log.error( str( list2 ) )
3189 else: # list of dpid's match in onos and mn
3190 switchResults = main.TRUE
3191 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003192
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003193 # FIXME: this does not look for extra ports in ONOS, only checks that
3194 # ONOS has what is in MN
3195 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003196
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003197 # PORTS
3198 for name, mnSwitch in switches.iteritems():
3199 mnPorts = []
3200 onosPorts = []
3201 switchResult = main.TRUE
3202 for port in mnSwitch[ 'ports' ]:
3203 if port[ 'enabled' ]:
3204 mnPorts.append( int( port[ 'of_port' ] ) )
3205 for onosSwitch in portsJson:
3206 if onosSwitch[ 'device' ][ 'available' ]:
3207 if onosSwitch[ 'device' ][ 'id' ].replace(
3208 ':',
3209 '' ).replace(
3210 "of",
3211 '' ) == mnSwitch[ 'dpid' ]:
3212 for port in onosSwitch[ 'ports' ]:
3213 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003214 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003215 # onosPorts.append( 'local' )
3216 onosPorts.append( long( uint64( -2 ) ) )
3217 else:
3218 onosPorts.append( int( port[ 'port' ] ) )
3219 break
3220 mnPorts.sort( key=float )
3221 onosPorts.sort( key=float )
3222
3223 mnPortsLog = mnPorts
3224 onosPortsLog = onosPorts
3225 mnPorts = [ x for x in mnPorts ]
3226 onosPorts = [ x for x in onosPorts ]
3227
3228 # TODO: handle other reserved port numbers besides LOCAL
3229 # NOTE: Reserved ports
3230 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3231 # long( uint64( -2 ) )
3232 for mnPort in mnPortsLog:
3233 if mnPort in onosPorts:
3234 # don't set results to true here as this is just one of
3235 # many checks and it might override a failure
3236 mnPorts.remove( mnPort )
3237 onosPorts.remove( mnPort )
3238
3239 # NOTE: OVS reports this as down since there is no link
3240 # So ignoring these for now
3241 # TODO: Come up with a better way of handling these
3242 if 65534 in mnPorts:
3243 mnPorts.remove( 65534 )
3244 if long( uint64( -2 ) ) in onosPorts:
3245 onosPorts.remove( long( uint64( -2 ) ) )
3246 if len( mnPorts ): # the ports of this switch don't match
3247 switchResult = main.FALSE
3248 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3249 if len( onosPorts ): # the ports of this switch don't match
3250 switchResult = main.FALSE
3251 main.log.warn(
3252 "Ports in ONOS but not MN: " +
3253 str( onosPorts ) )
3254 if switchResult == main.FALSE:
3255 main.log.error(
3256 "The list of ports for switch %s(%s) does not match:" %
3257 ( name, mnSwitch[ 'dpid' ] ) )
3258 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3259 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3260 portsResults = portsResults and switchResult
3261 finalResults = finalResults and portsResults
3262 return finalResults
3263 except pexpect.EOF:
3264 main.log.error( self.name + ": EOF exception found" )
3265 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003266 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003267 except Exception:
3268 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003269 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003270
Jon Hallafa8a472015-06-12 14:02:42 -07003271 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003272 """
3273 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003274 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003275
Jon Hallafa8a472015-06-12 14:02:42 -07003276 """
Jon Hall7eb38402015-01-08 17:19:54 -08003277 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003278 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003279 try:
3280 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003281
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003282 mnLinks = []
3283 for l in links:
3284 try:
3285 node1 = switches[ l[ 'node1' ] ]
3286 node2 = switches[ l[ 'node2' ] ]
3287 enabled = True
3288 for port in node1[ 'ports' ]:
3289 if port[ 'of_port' ] == l[ 'port1' ]:
3290 enabled = enabled and port[ 'enabled' ]
3291 for port in node2[ 'ports' ]:
3292 if port[ 'of_port' ] == l[ 'port2' ]:
3293 enabled = enabled and port[ 'enabled' ]
3294 if enabled:
3295 mnLinks.append( l )
3296 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003297 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003298 if 2 * len( mnLinks ) == len( onos ):
3299 linkResults = main.TRUE
3300 else:
3301 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003302 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003303 "Mininet has " + str( len( mnLinks ) ) +
3304 " bidirectional links and ONOS has " +
3305 str( len( onos ) ) + " unidirectional links" )
3306
3307 # iterate through MN links and check if an ONOS link exists in
3308 # both directions
3309 for link in mnLinks:
3310 # TODO: Find a more efficient search method
3311 node1 = None
3312 port1 = None
3313 node2 = None
3314 port2 = None
3315 firstDir = main.FALSE
3316 secondDir = main.FALSE
3317 for swName, switch in switches.iteritems():
3318 if swName == link[ 'node1' ]:
3319 node1 = switch[ 'dpid' ]
3320 for port in switch[ 'ports' ]:
3321 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3322 port1 = port[ 'of_port' ]
3323 if node1 is not None and node2 is not None:
3324 break
3325 if swName == link[ 'node2' ]:
3326 node2 = switch[ 'dpid' ]
3327 for port in switch[ 'ports' ]:
3328 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3329 port2 = port[ 'of_port' ]
3330 if node1 is not None and node2 is not None:
3331 break
3332
3333 for onosLink in onos:
3334 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3335 ":", '' ).replace( "of", '' )
3336 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3337 ":", '' ).replace( "of", '' )
3338 onosPort1 = onosLink[ 'src' ][ 'port' ]
3339 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3340
3341 # check onos link from node1 to node2
3342 if str( onosNode1 ) == str( node1 ) and str(
3343 onosNode2 ) == str( node2 ):
3344 if int( onosPort1 ) == int( port1 ) and int(
3345 onosPort2 ) == int( port2 ):
3346 firstDir = main.TRUE
3347 else:
Jon Hallab611372018-02-21 15:26:05 -08003348 # The right switches, but wrong ports, could be
3349 # another link between these devices, or onos
3350 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003351 main.log.warn(
3352 'The port numbers do not match for ' +
3353 str( link ) +
3354 ' between ONOS and MN. When checking ONOS for ' +
3355 'link %s/%s -> %s/%s' %
3356 ( node1, port1, node2, port2 ) +
3357 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003358 ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
3359 '. This could be another link between these devices' +
3360 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003361
3362 # check onos link from node2 to node1
3363 elif ( str( onosNode1 ) == str( node2 ) and
3364 str( onosNode2 ) == str( node1 ) ):
3365 if ( int( onosPort1 ) == int( port2 )
3366 and int( onosPort2 ) == int( port1 ) ):
3367 secondDir = main.TRUE
3368 else:
Jon Hallab611372018-02-21 15:26:05 -08003369 # The right switches, but wrong ports, could be
3370 # another link between these devices, or onos
3371 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003372 main.log.warn(
3373 'The port numbers do not match for ' +
3374 str( link ) +
3375 ' between ONOS and MN. When checking ONOS for ' +
3376 'link %s/%s -> %s/%s' %
3377 ( node1, port1, node2, port2 ) +
3378 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003379 ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
3380 '. This could be another link between these devices' +
3381 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003382 else: # this is not the link you're looking for
3383 pass
3384 if not firstDir:
3385 main.log.error(
3386 'ONOS does not have the link %s/%s -> %s/%s' %
3387 ( node1, port1, node2, port2 ) )
3388 if not secondDir:
3389 main.log.error(
3390 'ONOS does not have the link %s/%s -> %s/%s' %
3391 ( node2, port2, node1, port1 ) )
3392 linkResults = linkResults and firstDir and secondDir
3393 return linkResults
3394 except pexpect.EOF:
3395 main.log.error( self.name + ": EOF exception found" )
3396 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003397 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003398 except Exception:
3399 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003400 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003401
Jon Hallafa8a472015-06-12 14:02:42 -07003402 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003403 """
Jon Hallafa8a472015-06-12 14:02:42 -07003404 Compare mn and onos Hosts.
3405 Since Mininet hosts are quiet, ONOS will only know of them when they
3406 speak. For this reason, we will only check that the hosts in ONOS
3407 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003408
Jon Hallafa8a472015-06-12 14:02:42 -07003409 Arguments:
3410 hostsJson: parsed json object from the onos hosts api
3411 Returns:
3412 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003413 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003414 try:
3415 hostResults = main.TRUE
3416 for onosHost in hostsJson:
3417 onosMAC = onosHost[ 'mac' ].lower()
3418 match = False
3419 for mnHost, info in hosts.iteritems():
3420 for mnIntf in info[ 'interfaces' ]:
3421 if onosMAC == mnIntf[ 'mac' ].lower():
3422 match = True
3423 for ip in mnIntf[ 'ips' ]:
3424 if ip in onosHost[ 'ipAddresses' ]:
3425 pass # all is well
3426 else:
3427 # misssing ip
3428 main.log.error( "ONOS host " +
3429 onosHost[ 'id' ] +
3430 " has a different IP(" +
3431 str( onosHost[ 'ipAddresses' ] ) +
3432 ") than the Mininet host(" +
3433 str( ip ) +
3434 ")." )
3435 output = json.dumps(
3436 onosHost,
3437 sort_keys=True,
3438 indent=4,
3439 separators=( ',', ': ' ) )
3440 main.log.info( output )
3441 hostResults = main.FALSE
3442 if not match:
3443 hostResults = main.FALSE
3444 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3445 "corresponding Mininet host." )
3446 output = json.dumps( onosHost,
3447 sort_keys=True,
3448 indent=4,
3449 separators=( ',', ': ' ) )
3450 main.log.info( output )
3451 return hostResults
3452 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003453 main.log.error( self.name + ": EOF exception found" )
3454 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003455 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003456 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003457 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003458 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003459
You Wangd66de192018-04-30 17:30:12 -07003460 def verifyHostIp( self, hostList=[], prefix="", update=True ):
You Wang53dba1e2018-02-02 17:45:44 -08003461 """
3462 Description:
3463 Verify that all hosts have IP address assigned to them
3464 Optional:
3465 hostList: If specified, verifications only happen to the hosts
3466 in hostList
3467 prefix: at least one of the ip address assigned to the host
3468 needs to have the specified prefix
You Wangd66de192018-04-30 17:30:12 -07003469 update: Update Mininet information if True
You Wang53dba1e2018-02-02 17:45:44 -08003470 Returns:
3471 main.TRUE if all hosts have specific IP address assigned;
3472 main.FALSE otherwise
3473 """
3474 try:
You Wangd66de192018-04-30 17:30:12 -07003475 hosts = self.getHosts( update=update, getInterfaces=False )
You Wang53dba1e2018-02-02 17:45:44 -08003476 if not hostList:
3477 hostList = hosts.keys()
3478 for hostName in hosts.keys():
3479 if hostName not in hostList:
3480 continue
3481 ipList = []
3482 self.handle.sendline( str( hostName ) + " ip a" )
3483 self.handle.expect( "mininet>" )
3484 ipa = self.handle.before
3485 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3486 ipList += re.findall( ipv4Pattern, ipa )
3487 # It's tricky to make regex for IPv6 addresses and this one is simplified
3488 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})/'
3489 ipList += re.findall( ipv6Pattern, ipa )
3490 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3491 if not ipList:
3492 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3493 else:
3494 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3495 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3496 else:
3497 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3498 hostList.remove( hostName )
3499 return main.FALSE if hostList else main.TRUE
3500 except KeyError:
3501 main.log.exception( self.name + ": host data not as expected: " + hosts )
3502 return None
3503 except pexpect.EOF:
3504 main.log.error( self.name + ": EOF exception found" )
3505 main.log.error( self.name + ": " + self.handle.before )
3506 main.cleanAndExit()
3507 except Exception:
3508 main.log.exception( self.name + ": Uncaught exception" )
3509 return None
3510
Jon Hallafa8a472015-06-12 14:02:42 -07003511 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003512 """
3513 Returns a list of all hosts
3514 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003515 try:
3516 self.handle.sendline( "" )
3517 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003518
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003519 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3520 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003521
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003522 handlePy = self.handle.before
3523 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3524 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003525
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003526 self.handle.sendline( "" )
3527 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003528
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003529 hostStr = handlePy.replace( "]", "" )
3530 hostStr = hostStr.replace( "'", "" )
3531 hostStr = hostStr.replace( "[", "" )
3532 hostStr = hostStr.replace( " ", "" )
3533 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003534
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003535 return hostList
3536 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003537 main.log.error( self.name + ": TIMEOUT exception found" )
3538 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003539 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003540 except pexpect.EOF:
3541 main.log.error( self.name + ": EOF exception found" )
3542 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003543 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003544 except Exception:
3545 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003546 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003547
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003548 def getSwitch( self ):
3549 """
3550 Returns a list of all switches
3551 Again, don't ask question just use it...
3552 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003553 try:
3554 # get host list...
3555 hostList = self.getHosts()
3556 # Make host set
3557 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003558
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003559 # Getting all the nodes in mininet
3560 self.handle.sendline( "" )
3561 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003562
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003563 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3564 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003565
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003566 handlePy = self.handle.before
3567 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3568 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003569
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003570 self.handle.sendline( "" )
3571 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003572
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003573 nodesStr = handlePy.replace( "]", "" )
3574 nodesStr = nodesStr.replace( "'", "" )
3575 nodesStr = nodesStr.replace( "[", "" )
3576 nodesStr = nodesStr.replace( " ", "" )
3577 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003578
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003579 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003580 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003581 nodesSet.discard( 'c0' )
3582 nodesSet.discard( 'c1' )
3583 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003584
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003585 switchSet = nodesSet - hostSet
3586 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003587
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003588 return switchList
3589 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003590 main.log.error( self.name + ": TIMEOUT exception found" )
3591 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003592 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003593 except pexpect.EOF:
3594 main.log.error( self.name + ": EOF exception found" )
3595 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003596 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003597 except Exception:
3598 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003599 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003600
You Wangdb8cd0a2016-05-26 15:19:45 -07003601 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3602 """
3603 Return a dictionary which describes the latest Mininet topology data as a
3604 graph.
3605 An example of the dictionary:
3606 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3607 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3608 Each vertex should at least have an 'edges' attribute which describes the
3609 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003610 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003611 list of attributes.
3612 An example of the edges dictionary:
3613 'edges': { vertex2: { 'port': ..., 'weight': ... },
3614 vertex3: { 'port': ..., 'weight': ... } }
3615 If useId == True, dpid/mac will be used instead of names to identify
3616 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3617 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003618 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003619 in topology data.
3620 Note that link or switch that are brought down by 'link x x down' or 'switch
3621 x down' commands still show in the output of Mininet CLI commands such as
3622 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3623 recommended to use delLink() or delSwitch functions to simulate link/switch
3624 down, and addLink() or addSwitch to add them back.
3625 """
3626 graphDict = {}
3627 try:
3628 links = self.getLinks( timeout=timeout )
3629 portDict = {}
3630 if useId:
3631 switches = self.getSwitches()
3632 if includeHost:
3633 hosts = self.getHosts()
3634 for link in links:
3635 # FIXME: support 'includeHost' argument
3636 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3637 continue
3638 nodeName1 = link[ 'node1' ]
3639 nodeName2 = link[ 'node2' ]
3640 port1 = link[ 'port1' ]
3641 port2 = link[ 'port2' ]
3642 # Loop for two nodes
3643 for i in range( 2 ):
3644 # Get port index from OVS
3645 # The index extracted from port name may be inconsistent with ONOS
3646 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003647 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003648 portList = self.getOVSPorts( nodeName1 )
3649 if len( portList ) == 0:
3650 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3651 return None
3652 portDict[ nodeName1 ] = portList
3653 for port in portDict[ nodeName1 ]:
3654 if port[ 'port' ] == port1:
3655 portIndex = port[ 'index' ]
3656 break
3657 if portIndex == -1:
3658 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3659 return None
3660 if useId:
3661 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3662 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3663 else:
3664 node1 = nodeName1
3665 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003666 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003667 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003668 graphDict[ node1 ] = { 'edges': {},
3669 'dpid': switches[ nodeName1 ][ 'dpid' ],
3670 'name': nodeName1,
3671 'ports': switches[ nodeName1 ][ 'ports' ],
3672 'swClass': switches[ nodeName1 ][ 'swClass' ],
3673 'pid': switches[ nodeName1 ][ 'pid' ],
3674 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003675 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003676 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003677 else:
3678 # Assert node2 is not connected to any current links of node1
3679 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003680 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003681 # Swap two nodes/ports
3682 nodeName1, nodeName2 = nodeName2, nodeName1
3683 port1, port2 = port2, port1
3684 return graphDict
3685 except KeyError:
3686 main.log.exception( self.name + ": KeyError exception found" )
3687 return None
3688 except AssertionError:
3689 main.log.exception( self.name + ": AssertionError exception found" )
3690 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003691 except pexpect.EOF:
3692 main.log.error( self.name + ": EOF exception found" )
3693 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003694 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003695 except Exception:
3696 main.log.exception( self.name + ": Uncaught exception" )
3697 return None
3698
Devin Lima7cfdbd2017-09-29 15:02:22 -07003699 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003700 """
3701 updates the port address and status information for
3702 each port in mn"""
3703 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003704 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003705 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003706 self.handle.sendline( "" )
3707 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003708
Jon Hall7eb38402015-01-08 17:19:54 -08003709 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003710 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003711
Jon Hall7eb38402015-01-08 17:19:54 -08003712 self.handle.sendline( "" )
3713 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003714
Jon Hallb1290e82014-11-18 16:17:48 -05003715 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003716 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003717 main.log.error( self.name + ": TIMEOUT exception found" )
3718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003719 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003720 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003721 main.log.error( self.name + ": EOF exception found" )
3722 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003723 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003724 except Exception:
3725 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003726 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003727
Jon Halld80cc142015-07-06 13:36:05 -07003728 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003729 """
3730 Add vlan tag to a host.
3731 Dependencies:
3732 This class depends on the "vlan" package
3733 $ sudo apt-get install vlan
3734 Configuration:
3735 Load the 8021q module into the kernel
3736 $sudo modprobe 8021q
3737
3738 To make this setup permanent:
3739 $ sudo su -c 'echo "8021q" >> /etc/modules'
3740 """
3741 if self.handle:
3742 try:
Jon Halld80cc142015-07-06 13:36:05 -07003743 # get the ip address of the host
3744 main.log.info( "Get the ip address of the host" )
3745 ipaddr = self.getIPAddress( host )
3746 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003747
Jon Halld80cc142015-07-06 13:36:05 -07003748 # remove IP from interface intf
3749 # Ex: h1 ifconfig h1-eth0 inet 0
3750 main.log.info( "Remove IP from interface " )
3751 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3752 self.handle.sendline( cmd2 )
3753 self.handle.expect( "mininet>" )
3754 response = self.handle.before
3755 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003756
Jon Halld80cc142015-07-06 13:36:05 -07003757 # create VLAN interface
3758 # Ex: h1 vconfig add h1-eth0 100
3759 main.log.info( "Create Vlan" )
3760 cmd3 = host + " vconfig add " + intf + " " + vlan
3761 self.handle.sendline( cmd3 )
3762 self.handle.expect( "mininet>" )
3763 response = self.handle.before
3764 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003765
Jon Halld80cc142015-07-06 13:36:05 -07003766 # assign the host's IP to the VLAN interface
3767 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3768 main.log.info( "Assign the host IP to the vlan interface" )
3769 vintf = intf + "." + vlan
3770 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3771 self.handle.sendline( cmd4 )
3772 self.handle.expect( "mininet>" )
3773 response = self.handle.before
3774 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003775
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003776 # update Mininet node variables
3777 main.log.info( "Update Mininet node variables" )
3778 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3779 self.handle.sendline( cmd5 )
3780 self.handle.expect( "mininet>" )
3781 response = self.handle.before
3782 main.log.info( "====> %s ", response )
3783
3784 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3785 self.handle.sendline( cmd6 )
3786 self.handle.expect( "mininet>" )
3787 response = self.handle.before
3788 main.log.info( "====> %s ", response )
3789
3790 return main.TRUE
3791 except pexpect.TIMEOUT:
3792 main.log.error( self.name + ": TIMEOUT exception found" )
3793 main.log.error( self.name + ": " + self.handle.before )
3794 main.cleanAndExit()
3795 except pexpect.EOF:
3796 main.log.error( self.name + ": EOF exception found" )
3797 main.log.error( self.name + ": " + self.handle.before )
3798 return main.FALSE
3799 except Exception:
3800 main.log.exception( self.name + ": Uncaught exception!" )
3801 return main.FALSE
3802
3803 def removeVLAN( self, host, intf ):
3804 """
3805 Remove vlan tag from a host.
3806 Dependencies:
3807 This class depends on the "vlan" package
3808 $ sudo apt-get install vlan
3809 Configuration:
3810 Load the 8021q module into the kernel
3811 $sudo modprobe 8021q
3812
3813 To make this setup permanent:
3814 $ sudo su -c 'echo "8021q" >> /etc/modules'
3815 """
3816 if self.handle:
3817 try:
3818 # get the ip address of the host
3819 main.log.info( "Get the ip address of the host" )
3820 ipaddr = self.getIPAddress( host )
3821
3822 # remove VLAN interface
3823 # Ex: h1 vconfig rem h1-eth0.100
3824 main.log.info( "Remove Vlan interface" )
3825 cmd2 = host + " vconfig rem " + intf
3826 self.handle.sendline( cmd2 )
3827 self.handle.expect( "mininet>" )
3828 response = self.handle.before
3829 main.log.info( "====> %s ", response )
3830
3831 # assign the host's IP to the original interface
3832 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3833 main.log.info( "Assign the host IP to the original interface" )
3834 original_intf = intf.split(".")[0]
3835 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3836 self.handle.sendline( cmd3 )
3837 self.handle.expect( "mininet>" )
3838 response = self.handle.before
3839 main.log.info( "====> %s ", response )
3840
3841 # update Mininet node variables
3842 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3843 self.handle.sendline( cmd4 )
3844 self.handle.expect( "mininet>" )
3845 response = self.handle.before
3846 main.log.info( "====> %s ", response )
3847
3848 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3849 self.handle.sendline( cmd5 )
3850 self.handle.expect( "mininet>" )
3851 response = self.handle.before
3852 main.log.info( "====> %s ", response )
3853
kaouthera3f13ca22015-05-05 15:01:41 -07003854 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003855 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003856 main.log.error( self.name + ": TIMEOUT exception found" )
3857 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003858 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003859 except pexpect.EOF:
3860 main.log.error( self.name + ": EOF exception found" )
3861 main.log.error( self.name + ": " + self.handle.before )
3862 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003863 except Exception:
3864 main.log.exception( self.name + ": Uncaught exception!" )
3865 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003866
Jon Hall892818c2015-10-20 17:58:34 -07003867 def createHostComponent( self, name ):
3868 """
3869 Creates a new mininet cli component with the same parameters as self.
3870 This new component is intended to be used to login to the hosts created
3871 by mininet.
3872
3873 Arguments:
3874 name - The string of the name of this component. The new component
3875 will be assigned to main.<name> .
3876 In addition, main.<name>.name = str( name )
3877 """
3878 try:
3879 # look to see if this component already exists
3880 getattr( main, name )
3881 except AttributeError:
3882 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003883 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3884 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003885 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003886 except pexpect.EOF:
3887 main.log.error( self.name + ": EOF exception found" )
3888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003889 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003890 except Exception:
3891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003892 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003893 else:
3894 # namespace is not clear!
3895 main.log.error( name + " component already exists!" )
3896 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003897 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003898
3899 def removeHostComponent( self, name ):
3900 """
3901 Remove host component
3902 Arguments:
3903 name - The string of the name of the component to delete.
3904 """
3905 try:
3906 # Get host component
3907 component = getattr( main, name )
3908 except AttributeError:
3909 main.log.error( "Component " + name + " does not exist." )
3910 return
3911 try:
3912 # Disconnect from component
3913 component.disconnect()
3914 # Delete component
3915 delattr( main, name )
3916 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003917 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003918 except pexpect.EOF:
3919 main.log.error( self.name + ": EOF exception found" )
3920 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003921 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003922 except Exception:
3923 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003924 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003925
3926 def startHostCli( self, host=None ):
3927 """
3928 Use the mininet m utility to connect to the host's cli
3929 """
3930 # These are fields that can be used by scapy packets. Initialized to None
3931 self.hostIp = None
3932 self.hostMac = None
3933 try:
3934 if not host:
3935 host = self.name
3936 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003937 self.handle.sendline( "cd" )
3938 self.handle.expect( self.hostPrompt )
3939 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003940 self.handle.expect( self.hostPrompt )
3941 return main.TRUE
3942 except pexpect.TIMEOUT:
3943 main.log.exception( self.name + ": Command timed out" )
3944 return main.FALSE
3945 except pexpect.EOF:
3946 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003947 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003948 except Exception:
3949 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003950 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003951
YPZhang801d46d2016-08-08 13:26:28 -07003952 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003953 '''
3954
YPZhang801d46d2016-08-08 13:26:28 -07003955 Args:
3956 devicename: switch name
3957 intf: port name on switch
3958 status: up or down
3959
3960 Returns: boolean to show success change status
3961
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003962 '''
YPZhang801d46d2016-08-08 13:26:28 -07003963 if status == "down" or status == "up":
3964 try:
3965 cmd = devicename + " ifconfig " + intf + " " + status
3966 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003967 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003968 return main.TRUE
3969 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003970 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003971 return main.FALSE
3972 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003973 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003974 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003975 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003976 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003977 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003978 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003979 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003980 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003981 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003982 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003983 return main.FALSE
3984
3985
adminbae64d82013-08-01 10:50:15 -07003986if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003987 sys.modules[ __name__ ] = MininetCliDriver()