blob: 580b3b55cc18964ef3f848304ae00992b0d96536 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004Copyright 2012 Open Networking Foundation (ONF)
adminbae64d82013-08-01 10:50:15 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
Jon Hall7eb38402015-01-08 17:19:54 -080010TestON is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070014
Jon Hall7eb38402015-01-08 17:19:54 -080015TestON is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070019
Jon Hall7eb38402015-01-08 17:19:54 -080020You should have received a copy of the GNU General Public License
21along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
Jon Hallbe6dfc42015-01-12 17:37:25 -080023MininetCliDriver is the basic driver which will handle the Mininet functions
24
25Some functions rely on a modified version of Mininet. These functions
26should all be noted in the comments. To get this MN version run these commands
27from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080028 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080030 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git pull
32
Jon Hall272a4db2015-01-12 17:43:48 -080033
34 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080035changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070036import pexpect
adminbae64d82013-08-01 10:50:15 -070037import re
38import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070039import types
kelvin-onlaba4074292015-07-09 15:19:49 -070040import os
Devin Lima7cfdbd2017-09-29 15:02:22 -070041import time
Jon Hall1ccf82c2014-10-15 14:55:16 -040042from math import pow
adminbae64d82013-08-01 10:50:15 -070043from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070044from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
kelvin-onlab50907142015-04-01 13:37:45 -070047class MininetCliDriver( Emulator ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -070048
Jon Hall7eb38402015-01-08 17:19:54 -080049 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070053 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070056 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080057 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070058 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070059 # TODO: Refactor driver to use these everywhere
60 self.mnPrompt = "mininet>"
61 self.hostPrompt = "~#"
62 self.bashPrompt = "\$"
63 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070064 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070065
Jon Hall7eb38402015-01-08 17:19:54 -080066 def connect( self, **connectargs ):
67 """
68 Here the main is the TestON instance after creating
69 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080070 try:
71 for key in connectargs:
72 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070073 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080074 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070075 for key in self.options:
76 if key == "home":
77 self.home = self.options[ 'home' ]
78 break
79 if self.home is None or self.home == "":
80 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070081
82 try:
Jon Hall892818c2015-10-20 17:58:34 -070083 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070084 self.ip_address = os.getenv( str( self.ip_address ) )
85 else:
86 main.log.info( self.name +
87 ": Trying to connect to " +
88 self.ip_address )
89
90 except KeyError:
91 main.log.info( "Invalid host name," +
92 " connecting to local host instead" )
93 self.ip_address = 'localhost'
94 except Exception as inst:
95 main.log.error( "Uncaught exception: " + str( inst ) )
96
kelvin-onlaba1484582015-02-02 15:46:20 -080097 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070098 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080099 self ).connect(
100 user_name=self.user_name,
101 ip_address=self.ip_address,
102 port=None,
103 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800104
kelvin-onlaba1484582015-02-02 15:46:20 -0800105 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800106 main.log.info( "Connection successful to the host " +
107 self.user_name +
108 "@" +
109 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800110 return main.TRUE
111 else:
112 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800113 self.user_name +
114 "@" +
115 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800116 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800117 return main.FALSE
118 except pexpect.EOF:
119 main.log.error( self.name + ": EOF exception found" )
120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700121 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800122 except Exception:
123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700124 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800125
kelvin-onlab10e8d392015-06-03 13:53:45 -0700126 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800127 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700128 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000129 Starts Mininet accepts a topology(.py) file and/or an optional
kelvin-onlabf512e942015-06-08 19:42:59 -0700130 argument, to start the mininet, as a parameter.
131 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700132 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700133 Options:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000134 topoFile = file path for topology file (.py)
kelvin-onlabf512e942015-06-08 19:42:59 -0700135 args = extra option added when starting the topology from the file
136 mnCmd = Mininet command use to start topology
137 Returns:
138 main.TRUE if the mininet starts successfully, main.FALSE
139 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800140 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700141 try:
142 if self.handle:
143 # make sure old networks are cleaned up
144 main.log.info( self.name +
145 ": Clearing any residual state or processes" )
146 self.handle.sendline( "sudo mn -c" )
147 i = self.handle.expect( [ 'password\sfor\s',
148 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800149 pexpect.EOF,
150 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700151 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800152 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700153 # Sudo asking for password
154 main.log.info( self.name + ": Sending sudo password" )
155 self.handle.sendline( self.pwd )
Jon Hall173f2a02018-01-11 13:56:37 -0800156 i = self.handle.expect( [ '%s:' % self.user_name,
Devin Limdc78e202017-06-09 18:30:07 -0700157 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700158 pexpect.EOF,
159 pexpect.TIMEOUT ],
160 timeout )
161 if i == 1:
162 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700163 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700164 main.log.error( self.name + ": Connection terminated" )
165 elif i == 3: # timeout
166 main.log.error( self.name + ": Something while cleaning " +
167 "Mininet took too long... " )
168 # Craft the string to start mininet
169 cmdString = "sudo "
170 if not mnCmd:
171 if topoFile is None or topoFile == '': # If no file is given
172 main.log.info( self.name + ": building fresh Mininet" )
173 cmdString += "mn "
174 if args is None or args == '':
175 # If no args given, use args from .topo file
176 args = self.options[ 'arg1' ] +\
177 " " + self.options[ 'arg2' ] +\
178 " --mac --controller " +\
179 self.options[ 'controller' ] + " " +\
180 self.options[ 'arg3' ]
181 else: # else only use given args
182 pass
183 # TODO: allow use of topo args and method args?
184 else: # Use given topology file
185 main.log.info(
186 "Starting Mininet from topo file " +
187 topoFile )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700188 cmdString += "-E python " + topoFile + " "
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700189 if args is None:
190 args = ''
191 # TODO: allow use of args from .topo file?
192 cmdString += args
193 else:
194 main.log.info( "Starting Mininet topology using '" + mnCmd +
195 "' command" )
196 cmdString += mnCmd
197 # Send the command and check if network started
198 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700199 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700200 main.log.info( "Sending '" + cmdString + "' to " + self.name )
201 self.handle.sendline( cmdString )
Devin Lima7cfdbd2017-09-29 15:02:22 -0700202 startTime = time.time()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700203 while True:
204 i = self.handle.expect( [ 'mininet>',
205 'Exception',
206 '\*\*\*',
207 pexpect.EOF,
208 pexpect.TIMEOUT ],
209 timeout )
210 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -0700211 main.log.info( self.name + ": Mininet built\nTime Took : " + str( time.time() - startTime ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700212 return main.TRUE
213 elif i == 1:
214 response = str( self.handle.before +
215 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700216 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700217 response += str( self.handle.before +
218 self.handle.after )
219 main.log.error(
220 self.name +
221 ": Launching Mininet failed: " + response )
222 return main.FALSE
223 elif i == 2:
224 self.handle.expect( [ "\n",
225 pexpect.EOF,
226 pexpect.TIMEOUT ],
227 timeout )
228 main.log.info( self.handle.before )
229 elif i == 3:
230 main.log.error( self.name + ": Connection timeout" )
231 return main.FALSE
232 elif i == 4: # timeout
233 main.log.error(
234 self.name +
235 ": Something took too long... " )
236 return main.FALSE
237 # Why did we hit this part?
238 main.log.error( "startNet did not return correctly" )
239 return main.FASLE
240 else: # if no handle
241 main.log.error( self.name + ": Connection failed to the host " +
242 self.user_name + "@" + self.ip_address )
243 main.log.error( self.name + ": Failed to connect to the Mininet" )
244 return main.FALSE
245 except pexpect.TIMEOUT:
246 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
247 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700248 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700249 except pexpect.EOF:
250 main.log.error( self.name + ": EOF exception found" )
251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700252 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700253 except Exception:
254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700255 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800256
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800257 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700258 try:
259 if topoType == 'tree':
260 # In tree topology, if fanout arg is not given, by default it is 2
261 if fanout is None:
262 fanout = 2
263 k = 0
264 count = 0
265 while( k <= depth - 1 ):
266 count = count + pow( fanout, k )
267 k = k + 1
268 numSwitches = count
269 while( k <= depth - 2 ):
270 # depth-2 gives you only core links and not considering
271 # edge links as seen by ONOS. If all the links including
272 # edge links are required, do depth-1
273 count = count + pow( fanout, k )
274 k = k + 1
275 numLinks = count * fanout
276 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
277 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800278
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700279 elif topoType == 'linear':
280 # In linear topology, if fanout or numHostsPerSw is not given,
281 # by default it is 1
282 if fanout is None:
283 fanout = 1
284 numSwitches = depth
285 numHostsPerSw = fanout
286 totalNumHosts = numSwitches * numHostsPerSw
287 numLinks = totalNumHosts + ( numSwitches - 1 )
288 print "num_switches for %s(%d,%d) = %d and links=%d" %\
289 ( topoType, depth, fanout, numSwitches, numLinks )
290 topoDict = { "num_switches": int( numSwitches ),
291 "num_corelinks": int( numLinks ) }
292 return topoDict
293 except Exception:
294 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700295 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400296
kelvin-onlabd3b64892015-01-20 13:26:24 -0800297 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700298 """
299 Calculate the number of switches and links in a topo."""
300 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700301 try:
302 argList = self.options[ 'arg1' ].split( "," )
303 topoArgList = argList[ 0 ].split( " " )
304 argList = map( int, argList[ 1: ] )
305 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700306
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700307 topoDict = self.numSwitchesNlinks( *topoArgList )
308 return topoDict
309 except Exception:
310 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700311 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400312
GlennRCf07c44a2015-09-18 13:33:46 -0700313 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800314 """
315 Verifies the reachability of the hosts using pingall command.
316 Optional parameter timeout allows you to specify how long to
317 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700318 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700319 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700320 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700321 ping
322 acceptableFailed - Set the number of acceptable failed pings for the
323 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800324 Returns:
325 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700326 otherwise main.FALSE
327 """
328 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700329 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700330 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700331 if self.handle:
332 main.log.info(
333 self.name +
334 ": Checking reachabilty to the hosts using pingall" )
335 response = ""
336 failedPings = 0
337 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700338 cmd = "pingall"
339 if protocol == "IPv6":
340 cmd = "py net.pingAll6()"
341 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700342 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700343 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700344 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700345 pexpect.EOF,
346 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700347 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700348 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700349 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700350 response += self.handle.before
351 break
352 elif i == 1:
353 response += self.handle.before + self.handle.after
354 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700355 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700356 returnValue = main.FALSE
357 if shortCircuit:
358 main.log.error( self.name +
359 ": Aborting pingall - "
360 + str( failedPings ) +
361 " pings failed" )
362 break
Jon Hall390696c2015-05-05 17:13:41 -0700363 if ( time.time() - startTime ) > timeout:
364 returnValue = main.FALSE
365 main.log.error( self.name +
366 ": Aborting pingall - " +
367 "Function took too long " )
368 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700369 elif i == 2:
370 main.log.error( self.name +
371 ": EOF exception found" )
372 main.log.error( self.name + ": " +
373 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700374 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700375 elif i == 3:
376 response += self.handle.before
377 main.log.error( self.name +
378 ": TIMEOUT exception found" )
379 main.log.error( self.name +
380 ": " +
381 str( response ) )
382 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800383 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700384 self.handle.expect( "Interrupt" )
385 self.handle.expect( "mininet>" )
386 break
387 pattern = "Results\:"
388 main.log.info( "Pingall output: " + str( response ) )
389 if re.search( pattern, response ):
390 main.log.info( self.name + ": Pingall finished with "
391 + str( failedPings ) + " failed pings" )
392 return returnValue
393 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700394 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800395 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700396 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700397 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700398 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700399 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700400 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700401 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700402 except pexpect.TIMEOUT:
403 if response:
404 main.log.info( "Pingall output: " + str( response ) )
405 main.log.error( self.name + ": pexpect.TIMEOUT found" )
406 return main.FALSE
407 except pexpect.EOF:
408 main.log.error( self.name + ": EOF exception found" )
409 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700410 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700411
Jon Hall7eb38402015-01-08 17:19:54 -0800412 def fpingHost( self, **pingParams ):
413 """
414 Uses the fping package for faster pinging...
415 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700416 try:
417 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
418 command = args[ "SRC" ] + \
419 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
420 self.handle.sendline( command )
421 self.handle.expect(
422 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
423 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
424 response = self.handle.before
425 if re.search( ":\s-", response ):
426 main.log.info( self.name + ": Ping fail" )
427 return main.FALSE
428 elif re.search( ":\s\d{1,2}\.\d\d", response ):
429 main.log.info( self.name + ": Ping good!" )
430 return main.TRUE
431 main.log.info( self.name + ": Install fping on mininet machine... " )
432 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700433 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700434 except Exception:
435 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700436 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700437
Jon Hall3b489db2015-10-05 14:38:37 -0700438 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400439 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700440 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700441
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400442 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700443 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700444
445 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400446 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700447
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400448 Returns main.FALSE if one or more of hosts specified
449 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700450 wait = int( wait )
451 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400452
453 try:
454 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700455
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400456 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700457 pingResponse = "IPv4 ping across specified hosts\n"
458 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400459 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700460 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400461 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700462 pingList = hostList[ :listIndex ] + \
463 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700464
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700465 pingResponse += str( str( host ) + " -> " )
GlennRCd10d3cc2015-09-24 12:47:16 -0700466
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400467 for temp in pingList:
468 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700469 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700470 self.handle.sendline( pingCmd )
471 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400472 response = self.handle.before
473 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700474 pingResponse += str( " h" + str( temp[ 1: ] ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400475 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700476 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400477 # One of the host to host pair is unreachable
478 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700479 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700480 pingResponse += "\n"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700481 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700482 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700483 except pexpect.TIMEOUT:
484 main.log.exception( self.name + ": TIMEOUT exception" )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700485 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400486 except pexpect.EOF:
487 main.log.error( self.name + ": EOF exception found" )
488 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700489 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700490 except Exception:
491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400493
Jon Hall3b489db2015-10-05 14:38:37 -0700494 def pingIpv6Hosts( self, hostList, prefix='1000::', wait=1 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700495 """
Jon Hall3b489db2015-10-05 14:38:37 -0700496 IPv6 ping all hosts in hostList. If no prefix passed this will use
497 default prefix of 1000::
Hari Krishna9592fc82015-07-31 15:11:15 -0700498
Jon Hall3b489db2015-10-05 14:38:37 -0700499 Returns main.TRUE if all hosts specified can reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700500
Jon Hall3b489db2015-10-05 14:38:37 -0700501 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700502 """
503 try:
504 main.log.info( "Testing reachability between specified IPv6 hosts" )
505 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700506 wait = int( wait )
507 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700508 pingResponse = "IPv6 Pingall output:\n"
509 failedPings = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700510 for host in hostList:
511 listIndex = hostList.index( host )
512 # List of hosts to ping other than itself
513 pingList = hostList[ :listIndex ] + \
514 hostList[ ( listIndex + 1 ): ]
515
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700516 pingResponse += str( str( host ) + " -> " )
GlennRC2cf7d952015-09-11 16:32:13 -0700517
Hari Krishna9592fc82015-07-31 15:11:15 -0700518 for temp in pingList:
519 # Current host pings all other hosts specified
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700520 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
Jon Hall934576d2015-10-09 10:12:22 -0700521 self.handle.sendline( pingCmd )
522 self.handle.expect( "mininet>", timeout=wait + 1 )
Hari Krishna9592fc82015-07-31 15:11:15 -0700523 response = self.handle.before
524 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700525 pingResponse += str( " h" + str( temp[ 1: ] ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700526 else:
GlennRC2cf7d952015-09-11 16:32:13 -0700527 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700528 # One of the host to host pair is unreachable
529 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700530 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700531 pingResponse += "\n"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700532 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700533 return isReachable
534
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700535 except pexpect.TIMEOUT:
536 main.log.exception( self.name + ": TIMEOUT exception" )
537 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700538 except pexpect.EOF:
539 main.log.error( self.name + ": EOF exception found" )
540 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700541 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700542 except Exception:
543 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700544 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700545
Jon Hall7eb38402015-01-08 17:19:54 -0800546 def pingHost( self, **pingParams ):
547 """
Jon Hall3b489db2015-10-05 14:38:37 -0700548 Ping from one mininet host to another
549 Currently the only supported Params: SRC, TARGET, and WAIT
550 """
551 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700552 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700553 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800554 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700555 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700556 try:
Jon Hall61282e32015-03-19 11:34:11 -0700557 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800558 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700559 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
560 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700561 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800562 main.log.error(
563 self.name +
564 ": timeout when waiting for response from mininet" )
565 main.log.error( "response: " + str( self.handle.before ) )
566 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700567 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800568 main.log.error(
569 self.name +
570 ": timeout when waiting for response from mininet" )
571 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700572 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700573 if re.search( ',\s0\%\spacket\sloss', response ):
574 main.log.info( self.name + ": no packets lost, host is reachable" )
575 return main.TRUE
576 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800577 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700578 self.name +
579 ": PACKET LOST, HOST IS NOT REACHABLE" )
580 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800581 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800582 main.log.error( self.name + ": EOF exception found" )
583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700584 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700585 except Exception:
586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700587 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700588
589 def ping6pair( self, **pingParams ):
590 """
GlennRC2cf7d952015-09-11 16:32:13 -0700591 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700592 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000593 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700594 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
595 """
Jon Hall3b489db2015-10-05 14:38:37 -0700596 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700597 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700598 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530599 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700600 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700601 try:
602 main.log.info( "Sending: " + command )
603 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700604 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
605 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700606 if i == 1:
607 main.log.error(
608 self.name +
609 ": timeout when waiting for response from mininet" )
610 main.log.error( "response: " + str( self.handle.before ) )
611 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
612 if i == 1:
613 main.log.error(
614 self.name +
615 ": timeout when waiting for response from mininet" )
616 main.log.error( "response: " + str( self.handle.before ) )
617 response = self.handle.before
618 main.log.info( self.name + ": Ping Response: " + response )
619 if re.search( ',\s0\%\spacket\sloss', response ):
620 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700621 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700622 else:
alisone4121a92016-11-22 16:31:36 -0800623 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700624 self.name +
625 ": PACKET LOST, HOST IS NOT REACHABLE" )
626 return main.FALSE
627
628 except pexpect.EOF:
629 main.log.error( self.name + ": EOF exception found" )
630 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700631 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700632 except Exception:
633 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700634 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800635
You Wangdb927a52016-02-26 11:03:28 -0800636 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
637 """
638 Description:
639 Ping a set of destination host from host CLI.
640 Logging into a Mininet host CLI is required before calling this funtion.
641 Params:
642 dstIPList is a list of destination ip addresses
643 Returns:
644 main.TRUE if the destination host is reachable
645 main.FALSE otherwise
646 """
647 isReachable = main.TRUE
648 wait = int( wait )
649 cmd = "ping"
650 if IPv6:
651 cmd = cmd + "6"
652 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
653 try:
654 for dstIP in dstIPList:
655 pingCmd = cmd + " " + dstIP
656 self.handle.sendline( pingCmd )
657 i = self.handle.expect( [ self.hostPrompt,
658 '\*\*\* Unknown command: ' + pingCmd,
659 pexpect.TIMEOUT ],
660 timeout=wait + 1 )
661 if i == 0:
662 response = self.handle.before
663 if not re.search( ',\s0\%\spacket\sloss', response ):
664 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
665 isReachable = main.FALSE
666 elif i == 1:
667 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700668 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800669 elif i == 2:
670 main.log.error( self.name + ": timeout when waiting for response" )
671 isReachable = main.FALSE
672 else:
673 main.log.error( self.name + ": unknown response: " + self.handle.before )
674 isReachable = main.FALSE
675 except pexpect.TIMEOUT:
676 main.log.exception( self.name + ": TIMEOUT exception" )
677 isReachable = main.FALSE
678 except pexpect.EOF:
679 main.log.error( self.name + ": EOF exception found" )
680 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700681 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800682 except Exception:
683 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700684 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800685 return isReachable
686
Jon Hall7eb38402015-01-08 17:19:54 -0800687 def checkIP( self, host ):
688 """
689 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700690 try:
691 if self.handle:
692 try:
693 response = self.execute(
694 cmd=host +
695 " ifconfig",
696 prompt="mininet>",
697 timeout=10 )
698 except pexpect.EOF:
699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700701 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700702
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700703 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
704 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
705 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
706 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
707 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
708 "[0-9]|25[0-5]|[0-9]{1,2})"
709 # pattern = "inet addr:10.0.0.6"
710 if re.search( pattern, response ):
711 main.log.info( self.name + ": Host Ip configured properly" )
712 return main.TRUE
713 else:
714 main.log.error( self.name + ": Host IP not found" )
715 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700716 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700717 main.log.error( self.name + ": Connection failed to the host" )
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700720 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800721
Jon Hall7eb38402015-01-08 17:19:54 -0800722 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800723 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700724 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800725 response = self.execute(
726 cmd="h1 /usr/sbin/sshd -D&",
727 prompt="mininet>",
728 timeout=10 )
729 response = self.execute(
730 cmd="h4 /usr/sbin/sshd -D&",
731 prompt="mininet>",
732 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700733 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800734 vars( self )[ key ] = connectargs[ key ]
735 response = self.execute(
736 cmd="xterm h1 h4 ",
737 prompt="mininet>",
738 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800739 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.error( self.name + ": EOF exception found" )
741 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700742 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700743 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800744 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700745 if self.flag == 0:
746 self.flag = 1
747 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800748 else:
adminbae64d82013-08-01 10:50:15 -0700749 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800750
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700751 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700752 """
753 Moves a host from one switch to another on the fly
754 Note: The intf between host and oldSw when detached
755 using detach(), will still show up in the 'net'
756 cmd, because switch.detach() doesn't affect switch.intfs[]
757 ( which is correct behavior since the interfaces
758 haven't moved ).
759 """
760 if self.handle:
761 try:
762 # Bring link between oldSw-host down
763 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
764 "'," + "'down')"
765 print "cmd1= ", cmd
766 response = self.execute( cmd=cmd,
767 prompt="mininet>",
768 timeout=10 )
769
770 # Determine hostintf and Oldswitchintf
771 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
772 ")[0]"
773 print "cmd2= ", cmd
774 self.handle.sendline( cmd )
775 self.handle.expect( "mininet>" )
776
777 # Determine ip and mac address of the host-oldSw interface
778 cmd = "px ipaddr = hintf.IP()"
779 print "cmd3= ", cmd
780 self.handle.sendline( cmd )
781 self.handle.expect( "mininet>" )
782
783 cmd = "px macaddr = hintf.MAC()"
784 print "cmd3= ", cmd
785 self.handle.sendline( cmd )
786 self.handle.expect( "mininet>" )
787
788 # Detach interface between oldSw-host
789 cmd = "px " + oldSw + ".detach( sintf )"
790 print "cmd4= ", cmd
791 self.handle.sendline( cmd )
792 self.handle.expect( "mininet>" )
793
794 # Add link between host-newSw
795 cmd = "py net.addLink(" + host + "," + newSw + ")"
796 print "cmd5= ", cmd
797 self.handle.sendline( cmd )
798 self.handle.expect( "mininet>" )
799
800 # Determine hostintf and Newswitchintf
801 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
802 ")[0]"
803 print "cmd6= ", cmd
804 self.handle.sendline( cmd )
805 self.handle.expect( "mininet>" )
806
807 # Attach interface between newSw-host
808 cmd = "px " + newSw + ".attach( sintf )"
809 print "cmd3= ", cmd
810 self.handle.sendline( cmd )
811 self.handle.expect( "mininet>" )
812
813 # Set ipaddress of the host-newSw interface
814 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
815 print "cmd7 = ", cmd
816 self.handle.sendline( cmd )
817 self.handle.expect( "mininet>" )
818
819 # Set macaddress of the host-newSw interface
820 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
821 print "cmd8 = ", cmd
822 self.handle.sendline( cmd )
823 self.handle.expect( "mininet>" )
824
825 cmd = "net"
826 print "cmd9 = ", cmd
827 self.handle.sendline( cmd )
828 self.handle.expect( "mininet>" )
829 print "output = ", self.handle.before
830
831 # Determine ipaddress of the host-newSw interface
832 cmd = host + " ifconfig"
833 print "cmd10= ", cmd
834 self.handle.sendline( cmd )
835 self.handle.expect( "mininet>" )
836 print "ifconfig o/p = ", self.handle.before
837
838 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700839
840 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700841 main.log.error( self.name + ": TIMEOUT exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700843 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700844 except pexpect.EOF:
845 main.log.error( self.name + ": EOF exception found" )
846 main.log.error( self.name + ": " + self.handle.before )
847 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700848 except Exception:
849 main.log.exception( self.name + ": Uncaught exception!" )
850 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700851
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700852 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800853 """
854 Moves a host from one switch to another on the fly
855 Note: The intf between host and oldSw when detached
856 using detach(), will still show up in the 'net'
857 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700858 ( which is correct behavior since the interfaces
859 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800860 """
861 if self.handle:
862 try:
Jon Hall439c8912016-04-15 02:22:03 -0700863 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800864 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700865 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800866 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800867 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800868 response = self.execute( cmd=cmd,
869 prompt="mininet>",
870 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700871
kelvin-onlaba1484582015-02-02 15:46:20 -0800872 # Determine hostintf and Oldswitchintf
873 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800874 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800875 print "cmd2= ", cmd
876 self.handle.sendline( cmd )
877 self.handle.expect( "mininet>" )
878
shahshreya73537862015-02-11 15:15:24 -0800879 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700880 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800881 print "cmd3= ", cmd
882 self.handle.sendline( cmd )
883 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800884
885 cmd = "px macaddr = hintf.MAC()"
886 print "cmd3= ", cmd
887 self.handle.sendline( cmd )
888 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700889
kelvin-onlaba1484582015-02-02 15:46:20 -0800890 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700891 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800892 print "cmd4= ", cmd
893 self.handle.sendline( cmd )
894 self.handle.expect( "mininet>" )
895
896 # Add link between host-newSw
897 cmd = "py net.addLink(" + host + "," + newSw + ")"
898 print "cmd5= ", cmd
899 self.handle.sendline( cmd )
900 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700901
kelvin-onlaba1484582015-02-02 15:46:20 -0800902 # Determine hostintf and Newswitchintf
903 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800904 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800905 print "cmd6= ", cmd
906 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700907 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800908
909 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700910 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700911 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800912 self.handle.sendline( cmd )
913 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800914
915 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700916 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700917 print "cmd7 = ", cmd
918 self.handle.sendline( cmd )
919 self.handle.expect( "mininet>" )
920
921 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700922 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800923 print "cmd8 = ", cmd
924 self.handle.sendline( cmd )
925 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700926
Jon Hall439c8912016-04-15 02:22:03 -0700927 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700928 print "cmd9 =", cmd
929 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -0700930 print response
931 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700932 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700933 print ipAddressSearch.group( 1 )
934 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -0700935 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
936 print "cmd10 = ", cmd
937 self.handle.sendline( cmd )
938 self.handle.expect( "mininet>" )
939
kelvin-onlaba1484582015-02-02 15:46:20 -0800940 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700941 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800942 self.handle.sendline( cmd )
943 self.handle.expect( "mininet>" )
944 print "output = ", self.handle.before
945
946 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800947 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700948 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800949 self.handle.sendline( cmd )
950 self.handle.expect( "mininet>" )
951 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700952
kelvin-onlaba1484582015-02-02 15:46:20 -0800953 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700954 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700955 main.log.error( self.name + ": TIMEOUT exception found" )
956 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700957 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800958 except pexpect.EOF:
959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
961 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700962 except Exception:
963 main.log.exception( self.name + ": Uncaught exception!" )
964 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800965
Jon Hall7eb38402015-01-08 17:19:54 -0800966 def changeIP( self, host, intf, newIP, newNetmask ):
967 """
968 Changes the ip address of a host on the fly
969 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800970 if self.handle:
971 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800972 cmd = host + " ifconfig " + intf + " " + \
973 newIP + " " + 'netmask' + " " + newNetmask
974 self.handle.sendline( cmd )
975 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800976 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800977 main.log.info( "response = " + response )
978 main.log.info(
979 "Ip of host " +
980 host +
981 " changed to new IP " +
982 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800983 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700984 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700985 main.log.error( self.name + ": TIMEOUT exception found" )
986 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700987 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800988 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800989 main.log.error( self.name + ": EOF exception found" )
990 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800991 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700992 except Exception:
993 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700994 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800995
Jon Hall7eb38402015-01-08 17:19:54 -0800996 def changeDefaultGateway( self, host, newGW ):
997 """
998 Changes the default gateway of a host
999 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001000 if self.handle:
1001 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001002 cmd = host + " route add default gw " + newGW
1003 self.handle.sendline( cmd )
1004 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001005 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001006 main.log.info( "response = " + response )
1007 main.log.info(
1008 "Default gateway of host " +
1009 host +
1010 " changed to " +
1011 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001012 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001013 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001014 main.log.error( self.name + ": TIMEOUT exception found" )
1015 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001016 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001017 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001018 main.log.error( self.name + ": EOF exception found" )
1019 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001020 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001021 except Exception:
1022 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001023 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001024
Jon Hall7eb38402015-01-08 17:19:54 -08001025 def addStaticMACAddress( self, host, GW, macaddr ):
1026 """
Jon Hallefbd9792015-03-05 16:11:36 -08001027 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001028 if self.handle:
1029 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001030 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1031 cmd = host + " arp -s " + GW + " " + macaddr
1032 self.handle.sendline( cmd )
1033 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001034 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001035 main.log.info( "response = " + response )
1036 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001037 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001038 GW +
1039 " changed to " +
1040 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001041 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001042 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001043 main.log.error( self.name + ": TIMEOUT exception found" )
1044 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001045 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001046 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001047 main.log.error( self.name + ": EOF exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001049 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001050 except Exception:
1051 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001052 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001053
Jon Hall7eb38402015-01-08 17:19:54 -08001054 def verifyStaticGWandMAC( self, host ):
1055 """
1056 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001057 if self.handle:
1058 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001059 # h1 arp -an
1060 cmd = host + " arp -an "
1061 self.handle.sendline( cmd )
1062 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001063 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001064 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001065 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001066 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001067 main.log.error( self.name + ": TIMEOUT exception found" )
1068 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001069 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001070 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001073 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001074 except Exception:
1075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001077
Jon Hall7eb38402015-01-08 17:19:54 -08001078 def getMacAddress( self, host ):
1079 """
1080 Verifies the host's ip configured or not."""
1081 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001082 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001083 response = self.execute(
1084 cmd=host +
1085 " ifconfig",
1086 prompt="mininet>",
1087 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001088 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001089 main.log.error( self.name + ": EOF exception found" )
1090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001091 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001092 except Exception:
1093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001094 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001095
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001096 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001097 macAddressSearch = re.search( pattern, response, re.I )
1098 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001099 main.log.info(
1100 self.name +
1101 ": Mac-Address of Host " +
1102 host +
1103 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 macAddress )
1105 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001106 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001107 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001108
Jon Hall7eb38402015-01-08 17:19:54 -08001109 def getInterfaceMACAddress( self, host, interface ):
1110 """
1111 Return the IP address of the interface on the given host"""
1112 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001113 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001114 response = self.execute( cmd=host + " ifconfig " + interface,
1115 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001116 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 main.log.error( self.name + ": EOF exception found" )
1118 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001119 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001120 except Exception:
1121 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001122 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001123
1124 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 macAddressSearch = re.search( pattern, response, re.I )
1126 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001127 main.log.info( "No mac address found in %s" % response )
1128 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001130 main.log.info(
1131 "Mac-Address of " +
1132 host +
1133 ":" +
1134 interface +
1135 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 macAddress )
1137 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001138 else:
1139 main.log.error( "Connection failed to the host" )
1140
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001141 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001142 """
1143 Verifies the host's ip configured or not."""
1144 if self.handle:
1145 try:
1146 response = self.execute(
1147 cmd=host +
1148 " ifconfig",
1149 prompt="mininet>",
1150 timeout=10 )
1151 except pexpect.EOF:
1152 main.log.error( self.name + ": EOF exception found" )
1153 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001154 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001155 except Exception:
1156 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001157 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001158
sathishmad953462015-12-03 17:42:07 +05301159 pattern = ''
1160 if proto == 'IPV4':
1161 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1162 else:
Jon Hall439c8912016-04-15 02:22:03 -07001163 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001165 main.log.info(
1166 self.name +
1167 ": IP-Address of Host " +
1168 host +
1169 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 ipAddressSearch.group( 1 ) )
1171 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001172 else:
1173 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001174
Jon Hall7eb38402015-01-08 17:19:54 -08001175 def getSwitchDPID( self, switch ):
1176 """
1177 return the datapath ID of the switch"""
1178 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001179 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001180 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 response = self.execute(
1182 cmd=cmd,
1183 prompt="mininet>",
1184 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001185 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001188 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001189 except Exception:
1190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001191 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001192 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001193 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001194 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001195 main.log.info(
1196 "Couldn't find DPID for switch %s, found: %s" %
1197 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001198 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001199 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001200 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001201 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001202
Jon Hall7eb38402015-01-08 17:19:54 -08001203 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001204 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001205 self.handle.sendline( "" )
1206 self.expect( "mininet>" )
1207 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001208 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001209 response = self.execute(
1210 cmd=cmd,
1211 prompt="mininet>",
1212 timeout=10 )
1213 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001214 response = self.handle.before
1215 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001216 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001217 main.log.error( self.name + ": TIMEOUT exception found" )
1218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001219 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001220 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001221 main.log.error( self.name + ": EOF exception found" )
1222 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001223 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001224 except Exception:
1225 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001226 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001227
Jon Hall7eb38402015-01-08 17:19:54 -08001228 def getInterfaces( self, node ):
1229 """
1230 return information dict about interfaces connected to the node"""
1231 if self.handle:
1232 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001233 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001234 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001235 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 response = self.execute(
1237 cmd=cmd,
1238 prompt="mininet>",
1239 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001240 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 main.log.error( self.name + ": EOF exception found" )
1242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001243 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001244 except Exception:
1245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001246 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001247 return response
1248 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001250
Jon Hall7eb38402015-01-08 17:19:54 -08001251 def dump( self ):
1252 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001253 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001254 response = self.execute(
1255 cmd='dump',
1256 prompt='mininet>',
1257 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001258 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001261 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001262 except Exception:
1263 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001264 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001265 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001266
Jon Hall7eb38402015-01-08 17:19:54 -08001267 def intfs( self ):
1268 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001269 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001270 response = self.execute(
1271 cmd='intfs',
1272 prompt='mininet>',
1273 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001274 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001275 main.log.error( self.name + ": EOF exception found" )
1276 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001277 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001278 except Exception:
1279 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001280 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001281 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001282
Jon Hall7eb38402015-01-08 17:19:54 -08001283 def net( self ):
1284 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001285 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001286 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001287 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001288 main.log.error( self.name + ": EOF exception found" )
1289 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001290 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001291 except Exception:
1292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001293 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001294 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001295
Devin Lima7cfdbd2017-09-29 15:02:22 -07001296 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001297 main.log.info( self.name + ": List network links" )
1298 try:
1299 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001300 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001301 except pexpect.EOF:
1302 main.log.error( self.name + ": EOF exception found" )
1303 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001304 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001305 except Exception:
1306 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001307 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001308 return response
1309
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001310 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001311 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001312 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001313
kelvin-onlab7cce9382015-07-17 10:21:03 -07001314 @parm:
1315 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1316 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001317 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001318 try:
1319 for host1 in hosts:
1320 for host2 in hosts:
1321 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001322 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1323 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001324 except Exception:
1325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001326 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001327
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001328 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001329 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001330 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1331 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001332
kelvin-onlab7cce9382015-07-17 10:21:03 -07001333 @parm:
1334 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1335 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001336 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001337 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1338 try:
1339 # Setup the mininet command
1340 cmd1 = 'iperf ' + host1 + " " + host2
1341 self.handle.sendline( cmd1 )
1342 outcome = self.handle.expect( "mininet>", timeout )
1343 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001344
kelvin-onlab7cce9382015-07-17 10:21:03 -07001345 # checks if there are results in the mininet response
1346 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001347 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001348 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001349 response = response.split( "\r\n" )
1350 response = response[ len( response )-2 ]
1351 response = response.split( ": " )
1352 response = response[ len( response )-1 ]
1353 response = response.replace( "[", "" )
1354 response = response.replace( "]", "" )
1355 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001356
kelvin-onlab7cce9382015-07-17 10:21:03 -07001357 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001358 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001359
kelvin-onlab7cce9382015-07-17 10:21:03 -07001360 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001361 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001362 if len( bandwidth ) == 2:
1363 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001364 return main.TRUE
1365 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001366 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001367 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001368 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001369 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001370 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001371 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001372 main.log.error( self.name + ": TIMEOUT exception found" )
1373 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001374 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001375 # NOTE: Send ctrl-c to make sure iperf is done
1376 self.handle.sendline( "\x03" )
1377 self.handle.expect( "Interrupt" )
1378 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001379 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001380 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 main.log.error( self.name + ": EOF exception found" )
1382 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001383 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001384 except Exception:
1385 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001386 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001387
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001388 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001389 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1390 try:
1391 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001392 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001393 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001394 outcome1 = self.handle.expect( "mininet>" )
1395 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001396 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001397 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001398 response1 = self.handle.before
1399 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001400 print response1, response2
1401 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001402 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001403 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001404 return main.TRUE
1405 else:
1406 main.log.error( self.name + ": iperf test failed" )
1407 return main.FALSE
1408 except pexpect.TIMEOUT:
1409 main.log.error( self.name + ": TIMEOUT exception found" )
1410 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1411 self.handle.sendline( "\x03" )
1412 self.handle.expect( "Interrupt" )
1413 self.handle.expect( "mininet>" )
1414 return main.FALSE
1415 except pexpect.EOF:
1416 main.log.error( self.name + ": EOF exception found" )
1417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001418 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001419 except Exception:
1420 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001421 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001422
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001423 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001424 '''
GlennRC61321f22015-07-16 13:36:54 -07001425 Runs the iperfudp function with a given set of hosts and specified
1426 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001427
GlennRC61321f22015-07-16 13:36:54 -07001428 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001429 bandwidth: the targeted bandwidth, in megabits ('M')
1430 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001431 try:
1432 for host1 in hosts:
1433 for host2 in hosts:
1434 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001435 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1436 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001437 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001438 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001439 return main.FALSE
1440 except Exception:
1441 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001442 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001443
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001444 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001445 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001446 Creates an iperf UDP test with a specific bandwidth.
1447 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001448
kelvin-onlab7cce9382015-07-17 10:21:03 -07001449 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001450 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1451 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001452 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001453 try:
1454 # setup the mininet command
1455 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001456 self.handle.sendline( cmd )
1457 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001458 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001459
kelvin-onlab7cce9382015-07-17 10:21:03 -07001460 # check if there are in results in the mininet response
1461 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001462 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001463 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001464 response = response.split( "\r\n" )
1465 response = response[ len( response )-2 ]
1466 response = response.split( ": " )
1467 response = response[ len( response )-1 ]
1468 response = response.replace( "[", "" )
1469 response = response.replace( "]", "" )
1470 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001471
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001472 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001473
kelvin-onlab7cce9382015-07-17 10:21:03 -07001474 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001475 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001476 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001477 # if one entry is blank then something is wrong
1478 for item in mnBandwidth:
1479 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001480 main.log.error( self.name + ": Could not parse iperf output" )
1481 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001482 return main.FALSE
1483 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001484 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001485 return main.TRUE
1486 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001487 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001488 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001489
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001490 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001491 main.log.error( self.name + ": TIMEOUT exception found" )
1492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001493 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001494 except pexpect.EOF:
1495 main.log.error( self.name + ": EOF exception found" )
1496 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001497 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001498 except Exception:
1499 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001500 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001501
Jon Hall7eb38402015-01-08 17:19:54 -08001502 def nodes( self ):
1503 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001504 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001505 response = self.execute(
1506 cmd='nodes',
1507 prompt='mininet>',
1508 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001509 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001510 main.log.error( self.name + ": EOF exception found" )
1511 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001512 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001513 except Exception:
1514 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001515 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001516 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001517
Jon Hall7eb38402015-01-08 17:19:54 -08001518 def pingpair( self ):
1519 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001520 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001521 response = self.execute(
1522 cmd='pingpair',
1523 prompt='mininet>',
1524 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001525 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001526 main.log.error( self.name + ": EOF exception found" )
1527 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001528 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001529 except Exception:
1530 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001531 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001532
Jon Hall7eb38402015-01-08 17:19:54 -08001533 if re.search( ',\s0\%\spacket\sloss', response ):
1534 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001535 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001536 else:
alisone4121a92016-11-22 16:31:36 -08001537 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001538 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001539
Jon Hall7eb38402015-01-08 17:19:54 -08001540 def link( self, **linkargs ):
1541 """
GlennRCed771242016-01-13 17:02:47 -08001542 Bring link( s ) between two nodes up or down
1543 """
Jon Hall6094a362014-04-11 14:46:56 -07001544 try:
GlennRCed771242016-01-13 17:02:47 -08001545 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1546 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1547 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1548 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1549
1550 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1551 cmd = "link {} {} {}".format( end1, end2, option )
1552 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001553 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001554 response = self.handle.before
1555 main.log.info( response )
1556
1557 return main.TRUE
1558 except pexpect.TIMEOUT:
1559 main.log.exception( self.name + ": Command timed out" )
1560 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001561 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001562 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001563 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001564 except Exception:
1565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001566 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001567
pingping-lin8244a3b2015-09-16 13:36:56 -07001568 def switch( self, **switchargs ):
1569 """
1570 start/stop a switch
1571 """
1572 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1573 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1574 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1575 command = "switch " + str( sw ) + " " + str( option )
1576 main.log.info( command )
1577 try:
1578 self.handle.sendline( command )
1579 self.handle.expect( "mininet>" )
1580 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001581 main.log.error( self.name + ": TIMEOUT exception found" )
1582 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001583 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001584 except pexpect.EOF:
1585 main.log.error( self.name + ": EOF exception found" )
1586 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001587 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001588 return main.TRUE
1589
pingping-lin5bb663b2015-09-24 11:47:50 -07001590 def node( self, nodeName, commandStr ):
1591 """
1592 Carry out a command line on a given node
1593 @parm:
1594 nodeName: the node name in Mininet testbed
1595 commandStr: the command line will be carried out on the node
1596 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1597 """
1598 command = str( nodeName ) + " " + str( commandStr )
1599 main.log.info( command )
1600
1601 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001602 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001603 if re.search( "Unknown command", response ):
1604 main.log.warn( response )
1605 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001606 if re.search( "Permission denied", response ):
1607 main.log.warn( response )
1608 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001609 except pexpect.EOF:
1610 main.log.error( self.name + ": EOF exception found" )
1611 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001612 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001613 main.log.info( " response is :" )
1614 main.log.info( response )
1615 return response
1616
Jon Hall7eb38402015-01-08 17:19:54 -08001617 def yank( self, **yankargs ):
1618 """
1619 yank a mininet switch interface to a host"""
1620 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001621 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001622 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1623 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001624 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001625 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001626 response = self.execute(
1627 cmd=command,
1628 prompt="mininet>",
1629 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001630 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001631 main.log.error( self.name + ": EOF exception found" )
1632 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001633 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001634 except Exception:
1635 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001636 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001637 return main.TRUE
1638
Jon Hall7eb38402015-01-08 17:19:54 -08001639 def plug( self, **plugargs ):
1640 """
1641 plug the yanked mininet switch interface to a switch"""
1642 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001643 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001644 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1645 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001646 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001647 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001648 response = self.execute(
1649 cmd=command,
1650 prompt="mininet>",
1651 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001652 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001653 main.log.error( self.name + ": EOF exception found" )
1654 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001655 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001656 except Exception:
1657 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001658 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001659 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001660
Jon Hall7eb38402015-01-08 17:19:54 -08001661 def dpctl( self, **dpctlargs ):
1662 """
1663 Run dpctl command on all switches."""
1664 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001665 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001666 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1667 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1668 command = "dpctl " + cmd + " " + str( cmdargs )
1669 try:
1670 response = self.execute(
1671 cmd=command,
1672 prompt="mininet>",
1673 timeout=10 )
1674 except pexpect.EOF:
1675 main.log.error( self.name + ": EOF exception found" )
1676 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001677 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001678 except Exception:
1679 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001680 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001681 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001682
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001684 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001685 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001686 try:
1687 fileInput = path + '/lib/Mininet/INSTALL'
1688 version = super( Mininet, self ).getVersion()
1689 pattern = 'Mininet\s\w\.\w\.\w\w*'
1690 for line in open( fileInput, 'r' ).readlines():
1691 result = re.match( pattern, line )
1692 if result:
1693 version = result.group( 0 )
1694 return version
1695 except Exception:
1696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001698
kelvin-onlabd3b64892015-01-20 13:26:24 -08001699 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001700 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001701 Parameters:
1702 sw: The name of an OVS switch. Example "s1"
1703 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001704 The output of the command from the mininet cli
1705 or main.FALSE on timeout"""
1706 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001707 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001708 response = self.execute(
1709 cmd=command,
1710 prompt="mininet>",
1711 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001712 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001713 return response
admin2a9548d2014-06-17 14:08:07 -07001714 else:
1715 return main.FALSE
1716 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001717 main.log.error( self.name + ": EOF exception found" )
1718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001719 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001720 except Exception:
1721 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001722 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001723
Charles Chan029be652015-08-24 01:46:10 +08001724 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001725 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001726 Description:
1727 Assign switches to the controllers ( for ovs use only )
1728 Required:
1729 sw - Name of the switch. This can be a list or a string.
1730 ip - Ip addresses of controllers. This can be a list or a string.
1731 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001732 port - ONOS use port 6653, if no list of ports is passed, then
1733 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001734 ptcp - ptcp number, This can be a string or a list that has
1735 the same length as switch. This is optional and not required
1736 when using ovs switches.
1737 NOTE: If switches and ptcp are given in a list type they should have the
1738 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1739 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001740
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001741 Return:
1742 Returns main.TRUE if mininet correctly assigned switches to
1743 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001744 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001745 """
1746 assignResult = main.TRUE
1747 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001748 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001749 command = "sh ovs-vsctl set-controller "
1750 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001751 try:
1752 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001753 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001754 if isinstance( port, types.StringType ) or \
1755 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001756 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001757 elif isinstance( port, types.ListType ):
1758 main.log.error( self.name + ": Only one controller " +
1759 "assigned and a list of ports has" +
1760 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001761 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001762 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001763 main.log.error( self.name + ": Invalid controller port " +
1764 "number. Please specify correct " +
1765 "controller port" )
1766 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001767
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001768 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001769 if isinstance( port, types.StringType ) or \
1770 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001771 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001772 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1773 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001774 elif isinstance( port, types.ListType ):
1775 if ( len( ip ) != len( port ) ):
1776 main.log.error( self.name + ": Port list = " +
1777 str( len( port ) ) +
1778 "should be the same as controller" +
1779 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001780 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001781 else:
1782 onosIp = ""
1783 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001784 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1785 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001786 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001787 main.log.error( self.name + ": Invalid controller port " +
1788 "number. Please specify correct " +
1789 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001790 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001791 else:
1792 main.log.error( self.name + ": Invalid ip address" )
1793 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001794
1795 if isinstance( sw, types.StringType ):
1796 command += sw + " "
1797 if ptcp:
1798 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001799 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001800 elif isinstance( ptcp, types.ListType ):
1801 main.log.error( self.name + ": Only one switch is " +
1802 "being set and multiple PTCP is " +
1803 "being passed " )
1804 else:
1805 main.log.error( self.name + ": Invalid PTCP" )
1806 ptcp = ""
1807 command += onosIp
1808 commandList.append( command )
1809
1810 elif isinstance( sw, types.ListType ):
1811 if ptcp:
1812 if isinstance( ptcp, types.ListType ):
1813 if len( ptcp ) != len( sw ):
1814 main.log.error( self.name + ": PTCP length = " +
1815 str( len( ptcp ) ) +
1816 " is not the same as switch" +
1817 " length = " +
1818 str( len( sw ) ) )
1819 return main.FALSE
1820 else:
1821 for switch, ptcpNum in zip( sw, ptcp ):
1822 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001823 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001824 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001825 tempCmd += onosIp
1826 commandList.append( tempCmd )
1827 else:
1828 main.log.error( self.name + ": Invalid PTCP" )
1829 return main.FALSE
1830 else:
1831 for switch in sw:
1832 tempCmd = "sh ovs-vsctl set-controller "
1833 tempCmd += switch + " " + onosIp
1834 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001835 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001836 main.log.error( self.name + ": Invalid switch type " )
1837 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001838
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001839 for cmd in commandList:
1840 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001841 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001842 except pexpect.TIMEOUT:
1843 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1844 return main.FALSE
1845 except pexpect.EOF:
1846 main.log.error( self.name + ": EOF exception found" )
1847 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001848 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001849 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001850 except pexpect.EOF:
1851 main.log.error( self.name + ": EOF exception found" )
1852 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001853 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001854 except Exception:
1855 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001856 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001857
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001859 """
1860 Removes the controller target from sw"""
1861 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001862 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001863 response = self.execute(
1864 cmd=command,
1865 prompt="mininet>",
1866 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001867 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001868 main.log.error( self.name + ": EOF exception found" )
1869 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001870 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001871 except Exception:
1872 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001873 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001874 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001875 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001876
kelvin-onlabd3b64892015-01-20 13:26:24 -08001877 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001878 """
Jon Hallb1290e82014-11-18 16:17:48 -05001879 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001880 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001881 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001882 NOTE: cannot currently specify what type of switch
1883 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001884 sw = name of the new switch as a string
1885 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001886 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001887 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001888 """
1889 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001890 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001891 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001892 response = self.execute(
1893 cmd=command,
1894 prompt="mininet>",
1895 timeout=10 )
1896 if re.search( "already exists!", response ):
1897 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001898 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001899 elif re.search( "Error", response ):
1900 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001901 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001902 elif re.search( "usage:", response ):
1903 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001904 return main.FALSE
1905 else:
1906 return main.TRUE
1907 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001908 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001909 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001910 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001911 except Exception:
1912 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001913 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001914
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001916 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001917 delete a switch from the mininet topology
1918 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001919 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001920 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001921 sw = name of the switch as a string
1922 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001923 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001924 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001925 response = self.execute(
1926 cmd=command,
1927 prompt="mininet>",
1928 timeout=10 )
1929 if re.search( "no switch named", response ):
1930 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001931 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001932 elif re.search( "Error", response ):
1933 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001934 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001935 elif re.search( "usage:", response ):
1936 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001937 return main.FALSE
1938 else:
1939 return main.TRUE
1940 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001941 main.log.error( self.name + ": EOF exception found" )
1942 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001943 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001944 except Exception:
1945 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001946 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001947
You Wangdb8cd0a2016-05-26 15:19:45 -07001948 def getSwitchRandom( self, timeout=60, nonCut=True ):
1949 """
1950 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001951 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001952 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001953 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07001954 it just randomly returns one switch from all current switches in
1955 Mininet.
1956 Returns the name of the chosen switch.
1957 """
1958 import random
1959 candidateSwitches = []
1960 try:
1961 if not nonCut:
1962 switches = self.getSwitches( timeout=timeout )
1963 assert len( switches ) != 0
1964 for switchName in switches.keys():
1965 candidateSwitches.append( switchName )
1966 else:
1967 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001968 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001969 return None
1970 self.graph.update( graphDict )
1971 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001972 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001973 return None
1974 elif len( candidateSwitches ) == 0:
1975 main.log.info( self.name + ": No candidate switch for deletion" )
1976 return None
1977 else:
1978 switch = random.sample( candidateSwitches, 1 )
1979 return switch[ 0 ]
1980 except KeyError:
1981 main.log.exception( self.name + ": KeyError exception found" )
1982 return None
1983 except AssertionError:
1984 main.log.exception( self.name + ": AssertionError exception found" )
1985 return None
1986 except Exception:
1987 main.log.exception( self.name + ": Uncaught exception" )
1988 return None
1989
1990 def delSwitchRandom( self, timeout=60, nonCut=True ):
1991 """
1992 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001993 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001994 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001995 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07001996 otherwise it just randomly delete one switch from all current
1997 switches in Mininet.
1998 Returns the name of the deleted switch
1999 """
2000 try:
2001 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002002 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002003 return None
2004 else:
2005 deletionResult = self.delSwitch( switch )
2006 if deletionResult:
2007 return switch
2008 else:
2009 return None
2010 except Exception:
2011 main.log.exception( self.name + ": Uncaught exception" )
2012 return None
2013
kelvin-onlabd3b64892015-01-20 13:26:24 -08002014 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002015 """
2016 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002017 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002018 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002019 NOTE: cannot currently specify what type of link
2020 required params:
2021 node1 = the string node name of the first endpoint of the link
2022 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002023 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002024 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002025 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002026 response = self.execute(
2027 cmd=command,
2028 prompt="mininet>",
2029 timeout=10 )
2030 if re.search( "doesnt exist!", response ):
2031 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002032 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002033 elif re.search( "Error", response ):
2034 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002035 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002036 elif re.search( "usage:", response ):
2037 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002038 return main.FALSE
2039 else:
2040 return main.TRUE
2041 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002042 main.log.error( self.name + ": EOF exception found" )
2043 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002044 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002045 except Exception:
2046 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002047 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002048
kelvin-onlabd3b64892015-01-20 13:26:24 -08002049 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002050 """
2051 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002052 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002053 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002054 required params:
2055 node1 = the string node name of the first endpoint of the link
2056 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002057 returns: main.FALSE on an error, else main.TRUE
2058 """
Jon Hallffb386d2014-11-21 13:43:38 -08002059 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002060 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002061 response = self.execute(
2062 cmd=command,
2063 prompt="mininet>",
2064 timeout=10 )
2065 if re.search( "no node named", response ):
2066 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002067 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002068 elif re.search( "Error", response ):
2069 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002070 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002071 elif re.search( "usage:", response ):
2072 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002073 return main.FALSE
2074 else:
2075 return main.TRUE
2076 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002077 main.log.error( self.name + ": EOF exception found" )
2078 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002079 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002080 except Exception:
2081 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002082 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002083
You Wangdb8cd0a2016-05-26 15:19:45 -07002084 def getLinkRandom( self, timeout=60, nonCut=True ):
2085 """
2086 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002087 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002088 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002089 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002090 it just randomly returns one link from all current links in
2091 Mininet.
2092 Returns the link as a list, e.g. [ 's1', 's2' ]
2093 """
2094 import random
2095 candidateLinks = []
2096 try:
2097 if not nonCut:
2098 links = self.getLinks( timeout=timeout )
2099 assert len( links ) != 0
2100 for link in links:
2101 # Exclude host-switch link
2102 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2103 continue
2104 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2105 else:
2106 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002107 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002108 return None
2109 self.graph.update( graphDict )
2110 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002111 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002112 return None
2113 elif len( candidateLinks ) == 0:
2114 main.log.info( self.name + ": No candidate link for deletion" )
2115 return None
2116 else:
2117 link = random.sample( candidateLinks, 1 )
2118 return link[ 0 ]
2119 except KeyError:
2120 main.log.exception( self.name + ": KeyError exception found" )
2121 return None
2122 except AssertionError:
2123 main.log.exception( self.name + ": AssertionError exception found" )
2124 return None
2125 except Exception:
2126 main.log.exception( self.name + ": Uncaught exception" )
2127 return None
2128
2129 def delLinkRandom( self, timeout=60, nonCut=True ):
2130 """
2131 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002132 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002133 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002134 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002135 otherwise it just randomly delete one link from all current links
2136 in Mininet.
2137 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2138 """
2139 try:
2140 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002141 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002142 return None
2143 else:
2144 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2145 if deletionResult:
2146 return link
2147 else:
2148 return None
2149 except Exception:
2150 main.log.exception( self.name + ": Uncaught exception" )
2151 return None
2152
kelvin-onlabd3b64892015-01-20 13:26:24 -08002153 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002154 """
Jon Hallb1290e82014-11-18 16:17:48 -05002155 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002156 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002157 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002158 NOTE: cannot currently specify what type of host
2159 required params:
2160 hostname = the string hostname
2161 optional key-value params
2162 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002163 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002164 """
2165 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002166 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002167 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002168 response = self.execute(
2169 cmd=command,
2170 prompt="mininet>",
2171 timeout=10 )
2172 if re.search( "already exists!", response ):
2173 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002174 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002175 elif re.search( "doesnt exists!", response ):
2176 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002177 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002178 elif re.search( "Error", response ):
2179 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002180 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002181 elif re.search( "usage:", response ):
2182 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002183 return main.FALSE
2184 else:
2185 return main.TRUE
2186 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002187 main.log.error( self.name + ": EOF exception found" )
2188 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002189 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002190 except Exception:
2191 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002192 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002193
kelvin-onlabd3b64892015-01-20 13:26:24 -08002194 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002195 """
2196 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002197 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002198 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002199 NOTE: this uses a custom mn function
2200 required params:
2201 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002202 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002203 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002204 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002205 response = self.execute(
2206 cmd=command,
2207 prompt="mininet>",
2208 timeout=10 )
2209 if re.search( "no host named", response ):
2210 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002211 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002212 elif re.search( "Error", response ):
2213 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002214 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002215 elif re.search( "usage:", response ):
2216 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002217 return main.FALSE
2218 else:
2219 return main.TRUE
2220 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002221 main.log.error( self.name + ": EOF exception found" )
2222 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002223 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002224 except Exception:
2225 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002226 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002227
Jon Hall7eb38402015-01-08 17:19:54 -08002228 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002229 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002230 Called at the end of the test to stop the mininet and
2231 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002232 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002233 try:
2234 self.handle.sendline( '' )
2235 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2236 timeout=2 )
2237 response = main.TRUE
2238 if i == 0:
2239 response = self.stopNet()
2240 elif i == 1:
2241 return main.TRUE
2242 # print "Disconnecting Mininet"
2243 if self.handle:
2244 self.handle.sendline( "exit" )
2245 self.handle.expect( "exit" )
2246 self.handle.expect( "(.*)" )
2247 else:
2248 main.log.error( "Connection failed to the host" )
2249 return response
2250 except pexpect.EOF:
2251 main.log.error( self.name + ": EOF exception found" )
2252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002253 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002254 except Exception:
2255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002256 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002257
Devin Lima7cfdbd2017-09-29 15:02:22 -07002258 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002259 """
Jon Hall21270ac2015-02-16 17:59:55 -08002260 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002261 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002262 main.FALSE if the pexpect handle does not exist.
2263
Jon Halld61331b2015-02-17 16:35:47 -08002264 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002265 """
Jon Halld61331b2015-02-17 16:35:47 -08002266 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002267 response = ''
2268 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002269 try:
Jon Halld80cc142015-07-06 13:36:05 -07002270 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002271 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002272 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002273 pexpect.EOF,
2274 pexpect.TIMEOUT ],
2275 timeout )
2276 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002277 main.log.info( "Exiting mininet.." )
2278 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002279 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002280 prompt=self.prompt,
2281 timeout=exitTimeout )
2282 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002283 self.handle.sendline( "sudo mn -c" )
2284 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002285
Jeremyd9e4eb12016-04-13 12:09:06 -07002286 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002287 main.log.info( " Mininet trying to exit while not " +
2288 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002289 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002290 elif i == 2:
2291 main.log.error( "Something went wrong exiting mininet" )
2292 elif i == 3: # timeout
2293 main.log.error( "Something went wrong exiting mininet " +
2294 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002295
Hari Krishnab35c6d02015-03-18 11:13:51 -07002296 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002297 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002298 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002299 self.handle.sendline(
2300 "sudo kill -9 \`ps -ef | grep \"" +
2301 fileName +
2302 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002303 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002304 main.log.error( self.name + ": TIMEOUT exception found" )
2305 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002306 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002307 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002308 main.log.error( self.name + ": EOF exception found" )
2309 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002310 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002311 except Exception:
2312 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002313 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002314 else:
2315 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002316 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002317 return response
2318
YPZhang26a139e2016-04-25 14:01:55 -07002319 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002320 """
2321 Description:
2322 Sends arp message from mininet host for hosts discovery
2323 Required:
2324 host - hosts name
2325 Optional:
2326 ip - ip address that does not exist in the network so there would
2327 be no reply.
2328 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002329 if ethDevice:
2330 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002331 cmd = srcHost + " arping -c1 "
2332 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002333 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
YPZhang26a139e2016-04-25 14:01:55 -07002334 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002335 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002336 if output:
2337 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002338 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002339 i = self.handle.expect( [ "mininet>", "arping: " ] )
2340 if i == 0:
2341 return main.TRUE
2342 elif i == 1:
2343 response = self.handle.before + self.handle.after
2344 self.handle.expect( "mininet>" )
2345 response += self.handle.before + self.handle.after
2346 main.log.warn( "Error sending arping, output was: " +
2347 response )
2348 return main.FALSE
2349 except pexpect.TIMEOUT:
2350 main.log.error( self.name + ": TIMEOUT exception found" )
2351 main.log.warn( self.handle.before )
2352 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002353 except pexpect.EOF:
2354 main.log.error( self.name + ": EOF exception found" )
2355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002356 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002357 except Exception:
2358 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002359 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002360
Jon Hall7eb38402015-01-08 17:19:54 -08002361 def decToHex( self, num ):
2362 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002363
Jon Hall7eb38402015-01-08 17:19:54 -08002364 def getSwitchFlowCount( self, switch ):
2365 """
2366 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002367 if self.handle:
2368 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2369 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002370 response = self.execute(
2371 cmd=cmd,
2372 prompt="mininet>",
2373 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002374 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002375 main.log.error( self.name + ": EOF exception found" )
2376 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002377 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002378 except Exception:
2379 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002380 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002381 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002382 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002383 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002384 main.log.info(
2385 "Couldn't find flows on switch %s, found: %s" %
2386 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002387 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002388 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002389 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002390 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002391
Jon Hall9ed8f372016-02-24 17:34:07 -08002392 def checkFlows( self, sw, dumpFormat=None ):
2393 if dumpFormat:
2394 command = "sh ovs-ofctl -F " + \
2395 dumpFormat + " dump-flows " + str( sw )
2396 else:
2397 command = "sh ovs-ofctl dump-flows " + str( sw )
2398 try:
2399 response = self.execute(
2400 cmd=command,
2401 prompt="mininet>",
2402 timeout=10 )
2403 return response
2404 except pexpect.EOF:
2405 main.log.error( self.name + ": EOF exception found" )
2406 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002407 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002408 except Exception:
2409 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002410 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002411
GlennRC68467eb2015-11-16 18:01:01 -08002412 def flowTableComp( self, flowTable1, flowTable2 ):
2413 # This function compares the selctors and treatments of each flow
2414 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002415 assert flowTable1, "flowTable1 is empty or None"
2416 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002417 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002418 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002419 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002420 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002421 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2422 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002423 for field in dFields:
2424 try:
2425 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002426 except KeyError:
2427 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002428 try:
2429 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002430 except KeyError:
2431 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002432 for i in range( len( flowTable1 ) ):
2433 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002434 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002435 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002436 returnValue = main.FALSE
2437 break
2438 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002439 except AssertionError:
2440 main.log.exception( "Nothing to compare" )
2441 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002442 except Exception:
2443 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002444 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002445
GlennRC528ad292015-11-12 10:38:18 -08002446 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002447 '''
GlennRC956ea742015-11-05 16:14:15 -08002448 Discription: Parses flows into json format.
2449 NOTE: this can parse any string thats separated with commas
2450 Arguments:
2451 Required:
2452 flows: a list of strings that represnt flows
2453 Optional:
2454 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2455 debug: prints out the final result
2456 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002457 '''
GlennRC528ad292015-11-12 10:38:18 -08002458 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002459 try:
2460 for flow in flowTable:
2461 jsonFlow = {}
2462 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002463 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002464 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002465 for i in range( len( parsedFlow ) ):
2466 item = parsedFlow[ i ]
2467 if item[ 0 ] == " ":
2468 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002469 # grab the selector and treatment from the parsed flow
2470 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002471 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002472 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002473 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002474 index = 0
2475 # parse the flags
2476 # NOTE: This only parses one flag
2477 flag = {}
2478 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002479 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002480 index += 1
2481 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002482 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002483 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002484 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002485 # the priority is stuck in the selecter so put it back
2486 # in the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002487 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002488 # parse selector
2489 criteria = []
2490 for item in sel:
2491 # this is the type of the packet e.g. "arp"
2492 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002493 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002494 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002495 field = item.split( "=" )
2496 criteria.append( { field[ 0 ]: field[ 1 ] } )
2497 selector = { "selector": { "criteria": sorted( criteria ) } }
2498 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002499 # get rid of the action part e.g. "action=output:2"
2500 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002501 treat = treat.split( "=" )
2502 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002503 # parse treatment
2504 action = []
2505 for item in treat:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002506 field = item.split( ":" )
2507 action.append( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002508 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002509 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002510 # parse the rest of the flow
2511 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002512 field = item.split( "=" )
2513 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002514 # add the treatment and the selector to the json flow
2515 jsonFlow.update( selector )
2516 jsonFlow.update( treatment )
2517 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002518
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002519 if debug:
2520 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002521
You Wang91c37cf2016-05-23 09:39:42 -07002522 # add the json flow to the json flow table
2523 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002524
You Wang91c37cf2016-05-23 09:39:42 -07002525 return jsonFlowTable
2526
2527 except IndexError:
2528 main.log.exception( self.name + ": IndexError found" )
2529 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002530 except pexpect.EOF:
2531 main.log.error( self.name + ": EOF exception found" )
2532 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002533 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002534 except Exception:
2535 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002536 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002537
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002538 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002539 '''
2540 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002541 Each element is a flow.
2542 Arguments:
2543 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002544 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002545 a list of switches.
2546 Optional:
2547 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2548 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002549 '''
GlennRC956ea742015-11-05 16:14:15 -08002550 try:
2551 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002552 if isinstance( sw, list ):
2553 switches.extend( sw )
2554 else:
2555 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002556
2557 flows = []
2558 for s in switches:
2559 cmd = "sh ovs-ofctl dump-flows " + s
2560
GlennRC528ad292015-11-12 10:38:18 -08002561 if "1.0" == version:
2562 cmd += " -F OpenFlow10-table_id"
2563 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002564 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002565
2566 main.log.info( "Sending: " + cmd )
2567 self.handle.sendline( cmd )
2568 self.handle.expect( "mininet>" )
2569 response = self.handle.before
2570 response = response.split( "\r\n" )
2571 # dump the first two elements and the last
2572 # the first element is the command that was sent
2573 # the second is the table header
2574 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002575 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002576 flows.extend( response )
2577
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002578 if debug:
2579 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002580
GlennRC528ad292015-11-12 10:38:18 -08002581 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002582
GlennRC956ea742015-11-05 16:14:15 -08002583 except pexpect.EOF:
2584 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002585 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002586 except Exception:
2587 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002588 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002589
2590 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002591 '''
GlennRC956ea742015-11-05 16:14:15 -08002592 Discription: Checks whether the ID provided matches a flow ID in Mininet
2593 Arguments:
2594 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002595 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002596 a list of switches.
2597 flowId: the flow ID in hex format. Can also be a list of IDs
2598 Optional:
2599 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2600 debug: prints out the final result
2601 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2602 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002603 '''
GlennRC956ea742015-11-05 16:14:15 -08002604 try:
2605 main.log.info( "Getting flows from Mininet" )
2606 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002607 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002608 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002609
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002610 if debug:
2611 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002612
2613 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002614 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002615 result = False
2616 for f in flows:
2617 if flowId in f.get( 'cookie' ):
2618 result = True
2619 break
2620 # flowId is a list
2621 else:
2622 result = True
2623 # Get flow IDs from Mininet
2624 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2625 # Save the IDs that are not in Mininet
2626 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2627
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002628 if debug:
2629 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002630
2631 # Print out the IDs that are not in Mininet
2632 if absentIds:
2633 main.log.warn( "Absent ids: {}".format( absentIds ) )
2634 result = False
2635
2636 return main.TRUE if result else main.FALSE
2637
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 )
Devin Lim44075962017-08-11 10:56:37 -07002641 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002642 except Exception:
2643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002644 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002645
Charles Chan029be652015-08-24 01:46:10 +08002646 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002647 """
Jon Hallefbd9792015-03-05 16:11:36 -08002648 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002649 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002650 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002651 self.handle.sendline( "" )
2652 self.handle.expect( "mininet>" )
2653 self.handle.sendline(
2654 "sh sudo tcpdump -n -i " +
2655 intf +
2656 " " +
2657 port +
2658 " -w " +
2659 filename.strip() +
2660 " &" )
2661 self.handle.sendline( "" )
2662 i = self.handle.expect( [ 'No\ssuch\device',
2663 'listening\son',
2664 pexpect.TIMEOUT,
2665 "mininet>" ],
2666 timeout=10 )
2667 main.log.warn( self.handle.before + self.handle.after )
2668 self.handle.sendline( "" )
2669 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002670 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002671 main.log.error(
2672 self.name +
2673 ": tcpdump - No such device exists. " +
2674 "tcpdump attempted on: " +
2675 intf )
admin2a9548d2014-06-17 14:08:07 -07002676 return main.FALSE
2677 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002678 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002679 return main.TRUE
2680 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002681 main.log.error(
2682 self.name +
2683 ": tcpdump command timed out! Check interface name," +
2684 " given interface was: " +
2685 intf )
admin2a9548d2014-06-17 14:08:07 -07002686 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002687 elif i == 3:
2688 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002689 return main.TRUE
2690 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002691 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002692 return main.FALSE
2693 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002694 main.log.error( self.name + ": EOF exception found" )
2695 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002696 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002697 except Exception:
2698 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002699 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002700
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002702 """
2703 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002704 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002705 self.handle.sendline( "sh sudo pkill tcpdump" )
2706 self.handle.expect( "mininet>" )
2707 self.handle.sendline( "" )
2708 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002709 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002710 main.log.error( self.name + ": TIMEOUT exception found" )
2711 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002712 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002713 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002714 main.log.error( self.name + ": EOF exception found" )
2715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002716 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002717 except Exception:
2718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002719 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002720
Jon Halld80cc142015-07-06 13:36:05 -07002721 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002722 """
2723 Read ports from a Mininet switch.
2724
2725 Returns a json structure containing information about the
2726 ports of the given switch.
2727 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002728 try:
2729 response = self.getInterfaces( nodeName )
2730 # TODO: Sanity check on response. log if no such switch exists
2731 ports = []
2732 for line in response.split( "\n" ):
2733 if not line.startswith( "name=" ):
2734 continue
2735 portVars = {}
2736 for var in line.split( "," ):
2737 key, value = var.split( "=" )
2738 portVars[ key ] = value
2739 isUp = portVars.pop( 'enabled', "True" )
2740 isUp = "True" in isUp
2741 if verbose:
2742 main.log.info( "Reading switch port %s(%s)" %
2743 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2744 mac = portVars[ 'mac' ]
2745 if mac == 'None':
2746 mac = None
2747 ips = []
2748 ip = portVars[ 'ip' ]
2749 if ip == 'None':
2750 ip = None
2751 ips.append( ip )
2752 name = portVars[ 'name' ]
2753 if name == 'None':
2754 name = None
2755 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2756 if name == 'lo':
2757 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2758 else:
2759 portNo = re.search( portRe, name ).group( 'port' )
2760 ports.append( { 'of_port': portNo,
2761 'mac': str( mac ).replace( '\'', '' ),
2762 'name': name,
2763 'ips': ips,
2764 'enabled': isUp } )
2765 return ports
2766 except pexpect.EOF:
2767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002770 except Exception:
2771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002772 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002773
You Wangdb8cd0a2016-05-26 15:19:45 -07002774 def getOVSPorts( self, nodeName ):
2775 """
2776 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2777
2778 Returns a list of dictionaries containing information about each
2779 port of the given switch.
2780 """
2781 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2782 try:
2783 response = self.execute(
2784 cmd=command,
2785 prompt="mininet>",
2786 timeout=10 )
2787 ports = []
2788 if response:
2789 for line in response.split( "\n" ):
2790 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2791 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002792 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002793 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2794 result = re.search( pattern, line )
2795 if result:
2796 index = result.group( 'index' )
2797 name = result.group( 'name' )
2798 # This port number is extracted from port name
2799 port = result.group( 'port' )
2800 mac = result.group( 'mac' )
2801 ports.append( { 'index': index,
2802 'name': name,
2803 'port': port,
2804 'mac': mac } )
2805 return ports
2806 except pexpect.EOF:
2807 main.log.error( self.name + ": EOF exception found" )
2808 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002809 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002810 except Exception:
2811 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002812 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002813
Devin Lima7cfdbd2017-09-29 15:02:22 -07002814 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002815 """
2816 Read switches from Mininet.
2817
2818 Returns a dictionary whose keys are the switch names and the value is
2819 a dictionary containing information about the switch.
2820 """
Jon Halla22481b2015-07-28 17:46:01 -07002821 # NOTE: To support new Mininet switch classes, just append the new
2822 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002823
Jon Halla22481b2015-07-28 17:46:01 -07002824 # Regex patterns to parse 'dump' output
2825 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002826 # <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 -07002827 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002828 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2829 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2830 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002831 try:
2832 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2833 swRE = r"<(?P<class>" + switchClasses + r")" +\
2834 r"(?P<options>\{.*\})?\s" +\
2835 r"(?P<name>[^:]+)\:\s" +\
2836 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2837 r"\spid=(?P<pid>(\d)+)"
2838 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002839 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002840 output = {}
2841 dump = self.dump().split( "\n" )
2842 for line in dump:
2843 result = re.search( swRE, line, re.I )
2844 if result:
2845 name = result.group( 'name' )
2846 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2847 pid = result.group( 'pid' )
2848 swClass = result.group( 'class' )
2849 options = result.group( 'options' )
2850 if verbose:
2851 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2852 ports = self.getPorts( name )
2853 output[ name ] = { "dpid": dpid,
2854 "ports": ports,
2855 "swClass": swClass,
2856 "pid": pid,
2857 "options": options }
2858 return output
2859 except pexpect.EOF:
2860 main.log.error( self.name + ": EOF exception found" )
2861 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002862 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002863 except Exception:
2864 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002865 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002866
Devin Lima7cfdbd2017-09-29 15:02:22 -07002867 def getHosts( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002868 """
2869 Read hosts from Mininet.
2870
2871 Returns a dictionary whose keys are the host names and the value is
2872 a dictionary containing information about the host.
2873 """
2874 # Regex patterns to parse dump output
2875 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002876 # <Host h1: pid=12725>
2877 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2878 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2879 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002880 # NOTE: Does not correctly match hosts with multi-links
2881 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2882 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002883 try:
2884 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
2885 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
2886 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002887 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002888 # Get mininet dump
2889 dump = self.dump().split( "\n" )
2890 hosts = {}
2891 for line in dump:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002892 if "Host" in line :
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002893 result = re.search( hostRE, line )
2894 name = result.group( 'name' )
2895 interfaces = []
2896 response = self.getInterfaces( name )
2897 # Populate interface info
2898 for line in response.split( "\n" ):
2899 if line.startswith( "name=" ):
2900 portVars = {}
2901 for var in line.split( "," ):
2902 key, value = var.split( "=" )
2903 portVars[ key ] = value
2904 isUp = portVars.pop( 'enabled', "True" )
2905 isUp = "True" in isUp
2906 if verbose:
2907 main.log.info( "Reading host port %s(%s)" %
2908 ( portVars[ 'name' ],
2909 portVars[ 'mac' ] ) )
2910 mac = portVars[ 'mac' ]
2911 if mac == 'None':
2912 mac = None
2913 ips = []
2914 ip = portVars[ 'ip' ]
2915 if ip == 'None':
2916 ip = None
2917 ips.append( ip )
2918 intfName = portVars[ 'name' ]
2919 if name == 'None':
2920 name = None
2921 interfaces.append( {
2922 "name": intfName,
2923 "ips": ips,
2924 "mac": str( mac ),
2925 "isUp": isUp } )
2926 hosts[ name ] = { "interfaces": interfaces }
2927 return hosts
2928 except pexpect.EOF:
2929 main.log.error( self.name + ": EOF exception found" )
2930 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002932 except Exception:
2933 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002934 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002935
Devin Lima7cfdbd2017-09-29 15:02:22 -07002936 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002937 """
2938 Gathers information about current Mininet links. These links may not
2939 be up if one of the ports is down.
2940
2941 Returns a list of dictionaries with link endpoints.
2942
2943 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002944 { 'node1': str( node1 name )
2945 'node2': str( node2 name )
2946 'port1': str( port1 of_port )
2947 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002948 Note: The port number returned is the eth#, not necessarily the of_port
2949 number. In Mininet, for OVS switch, these should be the same. For
2950 hosts, this is just the eth#.
2951 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002952 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002953 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002954 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07002955
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002956 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002957 # s1-eth3<->s2-eth1 (OK OK)
2958 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002959 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2960 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2961 links = []
2962 for line in response:
2963 match = re.search( linkRE, line )
2964 if match:
2965 node1 = match.group( 'node1' )
2966 node2 = match.group( 'node2' )
2967 port1 = match.group( 'port1' )
2968 port2 = match.group( 'port2' )
2969 links.append( { 'node1': node1,
2970 'node2': node2,
2971 'port1': port1,
2972 'port2': port2 } )
2973 return links
2974
2975 except pexpect.EOF:
2976 main.log.error( self.name + ": EOF exception found" )
2977 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002978 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002979 except Exception:
2980 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002981 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002982
2983 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002984 """
2985 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002986 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002987
Jon Hallafa8a472015-06-12 14:02:42 -07002988 Dependencies:
2989 1. numpy - "sudo pip install numpy"
2990 """
2991 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002992 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002993 try:
2994 mnDPIDs = []
2995 for swName, switch in switches.iteritems():
2996 mnDPIDs.append( switch[ 'dpid' ].lower() )
2997 mnDPIDs.sort()
2998 if switchesJson == "": # if rest call fails
2999 main.log.error(
3000 self.name +
3001 ".compareSwitches(): Empty JSON object given from ONOS" )
3002 return main.FALSE
3003 onos = switchesJson
3004 onosDPIDs = []
3005 for switch in onos:
3006 if switch[ 'available' ]:
3007 onosDPIDs.append(
3008 switch[ 'id' ].replace(
3009 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003010 '' ).replace(
3011 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003012 '' ).lower() )
3013 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003014
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003015 if mnDPIDs != onosDPIDs:
3016 switchResults = main.FALSE
3017 main.log.error( "Switches in MN but not in ONOS:" )
3018 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3019 main.log.error( str( list1 ) )
3020 main.log.error( "Switches in ONOS but not in MN:" )
3021 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3022 main.log.error( str( list2 ) )
3023 else: # list of dpid's match in onos and mn
3024 switchResults = main.TRUE
3025 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003026
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003027 # FIXME: this does not look for extra ports in ONOS, only checks that
3028 # ONOS has what is in MN
3029 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003030
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003031 # PORTS
3032 for name, mnSwitch in switches.iteritems():
3033 mnPorts = []
3034 onosPorts = []
3035 switchResult = main.TRUE
3036 for port in mnSwitch[ 'ports' ]:
3037 if port[ 'enabled' ]:
3038 mnPorts.append( int( port[ 'of_port' ] ) )
3039 for onosSwitch in portsJson:
3040 if onosSwitch[ 'device' ][ 'available' ]:
3041 if onosSwitch[ 'device' ][ 'id' ].replace(
3042 ':',
3043 '' ).replace(
3044 "of",
3045 '' ) == mnSwitch[ 'dpid' ]:
3046 for port in onosSwitch[ 'ports' ]:
3047 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003048 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003049 # onosPorts.append( 'local' )
3050 onosPorts.append( long( uint64( -2 ) ) )
3051 else:
3052 onosPorts.append( int( port[ 'port' ] ) )
3053 break
3054 mnPorts.sort( key=float )
3055 onosPorts.sort( key=float )
3056
3057 mnPortsLog = mnPorts
3058 onosPortsLog = onosPorts
3059 mnPorts = [ x for x in mnPorts ]
3060 onosPorts = [ x for x in onosPorts ]
3061
3062 # TODO: handle other reserved port numbers besides LOCAL
3063 # NOTE: Reserved ports
3064 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3065 # long( uint64( -2 ) )
3066 for mnPort in mnPortsLog:
3067 if mnPort in onosPorts:
3068 # don't set results to true here as this is just one of
3069 # many checks and it might override a failure
3070 mnPorts.remove( mnPort )
3071 onosPorts.remove( mnPort )
3072
3073 # NOTE: OVS reports this as down since there is no link
3074 # So ignoring these for now
3075 # TODO: Come up with a better way of handling these
3076 if 65534 in mnPorts:
3077 mnPorts.remove( 65534 )
3078 if long( uint64( -2 ) ) in onosPorts:
3079 onosPorts.remove( long( uint64( -2 ) ) )
3080 if len( mnPorts ): # the ports of this switch don't match
3081 switchResult = main.FALSE
3082 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3083 if len( onosPorts ): # the ports of this switch don't match
3084 switchResult = main.FALSE
3085 main.log.warn(
3086 "Ports in ONOS but not MN: " +
3087 str( onosPorts ) )
3088 if switchResult == main.FALSE:
3089 main.log.error(
3090 "The list of ports for switch %s(%s) does not match:" %
3091 ( name, mnSwitch[ 'dpid' ] ) )
3092 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3093 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3094 portsResults = portsResults and switchResult
3095 finalResults = finalResults and portsResults
3096 return finalResults
3097 except pexpect.EOF:
3098 main.log.error( self.name + ": EOF exception found" )
3099 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003100 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003101 except Exception:
3102 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003103 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003104
Jon Hallafa8a472015-06-12 14:02:42 -07003105 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003106 """
3107 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003108 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003109
Jon Hallafa8a472015-06-12 14:02:42 -07003110 """
Jon Hall7eb38402015-01-08 17:19:54 -08003111 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003112 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003113 try:
3114 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003115
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003116 mnLinks = []
3117 for l in links:
3118 try:
3119 node1 = switches[ l[ 'node1' ] ]
3120 node2 = switches[ l[ 'node2' ] ]
3121 enabled = True
3122 for port in node1[ 'ports' ]:
3123 if port[ 'of_port' ] == l[ 'port1' ]:
3124 enabled = enabled and port[ 'enabled' ]
3125 for port in node2[ 'ports' ]:
3126 if port[ 'of_port' ] == l[ 'port2' ]:
3127 enabled = enabled and port[ 'enabled' ]
3128 if enabled:
3129 mnLinks.append( l )
3130 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003131 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003132 if 2 * len( mnLinks ) == len( onos ):
3133 linkResults = main.TRUE
3134 else:
3135 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003136 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003137 "Mininet has " + str( len( mnLinks ) ) +
3138 " bidirectional links and ONOS has " +
3139 str( len( onos ) ) + " unidirectional links" )
3140
3141 # iterate through MN links and check if an ONOS link exists in
3142 # both directions
3143 for link in mnLinks:
3144 # TODO: Find a more efficient search method
3145 node1 = None
3146 port1 = None
3147 node2 = None
3148 port2 = None
3149 firstDir = main.FALSE
3150 secondDir = main.FALSE
3151 for swName, switch in switches.iteritems():
3152 if swName == link[ 'node1' ]:
3153 node1 = switch[ 'dpid' ]
3154 for port in switch[ 'ports' ]:
3155 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3156 port1 = port[ 'of_port' ]
3157 if node1 is not None and node2 is not None:
3158 break
3159 if swName == link[ 'node2' ]:
3160 node2 = switch[ 'dpid' ]
3161 for port in switch[ 'ports' ]:
3162 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3163 port2 = port[ 'of_port' ]
3164 if node1 is not None and node2 is not None:
3165 break
3166
3167 for onosLink in onos:
3168 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3169 ":", '' ).replace( "of", '' )
3170 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3171 ":", '' ).replace( "of", '' )
3172 onosPort1 = onosLink[ 'src' ][ 'port' ]
3173 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3174
3175 # check onos link from node1 to node2
3176 if str( onosNode1 ) == str( node1 ) and str(
3177 onosNode2 ) == str( node2 ):
3178 if int( onosPort1 ) == int( port1 ) and int(
3179 onosPort2 ) == int( port2 ):
3180 firstDir = main.TRUE
3181 else:
3182 main.log.warn(
3183 'The port numbers do not match for ' +
3184 str( link ) +
3185 ' between ONOS and MN. When checking ONOS for ' +
3186 'link %s/%s -> %s/%s' %
3187 ( node1, port1, node2, port2 ) +
3188 ' ONOS has the values %s/%s -> %s/%s' %
3189 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3190
3191 # check onos link from node2 to node1
3192 elif ( str( onosNode1 ) == str( node2 ) and
3193 str( onosNode2 ) == str( node1 ) ):
3194 if ( int( onosPort1 ) == int( port2 )
3195 and int( onosPort2 ) == int( port1 ) ):
3196 secondDir = main.TRUE
3197 else:
3198 main.log.warn(
3199 'The port numbers do not match for ' +
3200 str( link ) +
3201 ' between ONOS and MN. When checking ONOS for ' +
3202 'link %s/%s -> %s/%s' %
3203 ( node1, port1, node2, port2 ) +
3204 ' ONOS has the values %s/%s -> %s/%s' %
3205 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3206 else: # this is not the link you're looking for
3207 pass
3208 if not firstDir:
3209 main.log.error(
3210 'ONOS does not have the link %s/%s -> %s/%s' %
3211 ( node1, port1, node2, port2 ) )
3212 if not secondDir:
3213 main.log.error(
3214 'ONOS does not have the link %s/%s -> %s/%s' %
3215 ( node2, port2, node1, port1 ) )
3216 linkResults = linkResults and firstDir and secondDir
3217 return linkResults
3218 except pexpect.EOF:
3219 main.log.error( self.name + ": EOF exception found" )
3220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003221 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003222 except Exception:
3223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003224 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003225
Jon Hallafa8a472015-06-12 14:02:42 -07003226 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003227 """
Jon Hallafa8a472015-06-12 14:02:42 -07003228 Compare mn and onos Hosts.
3229 Since Mininet hosts are quiet, ONOS will only know of them when they
3230 speak. For this reason, we will only check that the hosts in ONOS
3231 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003232
Jon Hallafa8a472015-06-12 14:02:42 -07003233 Arguments:
3234 hostsJson: parsed json object from the onos hosts api
3235 Returns:
3236 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003237 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003238 try:
3239 hostResults = main.TRUE
3240 for onosHost in hostsJson:
3241 onosMAC = onosHost[ 'mac' ].lower()
3242 match = False
3243 for mnHost, info in hosts.iteritems():
3244 for mnIntf in info[ 'interfaces' ]:
3245 if onosMAC == mnIntf[ 'mac' ].lower():
3246 match = True
3247 for ip in mnIntf[ 'ips' ]:
3248 if ip in onosHost[ 'ipAddresses' ]:
3249 pass # all is well
3250 else:
3251 # misssing ip
3252 main.log.error( "ONOS host " +
3253 onosHost[ 'id' ] +
3254 " has a different IP(" +
3255 str( onosHost[ 'ipAddresses' ] ) +
3256 ") than the Mininet host(" +
3257 str( ip ) +
3258 ")." )
3259 output = json.dumps(
3260 onosHost,
3261 sort_keys=True,
3262 indent=4,
3263 separators=( ',', ': ' ) )
3264 main.log.info( output )
3265 hostResults = main.FALSE
3266 if not match:
3267 hostResults = main.FALSE
3268 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3269 "corresponding Mininet host." )
3270 output = json.dumps( onosHost,
3271 sort_keys=True,
3272 indent=4,
3273 separators=( ',', ': ' ) )
3274 main.log.info( output )
3275 return hostResults
3276 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003277 main.log.error( self.name + ": EOF exception found" )
3278 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003279 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003280 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003281 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003282 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003283
Jon Hallafa8a472015-06-12 14:02:42 -07003284 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003285 """
3286 Returns a list of all hosts
3287 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003288 try:
3289 self.handle.sendline( "" )
3290 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003291
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003292 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3293 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003294
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003295 handlePy = self.handle.before
3296 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3297 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003298
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003299 self.handle.sendline( "" )
3300 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003301
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003302 hostStr = handlePy.replace( "]", "" )
3303 hostStr = hostStr.replace( "'", "" )
3304 hostStr = hostStr.replace( "[", "" )
3305 hostStr = hostStr.replace( " ", "" )
3306 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003307
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003308 return hostList
3309 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003310 main.log.error( self.name + ": TIMEOUT exception found" )
3311 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003312 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003313 except pexpect.EOF:
3314 main.log.error( self.name + ": EOF exception found" )
3315 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003316 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003317 except Exception:
3318 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003319 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003320
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003321 def getSwitch( self ):
3322 """
3323 Returns a list of all switches
3324 Again, don't ask question just use it...
3325 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003326 try:
3327 # get host list...
3328 hostList = self.getHosts()
3329 # Make host set
3330 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003331
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003332 # Getting all the nodes in mininet
3333 self.handle.sendline( "" )
3334 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003335
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003336 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3337 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003338
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003339 handlePy = self.handle.before
3340 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3341 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003342
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003343 self.handle.sendline( "" )
3344 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003345
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003346 nodesStr = handlePy.replace( "]", "" )
3347 nodesStr = nodesStr.replace( "'", "" )
3348 nodesStr = nodesStr.replace( "[", "" )
3349 nodesStr = nodesStr.replace( " ", "" )
3350 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003351
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003352 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003353 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003354 nodesSet.discard( 'c0' )
3355 nodesSet.discard( 'c1' )
3356 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003357
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003358 switchSet = nodesSet - hostSet
3359 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003360
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003361 return switchList
3362 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003363 main.log.error( self.name + ": TIMEOUT exception found" )
3364 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003365 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003366 except pexpect.EOF:
3367 main.log.error( self.name + ": EOF exception found" )
3368 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003369 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003370 except Exception:
3371 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003372 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003373
You Wangdb8cd0a2016-05-26 15:19:45 -07003374 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3375 """
3376 Return a dictionary which describes the latest Mininet topology data as a
3377 graph.
3378 An example of the dictionary:
3379 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3380 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3381 Each vertex should at least have an 'edges' attribute which describes the
3382 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003383 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003384 list of attributes.
3385 An example of the edges dictionary:
3386 'edges': { vertex2: { 'port': ..., 'weight': ... },
3387 vertex3: { 'port': ..., 'weight': ... } }
3388 If useId == True, dpid/mac will be used instead of names to identify
3389 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3390 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003391 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003392 in topology data.
3393 Note that link or switch that are brought down by 'link x x down' or 'switch
3394 x down' commands still show in the output of Mininet CLI commands such as
3395 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3396 recommended to use delLink() or delSwitch functions to simulate link/switch
3397 down, and addLink() or addSwitch to add them back.
3398 """
3399 graphDict = {}
3400 try:
3401 links = self.getLinks( timeout=timeout )
3402 portDict = {}
3403 if useId:
3404 switches = self.getSwitches()
3405 if includeHost:
3406 hosts = self.getHosts()
3407 for link in links:
3408 # FIXME: support 'includeHost' argument
3409 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3410 continue
3411 nodeName1 = link[ 'node1' ]
3412 nodeName2 = link[ 'node2' ]
3413 port1 = link[ 'port1' ]
3414 port2 = link[ 'port2' ]
3415 # Loop for two nodes
3416 for i in range( 2 ):
3417 # Get port index from OVS
3418 # The index extracted from port name may be inconsistent with ONOS
3419 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003420 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003421 portList = self.getOVSPorts( nodeName1 )
3422 if len( portList ) == 0:
3423 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3424 return None
3425 portDict[ nodeName1 ] = portList
3426 for port in portDict[ nodeName1 ]:
3427 if port[ 'port' ] == port1:
3428 portIndex = port[ 'index' ]
3429 break
3430 if portIndex == -1:
3431 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3432 return None
3433 if useId:
3434 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3435 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3436 else:
3437 node1 = nodeName1
3438 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003439 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003440 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003441 graphDict[ node1 ] = { 'edges': {},
3442 'dpid': switches[ nodeName1 ][ 'dpid' ],
3443 'name': nodeName1,
3444 'ports': switches[ nodeName1 ][ 'ports' ],
3445 'swClass': switches[ nodeName1 ][ 'swClass' ],
3446 'pid': switches[ nodeName1 ][ 'pid' ],
3447 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003448 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003449 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003450 else:
3451 # Assert node2 is not connected to any current links of node1
3452 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003453 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003454 # Swap two nodes/ports
3455 nodeName1, nodeName2 = nodeName2, nodeName1
3456 port1, port2 = port2, port1
3457 return graphDict
3458 except KeyError:
3459 main.log.exception( self.name + ": KeyError exception found" )
3460 return None
3461 except AssertionError:
3462 main.log.exception( self.name + ": AssertionError exception found" )
3463 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003464 except pexpect.EOF:
3465 main.log.error( self.name + ": EOF exception found" )
3466 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003467 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003468 except Exception:
3469 main.log.exception( self.name + ": Uncaught exception" )
3470 return None
3471
Devin Lima7cfdbd2017-09-29 15:02:22 -07003472 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003473 """
3474 updates the port address and status information for
3475 each port in mn"""
3476 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003477 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003478 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003479 self.handle.sendline( "" )
3480 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003481
Jon Hall7eb38402015-01-08 17:19:54 -08003482 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003483 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003484
Jon Hall7eb38402015-01-08 17:19:54 -08003485 self.handle.sendline( "" )
3486 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003487
Jon Hallb1290e82014-11-18 16:17:48 -05003488 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003489 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003490 main.log.error( self.name + ": TIMEOUT exception found" )
3491 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003492 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003493 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003494 main.log.error( self.name + ": EOF exception found" )
3495 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003496 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003497 except Exception:
3498 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003499 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003500
Jon Halld80cc142015-07-06 13:36:05 -07003501 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003502 """
3503 Add vlan tag to a host.
3504 Dependencies:
3505 This class depends on the "vlan" package
3506 $ sudo apt-get install vlan
3507 Configuration:
3508 Load the 8021q module into the kernel
3509 $sudo modprobe 8021q
3510
3511 To make this setup permanent:
3512 $ sudo su -c 'echo "8021q" >> /etc/modules'
3513 """
3514 if self.handle:
3515 try:
Jon Halld80cc142015-07-06 13:36:05 -07003516 # get the ip address of the host
3517 main.log.info( "Get the ip address of the host" )
3518 ipaddr = self.getIPAddress( host )
3519 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003520
Jon Halld80cc142015-07-06 13:36:05 -07003521 # remove IP from interface intf
3522 # Ex: h1 ifconfig h1-eth0 inet 0
3523 main.log.info( "Remove IP from interface " )
3524 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3525 self.handle.sendline( cmd2 )
3526 self.handle.expect( "mininet>" )
3527 response = self.handle.before
3528 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003529
Jon Halld80cc142015-07-06 13:36:05 -07003530 # create VLAN interface
3531 # Ex: h1 vconfig add h1-eth0 100
3532 main.log.info( "Create Vlan" )
3533 cmd3 = host + " vconfig add " + intf + " " + vlan
3534 self.handle.sendline( cmd3 )
3535 self.handle.expect( "mininet>" )
3536 response = self.handle.before
3537 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003538
Jon Halld80cc142015-07-06 13:36:05 -07003539 # assign the host's IP to the VLAN interface
3540 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3541 main.log.info( "Assign the host IP to the vlan interface" )
3542 vintf = intf + "." + vlan
3543 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3544 self.handle.sendline( cmd4 )
3545 self.handle.expect( "mininet>" )
3546 response = self.handle.before
3547 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003548
3549 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003550 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003551 main.log.error( self.name + ": TIMEOUT exception found" )
3552 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003553 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003554 except pexpect.EOF:
3555 main.log.error( self.name + ": EOF exception found" )
3556 main.log.error( self.name + ": " + self.handle.before )
3557 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003558 except Exception:
3559 main.log.exception( self.name + ": Uncaught exception!" )
3560 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003561
Jon Hall892818c2015-10-20 17:58:34 -07003562 def createHostComponent( self, name ):
3563 """
3564 Creates a new mininet cli component with the same parameters as self.
3565 This new component is intended to be used to login to the hosts created
3566 by mininet.
3567
3568 Arguments:
3569 name - The string of the name of this component. The new component
3570 will be assigned to main.<name> .
3571 In addition, main.<name>.name = str( name )
3572 """
3573 try:
3574 # look to see if this component already exists
3575 getattr( main, name )
3576 except AttributeError:
3577 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003578 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3579 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003580 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003581 except pexpect.EOF:
3582 main.log.error( self.name + ": EOF exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003585 except Exception:
3586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003587 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003588 else:
3589 # namespace is not clear!
3590 main.log.error( name + " component already exists!" )
3591 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003592 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003593
3594 def removeHostComponent( self, name ):
3595 """
3596 Remove host component
3597 Arguments:
3598 name - The string of the name of the component to delete.
3599 """
3600 try:
3601 # Get host component
3602 component = getattr( main, name )
3603 except AttributeError:
3604 main.log.error( "Component " + name + " does not exist." )
3605 return
3606 try:
3607 # Disconnect from component
3608 component.disconnect()
3609 # Delete component
3610 delattr( main, name )
3611 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003612 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003613 except pexpect.EOF:
3614 main.log.error( self.name + ": EOF exception found" )
3615 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003616 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003617 except Exception:
3618 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003619 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003620
3621 def startHostCli( self, host=None ):
3622 """
3623 Use the mininet m utility to connect to the host's cli
3624 """
3625 # These are fields that can be used by scapy packets. Initialized to None
3626 self.hostIp = None
3627 self.hostMac = None
3628 try:
3629 if not host:
3630 host = self.name
3631 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003632 self.handle.sendline( "cd" )
3633 self.handle.expect( self.hostPrompt )
3634 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003635 self.handle.expect( self.hostPrompt )
3636 return main.TRUE
3637 except pexpect.TIMEOUT:
3638 main.log.exception( self.name + ": Command timed out" )
3639 return main.FALSE
3640 except pexpect.EOF:
3641 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003642 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003643 except Exception:
3644 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003645 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003646
YPZhang801d46d2016-08-08 13:26:28 -07003647 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003648 '''
3649
YPZhang801d46d2016-08-08 13:26:28 -07003650 Args:
3651 devicename: switch name
3652 intf: port name on switch
3653 status: up or down
3654
3655 Returns: boolean to show success change status
3656
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003657 '''
YPZhang801d46d2016-08-08 13:26:28 -07003658 if status == "down" or status == "up":
3659 try:
3660 cmd = devicename + " ifconfig " + intf + " " + status
3661 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003662 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003663 return main.TRUE
3664 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003665 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003666 return main.FALSE
3667 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003668 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003669 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003670 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003671 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003672 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003673 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003674 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003675 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003676 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003677 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003678 return main.FALSE
3679
3680
adminbae64d82013-08-01 10:50:15 -07003681if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003682 sys.modules[ __name__ ] = MininetCliDriver()