blob: daa7b0a226e68475a012387198c0d12a40af8220 [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
You Wangf19d9f42018-02-23 16:34:19 -0800494 def pingIpv6Hosts( self, hostList, wait=1, acceptableFailed=0 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700495 """
You Wangf19d9f42018-02-23 16:34:19 -0800496 IPv6 ping all hosts in hostList.
497
498 acceptableFailed: max number of acceptable failed pings
Hari Krishna9592fc82015-07-31 15:11:15 -0700499
Jon Hall3b489db2015-10-05 14:38:37 -0700500 Returns main.TRUE if all hosts specified can reach each other
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"
You Wangf19d9f42018-02-23 16:34:19 -0800509 failedPingsTotal = 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
You Wangf19d9f42018-02-23 16:34:19 -0800520 failedPings = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700521 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
You Wangf19d9f42018-02-23 16:34:19 -0800522 while failedPings <= acceptableFailed:
523 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
524 self.handle.sendline( pingCmd )
525 self.handle.expect( "mininet>", timeout=wait + 1 )
526 response = self.handle.before
527 if re.search( ',\s0\%\spacket\sloss', response ):
528 pingResponse += str( " h" + str( temp[ 1: ] ) )
529 break
530 else:
531 failedPings += 1
532 time.sleep(1)
533 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700534 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800535 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700536 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800537 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700538 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800539 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700540 return isReachable
541
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700542 except pexpect.TIMEOUT:
543 main.log.exception( self.name + ": TIMEOUT exception" )
544 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700545 except pexpect.EOF:
546 main.log.error( self.name + ": EOF exception found" )
547 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700548 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700549 except Exception:
550 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700551 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700552
Jon Hall7eb38402015-01-08 17:19:54 -0800553 def pingHost( self, **pingParams ):
554 """
Jon Hall3b489db2015-10-05 14:38:37 -0700555 Ping from one mininet host to another
556 Currently the only supported Params: SRC, TARGET, and WAIT
557 """
558 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700559 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700560 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800561 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700562 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700563 try:
Jon Hall61282e32015-03-19 11:34:11 -0700564 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800565 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700566 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
567 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700568 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800569 main.log.error(
570 self.name +
571 ": timeout when waiting for response from mininet" )
572 main.log.error( "response: " + str( self.handle.before ) )
573 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700574 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800575 main.log.error(
576 self.name +
577 ": timeout when waiting for response from mininet" )
578 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700579 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700580 if re.search( ',\s0\%\spacket\sloss', response ):
581 main.log.info( self.name + ": no packets lost, host is reachable" )
582 return main.TRUE
583 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800584 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700585 self.name +
586 ": PACKET LOST, HOST IS NOT REACHABLE" )
587 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800588 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800589 main.log.error( self.name + ": EOF exception found" )
590 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700591 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700592 except Exception:
593 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700594 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700595
596 def ping6pair( self, **pingParams ):
597 """
GlennRC2cf7d952015-09-11 16:32:13 -0700598 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700599 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000600 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700601 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
602 """
Jon Hall3b489db2015-10-05 14:38:37 -0700603 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700604 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700605 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530606 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700607 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700608 try:
609 main.log.info( "Sending: " + command )
610 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700611 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
612 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700613 if i == 1:
614 main.log.error(
615 self.name +
616 ": timeout when waiting for response from mininet" )
617 main.log.error( "response: " + str( self.handle.before ) )
618 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
619 if i == 1:
620 main.log.error(
621 self.name +
622 ": timeout when waiting for response from mininet" )
623 main.log.error( "response: " + str( self.handle.before ) )
624 response = self.handle.before
625 main.log.info( self.name + ": Ping Response: " + response )
626 if re.search( ',\s0\%\spacket\sloss', response ):
627 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700628 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700629 else:
alisone4121a92016-11-22 16:31:36 -0800630 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700631 self.name +
632 ": PACKET LOST, HOST IS NOT REACHABLE" )
633 return main.FALSE
634
635 except pexpect.EOF:
636 main.log.error( self.name + ": EOF exception found" )
637 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700638 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700639 except Exception:
640 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700641 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800642
You Wangdb927a52016-02-26 11:03:28 -0800643 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
644 """
645 Description:
646 Ping a set of destination host from host CLI.
647 Logging into a Mininet host CLI is required before calling this funtion.
648 Params:
649 dstIPList is a list of destination ip addresses
650 Returns:
651 main.TRUE if the destination host is reachable
652 main.FALSE otherwise
653 """
654 isReachable = main.TRUE
655 wait = int( wait )
656 cmd = "ping"
657 if IPv6:
658 cmd = cmd + "6"
659 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
660 try:
661 for dstIP in dstIPList:
662 pingCmd = cmd + " " + dstIP
663 self.handle.sendline( pingCmd )
664 i = self.handle.expect( [ self.hostPrompt,
665 '\*\*\* Unknown command: ' + pingCmd,
666 pexpect.TIMEOUT ],
667 timeout=wait + 1 )
668 if i == 0:
669 response = self.handle.before
670 if not re.search( ',\s0\%\spacket\sloss', response ):
671 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
672 isReachable = main.FALSE
673 elif i == 1:
674 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800676 elif i == 2:
677 main.log.error( self.name + ": timeout when waiting for response" )
678 isReachable = main.FALSE
679 else:
680 main.log.error( self.name + ": unknown response: " + self.handle.before )
681 isReachable = main.FALSE
682 except pexpect.TIMEOUT:
683 main.log.exception( self.name + ": TIMEOUT exception" )
684 isReachable = main.FALSE
685 except pexpect.EOF:
686 main.log.error( self.name + ": EOF exception found" )
687 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700688 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800689 except Exception:
690 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700691 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800692 return isReachable
693
Jon Hall7eb38402015-01-08 17:19:54 -0800694 def checkIP( self, host ):
695 """
696 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700697 try:
698 if self.handle:
699 try:
700 response = self.execute(
701 cmd=host +
702 " ifconfig",
703 prompt="mininet>",
704 timeout=10 )
705 except pexpect.EOF:
706 main.log.error( self.name + ": EOF exception found" )
707 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700708 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700709
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700710 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
711 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
712 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
713 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
714 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
715 "[0-9]|25[0-5]|[0-9]{1,2})"
716 # pattern = "inet addr:10.0.0.6"
717 if re.search( pattern, response ):
718 main.log.info( self.name + ": Host Ip configured properly" )
719 return main.TRUE
720 else:
721 main.log.error( self.name + ": Host IP not found" )
722 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700723 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700724 main.log.error( self.name + ": Connection failed to the host" )
725 except Exception:
726 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700727 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800728
Jon Hall7eb38402015-01-08 17:19:54 -0800729 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800730 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700731 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 response = self.execute(
733 cmd="h1 /usr/sbin/sshd -D&",
734 prompt="mininet>",
735 timeout=10 )
736 response = self.execute(
737 cmd="h4 /usr/sbin/sshd -D&",
738 prompt="mininet>",
739 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700740 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 vars( self )[ key ] = connectargs[ key ]
742 response = self.execute(
743 cmd="xterm h1 h4 ",
744 prompt="mininet>",
745 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800746 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 main.log.error( self.name + ": EOF exception found" )
748 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700749 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700750 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800751 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700752 if self.flag == 0:
753 self.flag = 1
754 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800755 else:
adminbae64d82013-08-01 10:50:15 -0700756 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800757
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700758 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700759 """
760 Moves a host from one switch to another on the fly
761 Note: The intf between host and oldSw when detached
762 using detach(), will still show up in the 'net'
763 cmd, because switch.detach() doesn't affect switch.intfs[]
764 ( which is correct behavior since the interfaces
765 haven't moved ).
766 """
767 if self.handle:
768 try:
769 # Bring link between oldSw-host down
770 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
771 "'," + "'down')"
772 print "cmd1= ", cmd
773 response = self.execute( cmd=cmd,
774 prompt="mininet>",
775 timeout=10 )
776
777 # Determine hostintf and Oldswitchintf
778 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
779 ")[0]"
780 print "cmd2= ", cmd
781 self.handle.sendline( cmd )
782 self.handle.expect( "mininet>" )
783
784 # Determine ip and mac address of the host-oldSw interface
785 cmd = "px ipaddr = hintf.IP()"
786 print "cmd3= ", cmd
787 self.handle.sendline( cmd )
788 self.handle.expect( "mininet>" )
789
790 cmd = "px macaddr = hintf.MAC()"
791 print "cmd3= ", cmd
792 self.handle.sendline( cmd )
793 self.handle.expect( "mininet>" )
794
795 # Detach interface between oldSw-host
796 cmd = "px " + oldSw + ".detach( sintf )"
797 print "cmd4= ", cmd
798 self.handle.sendline( cmd )
799 self.handle.expect( "mininet>" )
800
801 # Add link between host-newSw
802 cmd = "py net.addLink(" + host + "," + newSw + ")"
803 print "cmd5= ", cmd
804 self.handle.sendline( cmd )
805 self.handle.expect( "mininet>" )
806
807 # Determine hostintf and Newswitchintf
808 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
809 ")[0]"
810 print "cmd6= ", cmd
811 self.handle.sendline( cmd )
812 self.handle.expect( "mininet>" )
813
814 # Attach interface between newSw-host
815 cmd = "px " + newSw + ".attach( sintf )"
816 print "cmd3= ", cmd
817 self.handle.sendline( cmd )
818 self.handle.expect( "mininet>" )
819
820 # Set ipaddress of the host-newSw interface
821 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
822 print "cmd7 = ", cmd
823 self.handle.sendline( cmd )
824 self.handle.expect( "mininet>" )
825
826 # Set macaddress of the host-newSw interface
827 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
828 print "cmd8 = ", cmd
829 self.handle.sendline( cmd )
830 self.handle.expect( "mininet>" )
831
832 cmd = "net"
833 print "cmd9 = ", cmd
834 self.handle.sendline( cmd )
835 self.handle.expect( "mininet>" )
836 print "output = ", self.handle.before
837
838 # Determine ipaddress of the host-newSw interface
839 cmd = host + " ifconfig"
840 print "cmd10= ", cmd
841 self.handle.sendline( cmd )
842 self.handle.expect( "mininet>" )
843 print "ifconfig o/p = ", self.handle.before
844
845 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700846
847 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700848 main.log.error( self.name + ": TIMEOUT exception found" )
849 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700850 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700851 except pexpect.EOF:
852 main.log.error( self.name + ": EOF exception found" )
853 main.log.error( self.name + ": " + self.handle.before )
854 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700855 except Exception:
856 main.log.exception( self.name + ": Uncaught exception!" )
857 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700858
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700859 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800860 """
861 Moves a host from one switch to another on the fly
862 Note: The intf between host and oldSw when detached
863 using detach(), will still show up in the 'net'
864 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700865 ( which is correct behavior since the interfaces
866 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800867 """
868 if self.handle:
869 try:
Jon Hall439c8912016-04-15 02:22:03 -0700870 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800871 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700872 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800873 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800874 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800875 response = self.execute( cmd=cmd,
876 prompt="mininet>",
877 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700878
kelvin-onlaba1484582015-02-02 15:46:20 -0800879 # Determine hostintf and Oldswitchintf
880 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800881 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800882 print "cmd2= ", cmd
883 self.handle.sendline( cmd )
884 self.handle.expect( "mininet>" )
885
shahshreya73537862015-02-11 15:15:24 -0800886 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700887 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800888 print "cmd3= ", cmd
889 self.handle.sendline( cmd )
890 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800891
892 cmd = "px macaddr = hintf.MAC()"
893 print "cmd3= ", cmd
894 self.handle.sendline( cmd )
895 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700896
kelvin-onlaba1484582015-02-02 15:46:20 -0800897 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700898 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800899 print "cmd4= ", cmd
900 self.handle.sendline( cmd )
901 self.handle.expect( "mininet>" )
902
903 # Add link between host-newSw
904 cmd = "py net.addLink(" + host + "," + newSw + ")"
905 print "cmd5= ", cmd
906 self.handle.sendline( cmd )
907 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700908
kelvin-onlaba1484582015-02-02 15:46:20 -0800909 # Determine hostintf and Newswitchintf
910 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800911 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800912 print "cmd6= ", cmd
913 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700914 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800915
916 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700917 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700918 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800919 self.handle.sendline( cmd )
920 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800921
922 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700923 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700924 print "cmd7 = ", cmd
925 self.handle.sendline( cmd )
926 self.handle.expect( "mininet>" )
927
928 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700929 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800930 print "cmd8 = ", cmd
931 self.handle.sendline( cmd )
932 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700933
Jon Hall439c8912016-04-15 02:22:03 -0700934 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700935 print "cmd9 =", cmd
936 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -0700937 print response
938 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700939 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700940 print ipAddressSearch.group( 1 )
941 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -0700942 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
943 print "cmd10 = ", cmd
944 self.handle.sendline( cmd )
945 self.handle.expect( "mininet>" )
946
kelvin-onlaba1484582015-02-02 15:46:20 -0800947 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700948 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800949 self.handle.sendline( cmd )
950 self.handle.expect( "mininet>" )
951 print "output = ", self.handle.before
952
953 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800954 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700955 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800956 self.handle.sendline( cmd )
957 self.handle.expect( "mininet>" )
958 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700959
kelvin-onlaba1484582015-02-02 15:46:20 -0800960 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700961 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700962 main.log.error( self.name + ": TIMEOUT exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700964 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800965 except pexpect.EOF:
966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
968 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700969 except Exception:
970 main.log.exception( self.name + ": Uncaught exception!" )
971 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800972
Jon Hall7eb38402015-01-08 17:19:54 -0800973 def changeIP( self, host, intf, newIP, newNetmask ):
974 """
975 Changes the ip address of a host on the fly
976 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800977 if self.handle:
978 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800979 cmd = host + " ifconfig " + intf + " " + \
980 newIP + " " + 'netmask' + " " + newNetmask
981 self.handle.sendline( cmd )
982 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800983 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800984 main.log.info( "response = " + response )
985 main.log.info(
986 "Ip of host " +
987 host +
988 " changed to new IP " +
989 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800990 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700991 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700992 main.log.error( self.name + ": TIMEOUT exception found" )
993 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700994 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800995 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800996 main.log.error( self.name + ": EOF exception found" )
997 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800998 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700999 except Exception:
1000 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001001 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001002
Jon Hall7eb38402015-01-08 17:19:54 -08001003 def changeDefaultGateway( self, host, newGW ):
1004 """
1005 Changes the default gateway of a host
1006 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001007 if self.handle:
1008 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001009 cmd = host + " route add default gw " + newGW
1010 self.handle.sendline( cmd )
1011 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001012 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001013 main.log.info( "response = " + response )
1014 main.log.info(
1015 "Default gateway of host " +
1016 host +
1017 " changed to " +
1018 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001019 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001020 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001021 main.log.error( self.name + ": TIMEOUT exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001023 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001024 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001025 main.log.error( self.name + ": EOF exception found" )
1026 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001027 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001028 except Exception:
1029 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001030 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001031
Jon Hall7eb38402015-01-08 17:19:54 -08001032 def addStaticMACAddress( self, host, GW, macaddr ):
1033 """
Jon Hallefbd9792015-03-05 16:11:36 -08001034 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001035 if self.handle:
1036 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001037 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1038 cmd = host + " arp -s " + GW + " " + macaddr
1039 self.handle.sendline( cmd )
1040 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001041 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001042 main.log.info( "response = " + response )
1043 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001044 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001045 GW +
1046 " changed to " +
1047 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001048 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001049 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001050 main.log.error( self.name + ": TIMEOUT exception found" )
1051 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001052 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001053 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001054 main.log.error( self.name + ": EOF exception found" )
1055 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001056 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001057 except Exception:
1058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001059 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001060
Jon Hall7eb38402015-01-08 17:19:54 -08001061 def verifyStaticGWandMAC( self, host ):
1062 """
1063 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001064 if self.handle:
1065 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001066 # h1 arp -an
1067 cmd = host + " arp -an "
1068 self.handle.sendline( cmd )
1069 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001070 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001071 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001072 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001073 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001074 main.log.error( self.name + ": TIMEOUT exception found" )
1075 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001077 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001078 main.log.error( self.name + ": EOF exception found" )
1079 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001080 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001081 except Exception:
1082 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001083 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001084
Jon Hall7eb38402015-01-08 17:19:54 -08001085 def getMacAddress( self, host ):
1086 """
1087 Verifies the host's ip configured or not."""
1088 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001089 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001090 response = self.execute(
1091 cmd=host +
1092 " ifconfig",
1093 prompt="mininet>",
1094 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001095 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001096 main.log.error( self.name + ": EOF exception found" )
1097 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001098 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001099 except Exception:
1100 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001101 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001102
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001103 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 macAddressSearch = re.search( pattern, response, re.I )
1105 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001106 main.log.info(
1107 self.name +
1108 ": Mac-Address of Host " +
1109 host +
1110 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 macAddress )
1112 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001113 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001114 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001115
Jon Hall7eb38402015-01-08 17:19:54 -08001116 def getInterfaceMACAddress( self, host, interface ):
1117 """
1118 Return the IP address of the interface on the given host"""
1119 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001120 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001121 response = self.execute( cmd=host + " ifconfig " + interface,
1122 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001123 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001126 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001127 except Exception:
1128 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001129 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001130
1131 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 macAddressSearch = re.search( pattern, response, re.I )
1133 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001134 main.log.info( "No mac address found in %s" % response )
1135 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001137 main.log.info(
1138 "Mac-Address of " +
1139 host +
1140 ":" +
1141 interface +
1142 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 macAddress )
1144 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001145 else:
1146 main.log.error( "Connection failed to the host" )
1147
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001148 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001149 """
1150 Verifies the host's ip configured or not."""
1151 if self.handle:
1152 try:
1153 response = self.execute(
1154 cmd=host +
1155 " ifconfig",
1156 prompt="mininet>",
1157 timeout=10 )
1158 except pexpect.EOF:
1159 main.log.error( self.name + ": EOF exception found" )
1160 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001161 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001162 except Exception:
1163 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001164 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001165
sathishmad953462015-12-03 17:42:07 +05301166 pattern = ''
1167 if proto == 'IPV4':
1168 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1169 else:
Jon Hall439c8912016-04-15 02:22:03 -07001170 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001172 main.log.info(
1173 self.name +
1174 ": IP-Address of Host " +
1175 host +
1176 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 ipAddressSearch.group( 1 ) )
1178 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001179 else:
1180 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001181
Jon Hall7eb38402015-01-08 17:19:54 -08001182 def getSwitchDPID( self, switch ):
1183 """
1184 return the datapath ID of the switch"""
1185 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001186 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001187 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001188 response = self.execute(
1189 cmd=cmd,
1190 prompt="mininet>",
1191 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001192 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001193 main.log.error( self.name + ": EOF exception found" )
1194 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001195 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001196 except Exception:
1197 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001198 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001199 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001200 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001201 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001202 main.log.info(
1203 "Couldn't find DPID for switch %s, found: %s" %
1204 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001205 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001206 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001207 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001208 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001209
Jon Hall7eb38402015-01-08 17:19:54 -08001210 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001211 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001212 self.handle.sendline( "" )
1213 self.expect( "mininet>" )
1214 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001215 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 response = self.execute(
1217 cmd=cmd,
1218 prompt="mininet>",
1219 timeout=10 )
1220 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001221 response = self.handle.before
1222 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001223 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001224 main.log.error( self.name + ": TIMEOUT exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001226 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001227 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001228 main.log.error( self.name + ": EOF exception found" )
1229 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001230 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001231 except Exception:
1232 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001233 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001234
Jon Hall7eb38402015-01-08 17:19:54 -08001235 def getInterfaces( self, node ):
1236 """
1237 return information dict about interfaces connected to the node"""
1238 if self.handle:
1239 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001240 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001241 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001242 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001243 response = self.execute(
1244 cmd=cmd,
1245 prompt="mininet>",
1246 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001247 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001248 main.log.error( self.name + ": EOF exception found" )
1249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001250 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001251 except Exception:
1252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001254 return response
1255 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001256 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001257
Jon Hall7eb38402015-01-08 17:19:54 -08001258 def dump( self ):
1259 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001260 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001261 response = self.execute(
1262 cmd='dump',
1263 prompt='mininet>',
1264 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001265 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001266 main.log.error( self.name + ": EOF exception found" )
1267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001268 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001269 except Exception:
1270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001271 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001272 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001273
Jon Hall7eb38402015-01-08 17:19:54 -08001274 def intfs( self ):
1275 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001276 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001277 response = self.execute(
1278 cmd='intfs',
1279 prompt='mininet>',
1280 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001281 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001282 main.log.error( self.name + ": EOF exception found" )
1283 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001284 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001285 except Exception:
1286 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001287 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001288 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001289
Jon Hall7eb38402015-01-08 17:19:54 -08001290 def net( self ):
1291 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001292 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001293 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001294 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001295 main.log.error( self.name + ": EOF exception found" )
1296 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001297 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001298 except Exception:
1299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001300 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001301 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001302
Devin Lima7cfdbd2017-09-29 15:02:22 -07001303 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001304 main.log.info( self.name + ": List network links" )
1305 try:
1306 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001307 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001308 except pexpect.EOF:
1309 main.log.error( self.name + ": EOF exception found" )
1310 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001311 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001312 except Exception:
1313 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001314 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001315 return response
1316
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001317 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001318 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001319 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001320
kelvin-onlab7cce9382015-07-17 10:21:03 -07001321 @parm:
1322 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1323 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001324 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001325 try:
1326 for host1 in hosts:
1327 for host2 in hosts:
1328 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001329 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1330 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001331 except Exception:
1332 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001333 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001334
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001335 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001336 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001337 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1338 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001339
kelvin-onlab7cce9382015-07-17 10:21:03 -07001340 @parm:
1341 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1342 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001343 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001344 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1345 try:
1346 # Setup the mininet command
1347 cmd1 = 'iperf ' + host1 + " " + host2
1348 self.handle.sendline( cmd1 )
1349 outcome = self.handle.expect( "mininet>", timeout )
1350 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001351
kelvin-onlab7cce9382015-07-17 10:21:03 -07001352 # checks if there are results in the mininet response
1353 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001354 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001355 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001356 response = response.split( "\r\n" )
1357 response = response[ len( response )-2 ]
1358 response = response.split( ": " )
1359 response = response[ len( response )-1 ]
1360 response = response.replace( "[", "" )
1361 response = response.replace( "]", "" )
1362 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001363
kelvin-onlab7cce9382015-07-17 10:21:03 -07001364 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001365 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001366
kelvin-onlab7cce9382015-07-17 10:21:03 -07001367 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001368 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001369 if len( bandwidth ) == 2:
1370 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001371 return main.TRUE
1372 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001373 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001374 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001375 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001376 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001377 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001378 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001379 main.log.error( self.name + ": TIMEOUT exception found" )
1380 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001381 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001382 # NOTE: Send ctrl-c to make sure iperf is done
1383 self.handle.sendline( "\x03" )
1384 self.handle.expect( "Interrupt" )
1385 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001386 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001387 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001388 main.log.error( self.name + ": EOF exception found" )
1389 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001390 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001391 except Exception:
1392 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001393 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001394
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001395 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001396 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1397 try:
1398 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001399 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001400 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001401 outcome1 = self.handle.expect( "mininet>" )
1402 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001403 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001404 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001405 response1 = self.handle.before
1406 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001407 print response1, response2
1408 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001409 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001410 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001411 return main.TRUE
1412 else:
1413 main.log.error( self.name + ": iperf test failed" )
1414 return main.FALSE
1415 except pexpect.TIMEOUT:
1416 main.log.error( self.name + ": TIMEOUT exception found" )
1417 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1418 self.handle.sendline( "\x03" )
1419 self.handle.expect( "Interrupt" )
1420 self.handle.expect( "mininet>" )
1421 return main.FALSE
1422 except pexpect.EOF:
1423 main.log.error( self.name + ": EOF exception found" )
1424 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001425 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001426 except Exception:
1427 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001428 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001429
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001430 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001431 '''
GlennRC61321f22015-07-16 13:36:54 -07001432 Runs the iperfudp function with a given set of hosts and specified
1433 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001434
GlennRC61321f22015-07-16 13:36:54 -07001435 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001436 bandwidth: the targeted bandwidth, in megabits ('M')
1437 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001438 try:
1439 for host1 in hosts:
1440 for host2 in hosts:
1441 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001442 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1443 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001444 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001445 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001446 return main.FALSE
1447 except Exception:
1448 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001449 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001450
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001451 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001452 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001453 Creates an iperf UDP test with a specific bandwidth.
1454 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001455
kelvin-onlab7cce9382015-07-17 10:21:03 -07001456 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001457 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1458 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001459 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001460 try:
1461 # setup the mininet command
1462 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001463 self.handle.sendline( cmd )
1464 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001465 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001466
kelvin-onlab7cce9382015-07-17 10:21:03 -07001467 # check if there are in results in the mininet response
1468 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001469 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001470 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001471 response = response.split( "\r\n" )
1472 response = response[ len( response )-2 ]
1473 response = response.split( ": " )
1474 response = response[ len( response )-1 ]
1475 response = response.replace( "[", "" )
1476 response = response.replace( "]", "" )
1477 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001478
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001479 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001480
kelvin-onlab7cce9382015-07-17 10:21:03 -07001481 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001482 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001483 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001484 # if one entry is blank then something is wrong
1485 for item in mnBandwidth:
1486 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001487 main.log.error( self.name + ": Could not parse iperf output" )
1488 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001489 return main.FALSE
1490 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001491 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001492 return main.TRUE
1493 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001494 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001495 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001496
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001497 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001498 main.log.error( self.name + ": TIMEOUT exception found" )
1499 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001500 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001501 except pexpect.EOF:
1502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001504 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001505 except Exception:
1506 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001507 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001508
Jon Hall7eb38402015-01-08 17:19:54 -08001509 def nodes( self ):
1510 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001511 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001512 response = self.execute(
1513 cmd='nodes',
1514 prompt='mininet>',
1515 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001516 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001517 main.log.error( self.name + ": EOF exception found" )
1518 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001519 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001520 except Exception:
1521 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001522 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001523 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001524
Jon Hall7eb38402015-01-08 17:19:54 -08001525 def pingpair( self ):
1526 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001527 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001528 response = self.execute(
1529 cmd='pingpair',
1530 prompt='mininet>',
1531 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001532 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001533 main.log.error( self.name + ": EOF exception found" )
1534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001535 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001536 except Exception:
1537 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001538 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001539
Jon Hall7eb38402015-01-08 17:19:54 -08001540 if re.search( ',\s0\%\spacket\sloss', response ):
1541 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001542 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001543 else:
alisone4121a92016-11-22 16:31:36 -08001544 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001545 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001546
Jon Hall7eb38402015-01-08 17:19:54 -08001547 def link( self, **linkargs ):
1548 """
GlennRCed771242016-01-13 17:02:47 -08001549 Bring link( s ) between two nodes up or down
1550 """
Jon Hall6094a362014-04-11 14:46:56 -07001551 try:
GlennRCed771242016-01-13 17:02:47 -08001552 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1553 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1554 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1555 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1556
1557 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1558 cmd = "link {} {} {}".format( end1, end2, option )
1559 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001560 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001561 response = self.handle.before
1562 main.log.info( response )
1563
1564 return main.TRUE
1565 except pexpect.TIMEOUT:
1566 main.log.exception( self.name + ": Command timed out" )
1567 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001568 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001569 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001570 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001571 except Exception:
1572 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001573 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001574
pingping-lin8244a3b2015-09-16 13:36:56 -07001575 def switch( self, **switchargs ):
1576 """
1577 start/stop a switch
1578 """
1579 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1580 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1581 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1582 command = "switch " + str( sw ) + " " + str( option )
1583 main.log.info( command )
1584 try:
1585 self.handle.sendline( command )
1586 self.handle.expect( "mininet>" )
1587 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001588 main.log.error( self.name + ": TIMEOUT exception found" )
1589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001590 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001591 except pexpect.EOF:
1592 main.log.error( self.name + ": EOF exception found" )
1593 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001594 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001595 return main.TRUE
1596
pingping-lin5bb663b2015-09-24 11:47:50 -07001597 def node( self, nodeName, commandStr ):
1598 """
1599 Carry out a command line on a given node
1600 @parm:
1601 nodeName: the node name in Mininet testbed
1602 commandStr: the command line will be carried out on the node
1603 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1604 """
1605 command = str( nodeName ) + " " + str( commandStr )
1606 main.log.info( command )
1607
1608 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001609 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001610 if re.search( "Unknown command", response ):
1611 main.log.warn( response )
1612 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001613 if re.search( "Permission denied", response ):
1614 main.log.warn( response )
1615 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001616 except pexpect.EOF:
1617 main.log.error( self.name + ": EOF exception found" )
1618 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001619 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001620 main.log.info( " response is :" )
1621 main.log.info( response )
1622 return response
1623
Jon Hall7eb38402015-01-08 17:19:54 -08001624 def yank( self, **yankargs ):
1625 """
1626 yank a mininet switch interface to a host"""
1627 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001628 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001629 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1630 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001631 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001632 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001633 response = self.execute(
1634 cmd=command,
1635 prompt="mininet>",
1636 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001637 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001638 main.log.error( self.name + ": EOF exception found" )
1639 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001640 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001641 except Exception:
1642 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001643 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001644 return main.TRUE
1645
Jon Hall7eb38402015-01-08 17:19:54 -08001646 def plug( self, **plugargs ):
1647 """
1648 plug the yanked mininet switch interface to a switch"""
1649 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001650 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001651 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1652 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001653 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001654 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001655 response = self.execute(
1656 cmd=command,
1657 prompt="mininet>",
1658 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001659 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001660 main.log.error( self.name + ": EOF exception found" )
1661 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001662 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001663 except Exception:
1664 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001665 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001666 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001667
Jon Hall7eb38402015-01-08 17:19:54 -08001668 def dpctl( self, **dpctlargs ):
1669 """
1670 Run dpctl command on all switches."""
1671 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001672 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001673 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1674 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1675 command = "dpctl " + cmd + " " + str( cmdargs )
1676 try:
1677 response = self.execute(
1678 cmd=command,
1679 prompt="mininet>",
1680 timeout=10 )
1681 except pexpect.EOF:
1682 main.log.error( self.name + ": EOF exception found" )
1683 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001684 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001685 except Exception:
1686 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001687 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001688 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001689
kelvin-onlabd3b64892015-01-20 13:26:24 -08001690 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001691 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001692 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001693 try:
1694 fileInput = path + '/lib/Mininet/INSTALL'
1695 version = super( Mininet, self ).getVersion()
1696 pattern = 'Mininet\s\w\.\w\.\w\w*'
1697 for line in open( fileInput, 'r' ).readlines():
1698 result = re.match( pattern, line )
1699 if result:
1700 version = result.group( 0 )
1701 return version
1702 except Exception:
1703 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001704 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001705
kelvin-onlabd3b64892015-01-20 13:26:24 -08001706 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001707 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001708 Parameters:
1709 sw: The name of an OVS switch. Example "s1"
1710 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001711 The output of the command from the mininet cli
1712 or main.FALSE on timeout"""
1713 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001714 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001715 response = self.execute(
1716 cmd=command,
1717 prompt="mininet>",
1718 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001719 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001720 return response
admin2a9548d2014-06-17 14:08:07 -07001721 else:
1722 return main.FALSE
1723 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001724 main.log.error( self.name + ": EOF exception found" )
1725 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001726 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001727 except Exception:
1728 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001729 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001730
Charles Chan029be652015-08-24 01:46:10 +08001731 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001732 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001733 Description:
1734 Assign switches to the controllers ( for ovs use only )
1735 Required:
1736 sw - Name of the switch. This can be a list or a string.
1737 ip - Ip addresses of controllers. This can be a list or a string.
1738 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001739 port - ONOS use port 6653, if no list of ports is passed, then
1740 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001741 ptcp - ptcp number, This can be a string or a list that has
1742 the same length as switch. This is optional and not required
1743 when using ovs switches.
1744 NOTE: If switches and ptcp are given in a list type they should have the
1745 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1746 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001747
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001748 Return:
1749 Returns main.TRUE if mininet correctly assigned switches to
1750 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001751 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001752 """
1753 assignResult = main.TRUE
1754 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001755 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001756 command = "sh ovs-vsctl set-controller "
1757 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001758 try:
1759 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001760 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001761 if isinstance( port, types.StringType ) or \
1762 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001763 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001764 elif isinstance( port, types.ListType ):
1765 main.log.error( self.name + ": Only one controller " +
1766 "assigned and a list of ports has" +
1767 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001768 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001769 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001770 main.log.error( self.name + ": Invalid controller port " +
1771 "number. Please specify correct " +
1772 "controller port" )
1773 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001774
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001775 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001776 if isinstance( port, types.StringType ) or \
1777 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001778 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001779 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1780 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001781 elif isinstance( port, types.ListType ):
1782 if ( len( ip ) != len( port ) ):
1783 main.log.error( self.name + ": Port list = " +
1784 str( len( port ) ) +
1785 "should be the same as controller" +
1786 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001787 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001788 else:
1789 onosIp = ""
1790 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001791 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1792 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001793 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001794 main.log.error( self.name + ": Invalid controller port " +
1795 "number. Please specify correct " +
1796 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001797 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001798 else:
1799 main.log.error( self.name + ": Invalid ip address" )
1800 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001801
1802 if isinstance( sw, types.StringType ):
1803 command += sw + " "
1804 if ptcp:
1805 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001806 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001807 elif isinstance( ptcp, types.ListType ):
1808 main.log.error( self.name + ": Only one switch is " +
1809 "being set and multiple PTCP is " +
1810 "being passed " )
1811 else:
1812 main.log.error( self.name + ": Invalid PTCP" )
1813 ptcp = ""
1814 command += onosIp
1815 commandList.append( command )
1816
1817 elif isinstance( sw, types.ListType ):
1818 if ptcp:
1819 if isinstance( ptcp, types.ListType ):
1820 if len( ptcp ) != len( sw ):
1821 main.log.error( self.name + ": PTCP length = " +
1822 str( len( ptcp ) ) +
1823 " is not the same as switch" +
1824 " length = " +
1825 str( len( sw ) ) )
1826 return main.FALSE
1827 else:
1828 for switch, ptcpNum in zip( sw, ptcp ):
1829 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001830 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001831 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001832 tempCmd += onosIp
1833 commandList.append( tempCmd )
1834 else:
1835 main.log.error( self.name + ": Invalid PTCP" )
1836 return main.FALSE
1837 else:
1838 for switch in sw:
1839 tempCmd = "sh ovs-vsctl set-controller "
1840 tempCmd += switch + " " + onosIp
1841 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001842 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001843 main.log.error( self.name + ": Invalid switch type " )
1844 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001845
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001846 for cmd in commandList:
1847 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001848 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001849 except pexpect.TIMEOUT:
1850 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1851 return main.FALSE
1852 except pexpect.EOF:
1853 main.log.error( self.name + ": EOF exception found" )
1854 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001855 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001856 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001857 except pexpect.EOF:
1858 main.log.error( self.name + ": EOF exception found" )
1859 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001860 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001861 except Exception:
1862 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001863 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001864
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001866 """
1867 Removes the controller target from sw"""
1868 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001869 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001870 response = self.execute(
1871 cmd=command,
1872 prompt="mininet>",
1873 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001874 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001875 main.log.error( self.name + ": EOF exception found" )
1876 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001877 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001878 except Exception:
1879 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001880 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001881 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001882 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001883
kelvin-onlabd3b64892015-01-20 13:26:24 -08001884 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001885 """
Jon Hallb1290e82014-11-18 16:17:48 -05001886 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001887 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001888 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001889 NOTE: cannot currently specify what type of switch
1890 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001891 sw = name of the new switch as a string
1892 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001893 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001894 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001895 """
1896 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001897 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001898 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001899 response = self.execute(
1900 cmd=command,
1901 prompt="mininet>",
1902 timeout=10 )
1903 if re.search( "already exists!", response ):
1904 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001905 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001906 elif re.search( "Error", response ):
1907 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001908 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001909 elif re.search( "usage:", response ):
1910 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001911 return main.FALSE
1912 else:
1913 return main.TRUE
1914 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001915 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001916 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001917 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001918 except Exception:
1919 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001920 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001921
kelvin-onlabd3b64892015-01-20 13:26:24 -08001922 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001923 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001924 delete a switch from the mininet topology
1925 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001926 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001927 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001928 sw = name of the switch as a string
1929 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001930 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001931 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001932 response = self.execute(
1933 cmd=command,
1934 prompt="mininet>",
1935 timeout=10 )
1936 if re.search( "no switch named", response ):
1937 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001938 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001939 elif re.search( "Error", response ):
1940 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001941 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001942 elif re.search( "usage:", response ):
1943 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001944 return main.FALSE
1945 else:
1946 return main.TRUE
1947 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001948 main.log.error( self.name + ": EOF exception found" )
1949 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001950 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001951 except Exception:
1952 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001953 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001954
You Wangdb8cd0a2016-05-26 15:19:45 -07001955 def getSwitchRandom( self, timeout=60, nonCut=True ):
1956 """
1957 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001958 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001959 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001960 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07001961 it just randomly returns one switch from all current switches in
1962 Mininet.
1963 Returns the name of the chosen switch.
1964 """
1965 import random
1966 candidateSwitches = []
1967 try:
1968 if not nonCut:
1969 switches = self.getSwitches( timeout=timeout )
1970 assert len( switches ) != 0
1971 for switchName in switches.keys():
1972 candidateSwitches.append( switchName )
1973 else:
1974 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001975 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001976 return None
1977 self.graph.update( graphDict )
1978 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001979 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001980 return None
1981 elif len( candidateSwitches ) == 0:
1982 main.log.info( self.name + ": No candidate switch for deletion" )
1983 return None
1984 else:
1985 switch = random.sample( candidateSwitches, 1 )
1986 return switch[ 0 ]
1987 except KeyError:
1988 main.log.exception( self.name + ": KeyError exception found" )
1989 return None
1990 except AssertionError:
1991 main.log.exception( self.name + ": AssertionError exception found" )
1992 return None
1993 except Exception:
1994 main.log.exception( self.name + ": Uncaught exception" )
1995 return None
1996
1997 def delSwitchRandom( self, timeout=60, nonCut=True ):
1998 """
1999 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002000 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002001 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002002 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002003 otherwise it just randomly delete one switch from all current
2004 switches in Mininet.
2005 Returns the name of the deleted switch
2006 """
2007 try:
2008 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002009 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002010 return None
2011 else:
2012 deletionResult = self.delSwitch( switch )
2013 if deletionResult:
2014 return switch
2015 else:
2016 return None
2017 except Exception:
2018 main.log.exception( self.name + ": Uncaught exception" )
2019 return None
2020
kelvin-onlabd3b64892015-01-20 13:26:24 -08002021 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002022 """
2023 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002024 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002025 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002026 NOTE: cannot currently specify what type of link
2027 required params:
2028 node1 = the string node name of the first endpoint of the link
2029 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002030 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002031 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002032 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002033 response = self.execute(
2034 cmd=command,
2035 prompt="mininet>",
2036 timeout=10 )
2037 if re.search( "doesnt exist!", response ):
2038 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002039 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002040 elif re.search( "Error", response ):
2041 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002042 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002043 elif re.search( "usage:", response ):
2044 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002045 return main.FALSE
2046 else:
2047 return main.TRUE
2048 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002051 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002052 except Exception:
2053 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002055
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002057 """
2058 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002059 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002060 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002061 required params:
2062 node1 = the string node name of the first endpoint of the link
2063 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002064 returns: main.FALSE on an error, else main.TRUE
2065 """
Jon Hallffb386d2014-11-21 13:43:38 -08002066 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002067 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002068 response = self.execute(
2069 cmd=command,
2070 prompt="mininet>",
2071 timeout=10 )
2072 if re.search( "no node named", response ):
2073 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002074 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002075 elif re.search( "Error", response ):
2076 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002077 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002078 elif re.search( "usage:", response ):
2079 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002080 return main.FALSE
2081 else:
2082 return main.TRUE
2083 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002084 main.log.error( self.name + ": EOF exception found" )
2085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002086 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002087 except Exception:
2088 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002089 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002090
You Wangdb8cd0a2016-05-26 15:19:45 -07002091 def getLinkRandom( self, timeout=60, nonCut=True ):
2092 """
2093 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002094 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002095 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002096 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002097 it just randomly returns one link from all current links in
2098 Mininet.
2099 Returns the link as a list, e.g. [ 's1', 's2' ]
2100 """
2101 import random
2102 candidateLinks = []
2103 try:
2104 if not nonCut:
2105 links = self.getLinks( timeout=timeout )
2106 assert len( links ) != 0
2107 for link in links:
2108 # Exclude host-switch link
2109 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2110 continue
2111 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2112 else:
2113 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002114 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002115 return None
2116 self.graph.update( graphDict )
2117 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002118 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002119 return None
2120 elif len( candidateLinks ) == 0:
2121 main.log.info( self.name + ": No candidate link for deletion" )
2122 return None
2123 else:
2124 link = random.sample( candidateLinks, 1 )
2125 return link[ 0 ]
2126 except KeyError:
2127 main.log.exception( self.name + ": KeyError exception found" )
2128 return None
2129 except AssertionError:
2130 main.log.exception( self.name + ": AssertionError exception found" )
2131 return None
2132 except Exception:
2133 main.log.exception( self.name + ": Uncaught exception" )
2134 return None
2135
2136 def delLinkRandom( self, timeout=60, nonCut=True ):
2137 """
2138 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002139 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002140 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002141 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002142 otherwise it just randomly delete one link from all current links
2143 in Mininet.
2144 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2145 """
2146 try:
2147 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002148 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002149 return None
2150 else:
2151 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2152 if deletionResult:
2153 return link
2154 else:
2155 return None
2156 except Exception:
2157 main.log.exception( self.name + ": Uncaught exception" )
2158 return None
2159
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002161 """
Jon Hallb1290e82014-11-18 16:17:48 -05002162 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002163 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002164 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002165 NOTE: cannot currently specify what type of host
2166 required params:
2167 hostname = the string hostname
2168 optional key-value params
2169 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002170 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002171 """
2172 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002173 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002174 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002175 response = self.execute(
2176 cmd=command,
2177 prompt="mininet>",
2178 timeout=10 )
2179 if re.search( "already exists!", response ):
2180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002181 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002182 elif re.search( "doesnt exists!", response ):
2183 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002184 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002185 elif re.search( "Error", response ):
2186 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002187 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002188 elif re.search( "usage:", response ):
2189 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002190 return main.FALSE
2191 else:
2192 return main.TRUE
2193 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002194 main.log.error( self.name + ": EOF exception found" )
2195 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002196 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002197 except Exception:
2198 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002199 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002200
kelvin-onlabd3b64892015-01-20 13:26:24 -08002201 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002202 """
2203 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002204 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002205 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002206 NOTE: this uses a custom mn function
2207 required params:
2208 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002209 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002210 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002211 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002212 response = self.execute(
2213 cmd=command,
2214 prompt="mininet>",
2215 timeout=10 )
2216 if re.search( "no host named", response ):
2217 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002218 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002219 elif re.search( "Error", response ):
2220 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002221 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002222 elif re.search( "usage:", response ):
2223 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002224 return main.FALSE
2225 else:
2226 return main.TRUE
2227 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002228 main.log.error( self.name + ": EOF exception found" )
2229 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002230 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002231 except Exception:
2232 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002233 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002234
Jon Hall7eb38402015-01-08 17:19:54 -08002235 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002236 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002237 Called at the end of the test to stop the mininet and
2238 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002239 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002240 try:
2241 self.handle.sendline( '' )
2242 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2243 timeout=2 )
2244 response = main.TRUE
2245 if i == 0:
2246 response = self.stopNet()
2247 elif i == 1:
2248 return main.TRUE
2249 # print "Disconnecting Mininet"
2250 if self.handle:
2251 self.handle.sendline( "exit" )
2252 self.handle.expect( "exit" )
2253 self.handle.expect( "(.*)" )
2254 else:
2255 main.log.error( "Connection failed to the host" )
2256 return response
2257 except pexpect.EOF:
2258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002260 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002261 except Exception:
2262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002263 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002264
Devin Lima7cfdbd2017-09-29 15:02:22 -07002265 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002266 """
Jon Hall21270ac2015-02-16 17:59:55 -08002267 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002268 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002269 main.FALSE if the pexpect handle does not exist.
2270
Jon Halld61331b2015-02-17 16:35:47 -08002271 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002272 """
Jon Halld61331b2015-02-17 16:35:47 -08002273 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002274 response = ''
2275 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002276 try:
Jon Halld80cc142015-07-06 13:36:05 -07002277 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002278 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002279 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002280 pexpect.EOF,
2281 pexpect.TIMEOUT ],
2282 timeout )
2283 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002284 main.log.info( "Exiting mininet.." )
2285 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002286 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002287 prompt=self.prompt,
2288 timeout=exitTimeout )
2289 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002290 self.handle.sendline( "sudo mn -c" )
2291 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002292
Jeremyd9e4eb12016-04-13 12:09:06 -07002293 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002294 main.log.info( " Mininet trying to exit while not " +
2295 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002296 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002297 elif i == 2:
2298 main.log.error( "Something went wrong exiting mininet" )
2299 elif i == 3: # timeout
2300 main.log.error( "Something went wrong exiting mininet " +
2301 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002302
Hari Krishnab35c6d02015-03-18 11:13:51 -07002303 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002304 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002305 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002306 self.handle.sendline(
2307 "sudo kill -9 \`ps -ef | grep \"" +
2308 fileName +
2309 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002310 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002311 main.log.error( self.name + ": TIMEOUT exception found" )
2312 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002313 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002314 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002315 main.log.error( self.name + ": EOF exception found" )
2316 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002317 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002318 except Exception:
2319 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002320 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002321 else:
2322 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002323 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002324 return response
2325
YPZhang26a139e2016-04-25 14:01:55 -07002326 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002327 """
2328 Description:
2329 Sends arp message from mininet host for hosts discovery
2330 Required:
2331 host - hosts name
2332 Optional:
2333 ip - ip address that does not exist in the network so there would
2334 be no reply.
2335 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002336 if ethDevice:
2337 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002338 cmd = srcHost + " arping -c1 "
2339 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002340 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 -07002341 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002342 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002343 if output:
2344 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002345 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002346 i = self.handle.expect( [ "mininet>", "arping: " ] )
2347 if i == 0:
2348 return main.TRUE
2349 elif i == 1:
2350 response = self.handle.before + self.handle.after
2351 self.handle.expect( "mininet>" )
2352 response += self.handle.before + self.handle.after
2353 main.log.warn( "Error sending arping, output was: " +
2354 response )
2355 return main.FALSE
2356 except pexpect.TIMEOUT:
2357 main.log.error( self.name + ": TIMEOUT exception found" )
2358 main.log.warn( self.handle.before )
2359 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002360 except pexpect.EOF:
2361 main.log.error( self.name + ": EOF exception found" )
2362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002363 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002364 except Exception:
2365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002366 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002367
Jon Hall7eb38402015-01-08 17:19:54 -08002368 def decToHex( self, num ):
2369 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002370
Jon Hall7eb38402015-01-08 17:19:54 -08002371 def getSwitchFlowCount( self, switch ):
2372 """
2373 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002374 if self.handle:
2375 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2376 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002377 response = self.execute(
2378 cmd=cmd,
2379 prompt="mininet>",
2380 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002381 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002382 main.log.error( self.name + ": EOF exception found" )
2383 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002384 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002385 except Exception:
2386 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002387 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002388 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002389 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002390 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002391 main.log.info(
2392 "Couldn't find flows on switch %s, found: %s" %
2393 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002394 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002395 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002396 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002397 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002398
Jon Hall9ed8f372016-02-24 17:34:07 -08002399 def checkFlows( self, sw, dumpFormat=None ):
2400 if dumpFormat:
2401 command = "sh ovs-ofctl -F " + \
2402 dumpFormat + " dump-flows " + str( sw )
2403 else:
2404 command = "sh ovs-ofctl dump-flows " + str( sw )
2405 try:
2406 response = self.execute(
2407 cmd=command,
2408 prompt="mininet>",
2409 timeout=10 )
2410 return response
2411 except pexpect.EOF:
2412 main.log.error( self.name + ": EOF exception found" )
2413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002414 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002415 except Exception:
2416 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002417 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002418
GlennRC68467eb2015-11-16 18:01:01 -08002419 def flowTableComp( self, flowTable1, flowTable2 ):
2420 # This function compares the selctors and treatments of each flow
2421 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002422 assert flowTable1, "flowTable1 is empty or None"
2423 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002424 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002425 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002426 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002427 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002428 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2429 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002430 for field in dFields:
2431 try:
2432 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002433 except KeyError:
2434 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002435 try:
2436 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002437 except KeyError:
2438 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002439 for i in range( len( flowTable1 ) ):
2440 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002441 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002442 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002443 returnValue = main.FALSE
2444 break
2445 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002446 except AssertionError:
2447 main.log.exception( "Nothing to compare" )
2448 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002449 except Exception:
2450 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002451 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002452
GlennRC528ad292015-11-12 10:38:18 -08002453 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002454 '''
GlennRC956ea742015-11-05 16:14:15 -08002455 Discription: Parses flows into json format.
2456 NOTE: this can parse any string thats separated with commas
2457 Arguments:
2458 Required:
2459 flows: a list of strings that represnt flows
2460 Optional:
2461 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2462 debug: prints out the final result
2463 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002464 '''
GlennRC528ad292015-11-12 10:38:18 -08002465 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002466 try:
2467 for flow in flowTable:
2468 jsonFlow = {}
2469 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002470 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002471 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002472 for i in range( len( parsedFlow ) ):
2473 item = parsedFlow[ i ]
2474 if item[ 0 ] == " ":
2475 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002476 # grab the selector and treatment from the parsed flow
2477 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002478 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002479 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002480 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002481 index = 0
2482 # parse the flags
2483 # NOTE: This only parses one flag
2484 flag = {}
2485 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002486 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002487 index += 1
2488 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002489 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002490 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002491 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002492 # the priority is stuck in the selecter so put it back
2493 # in the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002494 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002495 # parse selector
2496 criteria = []
2497 for item in sel:
2498 # this is the type of the packet e.g. "arp"
2499 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002500 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002501 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002502 field = item.split( "=" )
2503 criteria.append( { field[ 0 ]: field[ 1 ] } )
2504 selector = { "selector": { "criteria": sorted( criteria ) } }
2505 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002506 # get rid of the action part e.g. "action=output:2"
2507 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002508 treat = treat.split( "=" )
2509 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002510 # parse treatment
2511 action = []
2512 for item in treat:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002513 field = item.split( ":" )
2514 action.append( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002515 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002516 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002517 # parse the rest of the flow
2518 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002519 field = item.split( "=" )
2520 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002521 # add the treatment and the selector to the json flow
2522 jsonFlow.update( selector )
2523 jsonFlow.update( treatment )
2524 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002525
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002526 if debug:
2527 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002528
You Wang91c37cf2016-05-23 09:39:42 -07002529 # add the json flow to the json flow table
2530 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002531
You Wang91c37cf2016-05-23 09:39:42 -07002532 return jsonFlowTable
2533
2534 except IndexError:
2535 main.log.exception( self.name + ": IndexError found" )
2536 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002537 except pexpect.EOF:
2538 main.log.error( self.name + ": EOF exception found" )
2539 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002540 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002541 except Exception:
2542 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002543 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002544
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002545 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002546 '''
2547 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002548 Each element is a flow.
2549 Arguments:
2550 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002551 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002552 a list of switches.
2553 Optional:
2554 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2555 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002556 '''
GlennRC956ea742015-11-05 16:14:15 -08002557 try:
2558 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002559 if isinstance( sw, list ):
2560 switches.extend( sw )
2561 else:
2562 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002563
2564 flows = []
2565 for s in switches:
2566 cmd = "sh ovs-ofctl dump-flows " + s
2567
GlennRC528ad292015-11-12 10:38:18 -08002568 if "1.0" == version:
2569 cmd += " -F OpenFlow10-table_id"
2570 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002571 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002572
2573 main.log.info( "Sending: " + cmd )
2574 self.handle.sendline( cmd )
2575 self.handle.expect( "mininet>" )
2576 response = self.handle.before
2577 response = response.split( "\r\n" )
2578 # dump the first two elements and the last
2579 # the first element is the command that was sent
2580 # the second is the table header
2581 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002582 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002583 flows.extend( response )
2584
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002585 if debug:
2586 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002587
GlennRC528ad292015-11-12 10:38:18 -08002588 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002589
GlennRC956ea742015-11-05 16:14:15 -08002590 except pexpect.EOF:
2591 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002592 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002593 except Exception:
2594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002595 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002596
2597 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002598 '''
GlennRC956ea742015-11-05 16:14:15 -08002599 Discription: Checks whether the ID provided matches a flow ID in Mininet
2600 Arguments:
2601 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002602 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002603 a list of switches.
2604 flowId: the flow ID in hex format. Can also be a list of IDs
2605 Optional:
2606 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2607 debug: prints out the final result
2608 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2609 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002610 '''
GlennRC956ea742015-11-05 16:14:15 -08002611 try:
2612 main.log.info( "Getting flows from Mininet" )
2613 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002614 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002615 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002616
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002617 if debug:
2618 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002619
2620 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002621 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002622 result = False
2623 for f in flows:
2624 if flowId in f.get( 'cookie' ):
2625 result = True
2626 break
2627 # flowId is a list
2628 else:
2629 result = True
2630 # Get flow IDs from Mininet
2631 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2632 # Save the IDs that are not in Mininet
2633 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2634
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002635 if debug:
2636 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002637
2638 # Print out the IDs that are not in Mininet
2639 if absentIds:
2640 main.log.warn( "Absent ids: {}".format( absentIds ) )
2641 result = False
2642
2643 return main.TRUE if result else main.FALSE
2644
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002645 except pexpect.EOF:
2646 main.log.error( self.name + ": EOF exception found" )
2647 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002648 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002649 except Exception:
2650 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002651 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002652
Charles Chan029be652015-08-24 01:46:10 +08002653 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002654 """
Jon Hallefbd9792015-03-05 16:11:36 -08002655 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002656 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002657 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002658 self.handle.sendline( "" )
2659 self.handle.expect( "mininet>" )
2660 self.handle.sendline(
2661 "sh sudo tcpdump -n -i " +
2662 intf +
2663 " " +
2664 port +
2665 " -w " +
2666 filename.strip() +
2667 " &" )
2668 self.handle.sendline( "" )
2669 i = self.handle.expect( [ 'No\ssuch\device',
2670 'listening\son',
2671 pexpect.TIMEOUT,
2672 "mininet>" ],
2673 timeout=10 )
2674 main.log.warn( self.handle.before + self.handle.after )
2675 self.handle.sendline( "" )
2676 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002677 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002678 main.log.error(
2679 self.name +
2680 ": tcpdump - No such device exists. " +
2681 "tcpdump attempted on: " +
2682 intf )
admin2a9548d2014-06-17 14:08:07 -07002683 return main.FALSE
2684 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002685 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002686 return main.TRUE
2687 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002688 main.log.error(
2689 self.name +
2690 ": tcpdump command timed out! Check interface name," +
2691 " given interface was: " +
2692 intf )
admin2a9548d2014-06-17 14:08:07 -07002693 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002694 elif i == 3:
2695 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002696 return main.TRUE
2697 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002698 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002699 return main.FALSE
2700 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002703 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002704 except Exception:
2705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002706 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002707
kelvin-onlabd3b64892015-01-20 13:26:24 -08002708 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002709 """
2710 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002711 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002712 self.handle.sendline( "sh sudo pkill tcpdump" )
2713 self.handle.expect( "mininet>" )
2714 self.handle.sendline( "" )
2715 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002716 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002717 main.log.error( self.name + ": TIMEOUT exception found" )
2718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002719 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002720 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002721 main.log.error( self.name + ": EOF exception found" )
2722 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002723 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002724 except Exception:
2725 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002726 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002727
Jon Halld80cc142015-07-06 13:36:05 -07002728 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002729 """
2730 Read ports from a Mininet switch.
2731
2732 Returns a json structure containing information about the
2733 ports of the given switch.
2734 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002735 try:
2736 response = self.getInterfaces( nodeName )
2737 # TODO: Sanity check on response. log if no such switch exists
2738 ports = []
2739 for line in response.split( "\n" ):
2740 if not line.startswith( "name=" ):
2741 continue
2742 portVars = {}
2743 for var in line.split( "," ):
2744 key, value = var.split( "=" )
2745 portVars[ key ] = value
2746 isUp = portVars.pop( 'enabled', "True" )
2747 isUp = "True" in isUp
2748 if verbose:
2749 main.log.info( "Reading switch port %s(%s)" %
2750 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2751 mac = portVars[ 'mac' ]
2752 if mac == 'None':
2753 mac = None
2754 ips = []
2755 ip = portVars[ 'ip' ]
2756 if ip == 'None':
2757 ip = None
2758 ips.append( ip )
2759 name = portVars[ 'name' ]
2760 if name == 'None':
2761 name = None
2762 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2763 if name == 'lo':
2764 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2765 else:
2766 portNo = re.search( portRe, name ).group( 'port' )
2767 ports.append( { 'of_port': portNo,
2768 'mac': str( mac ).replace( '\'', '' ),
2769 'name': name,
2770 'ips': ips,
2771 'enabled': isUp } )
2772 return ports
2773 except pexpect.EOF:
2774 main.log.error( self.name + ": EOF exception found" )
2775 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002776 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002777 except Exception:
2778 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002779 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002780
You Wangdb8cd0a2016-05-26 15:19:45 -07002781 def getOVSPorts( self, nodeName ):
2782 """
2783 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2784
2785 Returns a list of dictionaries containing information about each
2786 port of the given switch.
2787 """
2788 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2789 try:
2790 response = self.execute(
2791 cmd=command,
2792 prompt="mininet>",
2793 timeout=10 )
2794 ports = []
2795 if response:
2796 for line in response.split( "\n" ):
2797 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2798 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002799 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002800 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2801 result = re.search( pattern, line )
2802 if result:
2803 index = result.group( 'index' )
2804 name = result.group( 'name' )
2805 # This port number is extracted from port name
2806 port = result.group( 'port' )
2807 mac = result.group( 'mac' )
2808 ports.append( { 'index': index,
2809 'name': name,
2810 'port': port,
2811 'mac': mac } )
2812 return ports
2813 except pexpect.EOF:
2814 main.log.error( self.name + ": EOF exception found" )
2815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002816 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002817 except Exception:
2818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002819 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002820
Devin Lima7cfdbd2017-09-29 15:02:22 -07002821 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002822 """
2823 Read switches from Mininet.
2824
2825 Returns a dictionary whose keys are the switch names and the value is
2826 a dictionary containing information about the switch.
2827 """
Jon Halla22481b2015-07-28 17:46:01 -07002828 # NOTE: To support new Mininet switch classes, just append the new
2829 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002830
Jon Halla22481b2015-07-28 17:46:01 -07002831 # Regex patterns to parse 'dump' output
2832 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002833 # <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 -07002834 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002835 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2836 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2837 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002838 try:
2839 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2840 swRE = r"<(?P<class>" + switchClasses + r")" +\
2841 r"(?P<options>\{.*\})?\s" +\
2842 r"(?P<name>[^:]+)\:\s" +\
2843 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2844 r"\spid=(?P<pid>(\d)+)"
2845 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002846 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002847 output = {}
2848 dump = self.dump().split( "\n" )
2849 for line in dump:
2850 result = re.search( swRE, line, re.I )
2851 if result:
2852 name = result.group( 'name' )
2853 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2854 pid = result.group( 'pid' )
2855 swClass = result.group( 'class' )
2856 options = result.group( 'options' )
2857 if verbose:
2858 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2859 ports = self.getPorts( name )
2860 output[ name ] = { "dpid": dpid,
2861 "ports": ports,
2862 "swClass": swClass,
2863 "pid": pid,
2864 "options": options }
2865 return output
2866 except pexpect.EOF:
2867 main.log.error( self.name + ": EOF exception found" )
2868 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002869 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002870 except Exception:
2871 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002872 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002873
You Wang53dba1e2018-02-02 17:45:44 -08002874 def getHosts( self, verbose=False, updateTimeout=1000, hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ] ):
Jon Hallafa8a472015-06-12 14:02:42 -07002875 """
2876 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08002877 Optional:
2878 hostClass: it is used to match the class of the mininet host. It
2879 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07002880 Returns a dictionary whose keys are the host names and the value is
2881 a dictionary containing information about the host.
2882 """
2883 # Regex patterns to parse dump output
2884 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002885 # <Host h1: pid=12725>
2886 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2887 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2888 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002889 # NOTE: Does not correctly match hosts with multi-links
2890 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2891 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002892 try:
You Wang53dba1e2018-02-02 17:45:44 -08002893 if not isinstance( hostClass, types.ListType ):
2894 hostClass = [ str( hostClass ) ]
2895 classRE = "(" + "|".join([c for c in hostClass]) + ")"
2896 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002897 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
2898 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002899 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002900 # Get mininet dump
2901 dump = self.dump().split( "\n" )
2902 hosts = {}
2903 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08002904 result = re.search( hostRE, line )
2905 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002906 name = result.group( 'name' )
2907 interfaces = []
2908 response = self.getInterfaces( name )
2909 # Populate interface info
2910 for line in response.split( "\n" ):
2911 if line.startswith( "name=" ):
2912 portVars = {}
2913 for var in line.split( "," ):
2914 key, value = var.split( "=" )
2915 portVars[ key ] = value
2916 isUp = portVars.pop( 'enabled', "True" )
2917 isUp = "True" in isUp
2918 if verbose:
2919 main.log.info( "Reading host port %s(%s)" %
2920 ( portVars[ 'name' ],
2921 portVars[ 'mac' ] ) )
2922 mac = portVars[ 'mac' ]
2923 if mac == 'None':
2924 mac = None
2925 ips = []
2926 ip = portVars[ 'ip' ]
2927 if ip == 'None':
2928 ip = None
2929 ips.append( ip )
2930 intfName = portVars[ 'name' ]
2931 if name == 'None':
2932 name = None
2933 interfaces.append( {
2934 "name": intfName,
2935 "ips": ips,
2936 "mac": str( mac ),
2937 "isUp": isUp } )
2938 hosts[ name ] = { "interfaces": interfaces }
2939 return hosts
2940 except pexpect.EOF:
2941 main.log.error( self.name + ": EOF exception found" )
2942 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002943 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002944 except Exception:
2945 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002946 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002947
Devin Lima7cfdbd2017-09-29 15:02:22 -07002948 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002949 """
2950 Gathers information about current Mininet links. These links may not
2951 be up if one of the ports is down.
2952
2953 Returns a list of dictionaries with link endpoints.
2954
2955 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002956 { 'node1': str( node1 name )
2957 'node2': str( node2 name )
2958 'port1': str( port1 of_port )
2959 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002960 Note: The port number returned is the eth#, not necessarily the of_port
2961 number. In Mininet, for OVS switch, these should be the same. For
2962 hosts, this is just the eth#.
2963 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002964 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002965 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002966 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07002967
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002968 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002969 # s1-eth3<->s2-eth1 (OK OK)
2970 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002971 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2972 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2973 links = []
2974 for line in response:
2975 match = re.search( linkRE, line )
2976 if match:
2977 node1 = match.group( 'node1' )
2978 node2 = match.group( 'node2' )
2979 port1 = match.group( 'port1' )
2980 port2 = match.group( 'port2' )
2981 links.append( { 'node1': node1,
2982 'node2': node2,
2983 'port1': port1,
2984 'port2': port2 } )
2985 return links
2986
2987 except pexpect.EOF:
2988 main.log.error( self.name + ": EOF exception found" )
2989 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002990 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002991 except Exception:
2992 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002993 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002994
2995 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002996 """
2997 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002998 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002999
Jon Hallafa8a472015-06-12 14:02:42 -07003000 Dependencies:
3001 1. numpy - "sudo pip install numpy"
3002 """
3003 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003004 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003005 try:
3006 mnDPIDs = []
3007 for swName, switch in switches.iteritems():
3008 mnDPIDs.append( switch[ 'dpid' ].lower() )
3009 mnDPIDs.sort()
3010 if switchesJson == "": # if rest call fails
3011 main.log.error(
3012 self.name +
3013 ".compareSwitches(): Empty JSON object given from ONOS" )
3014 return main.FALSE
3015 onos = switchesJson
3016 onosDPIDs = []
3017 for switch in onos:
3018 if switch[ 'available' ]:
3019 onosDPIDs.append(
3020 switch[ 'id' ].replace(
3021 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003022 '' ).replace(
3023 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003024 '' ).lower() )
3025 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003026
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003027 if mnDPIDs != onosDPIDs:
3028 switchResults = main.FALSE
3029 main.log.error( "Switches in MN but not in ONOS:" )
3030 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3031 main.log.error( str( list1 ) )
3032 main.log.error( "Switches in ONOS but not in MN:" )
3033 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3034 main.log.error( str( list2 ) )
3035 else: # list of dpid's match in onos and mn
3036 switchResults = main.TRUE
3037 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003038
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003039 # FIXME: this does not look for extra ports in ONOS, only checks that
3040 # ONOS has what is in MN
3041 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003042
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003043 # PORTS
3044 for name, mnSwitch in switches.iteritems():
3045 mnPorts = []
3046 onosPorts = []
3047 switchResult = main.TRUE
3048 for port in mnSwitch[ 'ports' ]:
3049 if port[ 'enabled' ]:
3050 mnPorts.append( int( port[ 'of_port' ] ) )
3051 for onosSwitch in portsJson:
3052 if onosSwitch[ 'device' ][ 'available' ]:
3053 if onosSwitch[ 'device' ][ 'id' ].replace(
3054 ':',
3055 '' ).replace(
3056 "of",
3057 '' ) == mnSwitch[ 'dpid' ]:
3058 for port in onosSwitch[ 'ports' ]:
3059 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003060 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003061 # onosPorts.append( 'local' )
3062 onosPorts.append( long( uint64( -2 ) ) )
3063 else:
3064 onosPorts.append( int( port[ 'port' ] ) )
3065 break
3066 mnPorts.sort( key=float )
3067 onosPorts.sort( key=float )
3068
3069 mnPortsLog = mnPorts
3070 onosPortsLog = onosPorts
3071 mnPorts = [ x for x in mnPorts ]
3072 onosPorts = [ x for x in onosPorts ]
3073
3074 # TODO: handle other reserved port numbers besides LOCAL
3075 # NOTE: Reserved ports
3076 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3077 # long( uint64( -2 ) )
3078 for mnPort in mnPortsLog:
3079 if mnPort in onosPorts:
3080 # don't set results to true here as this is just one of
3081 # many checks and it might override a failure
3082 mnPorts.remove( mnPort )
3083 onosPorts.remove( mnPort )
3084
3085 # NOTE: OVS reports this as down since there is no link
3086 # So ignoring these for now
3087 # TODO: Come up with a better way of handling these
3088 if 65534 in mnPorts:
3089 mnPorts.remove( 65534 )
3090 if long( uint64( -2 ) ) in onosPorts:
3091 onosPorts.remove( long( uint64( -2 ) ) )
3092 if len( mnPorts ): # the ports of this switch don't match
3093 switchResult = main.FALSE
3094 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3095 if len( onosPorts ): # the ports of this switch don't match
3096 switchResult = main.FALSE
3097 main.log.warn(
3098 "Ports in ONOS but not MN: " +
3099 str( onosPorts ) )
3100 if switchResult == main.FALSE:
3101 main.log.error(
3102 "The list of ports for switch %s(%s) does not match:" %
3103 ( name, mnSwitch[ 'dpid' ] ) )
3104 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3105 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3106 portsResults = portsResults and switchResult
3107 finalResults = finalResults and portsResults
3108 return finalResults
3109 except pexpect.EOF:
3110 main.log.error( self.name + ": EOF exception found" )
3111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003112 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003113 except Exception:
3114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003115 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003116
Jon Hallafa8a472015-06-12 14:02:42 -07003117 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003118 """
3119 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003121
Jon Hallafa8a472015-06-12 14:02:42 -07003122 """
Jon Hall7eb38402015-01-08 17:19:54 -08003123 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003124 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003125 try:
3126 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003127
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003128 mnLinks = []
3129 for l in links:
3130 try:
3131 node1 = switches[ l[ 'node1' ] ]
3132 node2 = switches[ l[ 'node2' ] ]
3133 enabled = True
3134 for port in node1[ 'ports' ]:
3135 if port[ 'of_port' ] == l[ 'port1' ]:
3136 enabled = enabled and port[ 'enabled' ]
3137 for port in node2[ 'ports' ]:
3138 if port[ 'of_port' ] == l[ 'port2' ]:
3139 enabled = enabled and port[ 'enabled' ]
3140 if enabled:
3141 mnLinks.append( l )
3142 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003143 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003144 if 2 * len( mnLinks ) == len( onos ):
3145 linkResults = main.TRUE
3146 else:
3147 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003148 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003149 "Mininet has " + str( len( mnLinks ) ) +
3150 " bidirectional links and ONOS has " +
3151 str( len( onos ) ) + " unidirectional links" )
3152
3153 # iterate through MN links and check if an ONOS link exists in
3154 # both directions
3155 for link in mnLinks:
3156 # TODO: Find a more efficient search method
3157 node1 = None
3158 port1 = None
3159 node2 = None
3160 port2 = None
3161 firstDir = main.FALSE
3162 secondDir = main.FALSE
3163 for swName, switch in switches.iteritems():
3164 if swName == link[ 'node1' ]:
3165 node1 = switch[ 'dpid' ]
3166 for port in switch[ 'ports' ]:
3167 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3168 port1 = port[ 'of_port' ]
3169 if node1 is not None and node2 is not None:
3170 break
3171 if swName == link[ 'node2' ]:
3172 node2 = switch[ 'dpid' ]
3173 for port in switch[ 'ports' ]:
3174 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3175 port2 = port[ 'of_port' ]
3176 if node1 is not None and node2 is not None:
3177 break
3178
3179 for onosLink in onos:
3180 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3181 ":", '' ).replace( "of", '' )
3182 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3183 ":", '' ).replace( "of", '' )
3184 onosPort1 = onosLink[ 'src' ][ 'port' ]
3185 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3186
3187 # check onos link from node1 to node2
3188 if str( onosNode1 ) == str( node1 ) and str(
3189 onosNode2 ) == str( node2 ):
3190 if int( onosPort1 ) == int( port1 ) and int(
3191 onosPort2 ) == int( port2 ):
3192 firstDir = main.TRUE
3193 else:
3194 main.log.warn(
3195 'The port numbers do not match for ' +
3196 str( link ) +
3197 ' between ONOS and MN. When checking ONOS for ' +
3198 'link %s/%s -> %s/%s' %
3199 ( node1, port1, node2, port2 ) +
3200 ' ONOS has the values %s/%s -> %s/%s' %
3201 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3202
3203 # check onos link from node2 to node1
3204 elif ( str( onosNode1 ) == str( node2 ) and
3205 str( onosNode2 ) == str( node1 ) ):
3206 if ( int( onosPort1 ) == int( port2 )
3207 and int( onosPort2 ) == int( port1 ) ):
3208 secondDir = main.TRUE
3209 else:
3210 main.log.warn(
3211 'The port numbers do not match for ' +
3212 str( link ) +
3213 ' between ONOS and MN. When checking ONOS for ' +
3214 'link %s/%s -> %s/%s' %
3215 ( node1, port1, node2, port2 ) +
3216 ' ONOS has the values %s/%s -> %s/%s' %
3217 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3218 else: # this is not the link you're looking for
3219 pass
3220 if not firstDir:
3221 main.log.error(
3222 'ONOS does not have the link %s/%s -> %s/%s' %
3223 ( node1, port1, node2, port2 ) )
3224 if not secondDir:
3225 main.log.error(
3226 'ONOS does not have the link %s/%s -> %s/%s' %
3227 ( node2, port2, node1, port1 ) )
3228 linkResults = linkResults and firstDir and secondDir
3229 return linkResults
3230 except pexpect.EOF:
3231 main.log.error( self.name + ": EOF exception found" )
3232 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003233 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003234 except Exception:
3235 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003236 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003237
Jon Hallafa8a472015-06-12 14:02:42 -07003238 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003239 """
Jon Hallafa8a472015-06-12 14:02:42 -07003240 Compare mn and onos Hosts.
3241 Since Mininet hosts are quiet, ONOS will only know of them when they
3242 speak. For this reason, we will only check that the hosts in ONOS
3243 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003244
Jon Hallafa8a472015-06-12 14:02:42 -07003245 Arguments:
3246 hostsJson: parsed json object from the onos hosts api
3247 Returns:
3248 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003249 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003250 try:
3251 hostResults = main.TRUE
3252 for onosHost in hostsJson:
3253 onosMAC = onosHost[ 'mac' ].lower()
3254 match = False
3255 for mnHost, info in hosts.iteritems():
3256 for mnIntf in info[ 'interfaces' ]:
3257 if onosMAC == mnIntf[ 'mac' ].lower():
3258 match = True
3259 for ip in mnIntf[ 'ips' ]:
3260 if ip in onosHost[ 'ipAddresses' ]:
3261 pass # all is well
3262 else:
3263 # misssing ip
3264 main.log.error( "ONOS host " +
3265 onosHost[ 'id' ] +
3266 " has a different IP(" +
3267 str( onosHost[ 'ipAddresses' ] ) +
3268 ") than the Mininet host(" +
3269 str( ip ) +
3270 ")." )
3271 output = json.dumps(
3272 onosHost,
3273 sort_keys=True,
3274 indent=4,
3275 separators=( ',', ': ' ) )
3276 main.log.info( output )
3277 hostResults = main.FALSE
3278 if not match:
3279 hostResults = main.FALSE
3280 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3281 "corresponding Mininet host." )
3282 output = json.dumps( onosHost,
3283 sort_keys=True,
3284 indent=4,
3285 separators=( ',', ': ' ) )
3286 main.log.info( output )
3287 return hostResults
3288 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003289 main.log.error( self.name + ": EOF exception found" )
3290 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003291 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003292 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003293 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003294 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003295
You Wang53dba1e2018-02-02 17:45:44 -08003296 def verifyHostIp( self, hostList=[], prefix="" ):
3297 """
3298 Description:
3299 Verify that all hosts have IP address assigned to them
3300 Optional:
3301 hostList: If specified, verifications only happen to the hosts
3302 in hostList
3303 prefix: at least one of the ip address assigned to the host
3304 needs to have the specified prefix
3305 Returns:
3306 main.TRUE if all hosts have specific IP address assigned;
3307 main.FALSE otherwise
3308 """
3309 try:
3310 hosts = self.getHosts()
3311 if not hostList:
3312 hostList = hosts.keys()
3313 for hostName in hosts.keys():
3314 if hostName not in hostList:
3315 continue
3316 ipList = []
3317 self.handle.sendline( str( hostName ) + " ip a" )
3318 self.handle.expect( "mininet>" )
3319 ipa = self.handle.before
3320 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3321 ipList += re.findall( ipv4Pattern, ipa )
3322 # It's tricky to make regex for IPv6 addresses and this one is simplified
3323 ipv6Pattern = r'inet6 ((?:[0-9a-fA-F]{1,4})?(?:[:0-9a-fA-F]{1,4}){1,7}(?:::)?(?:[:0-9a-fA-F]{1,4}){1,7})/'
3324 ipList += re.findall( ipv6Pattern, ipa )
3325 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3326 if not ipList:
3327 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3328 else:
3329 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3330 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3331 else:
3332 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3333 hostList.remove( hostName )
3334 return main.FALSE if hostList else main.TRUE
3335 except KeyError:
3336 main.log.exception( self.name + ": host data not as expected: " + hosts )
3337 return None
3338 except pexpect.EOF:
3339 main.log.error( self.name + ": EOF exception found" )
3340 main.log.error( self.name + ": " + self.handle.before )
3341 main.cleanAndExit()
3342 except Exception:
3343 main.log.exception( self.name + ": Uncaught exception" )
3344 return None
3345
Jon Hallafa8a472015-06-12 14:02:42 -07003346 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003347 """
3348 Returns a list of all hosts
3349 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003350 try:
3351 self.handle.sendline( "" )
3352 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003353
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003354 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3355 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003356
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003357 handlePy = self.handle.before
3358 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3359 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003360
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003361 self.handle.sendline( "" )
3362 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003363
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003364 hostStr = handlePy.replace( "]", "" )
3365 hostStr = hostStr.replace( "'", "" )
3366 hostStr = hostStr.replace( "[", "" )
3367 hostStr = hostStr.replace( " ", "" )
3368 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003369
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003370 return hostList
3371 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003372 main.log.error( self.name + ": TIMEOUT exception found" )
3373 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003374 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003375 except pexpect.EOF:
3376 main.log.error( self.name + ": EOF exception found" )
3377 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003378 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003379 except Exception:
3380 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003381 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003382
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003383 def getSwitch( self ):
3384 """
3385 Returns a list of all switches
3386 Again, don't ask question just use it...
3387 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003388 try:
3389 # get host list...
3390 hostList = self.getHosts()
3391 # Make host set
3392 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003393
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003394 # Getting all the nodes in mininet
3395 self.handle.sendline( "" )
3396 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003397
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003398 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3399 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003400
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003401 handlePy = self.handle.before
3402 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3403 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003404
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003405 self.handle.sendline( "" )
3406 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003407
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003408 nodesStr = handlePy.replace( "]", "" )
3409 nodesStr = nodesStr.replace( "'", "" )
3410 nodesStr = nodesStr.replace( "[", "" )
3411 nodesStr = nodesStr.replace( " ", "" )
3412 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003413
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003414 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003415 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003416 nodesSet.discard( 'c0' )
3417 nodesSet.discard( 'c1' )
3418 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003419
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003420 switchSet = nodesSet - hostSet
3421 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003422
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003423 return switchList
3424 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003425 main.log.error( self.name + ": TIMEOUT exception found" )
3426 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003427 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003428 except pexpect.EOF:
3429 main.log.error( self.name + ": EOF exception found" )
3430 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003431 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003432 except Exception:
3433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003434 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003435
You Wangdb8cd0a2016-05-26 15:19:45 -07003436 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3437 """
3438 Return a dictionary which describes the latest Mininet topology data as a
3439 graph.
3440 An example of the dictionary:
3441 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3442 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3443 Each vertex should at least have an 'edges' attribute which describes the
3444 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003445 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003446 list of attributes.
3447 An example of the edges dictionary:
3448 'edges': { vertex2: { 'port': ..., 'weight': ... },
3449 vertex3: { 'port': ..., 'weight': ... } }
3450 If useId == True, dpid/mac will be used instead of names to identify
3451 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3452 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003453 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003454 in topology data.
3455 Note that link or switch that are brought down by 'link x x down' or 'switch
3456 x down' commands still show in the output of Mininet CLI commands such as
3457 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3458 recommended to use delLink() or delSwitch functions to simulate link/switch
3459 down, and addLink() or addSwitch to add them back.
3460 """
3461 graphDict = {}
3462 try:
3463 links = self.getLinks( timeout=timeout )
3464 portDict = {}
3465 if useId:
3466 switches = self.getSwitches()
3467 if includeHost:
3468 hosts = self.getHosts()
3469 for link in links:
3470 # FIXME: support 'includeHost' argument
3471 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3472 continue
3473 nodeName1 = link[ 'node1' ]
3474 nodeName2 = link[ 'node2' ]
3475 port1 = link[ 'port1' ]
3476 port2 = link[ 'port2' ]
3477 # Loop for two nodes
3478 for i in range( 2 ):
3479 # Get port index from OVS
3480 # The index extracted from port name may be inconsistent with ONOS
3481 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003482 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003483 portList = self.getOVSPorts( nodeName1 )
3484 if len( portList ) == 0:
3485 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3486 return None
3487 portDict[ nodeName1 ] = portList
3488 for port in portDict[ nodeName1 ]:
3489 if port[ 'port' ] == port1:
3490 portIndex = port[ 'index' ]
3491 break
3492 if portIndex == -1:
3493 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3494 return None
3495 if useId:
3496 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3497 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3498 else:
3499 node1 = nodeName1
3500 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003501 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003502 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003503 graphDict[ node1 ] = { 'edges': {},
3504 'dpid': switches[ nodeName1 ][ 'dpid' ],
3505 'name': nodeName1,
3506 'ports': switches[ nodeName1 ][ 'ports' ],
3507 'swClass': switches[ nodeName1 ][ 'swClass' ],
3508 'pid': switches[ nodeName1 ][ 'pid' ],
3509 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003510 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003511 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003512 else:
3513 # Assert node2 is not connected to any current links of node1
3514 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003515 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003516 # Swap two nodes/ports
3517 nodeName1, nodeName2 = nodeName2, nodeName1
3518 port1, port2 = port2, port1
3519 return graphDict
3520 except KeyError:
3521 main.log.exception( self.name + ": KeyError exception found" )
3522 return None
3523 except AssertionError:
3524 main.log.exception( self.name + ": AssertionError exception found" )
3525 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003526 except pexpect.EOF:
3527 main.log.error( self.name + ": EOF exception found" )
3528 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003529 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003530 except Exception:
3531 main.log.exception( self.name + ": Uncaught exception" )
3532 return None
3533
Devin Lima7cfdbd2017-09-29 15:02:22 -07003534 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003535 """
3536 updates the port address and status information for
3537 each port in mn"""
3538 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003539 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003540 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003541 self.handle.sendline( "" )
3542 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003543
Jon Hall7eb38402015-01-08 17:19:54 -08003544 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003545 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003546
Jon Hall7eb38402015-01-08 17:19:54 -08003547 self.handle.sendline( "" )
3548 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003549
Jon Hallb1290e82014-11-18 16:17:48 -05003550 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003551 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003552 main.log.error( self.name + ": TIMEOUT exception found" )
3553 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003554 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003555 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003556 main.log.error( self.name + ": EOF exception found" )
3557 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003558 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003559 except Exception:
3560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003561 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003562
Jon Halld80cc142015-07-06 13:36:05 -07003563 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003564 """
3565 Add vlan tag to a host.
3566 Dependencies:
3567 This class depends on the "vlan" package
3568 $ sudo apt-get install vlan
3569 Configuration:
3570 Load the 8021q module into the kernel
3571 $sudo modprobe 8021q
3572
3573 To make this setup permanent:
3574 $ sudo su -c 'echo "8021q" >> /etc/modules'
3575 """
3576 if self.handle:
3577 try:
Jon Halld80cc142015-07-06 13:36:05 -07003578 # get the ip address of the host
3579 main.log.info( "Get the ip address of the host" )
3580 ipaddr = self.getIPAddress( host )
3581 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003582
Jon Halld80cc142015-07-06 13:36:05 -07003583 # remove IP from interface intf
3584 # Ex: h1 ifconfig h1-eth0 inet 0
3585 main.log.info( "Remove IP from interface " )
3586 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3587 self.handle.sendline( cmd2 )
3588 self.handle.expect( "mininet>" )
3589 response = self.handle.before
3590 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003591
Jon Halld80cc142015-07-06 13:36:05 -07003592 # create VLAN interface
3593 # Ex: h1 vconfig add h1-eth0 100
3594 main.log.info( "Create Vlan" )
3595 cmd3 = host + " vconfig add " + intf + " " + vlan
3596 self.handle.sendline( cmd3 )
3597 self.handle.expect( "mininet>" )
3598 response = self.handle.before
3599 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003600
Jon Halld80cc142015-07-06 13:36:05 -07003601 # assign the host's IP to the VLAN interface
3602 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3603 main.log.info( "Assign the host IP to the vlan interface" )
3604 vintf = intf + "." + vlan
3605 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3606 self.handle.sendline( cmd4 )
3607 self.handle.expect( "mininet>" )
3608 response = self.handle.before
3609 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003610
3611 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003612 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003613 main.log.error( self.name + ": TIMEOUT exception found" )
3614 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003615 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003616 except pexpect.EOF:
3617 main.log.error( self.name + ": EOF exception found" )
3618 main.log.error( self.name + ": " + self.handle.before )
3619 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003620 except Exception:
3621 main.log.exception( self.name + ": Uncaught exception!" )
3622 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003623
Jon Hall892818c2015-10-20 17:58:34 -07003624 def createHostComponent( self, name ):
3625 """
3626 Creates a new mininet cli component with the same parameters as self.
3627 This new component is intended to be used to login to the hosts created
3628 by mininet.
3629
3630 Arguments:
3631 name - The string of the name of this component. The new component
3632 will be assigned to main.<name> .
3633 In addition, main.<name>.name = str( name )
3634 """
3635 try:
3636 # look to see if this component already exists
3637 getattr( main, name )
3638 except AttributeError:
3639 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003640 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3641 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003642 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003643 except pexpect.EOF:
3644 main.log.error( self.name + ": EOF exception found" )
3645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003646 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003647 except Exception:
3648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003649 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003650 else:
3651 # namespace is not clear!
3652 main.log.error( name + " component already exists!" )
3653 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003654 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003655
3656 def removeHostComponent( self, name ):
3657 """
3658 Remove host component
3659 Arguments:
3660 name - The string of the name of the component to delete.
3661 """
3662 try:
3663 # Get host component
3664 component = getattr( main, name )
3665 except AttributeError:
3666 main.log.error( "Component " + name + " does not exist." )
3667 return
3668 try:
3669 # Disconnect from component
3670 component.disconnect()
3671 # Delete component
3672 delattr( main, name )
3673 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003674 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003675 except pexpect.EOF:
3676 main.log.error( self.name + ": EOF exception found" )
3677 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003678 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003679 except Exception:
3680 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003681 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003682
3683 def startHostCli( self, host=None ):
3684 """
3685 Use the mininet m utility to connect to the host's cli
3686 """
3687 # These are fields that can be used by scapy packets. Initialized to None
3688 self.hostIp = None
3689 self.hostMac = None
3690 try:
3691 if not host:
3692 host = self.name
3693 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003694 self.handle.sendline( "cd" )
3695 self.handle.expect( self.hostPrompt )
3696 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003697 self.handle.expect( self.hostPrompt )
3698 return main.TRUE
3699 except pexpect.TIMEOUT:
3700 main.log.exception( self.name + ": Command timed out" )
3701 return main.FALSE
3702 except pexpect.EOF:
3703 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003704 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003705 except Exception:
3706 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003707 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003708
YPZhang801d46d2016-08-08 13:26:28 -07003709 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003710 '''
3711
YPZhang801d46d2016-08-08 13:26:28 -07003712 Args:
3713 devicename: switch name
3714 intf: port name on switch
3715 status: up or down
3716
3717 Returns: boolean to show success change status
3718
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003719 '''
YPZhang801d46d2016-08-08 13:26:28 -07003720 if status == "down" or status == "up":
3721 try:
3722 cmd = devicename + " ifconfig " + intf + " " + status
3723 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003724 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003725 return main.TRUE
3726 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003727 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003728 return main.FALSE
3729 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003730 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003731 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003732 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003733 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003734 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003735 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003737 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003738 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003739 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003740 return main.FALSE
3741
3742
adminbae64d82013-08-01 10:50:15 -07003743if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003744 sys.modules[ __name__ ] = MininetCliDriver()