blob: 168797530f53e8f6871a92aad5000420ae4cb212 [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 Songsterae01bba2016-07-11 15:39:17 -07004Modified 2016 by ON.Lab
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
Jon Hall1ccf82c2014-10-15 14:55:16 -040041from math import pow
adminbae64d82013-08-01 10:50:15 -070042from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070043from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070044
Jon Hall7eb38402015-01-08 17:19:54 -080045
kelvin-onlab50907142015-04-01 13:37:45 -070046class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080047 """
48 MininetCliDriver is the basic driver which will handle
49 the Mininet functions"""
50 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070051 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070052 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080053 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070054 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080055 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070056 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070057 # TODO: Refactor driver to use these everywhere
58 self.mnPrompt = "mininet>"
59 self.hostPrompt = "~#"
60 self.bashPrompt = "\$"
61 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070062 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070063
Jon Hall7eb38402015-01-08 17:19:54 -080064 def connect( self, **connectargs ):
65 """
66 Here the main is the TestON instance after creating
67 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080068 try:
69 for key in connectargs:
70 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070071 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080072 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070073 for key in self.options:
74 if key == "home":
75 self.home = self.options[ 'home' ]
76 break
77 if self.home is None or self.home == "":
78 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070079
80 try:
Jon Hall892818c2015-10-20 17:58:34 -070081 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070082 self.ip_address = os.getenv( str( self.ip_address ) )
83 else:
84 main.log.info( self.name +
85 ": Trying to connect to " +
86 self.ip_address )
87
88 except KeyError:
89 main.log.info( "Invalid host name," +
90 " connecting to local host instead" )
91 self.ip_address = 'localhost'
92 except Exception as inst:
93 main.log.error( "Uncaught exception: " + str( inst ) )
94
kelvin-onlaba1484582015-02-02 15:46:20 -080095 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070096 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080097 self ).connect(
98 user_name=self.user_name,
99 ip_address=self.ip_address,
100 port=None,
101 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800102
kelvin-onlaba1484582015-02-02 15:46:20 -0800103 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800104 main.log.info( "Connection successful to the host " +
105 self.user_name +
106 "@" +
107 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800108 return main.TRUE
109 else:
110 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800111 self.user_name +
112 "@" +
113 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800114 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800115 return main.FALSE
116 except pexpect.EOF:
117 main.log.error( self.name + ": EOF exception found" )
118 main.log.error( self.name + ": " + self.handle.before )
119 main.cleanup()
120 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800121 except Exception:
122 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800123 main.cleanup()
124 main.exit()
125
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:
129 Starts Mininet accepts a topology(.py) file and/or an optional
130 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:
134 topoFile = file path for topology file (.py)
135 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 )
156 i = self.handle.expect( [ '%s:' % self.user,
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 )
188 cmdString += "-E python " + topoFile + " "
189 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 )
202 while True:
203 i = self.handle.expect( [ 'mininet>',
204 'Exception',
205 '\*\*\*',
206 pexpect.EOF,
207 pexpect.TIMEOUT ],
208 timeout )
209 if i == 0:
210 main.log.info( self.name + ": Mininet built" )
211 return main.TRUE
212 elif i == 1:
213 response = str( self.handle.before +
214 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700215 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700216 response += str( self.handle.before +
217 self.handle.after )
218 main.log.error(
219 self.name +
220 ": Launching Mininet failed: " + response )
221 return main.FALSE
222 elif i == 2:
223 self.handle.expect( [ "\n",
224 pexpect.EOF,
225 pexpect.TIMEOUT ],
226 timeout )
227 main.log.info( self.handle.before )
228 elif i == 3:
229 main.log.error( self.name + ": Connection timeout" )
230 return main.FALSE
231 elif i == 4: # timeout
232 main.log.error(
233 self.name +
234 ": Something took too long... " )
235 return main.FALSE
236 # Why did we hit this part?
237 main.log.error( "startNet did not return correctly" )
238 return main.FASLE
239 else: # if no handle
240 main.log.error( self.name + ": Connection failed to the host " +
241 self.user_name + "@" + self.ip_address )
242 main.log.error( self.name + ": Failed to connect to the Mininet" )
243 return main.FALSE
244 except pexpect.TIMEOUT:
245 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
246 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700247 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700248 except pexpect.EOF:
249 main.log.error( self.name + ": EOF exception found" )
250 main.log.error( self.name + ": " + self.handle.before )
251 main.cleanup()
252 main.exit()
253 except Exception:
254 main.log.exception( self.name + ": Uncaught exception!" )
255 main.cleanup()
256 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800257
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800258 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700259 try:
260 if topoType == 'tree':
261 # In tree topology, if fanout arg is not given, by default it is 2
262 if fanout is None:
263 fanout = 2
264 k = 0
265 count = 0
266 while( k <= depth - 1 ):
267 count = count + pow( fanout, k )
268 k = k + 1
269 numSwitches = count
270 while( k <= depth - 2 ):
271 # depth-2 gives you only core links and not considering
272 # edge links as seen by ONOS. If all the links including
273 # edge links are required, do depth-1
274 count = count + pow( fanout, k )
275 k = k + 1
276 numLinks = count * fanout
277 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
278 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800279
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700280 elif topoType == 'linear':
281 # In linear topology, if fanout or numHostsPerSw is not given,
282 # by default it is 1
283 if fanout is None:
284 fanout = 1
285 numSwitches = depth
286 numHostsPerSw = fanout
287 totalNumHosts = numSwitches * numHostsPerSw
288 numLinks = totalNumHosts + ( numSwitches - 1 )
289 print "num_switches for %s(%d,%d) = %d and links=%d" %\
290 ( topoType, depth, fanout, numSwitches, numLinks )
291 topoDict = { "num_switches": int( numSwitches ),
292 "num_corelinks": int( numLinks ) }
293 return topoDict
294 except Exception:
295 main.log.exception( self.name + ": Uncaught exception!" )
296 main.cleanup()
297 main.exit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400298
kelvin-onlabd3b64892015-01-20 13:26:24 -0800299 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700300 """
301 Calculate the number of switches and links in a topo."""
302 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700303 try:
304 argList = self.options[ 'arg1' ].split( "," )
305 topoArgList = argList[ 0 ].split( " " )
306 argList = map( int, argList[ 1: ] )
307 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700308
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700309 topoDict = self.numSwitchesNlinks( *topoArgList )
310 return topoDict
311 except Exception:
312 main.log.exception( self.name + ": Uncaught exception!" )
313 main.cleanup()
314 main.exit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400315
GlennRCf07c44a2015-09-18 13:33:46 -0700316 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800317 """
318 Verifies the reachability of the hosts using pingall command.
319 Optional parameter timeout allows you to specify how long to
320 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700321 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700322 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700323 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700324 ping
325 acceptableFailed - Set the number of acceptable failed pings for the
326 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800327 Returns:
328 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700329 otherwise main.FALSE
330 """
331 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700332 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700333 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700334 if self.handle:
335 main.log.info(
336 self.name +
337 ": Checking reachabilty to the hosts using pingall" )
338 response = ""
339 failedPings = 0
340 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700341 cmd = "pingall"
342 if protocol == "IPv6":
343 cmd = "py net.pingAll6()"
344 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700345 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700346 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700347 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700348 pexpect.EOF,
349 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700350 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700351 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700352 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700353 response += self.handle.before
354 break
355 elif i == 1:
356 response += self.handle.before + self.handle.after
357 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700358 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700359 returnValue = main.FALSE
360 if shortCircuit:
361 main.log.error( self.name +
362 ": Aborting pingall - "
363 + str( failedPings ) +
364 " pings failed" )
365 break
Jon Hall390696c2015-05-05 17:13:41 -0700366 if ( time.time() - startTime ) > timeout:
367 returnValue = main.FALSE
368 main.log.error( self.name +
369 ": Aborting pingall - " +
370 "Function took too long " )
371 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700372 elif i == 2:
373 main.log.error( self.name +
374 ": EOF exception found" )
375 main.log.error( self.name + ": " +
376 self.handle.before )
377 main.cleanup()
378 main.exit()
379 elif i == 3:
380 response += self.handle.before
381 main.log.error( self.name +
382 ": TIMEOUT exception found" )
383 main.log.error( self.name +
384 ": " +
385 str( response ) )
386 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800387 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700388 self.handle.expect( "Interrupt" )
389 self.handle.expect( "mininet>" )
390 break
391 pattern = "Results\:"
392 main.log.info( "Pingall output: " + str( response ) )
393 if re.search( pattern, response ):
394 main.log.info( self.name + ": Pingall finished with "
395 + str( failedPings ) + " failed pings" )
396 return returnValue
397 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700398 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800399 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700400 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700401 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700402 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700403 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700404 main.log.error( self.name + ": Connection failed to the host" )
405 main.cleanup()
406 main.exit()
407 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 )
Jon Hallb1290e82014-11-18 16:17:48 -0500415 main.cleanup()
416 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700417
Jon Hall7eb38402015-01-08 17:19:54 -0800418 def fpingHost( self, **pingParams ):
419 """
420 Uses the fping package for faster pinging...
421 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700422 try:
423 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
424 command = args[ "SRC" ] + \
425 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
426 self.handle.sendline( command )
427 self.handle.expect(
428 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
429 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
430 response = self.handle.before
431 if re.search( ":\s-", response ):
432 main.log.info( self.name + ": Ping fail" )
433 return main.FALSE
434 elif re.search( ":\s\d{1,2}\.\d\d", response ):
435 main.log.info( self.name + ": Ping good!" )
436 return main.TRUE
437 main.log.info( self.name + ": Install fping on mininet machine... " )
438 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700439 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700440 except Exception:
441 main.log.exception( self.name + ": Uncaught exception!" )
442 main.cleanup()
443 main.exit()
444
Jon Hallfbc828e2015-01-06 17:30:19 -0800445
Jon Hall3b489db2015-10-05 14:38:37 -0700446 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400447 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700448 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700449
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400450 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700451 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700452
453 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400454 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700455
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400456 Returns main.FALSE if one or more of hosts specified
457 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700458 wait = int( wait )
459 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400460
461 try:
462 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700463
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400464 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700465 pingResponse = "IPv4 ping across specified hosts\n"
466 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400467 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700468 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400469 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700470 pingList = hostList[ :listIndex ] + \
471 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700472
473 pingResponse += str(str(host) + " -> ")
474
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400475 for temp in pingList:
476 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700477 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700478 self.handle.sendline( pingCmd )
479 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400480 response = self.handle.before
481 if re.search( ',\s0\%\spacket\sloss', response ):
GlennRCd10d3cc2015-09-24 12:47:16 -0700482 pingResponse += str(" h" + str( temp[1:] ))
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400483 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700484 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400485 # One of the host to host pair is unreachable
486 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700487 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700488 pingResponse += "\n"
GlennRC6d506272015-09-25 11:36:07 -0700489 main.log.info( pingResponse + "Failed pings: " + str(failedPings) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700490 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700491 except pexpect.TIMEOUT:
492 main.log.exception( self.name + ": TIMEOUT exception" )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700493 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400494 except pexpect.EOF:
495 main.log.error( self.name + ": EOF exception found" )
496 main.log.error( self.name + ": " + self.handle.before )
497 main.cleanup()
498 main.exit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700499 except Exception:
500 main.log.exception( self.name + ": Uncaught exception!" )
501 main.cleanup()
502 main.exit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400503
Jon Hall3b489db2015-10-05 14:38:37 -0700504 def pingIpv6Hosts( self, hostList, prefix='1000::', wait=1 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700505 """
Jon Hall3b489db2015-10-05 14:38:37 -0700506 IPv6 ping all hosts in hostList. If no prefix passed this will use
507 default prefix of 1000::
Hari Krishna9592fc82015-07-31 15:11:15 -0700508
Jon Hall3b489db2015-10-05 14:38:37 -0700509 Returns main.TRUE if all hosts specified can reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700510
Jon Hall3b489db2015-10-05 14:38:37 -0700511 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700512 """
513 try:
514 main.log.info( "Testing reachability between specified IPv6 hosts" )
515 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700516 wait = int( wait )
517 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700518 pingResponse = "IPv6 Pingall output:\n"
519 failedPings = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700520 for host in hostList:
521 listIndex = hostList.index( host )
522 # List of hosts to ping other than itself
523 pingList = hostList[ :listIndex ] + \
524 hostList[ ( listIndex + 1 ): ]
525
GlennRC2cf7d952015-09-11 16:32:13 -0700526 pingResponse += str(str(host) + " -> ")
527
Hari Krishna9592fc82015-07-31 15:11:15 -0700528 for temp in pingList:
529 # Current host pings all other hosts specified
Jon Hall439c8912016-04-15 02:22:03 -0700530 pingCmd = str( host ) + cmd + str( self.getIPAddress(temp,proto='IPv6') )
Jon Hall934576d2015-10-09 10:12:22 -0700531 self.handle.sendline( pingCmd )
532 self.handle.expect( "mininet>", timeout=wait + 1 )
Hari Krishna9592fc82015-07-31 15:11:15 -0700533 response = self.handle.before
534 if re.search( ',\s0\%\spacket\sloss', response ):
GlennRC2cf7d952015-09-11 16:32:13 -0700535 pingResponse += str(" h" + str( temp[1:] ))
Hari Krishna9592fc82015-07-31 15:11:15 -0700536 else:
GlennRC2cf7d952015-09-11 16:32:13 -0700537 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700538 # One of the host to host pair is unreachable
539 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700540 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700541 pingResponse += "\n"
GlennRC6d506272015-09-25 11:36:07 -0700542 main.log.info( pingResponse + "Failed pings: " + str(failedPings) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700543 return isReachable
544
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700545 except pexpect.TIMEOUT:
546 main.log.exception( self.name + ": TIMEOUT exception" )
547 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700548 except pexpect.EOF:
549 main.log.error( self.name + ": EOF exception found" )
550 main.log.error( self.name + ": " + self.handle.before )
551 main.cleanup()
552 main.exit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700553 except Exception:
554 main.log.exception( self.name + ": Uncaught exception!" )
555 main.cleanup()
556 main.exit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700557
Jon Hall7eb38402015-01-08 17:19:54 -0800558 def pingHost( self, **pingParams ):
559 """
Jon Hall3b489db2015-10-05 14:38:37 -0700560 Ping from one mininet host to another
561 Currently the only supported Params: SRC, TARGET, and WAIT
562 """
563 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
564 wait = args['WAIT']
565 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800566 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700567 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700568 try:
Jon Hall61282e32015-03-19 11:34:11 -0700569 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800570 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700571 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
572 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700573 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800574 main.log.error(
575 self.name +
576 ": timeout when waiting for response from mininet" )
577 main.log.error( "response: " + str( self.handle.before ) )
578 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700579 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800580 main.log.error(
581 self.name +
582 ": timeout when waiting for response from mininet" )
583 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700584 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700585 if re.search( ',\s0\%\spacket\sloss', response ):
586 main.log.info( self.name + ": no packets lost, host is reachable" )
587 return main.TRUE
588 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800589 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700590 self.name +
591 ": PACKET LOST, HOST IS NOT REACHABLE" )
592 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800593 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800594 main.log.error( self.name + ": EOF exception found" )
595 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700596 main.cleanup()
597 main.exit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700598 except Exception:
599 main.log.exception( self.name + ": Uncaught exception!" )
600 main.cleanup()
601 main.exit()
602
603 def ping6pair( self, **pingParams ):
604 """
GlennRC2cf7d952015-09-11 16:32:13 -0700605 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700606 Currently the only supported Params are: SRC, TARGET, and WAIT
Hari Krishna012a1c12015-08-25 14:23:58 -0700607 FLOWLABEL and -I (src interface) will be added later after running some tests.
608 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
609 """
Jon Hall3b489db2015-10-05 14:38:37 -0700610 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
611 wait = args['WAIT']
612 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530613 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700614 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700615 try:
616 main.log.info( "Sending: " + command )
617 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700618 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
619 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700620 if i == 1:
621 main.log.error(
622 self.name +
623 ": timeout when waiting for response from mininet" )
624 main.log.error( "response: " + str( self.handle.before ) )
625 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
626 if i == 1:
627 main.log.error(
628 self.name +
629 ": timeout when waiting for response from mininet" )
630 main.log.error( "response: " + str( self.handle.before ) )
631 response = self.handle.before
632 main.log.info( self.name + ": Ping Response: " + response )
633 if re.search( ',\s0\%\spacket\sloss', response ):
634 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700635 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700636 else:
alisone4121a92016-11-22 16:31:36 -0800637 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700638 self.name +
639 ": PACKET LOST, HOST IS NOT REACHABLE" )
640 return main.FALSE
641
642 except pexpect.EOF:
643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
645 main.cleanup()
646 main.exit()
647 except Exception:
648 main.log.exception( self.name + ": Uncaught exception!" )
649 main.cleanup()
650 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800651
You Wangdb927a52016-02-26 11:03:28 -0800652 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
653 """
654 Description:
655 Ping a set of destination host from host CLI.
656 Logging into a Mininet host CLI is required before calling this funtion.
657 Params:
658 dstIPList is a list of destination ip addresses
659 Returns:
660 main.TRUE if the destination host is reachable
661 main.FALSE otherwise
662 """
663 isReachable = main.TRUE
664 wait = int( wait )
665 cmd = "ping"
666 if IPv6:
667 cmd = cmd + "6"
668 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
669 try:
670 for dstIP in dstIPList:
671 pingCmd = cmd + " " + dstIP
672 self.handle.sendline( pingCmd )
673 i = self.handle.expect( [ self.hostPrompt,
674 '\*\*\* Unknown command: ' + pingCmd,
675 pexpect.TIMEOUT ],
676 timeout=wait + 1 )
677 if i == 0:
678 response = self.handle.before
679 if not re.search( ',\s0\%\spacket\sloss', response ):
680 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
681 isReachable = main.FALSE
682 elif i == 1:
683 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
684 main.cleanup()
685 main.exit()
686 elif i == 2:
687 main.log.error( self.name + ": timeout when waiting for response" )
688 isReachable = main.FALSE
689 else:
690 main.log.error( self.name + ": unknown response: " + self.handle.before )
691 isReachable = main.FALSE
692 except pexpect.TIMEOUT:
693 main.log.exception( self.name + ": TIMEOUT exception" )
694 isReachable = main.FALSE
695 except pexpect.EOF:
696 main.log.error( self.name + ": EOF exception found" )
697 main.log.error( self.name + ": " + self.handle.before )
698 main.cleanup()
699 main.exit()
700 except Exception:
701 main.log.exception( self.name + ": Uncaught exception!" )
702 main.cleanup()
703 main.exit()
704 return isReachable
705
Jon Hall7eb38402015-01-08 17:19:54 -0800706 def checkIP( self, host ):
707 """
708 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700709 try:
710 if self.handle:
711 try:
712 response = self.execute(
713 cmd=host +
714 " ifconfig",
715 prompt="mininet>",
716 timeout=10 )
717 except pexpect.EOF:
718 main.log.error( self.name + ": EOF exception found" )
719 main.log.error( self.name + ": " + self.handle.before )
720 main.cleanup()
721 main.exit()
adminbae64d82013-08-01 10:50:15 -0700722
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700723 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
724 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
725 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
726 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
727 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
728 "[0-9]|25[0-5]|[0-9]{1,2})"
729 # pattern = "inet addr:10.0.0.6"
730 if re.search( pattern, response ):
731 main.log.info( self.name + ": Host Ip configured properly" )
732 return main.TRUE
733 else:
734 main.log.error( self.name + ": Host IP not found" )
735 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700736 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700737 main.log.error( self.name + ": Connection failed to the host" )
738 except Exception:
739 main.log.exception( self.name + ": Uncaught exception!" )
740 main.cleanup()
741 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800742
Jon Hall7eb38402015-01-08 17:19:54 -0800743 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800744 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700745 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 response = self.execute(
747 cmd="h1 /usr/sbin/sshd -D&",
748 prompt="mininet>",
749 timeout=10 )
750 response = self.execute(
751 cmd="h4 /usr/sbin/sshd -D&",
752 prompt="mininet>",
753 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700754 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800755 vars( self )[ key ] = connectargs[ key ]
756 response = self.execute(
757 cmd="xterm h1 h4 ",
758 prompt="mininet>",
759 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800760 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700763 main.cleanup()
764 main.exit()
adminbae64d82013-08-01 10:50:15 -0700765 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800766 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700767 if self.flag == 0:
768 self.flag = 1
769 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800770 else:
adminbae64d82013-08-01 10:50:15 -0700771 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800772
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700773 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700774 """
775 Moves a host from one switch to another on the fly
776 Note: The intf between host and oldSw when detached
777 using detach(), will still show up in the 'net'
778 cmd, because switch.detach() doesn't affect switch.intfs[]
779 ( which is correct behavior since the interfaces
780 haven't moved ).
781 """
782 if self.handle:
783 try:
784 # Bring link between oldSw-host down
785 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
786 "'," + "'down')"
787 print "cmd1= ", cmd
788 response = self.execute( cmd=cmd,
789 prompt="mininet>",
790 timeout=10 )
791
792 # Determine hostintf and Oldswitchintf
793 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
794 ")[0]"
795 print "cmd2= ", cmd
796 self.handle.sendline( cmd )
797 self.handle.expect( "mininet>" )
798
799 # Determine ip and mac address of the host-oldSw interface
800 cmd = "px ipaddr = hintf.IP()"
801 print "cmd3= ", cmd
802 self.handle.sendline( cmd )
803 self.handle.expect( "mininet>" )
804
805 cmd = "px macaddr = hintf.MAC()"
806 print "cmd3= ", cmd
807 self.handle.sendline( cmd )
808 self.handle.expect( "mininet>" )
809
810 # Detach interface between oldSw-host
811 cmd = "px " + oldSw + ".detach( sintf )"
812 print "cmd4= ", cmd
813 self.handle.sendline( cmd )
814 self.handle.expect( "mininet>" )
815
816 # Add link between host-newSw
817 cmd = "py net.addLink(" + host + "," + newSw + ")"
818 print "cmd5= ", cmd
819 self.handle.sendline( cmd )
820 self.handle.expect( "mininet>" )
821
822 # Determine hostintf and Newswitchintf
823 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
824 ")[0]"
825 print "cmd6= ", cmd
826 self.handle.sendline( cmd )
827 self.handle.expect( "mininet>" )
828
829 # Attach interface between newSw-host
830 cmd = "px " + newSw + ".attach( sintf )"
831 print "cmd3= ", cmd
832 self.handle.sendline( cmd )
833 self.handle.expect( "mininet>" )
834
835 # Set ipaddress of the host-newSw interface
836 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
837 print "cmd7 = ", cmd
838 self.handle.sendline( cmd )
839 self.handle.expect( "mininet>" )
840
841 # Set macaddress of the host-newSw interface
842 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
843 print "cmd8 = ", cmd
844 self.handle.sendline( cmd )
845 self.handle.expect( "mininet>" )
846
847 cmd = "net"
848 print "cmd9 = ", cmd
849 self.handle.sendline( cmd )
850 self.handle.expect( "mininet>" )
851 print "output = ", self.handle.before
852
853 # Determine ipaddress of the host-newSw interface
854 cmd = host + " ifconfig"
855 print "cmd10= ", cmd
856 self.handle.sendline( cmd )
857 self.handle.expect( "mininet>" )
858 print "ifconfig o/p = ", self.handle.before
859
860 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700861
862 except pexpect.TIMEOUT:
863 main.log.error(self.name + ": TIMEOUT exception found")
864 main.log.error(self.name + ": " + self.handle.before)
865 main.cleanup()
866 main.exit()
Jon Hall53c5e662016-04-13 16:06:56 -0700867 except pexpect.EOF:
868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
870 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700871 except Exception:
872 main.log.exception( self.name + ": Uncaught exception!" )
873 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700874
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700875 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800876 """
877 Moves a host from one switch to another on the fly
878 Note: The intf between host and oldSw when detached
879 using detach(), will still show up in the 'net'
880 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700881 ( which is correct behavior since the interfaces
882 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800883 """
884 if self.handle:
885 try:
Jon Hall439c8912016-04-15 02:22:03 -0700886 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800887 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700888 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800889 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800890 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800891 response = self.execute( cmd=cmd,
892 prompt="mininet>",
893 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700894
kelvin-onlaba1484582015-02-02 15:46:20 -0800895 # Determine hostintf and Oldswitchintf
896 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800897 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800898 print "cmd2= ", cmd
899 self.handle.sendline( cmd )
900 self.handle.expect( "mininet>" )
901
shahshreya73537862015-02-11 15:15:24 -0800902 # Determine ip and mac address of the host-oldSw interface
Jon Hall439c8912016-04-15 02:22:03 -0700903 cmd = "px ipaddr = " + str(IP)
kelvin-onlaba1484582015-02-02 15:46:20 -0800904 print "cmd3= ", cmd
905 self.handle.sendline( cmd )
906 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800907
908 cmd = "px macaddr = hintf.MAC()"
909 print "cmd3= ", cmd
910 self.handle.sendline( cmd )
911 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700912
kelvin-onlaba1484582015-02-02 15:46:20 -0800913 # Detach interface between oldSw-host
914 cmd = "px " + oldSw + ".detach( sintf )"
915 print "cmd4= ", cmd
916 self.handle.sendline( cmd )
917 self.handle.expect( "mininet>" )
918
919 # Add link between host-newSw
920 cmd = "py net.addLink(" + host + "," + newSw + ")"
921 print "cmd5= ", cmd
922 self.handle.sendline( cmd )
923 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700924
kelvin-onlaba1484582015-02-02 15:46:20 -0800925 # Determine hostintf and Newswitchintf
926 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800927 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800928 print "cmd6= ", cmd
929 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700930 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800931
932 # Attach interface between newSw-host
933 cmd = "px " + newSw + ".attach( sintf )"
Jon Hall439c8912016-04-15 02:22:03 -0700934 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800935 self.handle.sendline( cmd )
936 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800937
938 # Set macaddress of the host-newSw interface
939 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700940 print "cmd7 = ", cmd
941 self.handle.sendline( cmd )
942 self.handle.expect( "mininet>" )
943
944 # Set ipaddress of the host-newSw interface
945 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800946 print "cmd8 = ", cmd
947 self.handle.sendline( cmd )
948 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700949
Jon Hall439c8912016-04-15 02:22:03 -0700950 cmd = host + " ifconfig"
951 print "cmd9 =",cmd
952 response = self.execute( cmd = cmd, prompt="mininet>" ,timeout=10 )
953 print response
954 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700955 ipAddressSearch = re.search( pattern, response )
Jon Hall439c8912016-04-15 02:22:03 -0700956 print ipAddressSearch.group(1)
957 intf= host + "-eth" + str(ipAddressSearch.group(1))
958 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
959 print "cmd10 = ", cmd
960 self.handle.sendline( cmd )
961 self.handle.expect( "mininet>" )
962
kelvin-onlaba1484582015-02-02 15:46:20 -0800963 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700964 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800965 self.handle.sendline( cmd )
966 self.handle.expect( "mininet>" )
967 print "output = ", self.handle.before
968
969 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800970 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700971 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800972 self.handle.sendline( cmd )
973 self.handle.expect( "mininet>" )
974 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700975
kelvin-onlaba1484582015-02-02 15:46:20 -0800976 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700977 except pexpect.TIMEOUT:
978 main.log.error(self.name + ": TIMEOUT exception found")
979 main.log.error(self.name + ": " + self.handle.before)
980 main.cleanup()
981 main.exit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800982 except pexpect.EOF:
983 main.log.error( self.name + ": EOF exception found" )
984 main.log.error( self.name + ": " + self.handle.before )
985 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700986 except Exception:
987 main.log.exception( self.name + ": Uncaught exception!" )
988 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800989
Jon Hall7eb38402015-01-08 17:19:54 -0800990 def changeIP( self, host, intf, newIP, newNetmask ):
991 """
992 Changes the ip address of a host on the fly
993 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800994 if self.handle:
995 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800996 cmd = host + " ifconfig " + intf + " " + \
997 newIP + " " + 'netmask' + " " + newNetmask
998 self.handle.sendline( cmd )
999 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001000 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001001 main.log.info( "response = " + response )
1002 main.log.info(
1003 "Ip of host " +
1004 host +
1005 " changed to new IP " +
1006 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001007 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001008 except pexpect.TIMEOUT:
1009 main.log.error(self.name + ": TIMEOUT exception found")
1010 main.log.error(self.name + ": " + self.handle.before)
1011 main.cleanup()
1012 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001013 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001014 main.log.error( self.name + ": EOF exception found" )
1015 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001016 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001017 except Exception:
1018 main.log.exception( self.name + ": Uncaught exception!" )
1019 main.cleanup()
1020 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001021
Jon Hall7eb38402015-01-08 17:19:54 -08001022 def changeDefaultGateway( self, host, newGW ):
1023 """
1024 Changes the default gateway of a host
1025 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001026 if self.handle:
1027 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001028 cmd = host + " route add default gw " + newGW
1029 self.handle.sendline( cmd )
1030 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001031 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001032 main.log.info( "response = " + response )
1033 main.log.info(
1034 "Default gateway of host " +
1035 host +
1036 " changed to " +
1037 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001038 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001039 except pexpect.TIMEOUT:
1040 main.log.error(self.name + ": TIMEOUT exception found")
1041 main.log.error(self.name + ": " + self.handle.before)
1042 main.cleanup()
1043 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001044 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001047 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001048 except Exception:
1049 main.log.exception( self.name + ": Uncaught exception!" )
1050 main.cleanup()
1051 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001052
Jon Hall7eb38402015-01-08 17:19:54 -08001053 def addStaticMACAddress( self, host, GW, macaddr ):
1054 """
Jon Hallefbd9792015-03-05 16:11:36 -08001055 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001056 if self.handle:
1057 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001058 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1059 cmd = host + " arp -s " + GW + " " + macaddr
1060 self.handle.sendline( cmd )
1061 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001062 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001063 main.log.info( "response = " + response )
1064 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001065 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001066 GW +
1067 " changed to " +
1068 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001069 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001070 except pexpect.TIMEOUT:
1071 main.log.error(self.name + ": TIMEOUT exception found")
1072 main.log.error(self.name + ": " + self.handle.before)
1073 main.cleanup()
1074 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001075 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001076 main.log.error( self.name + ": EOF exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001078 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001079 except Exception:
1080 main.log.exception( self.name + ": Uncaught exception!" )
1081 main.cleanup()
1082 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001083
Jon Hall7eb38402015-01-08 17:19:54 -08001084 def verifyStaticGWandMAC( self, host ):
1085 """
1086 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001087 if self.handle:
1088 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001089 # h1 arp -an
1090 cmd = host + " arp -an "
1091 self.handle.sendline( cmd )
1092 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001093 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001094 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001095 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001096 except pexpect.TIMEOUT:
1097 main.log.error(self.name + ": TIMEOUT exception found")
1098 main.log.error(self.name + ": " + self.handle.before)
1099 main.cleanup()
1100 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001101 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001102 main.log.error( self.name + ": EOF exception found" )
1103 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001104 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001105 except Exception:
1106 main.log.exception( self.name + ": Uncaught exception!" )
1107 main.cleanup()
1108 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001109
Jon Hall7eb38402015-01-08 17:19:54 -08001110 def getMacAddress( self, host ):
1111 """
1112 Verifies the host's ip configured or not."""
1113 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001114 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001115 response = self.execute(
1116 cmd=host +
1117 " ifconfig",
1118 prompt="mininet>",
1119 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001120 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001121 main.log.error( self.name + ": EOF exception found" )
1122 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001123 main.cleanup()
1124 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001125 except Exception:
1126 main.log.exception( self.name + ": Uncaught exception!" )
1127 main.cleanup()
1128 main.exit()
adminbae64d82013-08-01 10:50:15 -07001129
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001130 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 macAddressSearch = re.search( pattern, response, re.I )
1132 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001133 main.log.info(
1134 self.name +
1135 ": Mac-Address of Host " +
1136 host +
1137 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 macAddress )
1139 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001140 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001141 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001142
Jon Hall7eb38402015-01-08 17:19:54 -08001143 def getInterfaceMACAddress( self, host, interface ):
1144 """
1145 Return the IP address of the interface on the given host"""
1146 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001147 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001148 response = self.execute( cmd=host + " ifconfig " + interface,
1149 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001150 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001151 main.log.error( self.name + ": EOF exception found" )
1152 main.log.error( self.name + ": " + self.handle.before )
1153 main.cleanup()
1154 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001155 except Exception:
1156 main.log.exception( self.name + ": Uncaught exception!" )
1157 main.cleanup()
1158 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001159
1160 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 macAddressSearch = re.search( pattern, response, re.I )
1162 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001163 main.log.info( "No mac address found in %s" % response )
1164 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001166 main.log.info(
1167 "Mac-Address of " +
1168 host +
1169 ":" +
1170 interface +
1171 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 macAddress )
1173 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001174 else:
1175 main.log.error( "Connection failed to the host" )
1176
sathishmad953462015-12-03 17:42:07 +05301177 def getIPAddress( self, host , proto='IPV4'):
Jon Hall7eb38402015-01-08 17:19:54 -08001178 """
1179 Verifies the host's ip configured or not."""
1180 if self.handle:
1181 try:
1182 response = self.execute(
1183 cmd=host +
1184 " ifconfig",
1185 prompt="mininet>",
1186 timeout=10 )
1187 except pexpect.EOF:
1188 main.log.error( self.name + ": EOF exception found" )
1189 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001190 main.cleanup()
1191 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001192 except Exception:
1193 main.log.exception( self.name + ": Uncaught exception!" )
1194 main.cleanup()
1195 main.exit()
adminbae64d82013-08-01 10:50:15 -07001196
sathishmad953462015-12-03 17:42:07 +05301197 pattern = ''
1198 if proto == 'IPV4':
1199 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1200 else:
Jon Hall439c8912016-04-15 02:22:03 -07001201 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001203 main.log.info(
1204 self.name +
1205 ": IP-Address of Host " +
1206 host +
1207 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 ipAddressSearch.group( 1 ) )
1209 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001210 else:
1211 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001212
Jon Hall7eb38402015-01-08 17:19:54 -08001213 def getSwitchDPID( self, switch ):
1214 """
1215 return the datapath ID of the switch"""
1216 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001217 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001218 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001219 response = self.execute(
1220 cmd=cmd,
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 )
Jon Hall6094a362014-04-11 14:46:56 -07001226 main.cleanup()
1227 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001228 except Exception:
1229 main.log.exception( self.name + ": Uncaught exception!" )
1230 main.cleanup()
1231 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001232 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001233 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001234 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001235 main.log.info(
1236 "Couldn't find DPID for switch %s, found: %s" %
1237 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001238 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001239 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001240 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001242
Jon Hall7eb38402015-01-08 17:19:54 -08001243 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001244 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001245 self.handle.sendline( "" )
1246 self.expect( "mininet>" )
1247 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001248 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 response = self.execute(
1250 cmd=cmd,
1251 prompt="mininet>",
1252 timeout=10 )
1253 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001254 response = self.handle.before
1255 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001256 except pexpect.TIMEOUT:
1257 main.log.error(self.name + ": TIMEOUT exception found")
1258 main.log.error(self.name + ": " + self.handle.before)
1259 main.cleanup()
1260 main.exit()
admin2580a0e2014-07-29 11:24:34 -07001261 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001262 main.log.error( self.name + ": EOF exception found" )
1263 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -07001264 main.cleanup()
1265 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001266 except Exception:
1267 main.log.exception( self.name + ": Uncaught exception!" )
1268 main.cleanup()
1269 main.exit()
admin2580a0e2014-07-29 11:24:34 -07001270
Jon Hall7eb38402015-01-08 17:19:54 -08001271 def getInterfaces( self, node ):
1272 """
1273 return information dict about interfaces connected to the node"""
1274 if self.handle:
1275 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001276 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001277 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001278 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001279 response = self.execute(
1280 cmd=cmd,
1281 prompt="mininet>",
1282 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001283 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001284 main.log.error( self.name + ": EOF exception found" )
1285 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001286 main.cleanup()
1287 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001288 except Exception:
1289 main.log.exception( self.name + ": Uncaught exception!" )
1290 main.cleanup()
1291 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001292 return response
1293 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001294 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001295
Jon Hall7eb38402015-01-08 17:19:54 -08001296 def dump( self ):
1297 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001298 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001299 response = self.execute(
1300 cmd='dump',
1301 prompt='mininet>',
1302 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001303 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001304 main.log.error( self.name + ": EOF exception found" )
1305 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001306 main.cleanup()
1307 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001308 except Exception:
1309 main.log.exception( self.name + ": Uncaught exception!" )
1310 main.cleanup()
1311 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001312 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001313
Jon Hall7eb38402015-01-08 17:19:54 -08001314 def intfs( self ):
1315 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001316 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001317 response = self.execute(
1318 cmd='intfs',
1319 prompt='mininet>',
1320 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001321 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001324 main.cleanup()
1325 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001326 except Exception:
1327 main.log.exception( self.name + ": Uncaught exception!" )
1328 main.cleanup()
1329 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001330 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001331
Jon Hall7eb38402015-01-08 17:19:54 -08001332 def net( self ):
1333 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001334 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001335 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001336 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001337 main.log.error( self.name + ": EOF exception found" )
1338 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001339 main.cleanup()
1340 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001341 except Exception:
1342 main.log.exception( self.name + ": Uncaught exception!" )
1343 main.cleanup()
1344 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001345 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001346
YPZhang81a7d4e2016-04-18 13:10:17 -07001347 def links( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001348 main.log.info( self.name + ": List network links" )
1349 try:
1350 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001351 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001352 except pexpect.EOF:
1353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
1355 main.cleanup()
1356 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001357 except Exception:
1358 main.log.exception( self.name + ": Uncaught exception!" )
1359 main.cleanup()
1360 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07001361 return response
1362
GlennRC61321f22015-07-16 13:36:54 -07001363 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001364 '''
1365 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001366
kelvin-onlab7cce9382015-07-17 10:21:03 -07001367 @parm:
1368 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1369 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1370 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001371 try:
1372 for host1 in hosts:
1373 for host2 in hosts:
1374 if host1 != host2:
1375 if self.iperftcp(host1, host2, timeout) == main.FALSE:
1376 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
1377 except Exception:
1378 main.log.exception( self.name + ": Uncaught exception!" )
1379 main.cleanup()
1380 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001381
1382 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001383 '''
1384 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1385 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001386
kelvin-onlab7cce9382015-07-17 10:21:03 -07001387 @parm:
1388 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1389 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1390 '''
1391 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1392 try:
1393 # Setup the mininet command
1394 cmd1 = 'iperf ' + host1 + " " + host2
1395 self.handle.sendline( cmd1 )
1396 outcome = self.handle.expect( "mininet>", timeout )
1397 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001398
kelvin-onlab7cce9382015-07-17 10:21:03 -07001399 # checks if there are results in the mininet response
1400 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001401 main.log.report(self.name + ": iperf test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001402 # parse the mn results
1403 response = response.split("\r\n")
1404 response = response[len(response)-2]
1405 response = response.split(": ")
1406 response = response[len(response)-1]
1407 response = response.replace("[", "")
1408 response = response.replace("]", "")
1409 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001410
kelvin-onlab7cce9382015-07-17 10:21:03 -07001411 # this is the bandwith two and from the two hosts
1412 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001413
kelvin-onlab7cce9382015-07-17 10:21:03 -07001414 # there should be two elements in the bandwidth list
1415 # ['host1 to host2', 'host2 to host1"]
1416 if len(bandwidth) == 2:
1417 main.log.report(self.name + ": iperf test successful")
1418 return main.TRUE
1419 else:
1420 main.log.error(self.name + ": invalid iperf results")
1421 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001422 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001423 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001424 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001425 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001426 main.log.error( self.name + ": TIMEOUT exception found" )
1427 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001428 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001429 # NOTE: Send ctrl-c to make sure iperf is done
1430 self.handle.sendline( "\x03" )
1431 self.handle.expect( "Interrupt" )
1432 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001433 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001434 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001437 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001438 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001439 except Exception:
1440 main.log.exception( self.name + ": Uncaught exception!" )
1441 main.cleanup()
1442 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001443
Jon Hall439c8912016-04-15 02:22:03 -07001444 def iperftcpipv6(self, host1="h1", host2="h2", timeout=50):
1445 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1446 try:
1447 IP1 = self.getIPAddress( host1, proto='IPV6' )
1448 cmd1 = host1 +' iperf -V -sD -B '+ str(IP1)
1449 self.handle.sendline( cmd1 )
1450 outcome1 = self.handle.expect( "mininet>")
1451 cmd2 = host2 +' iperf -V -c '+ str(IP1) +' -t 5'
1452 self.handle.sendline( cmd2 )
1453 outcome2 = self.handle.expect( "mininet>")
1454 response1 = self.handle.before
1455 response2 = self.handle.after
1456 print response1,response2
1457 pattern = "connected with "+ str(IP1)
1458 if pattern in response1:
1459 main.log.report(self.name + ": iperf test completed")
1460 return main.TRUE
1461 else:
1462 main.log.error( self.name + ": iperf test failed" )
1463 return main.FALSE
1464 except pexpect.TIMEOUT:
1465 main.log.error( self.name + ": TIMEOUT exception found" )
1466 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1467 self.handle.sendline( "\x03" )
1468 self.handle.expect( "Interrupt" )
1469 self.handle.expect( "mininet>" )
1470 return main.FALSE
1471 except pexpect.EOF:
1472 main.log.error( self.name + ": EOF exception found" )
1473 main.log.error( self.name + ": " + self.handle.before )
1474 main.cleanup()
1475 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001476 except Exception:
1477 main.log.exception( self.name + ": Uncaught exception!" )
1478 main.cleanup()
1479 main.exit()
Jon Hall439c8912016-04-15 02:22:03 -07001480
GlennRC61321f22015-07-16 13:36:54 -07001481 def iperfudpAll(self, hosts, bandwidth="10M"):
1482 '''
1483 Runs the iperfudp function with a given set of hosts and specified
1484 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001485
GlennRC61321f22015-07-16 13:36:54 -07001486 @param:
1487 bandwidth: the targeted bandwidth, in megabits ('M')
1488 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001489 try:
1490 for host1 in hosts:
1491 for host2 in hosts:
1492 if host1 != host2:
1493 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1494 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1495 except TypeError:
1496 main.log.exception(self.name + ": Object not as expected")
1497 return main.FALSE
1498 except Exception:
1499 main.log.exception( self.name + ": Uncaught exception!" )
1500 main.cleanup()
1501 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001502
1503 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1504
kelvin-onlab7cce9382015-07-17 10:21:03 -07001505 '''
1506 Creates an iperf UDP test with a specific bandwidth.
1507 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001508
kelvin-onlab7cce9382015-07-17 10:21:03 -07001509 @param:
1510 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1511 '''
1512 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1513 try:
1514 # setup the mininet command
1515 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1516 self.handle.sendline(cmd)
1517 self.handle.expect("mininet>")
1518 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001519
kelvin-onlab7cce9382015-07-17 10:21:03 -07001520 # check if there are in results in the mininet response
1521 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001522 main.log.report(self.name + ": iperfudp test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001523 # parse the results
1524 response = response.split("\r\n")
1525 response = response[len(response)-2]
1526 response = response.split(": ")
1527 response = response[len(response)-1]
1528 response = response.replace("[", "")
1529 response = response.replace("]", "")
1530 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001531
kelvin-onlab7cce9382015-07-17 10:21:03 -07001532 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001533
kelvin-onlab7cce9382015-07-17 10:21:03 -07001534 # check to see if there are at least three entries
1535 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1536 if len(mnBandwidth) == 3:
1537 # if one entry is blank then something is wrong
1538 for item in mnBandwidth:
1539 if item == "":
1540 main.log.error(self.name + ": Could not parse iperf output")
1541 main.log.error(self.name + ": invalid iperfudp results")
1542 return main.FALSE
1543 # otherwise results are vaild
1544 main.log.report(self.name + ": iperfudp test successful")
1545 return main.TRUE
1546 else:
1547 main.log.error(self.name + ": invalid iperfudp results")
1548 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001549
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001550 except pexpect.TIMEOUT:
1551 main.log.error(self.name + ": TIMEOUT exception found")
1552 main.log.error(self.name + ": " + self.handle.before)
1553 main.cleanup()
1554 main.exit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001555 except pexpect.EOF:
1556 main.log.error( self.name + ": EOF exception found" )
1557 main.log.error( self.name + ": " + self.handle.before )
1558 main.cleanup()
1559 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001560 except Exception:
1561 main.log.exception( self.name + ": Uncaught exception!" )
1562 main.cleanup()
1563 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001564
Jon Hall7eb38402015-01-08 17:19:54 -08001565 def nodes( self ):
1566 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001567 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001568 response = self.execute(
1569 cmd='nodes',
1570 prompt='mininet>',
1571 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001572 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001573 main.log.error( self.name + ": EOF exception found" )
1574 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001575 main.cleanup()
1576 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001577 except Exception:
1578 main.log.exception( self.name + ": Uncaught exception!" )
1579 main.cleanup()
1580 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001581 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001582
Jon Hall7eb38402015-01-08 17:19:54 -08001583 def pingpair( self ):
1584 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001585 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001586 response = self.execute(
1587 cmd='pingpair',
1588 prompt='mininet>',
1589 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001590 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001591 main.log.error( self.name + ": EOF exception found" )
1592 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001593 main.cleanup()
1594 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001595 except Exception:
1596 main.log.exception( self.name + ": Uncaught exception!" )
1597 main.cleanup()
1598 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001599
Jon Hall7eb38402015-01-08 17:19:54 -08001600 if re.search( ',\s0\%\spacket\sloss', response ):
1601 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001602 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001603 else:
alisone4121a92016-11-22 16:31:36 -08001604 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001605 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001606
Jon Hall7eb38402015-01-08 17:19:54 -08001607 def link( self, **linkargs ):
1608 """
GlennRCed771242016-01-13 17:02:47 -08001609 Bring link( s ) between two nodes up or down
1610 """
Jon Hall6094a362014-04-11 14:46:56 -07001611 try:
GlennRCed771242016-01-13 17:02:47 -08001612 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1613 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1614 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1615 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1616
1617 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1618 cmd = "link {} {} {}".format( end1, end2, option )
1619 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001620 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001621 response = self.handle.before
1622 main.log.info( response )
1623
1624 return main.TRUE
1625 except pexpect.TIMEOUT:
1626 main.log.exception( self.name + ": Command timed out" )
1627 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001628 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001629 main.log.exception( self.name + ": connection closed." )
Jon Hall6094a362014-04-11 14:46:56 -07001630 main.cleanup()
1631 main.exit()
GlennRCed771242016-01-13 17:02:47 -08001632 except Exception:
1633 main.log.exception( self.name + ": Uncaught exception!" )
1634 main.cleanup()
1635 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001636
pingping-lin8244a3b2015-09-16 13:36:56 -07001637 def switch( self, **switchargs ):
1638 """
1639 start/stop a switch
1640 """
1641 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1642 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1643 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1644 command = "switch " + str( sw ) + " " + str( option )
1645 main.log.info( command )
1646 try:
1647 self.handle.sendline( command )
1648 self.handle.expect( "mininet>" )
1649 except pexpect.TIMEOUT:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001650 main.log.error(self.name + ": TIMEOUT exception found")
1651 main.log.error(self.name + ": " + self.handle.before)
pingping-lin8244a3b2015-09-16 13:36:56 -07001652 main.cleanup()
1653 main.exit()
1654 except pexpect.EOF:
1655 main.log.error( self.name + ": EOF exception found" )
1656 main.log.error( self.name + ": " + self.handle.before )
1657 main.cleanup()
1658 main.exit()
1659 return main.TRUE
1660
pingping-lin5bb663b2015-09-24 11:47:50 -07001661 def node( self, nodeName, commandStr ):
1662 """
1663 Carry out a command line on a given node
1664 @parm:
1665 nodeName: the node name in Mininet testbed
1666 commandStr: the command line will be carried out on the node
1667 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1668 """
1669 command = str( nodeName ) + " " + str( commandStr )
1670 main.log.info( command )
1671
1672 try:
1673 response = self.execute( cmd = command, prompt = "mininet>" )
1674 if re.search( "Unknown command", response ):
1675 main.log.warn( response )
1676 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001677 if re.search( "Permission denied", response ):
1678 main.log.warn( response )
1679 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001680 except pexpect.EOF:
1681 main.log.error( self.name + ": EOF exception found" )
1682 main.log.error( self.name + ": " + self.handle.before )
1683 main.cleanup()
1684 main.exit()
1685 main.log.info( " response is :" )
1686 main.log.info( response )
1687 return response
1688
Jon Hall7eb38402015-01-08 17:19:54 -08001689 def yank( self, **yankargs ):
1690 """
1691 yank a mininet switch interface to a host"""
1692 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001693 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001694 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1695 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1696 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001697 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001698 response = self.execute(
1699 cmd=command,
1700 prompt="mininet>",
1701 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001702 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001703 main.log.error( self.name + ": EOF exception found" )
1704 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001705 main.cleanup()
1706 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001707 except Exception:
1708 main.log.exception( self.name + ": Uncaught exception!" )
1709 main.cleanup()
1710 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001711 return main.TRUE
1712
Jon Hall7eb38402015-01-08 17:19:54 -08001713 def plug( self, **plugargs ):
1714 """
1715 plug the yanked mininet switch interface to a switch"""
1716 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001717 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001718 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1719 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1720 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001721 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001722 response = self.execute(
1723 cmd=command,
1724 prompt="mininet>",
1725 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001726 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001727 main.log.error( self.name + ": EOF exception found" )
1728 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001729 main.cleanup()
1730 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001731 except Exception:
1732 main.log.exception( self.name + ": Uncaught exception!" )
1733 main.cleanup()
1734 main.exit()
adminbae64d82013-08-01 10:50:15 -07001735 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001736
Jon Hall7eb38402015-01-08 17:19:54 -08001737 def dpctl( self, **dpctlargs ):
1738 """
1739 Run dpctl command on all switches."""
1740 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001741 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001742 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1743 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1744 command = "dpctl " + cmd + " " + str( cmdargs )
1745 try:
1746 response = self.execute(
1747 cmd=command,
1748 prompt="mininet>",
1749 timeout=10 )
1750 except pexpect.EOF:
1751 main.log.error( self.name + ": EOF exception found" )
1752 main.log.error( self.name + ": " + self.handle.before )
1753 main.cleanup()
1754 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001755 except Exception:
1756 main.log.exception( self.name + ": Uncaught exception!" )
1757 main.cleanup()
1758 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001759 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001760
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001762 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001763 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001764 try:
1765 fileInput = path + '/lib/Mininet/INSTALL'
1766 version = super( Mininet, self ).getVersion()
1767 pattern = 'Mininet\s\w\.\w\.\w\w*'
1768 for line in open( fileInput, 'r' ).readlines():
1769 result = re.match( pattern, line )
1770 if result:
1771 version = result.group( 0 )
1772 return version
1773 except Exception:
1774 main.log.exception( self.name + ": Uncaught exception!" )
1775 main.cleanup()
1776 main.exit()
adminbae64d82013-08-01 10:50:15 -07001777
kelvin-onlabd3b64892015-01-20 13:26:24 -08001778 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001779 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001780 Parameters:
1781 sw: The name of an OVS switch. Example "s1"
1782 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001783 The output of the command from the mininet cli
1784 or main.FALSE on timeout"""
1785 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001786 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001787 response = self.execute(
1788 cmd=command,
1789 prompt="mininet>",
1790 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001791 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001792 return response
admin2a9548d2014-06-17 14:08:07 -07001793 else:
1794 return main.FALSE
1795 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001796 main.log.error( self.name + ": EOF exception found" )
1797 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001798 main.cleanup()
1799 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001800 except Exception:
1801 main.log.exception( self.name + ": Uncaught exception!" )
1802 main.cleanup()
1803 main.exit()
adminbae64d82013-08-01 10:50:15 -07001804
Charles Chan029be652015-08-24 01:46:10 +08001805 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001806 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001807 Description:
1808 Assign switches to the controllers ( for ovs use only )
1809 Required:
1810 sw - Name of the switch. This can be a list or a string.
1811 ip - Ip addresses of controllers. This can be a list or a string.
1812 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001813 port - ONOS use port 6653, if no list of ports is passed, then
1814 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001815 ptcp - ptcp number, This can be a string or a list that has
1816 the same length as switch. This is optional and not required
1817 when using ovs switches.
1818 NOTE: If switches and ptcp are given in a list type they should have the
1819 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1820 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001821
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001822 Return:
1823 Returns main.TRUE if mininet correctly assigned switches to
1824 controllers, otherwise it will return main.FALSE or an appropriate
1825 exception(s)
1826 """
1827 assignResult = main.TRUE
1828 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001829 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001830 command = "sh ovs-vsctl set-controller "
1831 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001832 try:
1833 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001834 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001835 if isinstance( port, types.StringType ) or \
1836 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001837 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001838 elif isinstance( port, types.ListType ):
1839 main.log.error( self.name + ": Only one controller " +
1840 "assigned and a list of ports has" +
1841 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001842 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001843 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001844 main.log.error( self.name + ": Invalid controller port " +
1845 "number. Please specify correct " +
1846 "controller port" )
1847 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001848
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001849 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001850 if isinstance( port, types.StringType ) or \
1851 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001852 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001853 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1854 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001855 elif isinstance( port, types.ListType ):
1856 if ( len( ip ) != len( port ) ):
1857 main.log.error( self.name + ": Port list = " +
1858 str( len( port ) ) +
1859 "should be the same as controller" +
1860 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001861 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001862 else:
1863 onosIp = ""
1864 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001865 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1866 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001867 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001868 main.log.error( self.name + ": Invalid controller port " +
1869 "number. Please specify correct " +
1870 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001871 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001872 else:
1873 main.log.error( self.name + ": Invalid ip address" )
1874 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001875
1876 if isinstance( sw, types.StringType ):
1877 command += sw + " "
1878 if ptcp:
1879 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001880 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001881 elif isinstance( ptcp, types.ListType ):
1882 main.log.error( self.name + ": Only one switch is " +
1883 "being set and multiple PTCP is " +
1884 "being passed " )
1885 else:
1886 main.log.error( self.name + ": Invalid PTCP" )
1887 ptcp = ""
1888 command += onosIp
1889 commandList.append( command )
1890
1891 elif isinstance( sw, types.ListType ):
1892 if ptcp:
1893 if isinstance( ptcp, types.ListType ):
1894 if len( ptcp ) != len( sw ):
1895 main.log.error( self.name + ": PTCP length = " +
1896 str( len( ptcp ) ) +
1897 " is not the same as switch" +
1898 " length = " +
1899 str( len( sw ) ) )
1900 return main.FALSE
1901 else:
1902 for switch, ptcpNum in zip( sw, ptcp ):
1903 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001904 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001905 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001906 tempCmd += onosIp
1907 commandList.append( tempCmd )
1908 else:
1909 main.log.error( self.name + ": Invalid PTCP" )
1910 return main.FALSE
1911 else:
1912 for switch in sw:
1913 tempCmd = "sh ovs-vsctl set-controller "
1914 tempCmd += switch + " " + onosIp
1915 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001916 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001917 main.log.error( self.name + ": Invalid switch type " )
1918 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001919
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001920 for cmd in commandList:
1921 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001922 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001923 except pexpect.TIMEOUT:
1924 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1925 return main.FALSE
1926 except pexpect.EOF:
1927 main.log.error( self.name + ": EOF exception found" )
1928 main.log.error( self.name + ": " + self.handle.before )
1929 main.cleanup()
1930 main.exit()
1931 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001932 except pexpect.EOF:
1933 main.log.error( self.name + ": EOF exception found" )
1934 main.log.error( self.name + ": " + self.handle.before )
1935 main.cleanup()
1936 main.exit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001937 except Exception:
1938 main.log.exception( self.name + ": Uncaught exception!" )
1939 main.cleanup()
1940 main.exit()
adminbae64d82013-08-01 10:50:15 -07001941
kelvin-onlabd3b64892015-01-20 13:26:24 -08001942 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001943 """
1944 Removes the controller target from sw"""
1945 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001946 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001947 response = self.execute(
1948 cmd=command,
1949 prompt="mininet>",
1950 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001951 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001952 main.log.error( self.name + ": EOF exception found" )
1953 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001954 main.cleanup()
1955 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001956 except Exception:
1957 main.log.exception( self.name + ": Uncaught exception!" )
1958 main.cleanup()
1959 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001960 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001961 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001962
kelvin-onlabd3b64892015-01-20 13:26:24 -08001963 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001964 """
Jon Hallb1290e82014-11-18 16:17:48 -05001965 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001966 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001967 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001968 NOTE: cannot currently specify what type of switch
1969 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001970 sw = name of the new switch as a string
1971 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001972 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001973 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001974 """
1975 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001976 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001977 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001978 response = self.execute(
1979 cmd=command,
1980 prompt="mininet>",
1981 timeout=10 )
1982 if re.search( "already exists!", response ):
1983 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001984 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001985 elif re.search( "Error", response ):
1986 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001987 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001988 elif re.search( "usage:", response ):
1989 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001990 return main.FALSE
1991 else:
1992 return main.TRUE
1993 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001994 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001995 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001996 main.cleanup()
1997 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001998 except Exception:
1999 main.log.exception( self.name + ": Uncaught exception!" )
2000 main.cleanup()
2001 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002002
kelvin-onlabd3b64892015-01-20 13:26:24 -08002003 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002004 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002005 delete a switch from the mininet topology
2006 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002007 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002008 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002009 sw = name of the switch as a string
2010 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002011 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002012 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002013 response = self.execute(
2014 cmd=command,
2015 prompt="mininet>",
2016 timeout=10 )
2017 if re.search( "no switch named", response ):
2018 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002019 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002020 elif re.search( "Error", response ):
2021 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002022 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002023 elif re.search( "usage:", response ):
2024 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002025 return main.FALSE
2026 else:
2027 return main.TRUE
2028 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002029 main.log.error( self.name + ": EOF exception found" )
2030 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002031 main.cleanup()
2032 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002033 except Exception:
2034 main.log.exception( self.name + ": Uncaught exception!" )
2035 main.cleanup()
2036 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002037
You Wangdb8cd0a2016-05-26 15:19:45 -07002038 def getSwitchRandom( self, timeout=60, nonCut=True ):
2039 """
2040 Randomly get a switch from Mininet topology.
2041 If nonCut is True, it gets a list of non-cut switches (the deletion
2042 of a non-cut switch will not increase the number of connected
2043 components of a graph) and randomly returns one of them, otherwise
2044 it just randomly returns one switch from all current switches in
2045 Mininet.
2046 Returns the name of the chosen switch.
2047 """
2048 import random
2049 candidateSwitches = []
2050 try:
2051 if not nonCut:
2052 switches = self.getSwitches( timeout=timeout )
2053 assert len( switches ) != 0
2054 for switchName in switches.keys():
2055 candidateSwitches.append( switchName )
2056 else:
2057 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2058 if graphDict == None:
2059 return None
2060 self.graph.update( graphDict )
2061 candidateSwitches = self.graph.getNonCutVertices()
2062 if candidateSwitches == None:
2063 return None
2064 elif len( candidateSwitches ) == 0:
2065 main.log.info( self.name + ": No candidate switch for deletion" )
2066 return None
2067 else:
2068 switch = random.sample( candidateSwitches, 1 )
2069 return switch[ 0 ]
2070 except KeyError:
2071 main.log.exception( self.name + ": KeyError exception found" )
2072 return None
2073 except AssertionError:
2074 main.log.exception( self.name + ": AssertionError exception found" )
2075 return None
2076 except Exception:
2077 main.log.exception( self.name + ": Uncaught exception" )
2078 return None
2079
2080 def delSwitchRandom( self, timeout=60, nonCut=True ):
2081 """
2082 Randomly delete a switch from Mininet topology.
2083 If nonCut is True, it gets a list of non-cut switches (the deletion
2084 of a non-cut switch will not increase the number of connected
2085 components of a graph) and randomly chooses one for deletion,
2086 otherwise it just randomly delete one switch from all current
2087 switches in Mininet.
2088 Returns the name of the deleted switch
2089 """
2090 try:
2091 switch = self.getSwitchRandom( timeout, nonCut )
2092 if switch == None:
2093 return None
2094 else:
2095 deletionResult = self.delSwitch( switch )
2096 if deletionResult:
2097 return switch
2098 else:
2099 return None
2100 except Exception:
2101 main.log.exception( self.name + ": Uncaught exception" )
2102 return None
2103
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002105 """
2106 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002107 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002108 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002109 NOTE: cannot currently specify what type of link
2110 required params:
2111 node1 = the string node name of the first endpoint of the link
2112 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002113 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002114 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002115 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002116 response = self.execute(
2117 cmd=command,
2118 prompt="mininet>",
2119 timeout=10 )
2120 if re.search( "doesnt exist!", response ):
2121 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002122 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002123 elif re.search( "Error", response ):
2124 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002125 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002126 elif re.search( "usage:", response ):
2127 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002128 return main.FALSE
2129 else:
2130 return main.TRUE
2131 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002132 main.log.error( self.name + ": EOF exception found" )
2133 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002134 main.cleanup()
2135 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002136 except Exception:
2137 main.log.exception( self.name + ": Uncaught exception!" )
2138 main.cleanup()
2139 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002140
kelvin-onlabd3b64892015-01-20 13:26:24 -08002141 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002142 """
2143 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002144 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002145 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002146 required params:
2147 node1 = the string node name of the first endpoint of the link
2148 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002149 returns: main.FALSE on an error, else main.TRUE
2150 """
Jon Hallffb386d2014-11-21 13:43:38 -08002151 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002152 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002153 response = self.execute(
2154 cmd=command,
2155 prompt="mininet>",
2156 timeout=10 )
2157 if re.search( "no node named", response ):
2158 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002159 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002160 elif re.search( "Error", response ):
2161 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002162 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002163 elif re.search( "usage:", response ):
2164 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002165 return main.FALSE
2166 else:
2167 return main.TRUE
2168 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002169 main.log.error( self.name + ": EOF exception found" )
2170 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002171 main.cleanup()
2172 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002173 except Exception:
2174 main.log.exception( self.name + ": Uncaught exception!" )
2175 main.cleanup()
2176 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002177
You Wangdb8cd0a2016-05-26 15:19:45 -07002178 def getLinkRandom( self, timeout=60, nonCut=True ):
2179 """
2180 Randomly get a link from Mininet topology.
2181 If nonCut is True, it gets a list of non-cut links (the deletion
2182 of a non-cut link will not increase the number of connected
2183 component of a graph) and randomly returns one of them, otherwise
2184 it just randomly returns one link from all current links in
2185 Mininet.
2186 Returns the link as a list, e.g. [ 's1', 's2' ]
2187 """
2188 import random
2189 candidateLinks = []
2190 try:
2191 if not nonCut:
2192 links = self.getLinks( timeout=timeout )
2193 assert len( links ) != 0
2194 for link in links:
2195 # Exclude host-switch link
2196 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2197 continue
2198 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2199 else:
2200 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2201 if graphDict == None:
2202 return None
2203 self.graph.update( graphDict )
2204 candidateLinks = self.graph.getNonCutEdges()
2205 if candidateLinks == None:
2206 return None
2207 elif len( candidateLinks ) == 0:
2208 main.log.info( self.name + ": No candidate link for deletion" )
2209 return None
2210 else:
2211 link = random.sample( candidateLinks, 1 )
2212 return link[ 0 ]
2213 except KeyError:
2214 main.log.exception( self.name + ": KeyError exception found" )
2215 return None
2216 except AssertionError:
2217 main.log.exception( self.name + ": AssertionError exception found" )
2218 return None
2219 except Exception:
2220 main.log.exception( self.name + ": Uncaught exception" )
2221 return None
2222
2223 def delLinkRandom( self, timeout=60, nonCut=True ):
2224 """
2225 Randomly delete a link from Mininet topology.
2226 If nonCut is True, it gets a list of non-cut links (the deletion
2227 of a non-cut link will not increase the number of connected
2228 component of a graph) and randomly chooses one for deletion,
2229 otherwise it just randomly delete one link from all current links
2230 in Mininet.
2231 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2232 """
2233 try:
2234 link = self.getLinkRandom( timeout, nonCut )
2235 if link == None:
2236 return None
2237 else:
2238 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2239 if deletionResult:
2240 return link
2241 else:
2242 return None
2243 except Exception:
2244 main.log.exception( self.name + ": Uncaught exception" )
2245 return None
2246
kelvin-onlabd3b64892015-01-20 13:26:24 -08002247 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002248 """
Jon Hallb1290e82014-11-18 16:17:48 -05002249 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002250 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002251 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002252 NOTE: cannot currently specify what type of host
2253 required params:
2254 hostname = the string hostname
2255 optional key-value params
2256 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002257 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002258 """
2259 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002260 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002261 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002262 response = self.execute(
2263 cmd=command,
2264 prompt="mininet>",
2265 timeout=10 )
2266 if re.search( "already exists!", response ):
2267 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002268 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002269 elif re.search( "doesnt exists!", response ):
2270 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002271 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002272 elif re.search( "Error", response ):
2273 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002274 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002275 elif re.search( "usage:", response ):
2276 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002277 return main.FALSE
2278 else:
2279 return main.TRUE
2280 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002281 main.log.error( self.name + ": EOF exception found" )
2282 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002283 main.cleanup()
2284 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002285 except Exception:
2286 main.log.exception( self.name + ": Uncaught exception!" )
2287 main.cleanup()
2288 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002289
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002291 """
2292 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002293 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002294 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002295 NOTE: this uses a custom mn function
2296 required params:
2297 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002298 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002299 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002300 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002301 response = self.execute(
2302 cmd=command,
2303 prompt="mininet>",
2304 timeout=10 )
2305 if re.search( "no host named", response ):
2306 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002307 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002308 elif re.search( "Error", response ):
2309 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002310 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002311 elif re.search( "usage:", response ):
2312 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002313 return main.FALSE
2314 else:
2315 return main.TRUE
2316 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002317 main.log.error( self.name + ": EOF exception found" )
2318 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002319 main.cleanup()
2320 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002321 except Exception:
2322 main.log.exception( self.name + ": Uncaught exception!" )
2323 main.cleanup()
2324 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07002325
Jon Hall7eb38402015-01-08 17:19:54 -08002326 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002327 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002328 Called at the end of the test to stop the mininet and
2329 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002330 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002331 try:
2332 self.handle.sendline( '' )
2333 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2334 timeout=2 )
2335 response = main.TRUE
2336 if i == 0:
2337 response = self.stopNet()
2338 elif i == 1:
2339 return main.TRUE
2340 # print "Disconnecting Mininet"
2341 if self.handle:
2342 self.handle.sendline( "exit" )
2343 self.handle.expect( "exit" )
2344 self.handle.expect( "(.*)" )
2345 else:
2346 main.log.error( "Connection failed to the host" )
2347 return response
2348 except pexpect.EOF:
2349 main.log.error( self.name + ": EOF exception found" )
2350 main.log.error( self.name + ": " + self.handle.before )
2351 main.cleanup()
2352 main.exit()
2353 except Exception:
2354 main.log.exception( self.name + ": Uncaught exception!" )
2355 main.cleanup()
2356 main.exit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002357
Jon Halld80cc142015-07-06 13:36:05 -07002358 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002359 """
Jon Hall21270ac2015-02-16 17:59:55 -08002360 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002361 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002362 main.FALSE if the pexpect handle does not exist.
2363
Jon Halld61331b2015-02-17 16:35:47 -08002364 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002365 """
Jon Halld61331b2015-02-17 16:35:47 -08002366 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002367 response = ''
2368 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002369 try:
Jon Halld80cc142015-07-06 13:36:05 -07002370 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002371 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002372 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002373 pexpect.EOF,
2374 pexpect.TIMEOUT ],
2375 timeout )
2376 if i == 0:
2377 main.log.info( "Exiting mininet..." )
Jeremyd9e4eb12016-04-13 12:09:06 -07002378 response = self.execute( cmd="exit",
2379 prompt="(.*)",
2380 timeout=120 )
2381 main.log.info( self.name + ": Stopped" )
2382 self.handle.sendline( "sudo mn -c" )
2383 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002384
Jeremyd9e4eb12016-04-13 12:09:06 -07002385 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002386 main.log.info( " Mininet trying to exit while not " +
2387 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002388 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002389 elif i == 2:
2390 main.log.error( "Something went wrong exiting mininet" )
2391 elif i == 3: # timeout
2392 main.log.error( "Something went wrong exiting mininet " +
2393 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002394
Hari Krishnab35c6d02015-03-18 11:13:51 -07002395 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002396 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002397 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002398 self.handle.sendline(
2399 "sudo kill -9 \`ps -ef | grep \"" +
2400 fileName +
2401 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002402 except pexpect.TIMEOUT:
2403 main.log.error(self.name + ": TIMEOUT exception found")
2404 main.log.error(self.name + ": " + self.handle.before)
2405 main.cleanup()
2406 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002407 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002408 main.log.error( self.name + ": EOF exception found" )
2409 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07002410 main.cleanup()
2411 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002412 except Exception:
2413 main.log.exception( self.name + ": Uncaught exception!" )
2414 main.cleanup()
2415 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08002416 else:
2417 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002418 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002419 return response
2420
YPZhang26a139e2016-04-25 14:01:55 -07002421 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002422 """
2423 Description:
2424 Sends arp message from mininet host for hosts discovery
2425 Required:
2426 host - hosts name
2427 Optional:
2428 ip - ip address that does not exist in the network so there would
2429 be no reply.
2430 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002431 if ethDevice:
2432 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002433 cmd = srcHost + " arping -c1 "
2434 if noResult:
2435 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
2436 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002437 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002438 if output:
2439 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002440 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002441 i = self.handle.expect( [ "mininet>", "arping: " ] )
2442 if i == 0:
2443 return main.TRUE
2444 elif i == 1:
2445 response = self.handle.before + self.handle.after
2446 self.handle.expect( "mininet>" )
2447 response += self.handle.before + self.handle.after
2448 main.log.warn( "Error sending arping, output was: " +
2449 response )
2450 return main.FALSE
2451 except pexpect.TIMEOUT:
2452 main.log.error( self.name + ": TIMEOUT exception found" )
2453 main.log.warn( self.handle.before )
2454 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002455 except pexpect.EOF:
2456 main.log.error( self.name + ": EOF exception found" )
2457 main.log.error( self.name + ": " + self.handle.before )
2458 main.cleanup()
2459 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002460 except Exception:
2461 main.log.exception( self.name + ": Uncaught exception!" )
2462 main.cleanup()
2463 main.exit()
admin07529932013-11-22 14:58:28 -08002464
Jon Hall7eb38402015-01-08 17:19:54 -08002465 def decToHex( self, num ):
2466 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002467
Jon Hall7eb38402015-01-08 17:19:54 -08002468 def getSwitchFlowCount( self, switch ):
2469 """
2470 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002471 if self.handle:
2472 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2473 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002474 response = self.execute(
2475 cmd=cmd,
2476 prompt="mininet>",
2477 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002478 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002479 main.log.error( self.name + ": EOF exception found" )
2480 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002481 main.cleanup()
2482 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002483 except Exception:
2484 main.log.exception( self.name + ": Uncaught exception!" )
2485 main.cleanup()
2486 main.exit()
admin2a9548d2014-06-17 14:08:07 -07002487 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002488 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002489 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002490 main.log.info(
2491 "Couldn't find flows on switch %s, found: %s" %
2492 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002493 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002494 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002495 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002496 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002497
Jon Hall9ed8f372016-02-24 17:34:07 -08002498 def checkFlows( self, sw, dumpFormat=None ):
2499 if dumpFormat:
2500 command = "sh ovs-ofctl -F " + \
2501 dumpFormat + " dump-flows " + str( sw )
2502 else:
2503 command = "sh ovs-ofctl dump-flows " + str( sw )
2504 try:
2505 response = self.execute(
2506 cmd=command,
2507 prompt="mininet>",
2508 timeout=10 )
2509 return response
2510 except pexpect.EOF:
2511 main.log.error( self.name + ": EOF exception found" )
2512 main.log.error( self.name + ": " + self.handle.before )
2513 main.cleanup()
2514 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002515 except Exception:
2516 main.log.exception( self.name + ": Uncaught exception!" )
2517 main.cleanup()
2518 main.exit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002519
GlennRC68467eb2015-11-16 18:01:01 -08002520 def flowTableComp( self, flowTable1, flowTable2 ):
2521 # This function compares the selctors and treatments of each flow
2522 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002523 assert flowTable1, "flowTable1 is empty or None"
2524 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002525 returnValue = main.TRUE
GlennRC68467eb2015-11-16 18:01:01 -08002526 if len(flowTable1) != len(flowTable2):
2527 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002528 returnValue = main.FALSE
GlennRCfa65fce2015-12-16 13:16:08 -08002529 dFields = ["n_bytes", "cookie", "n_packets", "duration"]
2530 for flow1, flow2 in zip(flowTable1, flowTable2):
Jon Hallacd1b182015-12-17 11:43:20 -08002531 for field in dFields:
2532 try:
2533 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002534 except KeyError:
2535 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002536 try:
2537 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002538 except KeyError:
2539 pass
GlennRC68467eb2015-11-16 18:01:01 -08002540 for i in range( len(flowTable1) ):
GlennRC17bbcf52015-12-14 17:31:50 -08002541 if flowTable1[i] not in flowTable2:
2542 main.log.warn( "Flow tables do not match:" )
2543 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[i] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002544 returnValue = main.FALSE
2545 break
2546 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002547 except AssertionError:
2548 main.log.exception( "Nothing to compare" )
2549 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002550 except Exception:
2551 main.log.exception( "Uncaught exception!" )
2552 main.cleanup()
2553 main.exit()
Jon Hall9043c902015-07-30 14:23:44 -07002554
GlennRC528ad292015-11-12 10:38:18 -08002555 def parseFlowTable( self, flowTable, version="", debug=True ):
GlennRC956ea742015-11-05 16:14:15 -08002556 '''
2557 Discription: Parses flows into json format.
2558 NOTE: this can parse any string thats separated with commas
2559 Arguments:
2560 Required:
2561 flows: a list of strings that represnt flows
2562 Optional:
2563 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2564 debug: prints out the final result
2565 returns: A list of flows in json format
2566 '''
GlennRC528ad292015-11-12 10:38:18 -08002567 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002568 try:
2569 for flow in flowTable:
2570 jsonFlow = {}
2571 # split up the fields of the flow
2572 parsedFlow = flow.split(", ")
2573 # get rid of any spaces in front of the field
2574 for i in range( len(parsedFlow) ):
2575 item = parsedFlow[i]
2576 if item[0] == " ":
2577 parsedFlow[i] = item[1:]
2578 # grab the selector and treatment from the parsed flow
2579 # the last element is the selector and the treatment
2580 temp = parsedFlow.pop(-1)
2581 # split up the selector and the treatment
2582 temp = temp.split(" ")
2583 index = 0
2584 # parse the flags
2585 # NOTE: This only parses one flag
2586 flag = {}
2587 if version == "1.3":
2588 flag = {"flag":[temp[index]]}
2589 index += 1
2590 # the first element is the selector and split it up
2591 sel = temp[index]
GlennRC528ad292015-11-12 10:38:18 -08002592 index += 1
You Wang91c37cf2016-05-23 09:39:42 -07002593 sel = sel.split(",")
2594 # the priority is stuck in the selecter so put it back
2595 # in the flow
2596 parsedFlow.append(sel.pop(0))
2597 # parse selector
2598 criteria = []
2599 for item in sel:
2600 # this is the type of the packet e.g. "arp"
2601 if "=" not in item:
2602 criteria.append( {"type":item} )
2603 else:
2604 field = item.split("=")
2605 criteria.append( {field[0]:field[1]} )
2606 selector = {"selector": {"criteria":sorted(criteria)} }
2607 treat = temp[index]
2608 # get rid of the action part e.g. "action=output:2"
2609 # we will add it back later
2610 treat = treat.split("=")
2611 treat.pop(0)
2612 # parse treatment
2613 action = []
2614 for item in treat:
2615 field = item.split(":")
2616 action.append( {field[0]:field[1]} )
2617 # create the treatment field and add the actions
2618 treatment = {"treatment": {"action":sorted(action)} }
2619 # parse the rest of the flow
2620 for item in parsedFlow:
GlennRC528ad292015-11-12 10:38:18 -08002621 field = item.split("=")
You Wang91c37cf2016-05-23 09:39:42 -07002622 jsonFlow.update( {field[0]:field[1]} )
2623 # add the treatment and the selector to the json flow
2624 jsonFlow.update( selector )
2625 jsonFlow.update( treatment )
2626 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002627
You Wang91c37cf2016-05-23 09:39:42 -07002628 if debug: main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format(jsonFlow) )
GlennRC956ea742015-11-05 16:14:15 -08002629
You Wang91c37cf2016-05-23 09:39:42 -07002630 # add the json flow to the json flow table
2631 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002632
You Wang91c37cf2016-05-23 09:39:42 -07002633 return jsonFlowTable
2634
2635 except IndexError:
2636 main.log.exception( self.name + ": IndexError found" )
2637 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002638 except pexpect.EOF:
2639 main.log.error( self.name + ": EOF exception found" )
2640 main.log.error( self.name + ": " + self.handle.before )
2641 main.cleanup()
2642 main.exit()
You Wang91c37cf2016-05-23 09:39:42 -07002643 except Exception:
2644 main.log.exception( self.name + ": Uncaught exception!" )
2645 main.cleanup()
2646 main.exit()
GlennRC528ad292015-11-12 10:38:18 -08002647
Jon Hall0a543792015-12-14 11:00:26 -08002648 def getFlowTable( self, sw, version="", debug=False):
GlennRC956ea742015-11-05 16:14:15 -08002649 '''
2650 Discription: Returns the flow table(s) on a switch or switches in a list.
2651 Each element is a flow.
2652 Arguments:
2653 Required:
2654 sw: The switch name ("s1") to retrive the flow table. Can also be
2655 a list of switches.
2656 Optional:
2657 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2658 debug: prints out the final result
2659 '''
2660 try:
2661 switches = []
2662 if type(sw) is list:
Jon Hallca7ac292015-11-11 09:28:12 -08002663 switches.extend(sw)
GlennRC956ea742015-11-05 16:14:15 -08002664 else: switches.append(sw)
2665
2666 flows = []
2667 for s in switches:
2668 cmd = "sh ovs-ofctl dump-flows " + s
2669
GlennRC528ad292015-11-12 10:38:18 -08002670 if "1.0" == version:
2671 cmd += " -F OpenFlow10-table_id"
2672 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002673 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002674
2675 main.log.info( "Sending: " + cmd )
2676 self.handle.sendline( cmd )
2677 self.handle.expect( "mininet>" )
2678 response = self.handle.before
2679 response = response.split( "\r\n" )
2680 # dump the first two elements and the last
2681 # the first element is the command that was sent
2682 # the second is the table header
2683 # the last element is empty
2684 response = response[2:-1]
2685 flows.extend( response )
2686
2687 if debug: print "Flows:\n{}\n\n".format(flows)
2688
GlennRC528ad292015-11-12 10:38:18 -08002689 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002690
GlennRC956ea742015-11-05 16:14:15 -08002691 except pexpect.EOF:
2692 main.log.exception( self.name + ": connection closed." )
2693 main.cleanup()
2694 main.exit()
2695 except Exception:
2696 main.log.exception( self.name + ": Uncaught exception!" )
2697 main.cleanup()
2698 main.exit()
2699
2700 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
2701 '''
2702 Discription: Checks whether the ID provided matches a flow ID in Mininet
2703 Arguments:
2704 Required:
2705 sw: The switch name ("s1") to retrive the flow table. Can also be
2706 a list of switches.
2707 flowId: the flow ID in hex format. Can also be a list of IDs
2708 Optional:
2709 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2710 debug: prints out the final result
2711 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2712 NOTE: prints out IDs that are not present
2713 '''
2714 try:
2715 main.log.info( "Getting flows from Mininet" )
2716 flows = self.getFlowTable( sw, version, debug )
You Wang083ae982016-05-25 09:31:09 -07002717 if flows == None:
2718 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002719
2720 if debug: print "flow ids:\n{}\n\n".format(flowId)
2721
2722 # Check flowId is a list or a string
2723 if type( flowId ) is str:
2724 result = False
2725 for f in flows:
2726 if flowId in f.get( 'cookie' ):
2727 result = True
2728 break
2729 # flowId is a list
2730 else:
2731 result = True
2732 # Get flow IDs from Mininet
2733 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2734 # Save the IDs that are not in Mininet
2735 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2736
2737 if debug: print "mn flow ids:\n{}\n\n".format(mnFlowIds)
2738
2739 # Print out the IDs that are not in Mininet
2740 if absentIds:
2741 main.log.warn( "Absent ids: {}".format( absentIds ) )
2742 result = False
2743
2744 return main.TRUE if result else main.FALSE
2745
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002746 except pexpect.EOF:
2747 main.log.error( self.name + ": EOF exception found" )
2748 main.log.error( self.name + ": " + self.handle.before )
2749 main.cleanup()
2750 main.exit()
GlennRC956ea742015-11-05 16:14:15 -08002751 except Exception:
2752 main.log.exception( self.name + ": Uncaught exception!" )
2753 main.cleanup()
2754 main.exit()
2755
2756
Charles Chan029be652015-08-24 01:46:10 +08002757 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002758 """
Jon Hallefbd9792015-03-05 16:11:36 -08002759 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002760 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002761 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002762 self.handle.sendline( "" )
2763 self.handle.expect( "mininet>" )
2764 self.handle.sendline(
2765 "sh sudo tcpdump -n -i " +
2766 intf +
2767 " " +
2768 port +
2769 " -w " +
2770 filename.strip() +
2771 " &" )
2772 self.handle.sendline( "" )
2773 i = self.handle.expect( [ 'No\ssuch\device',
2774 'listening\son',
2775 pexpect.TIMEOUT,
2776 "mininet>" ],
2777 timeout=10 )
2778 main.log.warn( self.handle.before + self.handle.after )
2779 self.handle.sendline( "" )
2780 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002781 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002782 main.log.error(
2783 self.name +
2784 ": tcpdump - No such device exists. " +
2785 "tcpdump attempted on: " +
2786 intf )
admin2a9548d2014-06-17 14:08:07 -07002787 return main.FALSE
2788 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002789 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002790 return main.TRUE
2791 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002792 main.log.error(
2793 self.name +
2794 ": tcpdump command timed out! Check interface name," +
2795 " given interface was: " +
2796 intf )
admin2a9548d2014-06-17 14:08:07 -07002797 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002798 elif i == 3:
2799 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002800 return main.TRUE
2801 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002802 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002803 return main.FALSE
2804 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002805 main.log.error( self.name + ": EOF exception found" )
2806 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002807 main.cleanup()
2808 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002809 except Exception:
2810 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07002811 main.cleanup()
2812 main.exit()
2813
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002815 """
2816 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002817 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002818 self.handle.sendline( "sh sudo pkill tcpdump" )
2819 self.handle.expect( "mininet>" )
2820 self.handle.sendline( "" )
2821 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002822 except pexpect.TIMEOUT:
2823 main.log.error(self.name + ": TIMEOUT exception found")
2824 main.log.error(self.name + ": " + self.handle.before)
2825 main.cleanup()
2826 main.exit()
admin2a9548d2014-06-17 14:08:07 -07002827 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002828 main.log.error( self.name + ": EOF exception found" )
2829 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002830 main.cleanup()
2831 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002832 except Exception:
2833 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07002834 main.cleanup()
2835 main.exit()
2836
Jon Halld80cc142015-07-06 13:36:05 -07002837 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002838 """
2839 Read ports from a Mininet switch.
2840
2841 Returns a json structure containing information about the
2842 ports of the given switch.
2843 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002844 try:
2845 response = self.getInterfaces( nodeName )
2846 # TODO: Sanity check on response. log if no such switch exists
2847 ports = []
2848 for line in response.split( "\n" ):
2849 if not line.startswith( "name=" ):
2850 continue
2851 portVars = {}
2852 for var in line.split( "," ):
2853 key, value = var.split( "=" )
2854 portVars[ key ] = value
2855 isUp = portVars.pop( 'enabled', "True" )
2856 isUp = "True" in isUp
2857 if verbose:
2858 main.log.info( "Reading switch port %s(%s)" %
2859 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2860 mac = portVars[ 'mac' ]
2861 if mac == 'None':
2862 mac = None
2863 ips = []
2864 ip = portVars[ 'ip' ]
2865 if ip == 'None':
2866 ip = None
2867 ips.append( ip )
2868 name = portVars[ 'name' ]
2869 if name == 'None':
2870 name = None
2871 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2872 if name == 'lo':
2873 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2874 else:
2875 portNo = re.search( portRe, name ).group( 'port' )
2876 ports.append( { 'of_port': portNo,
2877 'mac': str( mac ).replace( '\'', '' ),
2878 'name': name,
2879 'ips': ips,
2880 'enabled': isUp } )
2881 return ports
2882 except pexpect.EOF:
2883 main.log.error( self.name + ": EOF exception found" )
2884 main.log.error( self.name + ": " + self.handle.before )
2885 main.cleanup()
2886 main.exit()
2887 except Exception:
2888 main.log.exception( self.name + ": Uncaught exception!" )
2889 main.cleanup()
2890 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07002891
You Wangdb8cd0a2016-05-26 15:19:45 -07002892 def getOVSPorts( self, nodeName ):
2893 """
2894 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2895
2896 Returns a list of dictionaries containing information about each
2897 port of the given switch.
2898 """
2899 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2900 try:
2901 response = self.execute(
2902 cmd=command,
2903 prompt="mininet>",
2904 timeout=10 )
2905 ports = []
2906 if response:
2907 for line in response.split( "\n" ):
2908 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2909 # Example port:
2910 # 1(s1-eth1): addr:ae:60:72:77:55:51
2911 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2912 result = re.search( pattern, line )
2913 if result:
2914 index = result.group( 'index' )
2915 name = result.group( 'name' )
2916 # This port number is extracted from port name
2917 port = result.group( 'port' )
2918 mac = result.group( 'mac' )
2919 ports.append( { 'index': index,
2920 'name': name,
2921 'port': port,
2922 'mac': mac } )
2923 return ports
2924 except pexpect.EOF:
2925 main.log.error( self.name + ": EOF exception found" )
2926 main.log.error( self.name + ": " + self.handle.before )
2927 main.cleanup()
2928 main.exit()
2929 except Exception:
2930 main.log.exception( self.name + ": Uncaught exception!" )
2931 main.cleanup()
2932 main.exit()
2933
Jon Halld80cc142015-07-06 13:36:05 -07002934 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002935 """
2936 Read switches from Mininet.
2937
2938 Returns a dictionary whose keys are the switch names and the value is
2939 a dictionary containing information about the switch.
2940 """
Jon Halla22481b2015-07-28 17:46:01 -07002941 # NOTE: To support new Mininet switch classes, just append the new
2942 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002943
Jon Halla22481b2015-07-28 17:46:01 -07002944 # Regex patterns to parse 'dump' output
2945 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002946 # <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=5238>
Jon Halld80cc142015-07-06 13:36:05 -07002947 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002948 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2949 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2950 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002951 try:
2952 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2953 swRE = r"<(?P<class>" + switchClasses + r")" +\
2954 r"(?P<options>\{.*\})?\s" +\
2955 r"(?P<name>[^:]+)\:\s" +\
2956 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2957 r"\spid=(?P<pid>(\d)+)"
2958 # Update mn port info
2959 self.update()
2960 output = {}
2961 dump = self.dump().split( "\n" )
2962 for line in dump:
2963 result = re.search( swRE, line, re.I )
2964 if result:
2965 name = result.group( 'name' )
2966 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2967 pid = result.group( 'pid' )
2968 swClass = result.group( 'class' )
2969 options = result.group( 'options' )
2970 if verbose:
2971 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2972 ports = self.getPorts( name )
2973 output[ name ] = { "dpid": dpid,
2974 "ports": ports,
2975 "swClass": swClass,
2976 "pid": pid,
2977 "options": options }
2978 return output
2979 except pexpect.EOF:
2980 main.log.error( self.name + ": EOF exception found" )
2981 main.log.error( self.name + ": " + self.handle.before )
2982 main.cleanup()
2983 main.exit()
2984 except Exception:
2985 main.log.exception( self.name + ": Uncaught exception!" )
2986 main.cleanup()
2987 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07002988
Jon Halld80cc142015-07-06 13:36:05 -07002989 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002990 """
2991 Read hosts from Mininet.
2992
2993 Returns a dictionary whose keys are the host names and the value is
2994 a dictionary containing information about the host.
2995 """
2996 # Regex patterns to parse dump output
2997 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002998 # <Host h1: pid=12725>
2999 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3000 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3001 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003002 # NOTE: Does not correctly match hosts with multi-links
3003 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3004 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003005 try:
3006 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
3007 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
3008 # update mn port info
3009 self.update()
3010 # Get mininet dump
3011 dump = self.dump().split( "\n" )
3012 hosts = {}
3013 for line in dump:
3014 if "Host" in line :
3015 result = re.search( hostRE, line )
3016 name = result.group( 'name' )
3017 interfaces = []
3018 response = self.getInterfaces( name )
3019 # Populate interface info
3020 for line in response.split( "\n" ):
3021 if line.startswith( "name=" ):
3022 portVars = {}
3023 for var in line.split( "," ):
3024 key, value = var.split( "=" )
3025 portVars[ key ] = value
3026 isUp = portVars.pop( 'enabled', "True" )
3027 isUp = "True" in isUp
3028 if verbose:
3029 main.log.info( "Reading host port %s(%s)" %
3030 ( portVars[ 'name' ],
3031 portVars[ 'mac' ] ) )
3032 mac = portVars[ 'mac' ]
3033 if mac == 'None':
3034 mac = None
3035 ips = []
3036 ip = portVars[ 'ip' ]
3037 if ip == 'None':
3038 ip = None
3039 ips.append( ip )
3040 intfName = portVars[ 'name' ]
3041 if name == 'None':
3042 name = None
3043 interfaces.append( {
3044 "name": intfName,
3045 "ips": ips,
3046 "mac": str( mac ),
3047 "isUp": isUp } )
3048 hosts[ name ] = { "interfaces": interfaces }
3049 return hosts
3050 except pexpect.EOF:
3051 main.log.error( self.name + ": EOF exception found" )
3052 main.log.error( self.name + ": " + self.handle.before )
3053 main.cleanup()
3054 main.exit()
3055 except Exception:
3056 main.log.exception( self.name + ": Uncaught exception!" )
3057 main.cleanup()
3058 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07003059
YPZhang81a7d4e2016-04-18 13:10:17 -07003060 def getLinks( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003061 """
3062 Gathers information about current Mininet links. These links may not
3063 be up if one of the ports is down.
3064
3065 Returns a list of dictionaries with link endpoints.
3066
3067 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003068 { 'node1': str( node1 name )
3069 'node2': str( node2 name )
3070 'port1': str( port1 of_port )
3071 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003072 Note: The port number returned is the eth#, not necessarily the of_port
3073 number. In Mininet, for OVS switch, these should be the same. For
3074 hosts, this is just the eth#.
3075 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003076 try:
3077 self.update()
3078 response = self.links(timeout=timeout).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003079
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003080 # Examples:
3081 # s1-eth3<->s2-eth1 (OK OK)
3082 # s13-eth3<->h27-eth0 (OK OK)
3083 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3084 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3085 links = []
3086 for line in response:
3087 match = re.search( linkRE, line )
3088 if match:
3089 node1 = match.group( 'node1' )
3090 node2 = match.group( 'node2' )
3091 port1 = match.group( 'port1' )
3092 port2 = match.group( 'port2' )
3093 links.append( { 'node1': node1,
3094 'node2': node2,
3095 'port1': port1,
3096 'port2': port2 } )
3097 return links
3098
3099 except pexpect.EOF:
3100 main.log.error( self.name + ": EOF exception found" )
3101 main.log.error( self.name + ": " + self.handle.before )
3102 main.cleanup()
3103 main.exit()
3104 except Exception:
3105 main.log.exception( self.name + ": Uncaught exception!" )
3106 main.cleanup()
3107 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07003108
3109 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003110 """
3111 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003112 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003113
Jon Hallafa8a472015-06-12 14:02:42 -07003114 Dependencies:
3115 1. numpy - "sudo pip install numpy"
3116 """
3117 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003118 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003119 try:
3120 mnDPIDs = []
3121 for swName, switch in switches.iteritems():
3122 mnDPIDs.append( switch[ 'dpid' ].lower() )
3123 mnDPIDs.sort()
3124 if switchesJson == "": # if rest call fails
3125 main.log.error(
3126 self.name +
3127 ".compareSwitches(): Empty JSON object given from ONOS" )
3128 return main.FALSE
3129 onos = switchesJson
3130 onosDPIDs = []
3131 for switch in onos:
3132 if switch[ 'available' ]:
3133 onosDPIDs.append(
3134 switch[ 'id' ].replace(
3135 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003136 '' ).replace(
3137 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003138 '' ).lower() )
3139 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003140
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003141 if mnDPIDs != onosDPIDs:
3142 switchResults = main.FALSE
3143 main.log.error( "Switches in MN but not in ONOS:" )
3144 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3145 main.log.error( str( list1 ) )
3146 main.log.error( "Switches in ONOS but not in MN:" )
3147 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3148 main.log.error( str( list2 ) )
3149 else: # list of dpid's match in onos and mn
3150 switchResults = main.TRUE
3151 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003152
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003153 # FIXME: this does not look for extra ports in ONOS, only checks that
3154 # ONOS has what is in MN
3155 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003156
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003157 # PORTS
3158 for name, mnSwitch in switches.iteritems():
3159 mnPorts = []
3160 onosPorts = []
3161 switchResult = main.TRUE
3162 for port in mnSwitch[ 'ports' ]:
3163 if port[ 'enabled' ]:
3164 mnPorts.append( int( port[ 'of_port' ] ) )
3165 for onosSwitch in portsJson:
3166 if onosSwitch[ 'device' ][ 'available' ]:
3167 if onosSwitch[ 'device' ][ 'id' ].replace(
3168 ':',
3169 '' ).replace(
3170 "of",
3171 '' ) == mnSwitch[ 'dpid' ]:
3172 for port in onosSwitch[ 'ports' ]:
3173 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003174 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003175 # onosPorts.append( 'local' )
3176 onosPorts.append( long( uint64( -2 ) ) )
3177 else:
3178 onosPorts.append( int( port[ 'port' ] ) )
3179 break
3180 mnPorts.sort( key=float )
3181 onosPorts.sort( key=float )
3182
3183 mnPortsLog = mnPorts
3184 onosPortsLog = onosPorts
3185 mnPorts = [ x for x in mnPorts ]
3186 onosPorts = [ x for x in onosPorts ]
3187
3188 # TODO: handle other reserved port numbers besides LOCAL
3189 # NOTE: Reserved ports
3190 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3191 # long( uint64( -2 ) )
3192 for mnPort in mnPortsLog:
3193 if mnPort in onosPorts:
3194 # don't set results to true here as this is just one of
3195 # many checks and it might override a failure
3196 mnPorts.remove( mnPort )
3197 onosPorts.remove( mnPort )
3198
3199 # NOTE: OVS reports this as down since there is no link
3200 # So ignoring these for now
3201 # TODO: Come up with a better way of handling these
3202 if 65534 in mnPorts:
3203 mnPorts.remove( 65534 )
3204 if long( uint64( -2 ) ) in onosPorts:
3205 onosPorts.remove( long( uint64( -2 ) ) )
3206 if len( mnPorts ): # the ports of this switch don't match
3207 switchResult = main.FALSE
3208 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3209 if len( onosPorts ): # the ports of this switch don't match
3210 switchResult = main.FALSE
3211 main.log.warn(
3212 "Ports in ONOS but not MN: " +
3213 str( onosPorts ) )
3214 if switchResult == main.FALSE:
3215 main.log.error(
3216 "The list of ports for switch %s(%s) does not match:" %
3217 ( name, mnSwitch[ 'dpid' ] ) )
3218 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3219 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3220 portsResults = portsResults and switchResult
3221 finalResults = finalResults and portsResults
3222 return finalResults
3223 except pexpect.EOF:
3224 main.log.error( self.name + ": EOF exception found" )
3225 main.log.error( self.name + ": " + self.handle.before )
3226 main.cleanup()
3227 main.exit()
3228 except Exception:
3229 main.log.exception( self.name + ": Uncaught exception!" )
3230 main.cleanup()
3231 main.exit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003232
Jon Hallafa8a472015-06-12 14:02:42 -07003233 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003234 """
3235 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003236 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003237
Jon Hallafa8a472015-06-12 14:02:42 -07003238 """
Jon Hall7eb38402015-01-08 17:19:54 -08003239 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003240 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003241 try:
3242 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003243
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003244 mnLinks = []
3245 for l in links:
3246 try:
3247 node1 = switches[ l[ 'node1' ] ]
3248 node2 = switches[ l[ 'node2' ] ]
3249 enabled = True
3250 for port in node1[ 'ports' ]:
3251 if port[ 'of_port' ] == l[ 'port1' ]:
3252 enabled = enabled and port[ 'enabled' ]
3253 for port in node2[ 'ports' ]:
3254 if port[ 'of_port' ] == l[ 'port2' ]:
3255 enabled = enabled and port[ 'enabled' ]
3256 if enabled:
3257 mnLinks.append( l )
3258 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003259 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003260 if 2 * len( mnLinks ) == len( onos ):
3261 linkResults = main.TRUE
3262 else:
3263 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003264 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003265 "Mininet has " + str( len( mnLinks ) ) +
3266 " bidirectional links and ONOS has " +
3267 str( len( onos ) ) + " unidirectional links" )
3268
3269 # iterate through MN links and check if an ONOS link exists in
3270 # both directions
3271 for link in mnLinks:
3272 # TODO: Find a more efficient search method
3273 node1 = None
3274 port1 = None
3275 node2 = None
3276 port2 = None
3277 firstDir = main.FALSE
3278 secondDir = main.FALSE
3279 for swName, switch in switches.iteritems():
3280 if swName == link[ 'node1' ]:
3281 node1 = switch[ 'dpid' ]
3282 for port in switch[ 'ports' ]:
3283 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3284 port1 = port[ 'of_port' ]
3285 if node1 is not None and node2 is not None:
3286 break
3287 if swName == link[ 'node2' ]:
3288 node2 = switch[ 'dpid' ]
3289 for port in switch[ 'ports' ]:
3290 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3291 port2 = port[ 'of_port' ]
3292 if node1 is not None and node2 is not None:
3293 break
3294
3295 for onosLink in onos:
3296 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3297 ":", '' ).replace( "of", '' )
3298 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3299 ":", '' ).replace( "of", '' )
3300 onosPort1 = onosLink[ 'src' ][ 'port' ]
3301 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3302
3303 # check onos link from node1 to node2
3304 if str( onosNode1 ) == str( node1 ) and str(
3305 onosNode2 ) == str( node2 ):
3306 if int( onosPort1 ) == int( port1 ) and int(
3307 onosPort2 ) == int( port2 ):
3308 firstDir = main.TRUE
3309 else:
3310 main.log.warn(
3311 'The port numbers do not match for ' +
3312 str( link ) +
3313 ' between ONOS and MN. When checking ONOS for ' +
3314 'link %s/%s -> %s/%s' %
3315 ( node1, port1, node2, port2 ) +
3316 ' ONOS has the values %s/%s -> %s/%s' %
3317 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3318
3319 # check onos link from node2 to node1
3320 elif ( str( onosNode1 ) == str( node2 ) and
3321 str( onosNode2 ) == str( node1 ) ):
3322 if ( int( onosPort1 ) == int( port2 )
3323 and int( onosPort2 ) == int( port1 ) ):
3324 secondDir = main.TRUE
3325 else:
3326 main.log.warn(
3327 'The port numbers do not match for ' +
3328 str( link ) +
3329 ' between ONOS and MN. When checking ONOS for ' +
3330 'link %s/%s -> %s/%s' %
3331 ( node1, port1, node2, port2 ) +
3332 ' ONOS has the values %s/%s -> %s/%s' %
3333 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3334 else: # this is not the link you're looking for
3335 pass
3336 if not firstDir:
3337 main.log.error(
3338 'ONOS does not have the link %s/%s -> %s/%s' %
3339 ( node1, port1, node2, port2 ) )
3340 if not secondDir:
3341 main.log.error(
3342 'ONOS does not have the link %s/%s -> %s/%s' %
3343 ( node2, port2, node1, port1 ) )
3344 linkResults = linkResults and firstDir and secondDir
3345 return linkResults
3346 except pexpect.EOF:
3347 main.log.error( self.name + ": EOF exception found" )
3348 main.log.error( self.name + ": " + self.handle.before )
3349 main.cleanup()
3350 main.exit()
3351 except Exception:
3352 main.log.exception( self.name + ": Uncaught exception!" )
3353 main.cleanup()
3354 main.exit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003355
Jon Hallafa8a472015-06-12 14:02:42 -07003356 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003357 """
Jon Hallafa8a472015-06-12 14:02:42 -07003358 Compare mn and onos Hosts.
3359 Since Mininet hosts are quiet, ONOS will only know of them when they
3360 speak. For this reason, we will only check that the hosts in ONOS
3361 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003362
Jon Hallafa8a472015-06-12 14:02:42 -07003363 Arguments:
3364 hostsJson: parsed json object from the onos hosts api
3365 Returns:
3366 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003367 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003368 try:
3369 hostResults = main.TRUE
3370 for onosHost in hostsJson:
3371 onosMAC = onosHost[ 'mac' ].lower()
3372 match = False
3373 for mnHost, info in hosts.iteritems():
3374 for mnIntf in info[ 'interfaces' ]:
3375 if onosMAC == mnIntf[ 'mac' ].lower():
3376 match = True
3377 for ip in mnIntf[ 'ips' ]:
3378 if ip in onosHost[ 'ipAddresses' ]:
3379 pass # all is well
3380 else:
3381 # misssing ip
3382 main.log.error( "ONOS host " +
3383 onosHost[ 'id' ] +
3384 " has a different IP(" +
3385 str( onosHost[ 'ipAddresses' ] ) +
3386 ") than the Mininet host(" +
3387 str( ip ) +
3388 ")." )
3389 output = json.dumps(
3390 onosHost,
3391 sort_keys=True,
3392 indent=4,
3393 separators=( ',', ': ' ) )
3394 main.log.info( output )
3395 hostResults = main.FALSE
3396 if not match:
3397 hostResults = main.FALSE
3398 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3399 "corresponding Mininet host." )
3400 output = json.dumps( onosHost,
3401 sort_keys=True,
3402 indent=4,
3403 separators=( ',', ': ' ) )
3404 main.log.info( output )
3405 return hostResults
3406 except pexpect.EOF:
3407 main.log.error(self.name + ": EOF exception found")
3408 main.log.error(self.name + ": " + self.handle.before)
3409 main.cleanup()
3410 main.exit()
3411 except Exception:
3412 main.log.exception(self.name + ": Uncaught exception!")
3413 main.cleanup()
3414 main.exit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003415
Jon Hallafa8a472015-06-12 14:02:42 -07003416 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003417 """
3418 Returns a list of all hosts
3419 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003420 try:
3421 self.handle.sendline( "" )
3422 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003423
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003424 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3425 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003426
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003427 handlePy = self.handle.before
3428 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3429 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003430
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003431 self.handle.sendline( "" )
3432 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003433
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003434 hostStr = handlePy.replace( "]", "" )
3435 hostStr = hostStr.replace( "'", "" )
3436 hostStr = hostStr.replace( "[", "" )
3437 hostStr = hostStr.replace( " ", "" )
3438 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003439
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003440 return hostList
3441 except pexpect.TIMEOUT:
3442 main.log.error(self.name + ": TIMEOUT exception found")
3443 main.log.error(self.name + ": " + self.handle.before)
3444 main.cleanup()
3445 main.exit()
3446 except pexpect.EOF:
3447 main.log.error( self.name + ": EOF exception found" )
3448 main.log.error( self.name + ": " + self.handle.before )
3449 main.cleanup()
3450 main.exit()
3451 except Exception:
3452 main.log.exception( self.name + ": Uncaught exception!" )
3453 main.cleanup()
3454 main.exit()
adminbae64d82013-08-01 10:50:15 -07003455
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003456 def getSwitch( self ):
3457 """
3458 Returns a list of all switches
3459 Again, don't ask question just use it...
3460 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003461 try:
3462 # get host list...
3463 hostList = self.getHosts()
3464 # Make host set
3465 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003466
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003467 # Getting all the nodes in mininet
3468 self.handle.sendline( "" )
3469 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003470
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003471 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3472 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003473
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003474 handlePy = self.handle.before
3475 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3476 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003477
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003478 self.handle.sendline( "" )
3479 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003480
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003481 nodesStr = handlePy.replace( "]", "" )
3482 nodesStr = nodesStr.replace( "'", "" )
3483 nodesStr = nodesStr.replace( "[", "" )
3484 nodesStr = nodesStr.replace( " ", "" )
3485 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003486
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003487 nodesSet = set( nodesList )
3488 # discarding default controller(s) node
3489 nodesSet.discard( 'c0' )
3490 nodesSet.discard( 'c1' )
3491 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003492
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003493 switchSet = nodesSet - hostSet
3494 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003495
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003496 return switchList
3497 except pexpect.TIMEOUT:
3498 main.log.error(self.name + ": TIMEOUT exception found")
3499 main.log.error(self.name + ": " + self.handle.before)
3500 main.cleanup()
3501 main.exit()
3502 except pexpect.EOF:
3503 main.log.error( self.name + ": EOF exception found" )
3504 main.log.error( self.name + ": " + self.handle.before )
3505 main.cleanup()
3506 main.exit()
3507 except Exception:
3508 main.log.exception( self.name + ": Uncaught exception!" )
3509 main.cleanup()
3510 main.exit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003511
You Wangdb8cd0a2016-05-26 15:19:45 -07003512 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3513 """
3514 Return a dictionary which describes the latest Mininet topology data as a
3515 graph.
3516 An example of the dictionary:
3517 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3518 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3519 Each vertex should at least have an 'edges' attribute which describes the
3520 adjacency information. The value of 'edges' attribute is also represented by
3521 a dictionary, which maps each edge (identified by the neighbor vertex) to a
3522 list of attributes.
3523 An example of the edges dictionary:
3524 'edges': { vertex2: { 'port': ..., 'weight': ... },
3525 vertex3: { 'port': ..., 'weight': ... } }
3526 If useId == True, dpid/mac will be used instead of names to identify
3527 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3528 topology.
3529 If includeHost == True, all hosts (and host-switch links) will be included
3530 in topology data.
3531 Note that link or switch that are brought down by 'link x x down' or 'switch
3532 x down' commands still show in the output of Mininet CLI commands such as
3533 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3534 recommended to use delLink() or delSwitch functions to simulate link/switch
3535 down, and addLink() or addSwitch to add them back.
3536 """
3537 graphDict = {}
3538 try:
3539 links = self.getLinks( timeout=timeout )
3540 portDict = {}
3541 if useId:
3542 switches = self.getSwitches()
3543 if includeHost:
3544 hosts = self.getHosts()
3545 for link in links:
3546 # FIXME: support 'includeHost' argument
3547 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3548 continue
3549 nodeName1 = link[ 'node1' ]
3550 nodeName2 = link[ 'node2' ]
3551 port1 = link[ 'port1' ]
3552 port2 = link[ 'port2' ]
3553 # Loop for two nodes
3554 for i in range( 2 ):
3555 # Get port index from OVS
3556 # The index extracted from port name may be inconsistent with ONOS
3557 portIndex = -1
3558 if not nodeName1 in portDict.keys():
3559 portList = self.getOVSPorts( nodeName1 )
3560 if len( portList ) == 0:
3561 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3562 return None
3563 portDict[ nodeName1 ] = portList
3564 for port in portDict[ nodeName1 ]:
3565 if port[ 'port' ] == port1:
3566 portIndex = port[ 'index' ]
3567 break
3568 if portIndex == -1:
3569 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3570 return None
3571 if useId:
3572 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3573 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3574 else:
3575 node1 = nodeName1
3576 node2 = nodeName2
3577 if not node1 in graphDict.keys():
3578 if useId:
3579 graphDict[ node1 ] = { 'edges':{},
3580 'dpid':switches[ nodeName1 ][ 'dpid' ],
3581 'name':nodeName1,
3582 'ports':switches[ nodeName1 ][ 'ports' ],
3583 'swClass':switches[ nodeName1 ][ 'swClass' ],
3584 'pid':switches[ nodeName1 ][ 'pid' ],
3585 'options':switches[ nodeName1 ][ 'options' ] }
3586 else:
3587 graphDict[ node1 ] = { 'edges':{} }
3588 else:
3589 # Assert node2 is not connected to any current links of node1
3590 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
3591 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port':portIndex }
3592 # Swap two nodes/ports
3593 nodeName1, nodeName2 = nodeName2, nodeName1
3594 port1, port2 = port2, port1
3595 return graphDict
3596 except KeyError:
3597 main.log.exception( self.name + ": KeyError exception found" )
3598 return None
3599 except AssertionError:
3600 main.log.exception( self.name + ": AssertionError exception found" )
3601 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003602 except pexpect.EOF:
3603 main.log.error( self.name + ": EOF exception found" )
3604 main.log.error( self.name + ": " + self.handle.before )
3605 main.cleanup()
3606 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003607 except Exception:
3608 main.log.exception( self.name + ": Uncaught exception" )
3609 return None
3610
Jon Hall7eb38402015-01-08 17:19:54 -08003611 def update( self ):
3612 """
3613 updates the port address and status information for
3614 each port in mn"""
3615 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003616 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003617 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003618 self.handle.sendline( "" )
3619 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003620
Jon Hall7eb38402015-01-08 17:19:54 -08003621 self.handle.sendline( "update" )
3622 self.handle.expect( "update" )
3623 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003624
Jon Hall7eb38402015-01-08 17:19:54 -08003625 self.handle.sendline( "" )
3626 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003627
Jon Hallb1290e82014-11-18 16:17:48 -05003628 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003629 except pexpect.TIMEOUT:
3630 main.log.error(self.name + ": TIMEOUT exception found")
3631 main.log.error(self.name + ": " + self.handle.before)
3632 main.cleanup()
3633 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05003634 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003635 main.log.error( self.name + ": EOF exception found" )
3636 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05003637 main.cleanup()
3638 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003639 except Exception:
3640 main.log.exception( self.name + ": Uncaught exception!" )
3641 main.cleanup()
3642 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05003643
Jon Halld80cc142015-07-06 13:36:05 -07003644 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003645 """
3646 Add vlan tag to a host.
3647 Dependencies:
3648 This class depends on the "vlan" package
3649 $ sudo apt-get install vlan
3650 Configuration:
3651 Load the 8021q module into the kernel
3652 $sudo modprobe 8021q
3653
3654 To make this setup permanent:
3655 $ sudo su -c 'echo "8021q" >> /etc/modules'
3656 """
3657 if self.handle:
3658 try:
Jon Halld80cc142015-07-06 13:36:05 -07003659 # get the ip address of the host
3660 main.log.info( "Get the ip address of the host" )
3661 ipaddr = self.getIPAddress( host )
3662 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003663
Jon Halld80cc142015-07-06 13:36:05 -07003664 # remove IP from interface intf
3665 # Ex: h1 ifconfig h1-eth0 inet 0
3666 main.log.info( "Remove IP from interface " )
3667 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3668 self.handle.sendline( cmd2 )
3669 self.handle.expect( "mininet>" )
3670 response = self.handle.before
3671 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003672
Jon Halld80cc142015-07-06 13:36:05 -07003673 # create VLAN interface
3674 # Ex: h1 vconfig add h1-eth0 100
3675 main.log.info( "Create Vlan" )
3676 cmd3 = host + " vconfig add " + intf + " " + vlan
3677 self.handle.sendline( cmd3 )
3678 self.handle.expect( "mininet>" )
3679 response = self.handle.before
3680 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003681
Jon Halld80cc142015-07-06 13:36:05 -07003682 # assign the host's IP to the VLAN interface
3683 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3684 main.log.info( "Assign the host IP to the vlan interface" )
3685 vintf = intf + "." + vlan
3686 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3687 self.handle.sendline( cmd4 )
3688 self.handle.expect( "mininet>" )
3689 response = self.handle.before
3690 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003691
3692 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003693 except pexpect.TIMEOUT:
3694 main.log.error(self.name + ": TIMEOUT exception found")
3695 main.log.error(self.name + ": " + self.handle.before)
3696 main.cleanup()
3697 main.exit()
kaouthera3f13ca22015-05-05 15:01:41 -07003698 except pexpect.EOF:
3699 main.log.error( self.name + ": EOF exception found" )
3700 main.log.error( self.name + ": " + self.handle.before )
3701 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003702 except Exception:
3703 main.log.exception( self.name + ": Uncaught exception!" )
3704 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003705
Jon Hall892818c2015-10-20 17:58:34 -07003706 def createHostComponent( self, name ):
3707 """
3708 Creates a new mininet cli component with the same parameters as self.
3709 This new component is intended to be used to login to the hosts created
3710 by mininet.
3711
3712 Arguments:
3713 name - The string of the name of this component. The new component
3714 will be assigned to main.<name> .
3715 In addition, main.<name>.name = str( name )
3716 """
3717 try:
3718 # look to see if this component already exists
3719 getattr( main, name )
3720 except AttributeError:
3721 # namespace is clear, creating component
3722 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
3723 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
3724 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003725 except pexpect.EOF:
3726 main.log.error( self.name + ": EOF exception found" )
3727 main.log.error( self.name + ": " + self.handle.before )
3728 main.cleanup()
3729 main.exit()
Jon Hall892818c2015-10-20 17:58:34 -07003730 except Exception:
3731 main.log.exception( self.name + ": Uncaught exception!" )
3732 main.cleanup()
3733 main.exit()
3734 else:
3735 # namespace is not clear!
3736 main.log.error( name + " component already exists!" )
3737 # FIXME: Should we exit here?
3738 main.cleanup()
3739 main.exit()
3740
3741 def removeHostComponent( self, name ):
3742 """
3743 Remove host component
3744 Arguments:
3745 name - The string of the name of the component to delete.
3746 """
3747 try:
3748 # Get host component
3749 component = getattr( main, name )
3750 except AttributeError:
3751 main.log.error( "Component " + name + " does not exist." )
3752 return
3753 try:
3754 # Disconnect from component
3755 component.disconnect()
3756 # Delete component
3757 delattr( main, name )
3758 # Delete component from ComponentDictionary
3759 del( main.componentDictionary[name] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003760 except pexpect.EOF:
3761 main.log.error( self.name + ": EOF exception found" )
3762 main.log.error( self.name + ": " + self.handle.before )
3763 main.cleanup()
3764 main.exit()
Jon Hall892818c2015-10-20 17:58:34 -07003765 except Exception:
3766 main.log.exception( self.name + ": Uncaught exception!" )
3767 main.cleanup()
3768 main.exit()
3769
3770 def startHostCli( self, host=None ):
3771 """
3772 Use the mininet m utility to connect to the host's cli
3773 """
3774 # These are fields that can be used by scapy packets. Initialized to None
3775 self.hostIp = None
3776 self.hostMac = None
3777 try:
3778 if not host:
3779 host = self.name
3780 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003781 self.handle.sendline( "cd" )
3782 self.handle.expect( self.hostPrompt )
3783 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003784 self.handle.expect( self.hostPrompt )
3785 return main.TRUE
3786 except pexpect.TIMEOUT:
3787 main.log.exception( self.name + ": Command timed out" )
3788 return main.FALSE
3789 except pexpect.EOF:
3790 main.log.exception( self.name + ": connection closed." )
3791 main.cleanup()
3792 main.exit()
3793 except Exception:
3794 main.log.exception( self.name + ": Uncaught exception!" )
3795 main.cleanup()
3796 main.exit()
3797
YPZhang801d46d2016-08-08 13:26:28 -07003798 def changeInterfaceStatus( self, devicename, intf, status ):
3799 '''
3800
3801 Args:
3802 devicename: switch name
3803 intf: port name on switch
3804 status: up or down
3805
3806 Returns: boolean to show success change status
3807
3808 '''
3809 if status == "down" or status == "up":
3810 try:
3811 cmd = devicename + " ifconfig " + intf + " " + status
3812 self.handle.sendline( cmd )
3813 self.handle.expect("mininet>")
3814 return main.TRUE
3815 except pexpect.TIMEOUT:
3816 main.log.exception(self.name + ": Command timed out")
3817 return main.FALSE
3818 except pexpect.EOF:
3819 main.log.exception(self.name + ": connection closed.")
3820 main.cleanup()
3821 main.exit()
3822 except TypeError:
3823 main.log.exception(self.name + ": TypeError")
3824 main.cleanup()
3825 main.exit()
3826 except Exception:
3827 main.log.exception(self.name + ": Uncaught exception!")
3828 main.cleanup()
3829 main.exit()
3830 else:
3831 main.log.warn("Interface status should be up or down!")
3832 return main.FALSE
3833
3834
Jon Hall892818c2015-10-20 17:58:34 -07003835
adminbae64d82013-08-01 10:50:15 -07003836if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003837 sys.modules[ __name__ ] = MininetCliDriver()