blob: d9b333afb7fa59896ab321ed6233122fb69dd6fe [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 ):
You Wangba231e72018-03-01 13:18:21 -0800528 pingResponse += " " + str( temp )
529 break
530 else:
531 failedPings += 1
532 time.sleep(1)
533 if failedPings > acceptableFailed:
534 # One of the host to host pair is unreachable
535 pingResponse += " X"
536 isReachable = main.FALSE
537 failedPingsTotal += 1
538 pingResponse += "\n"
539 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
540 return isReachable
541
542 except pexpect.TIMEOUT:
543 main.log.exception( self.name + ": TIMEOUT exception" )
544 return main.FALSE
545 except pexpect.EOF:
546 main.log.error( self.name + ": EOF exception found" )
547 main.log.error( self.name + ": " + self.handle.before )
548 main.cleanAndExit()
549 except Exception:
550 main.log.exception( self.name + ": Uncaught exception!" )
551 main.cleanAndExit()
552
553 def pingallHostsUnidirectional( self, srcList, dstList, ipv6=False, wait=1, acceptableFailed=0 ):
554 """
555 Verify ping from each host in srcList to each host in dstList
556
557 acceptableFailed: max number of acceptable failed pings
558
559 Returns main.TRUE if all src hosts can reach all dst hosts
560 Returns main.FALSE if one or more of src hosts cannot reach one or more of dst hosts
561 """
562 try:
563 main.log.info( "Verifying ping from each src host to each dst host" )
564 isReachable = main.TRUE
565 wait = int( wait )
566 cmd = " ping" + ("6" if ipv6 else "") + " -c 1 -i 1 -W " + str( wait ) + " "
567 pingResponse = "Ping output:\n"
568 failedPingsTotal = 0
569 for host in srcList:
570 pingResponse += str( str( host ) + " -> " )
571 for temp in dstList:
572 failedPings = 0
573 if ipv6:
574 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
575 else:
576 pingCmd = str( host ) + cmd + str( temp )
577 while failedPings <= acceptableFailed:
578 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
579 self.handle.sendline( pingCmd )
580 self.handle.expect( "mininet>", timeout=wait + 1 )
581 response = self.handle.before
582 if re.search( ',\s0\%\spacket\sloss', response ):
583 pingResponse += " " + str( temp )
You Wangf19d9f42018-02-23 16:34:19 -0800584 break
585 else:
586 failedPings += 1
587 time.sleep(1)
588 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700589 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800590 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700591 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800592 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700593 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800594 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700595 return isReachable
596
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700597 except pexpect.TIMEOUT:
598 main.log.exception( self.name + ": TIMEOUT exception" )
599 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700600 except pexpect.EOF:
601 main.log.error( self.name + ": EOF exception found" )
602 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700603 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700604 except Exception:
605 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700606 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700607
Jon Hall7eb38402015-01-08 17:19:54 -0800608 def pingHost( self, **pingParams ):
609 """
Jon Hall3b489db2015-10-05 14:38:37 -0700610 Ping from one mininet host to another
611 Currently the only supported Params: SRC, TARGET, and WAIT
612 """
613 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700614 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700615 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800616 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700617 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700618 try:
Jon Hall61282e32015-03-19 11:34:11 -0700619 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800620 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700621 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
622 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700623 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800624 main.log.error(
625 self.name +
626 ": timeout when waiting for response from mininet" )
627 main.log.error( "response: " + str( self.handle.before ) )
628 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700629 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800630 main.log.error(
631 self.name +
632 ": timeout when waiting for response from mininet" )
633 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700634 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700635 if re.search( ',\s0\%\spacket\sloss', response ):
636 main.log.info( self.name + ": no packets lost, host is reachable" )
637 return main.TRUE
638 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800639 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700640 self.name +
641 ": PACKET LOST, HOST IS NOT REACHABLE" )
642 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800643 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700646 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700647 except Exception:
648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700650
651 def ping6pair( self, **pingParams ):
652 """
GlennRC2cf7d952015-09-11 16:32:13 -0700653 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700654 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000655 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700656 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
657 """
Jon Hall3b489db2015-10-05 14:38:37 -0700658 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700659 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700660 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530661 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700662 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700663 try:
664 main.log.info( "Sending: " + command )
665 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700666 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
667 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700668 if i == 1:
669 main.log.error(
670 self.name +
671 ": timeout when waiting for response from mininet" )
672 main.log.error( "response: " + str( self.handle.before ) )
673 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
674 if i == 1:
675 main.log.error(
676 self.name +
677 ": timeout when waiting for response from mininet" )
678 main.log.error( "response: " + str( self.handle.before ) )
679 response = self.handle.before
680 main.log.info( self.name + ": Ping Response: " + response )
681 if re.search( ',\s0\%\spacket\sloss', response ):
682 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700683 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700684 else:
alisone4121a92016-11-22 16:31:36 -0800685 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700686 self.name +
687 ": PACKET LOST, HOST IS NOT REACHABLE" )
688 return main.FALSE
689
690 except pexpect.EOF:
691 main.log.error( self.name + ": EOF exception found" )
692 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700693 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700694 except Exception:
695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700696 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800697
You Wangdb927a52016-02-26 11:03:28 -0800698 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
699 """
700 Description:
701 Ping a set of destination host from host CLI.
702 Logging into a Mininet host CLI is required before calling this funtion.
703 Params:
704 dstIPList is a list of destination ip addresses
705 Returns:
706 main.TRUE if the destination host is reachable
707 main.FALSE otherwise
708 """
709 isReachable = main.TRUE
710 wait = int( wait )
711 cmd = "ping"
712 if IPv6:
713 cmd = cmd + "6"
714 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
715 try:
716 for dstIP in dstIPList:
717 pingCmd = cmd + " " + dstIP
718 self.handle.sendline( pingCmd )
719 i = self.handle.expect( [ self.hostPrompt,
720 '\*\*\* Unknown command: ' + pingCmd,
721 pexpect.TIMEOUT ],
722 timeout=wait + 1 )
723 if i == 0:
724 response = self.handle.before
725 if not re.search( ',\s0\%\spacket\sloss', response ):
726 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
727 isReachable = main.FALSE
728 elif i == 1:
729 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700730 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800731 elif i == 2:
732 main.log.error( self.name + ": timeout when waiting for response" )
733 isReachable = main.FALSE
734 else:
735 main.log.error( self.name + ": unknown response: " + self.handle.before )
736 isReachable = main.FALSE
737 except pexpect.TIMEOUT:
738 main.log.exception( self.name + ": TIMEOUT exception" )
739 isReachable = main.FALSE
740 except pexpect.EOF:
741 main.log.error( self.name + ": EOF exception found" )
742 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700743 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800744 except Exception:
745 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700746 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800747 return isReachable
748
Jon Hall7eb38402015-01-08 17:19:54 -0800749 def checkIP( self, host ):
750 """
751 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700752 try:
753 if self.handle:
754 try:
755 response = self.execute(
756 cmd=host +
757 " ifconfig",
758 prompt="mininet>",
759 timeout=10 )
760 except pexpect.EOF:
761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700763 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700764
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700765 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
766 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
767 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
768 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
769 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
770 "[0-9]|25[0-5]|[0-9]{1,2})"
771 # pattern = "inet addr:10.0.0.6"
772 if re.search( pattern, response ):
773 main.log.info( self.name + ": Host Ip configured properly" )
774 return main.TRUE
775 else:
776 main.log.error( self.name + ": Host IP not found" )
777 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700778 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700779 main.log.error( self.name + ": Connection failed to the host" )
780 except Exception:
781 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700782 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800783
Jon Hall7eb38402015-01-08 17:19:54 -0800784 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800785 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700786 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800787 response = self.execute(
788 cmd="h1 /usr/sbin/sshd -D&",
789 prompt="mininet>",
790 timeout=10 )
791 response = self.execute(
792 cmd="h4 /usr/sbin/sshd -D&",
793 prompt="mininet>",
794 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700795 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800796 vars( self )[ key ] = connectargs[ key ]
797 response = self.execute(
798 cmd="xterm h1 h4 ",
799 prompt="mininet>",
800 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800801 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800802 main.log.error( self.name + ": EOF exception found" )
803 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700804 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700805 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800806 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700807 if self.flag == 0:
808 self.flag = 1
809 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800810 else:
adminbae64d82013-08-01 10:50:15 -0700811 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800812
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700813 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700814 """
815 Moves a host from one switch to another on the fly
816 Note: The intf between host and oldSw when detached
817 using detach(), will still show up in the 'net'
818 cmd, because switch.detach() doesn't affect switch.intfs[]
819 ( which is correct behavior since the interfaces
820 haven't moved ).
821 """
822 if self.handle:
823 try:
824 # Bring link between oldSw-host down
825 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
826 "'," + "'down')"
827 print "cmd1= ", cmd
828 response = self.execute( cmd=cmd,
829 prompt="mininet>",
830 timeout=10 )
831
832 # Determine hostintf and Oldswitchintf
833 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
834 ")[0]"
835 print "cmd2= ", cmd
836 self.handle.sendline( cmd )
837 self.handle.expect( "mininet>" )
838
839 # Determine ip and mac address of the host-oldSw interface
840 cmd = "px ipaddr = hintf.IP()"
841 print "cmd3= ", cmd
842 self.handle.sendline( cmd )
843 self.handle.expect( "mininet>" )
844
845 cmd = "px macaddr = hintf.MAC()"
846 print "cmd3= ", cmd
847 self.handle.sendline( cmd )
848 self.handle.expect( "mininet>" )
849
850 # Detach interface between oldSw-host
851 cmd = "px " + oldSw + ".detach( sintf )"
852 print "cmd4= ", cmd
853 self.handle.sendline( cmd )
854 self.handle.expect( "mininet>" )
855
856 # Add link between host-newSw
857 cmd = "py net.addLink(" + host + "," + newSw + ")"
858 print "cmd5= ", cmd
859 self.handle.sendline( cmd )
860 self.handle.expect( "mininet>" )
861
862 # Determine hostintf and Newswitchintf
863 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
864 ")[0]"
865 print "cmd6= ", cmd
866 self.handle.sendline( cmd )
867 self.handle.expect( "mininet>" )
868
869 # Attach interface between newSw-host
870 cmd = "px " + newSw + ".attach( sintf )"
871 print "cmd3= ", cmd
872 self.handle.sendline( cmd )
873 self.handle.expect( "mininet>" )
874
875 # Set ipaddress of the host-newSw interface
876 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
877 print "cmd7 = ", cmd
878 self.handle.sendline( cmd )
879 self.handle.expect( "mininet>" )
880
881 # Set macaddress of the host-newSw interface
882 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
883 print "cmd8 = ", cmd
884 self.handle.sendline( cmd )
885 self.handle.expect( "mininet>" )
886
887 cmd = "net"
888 print "cmd9 = ", cmd
889 self.handle.sendline( cmd )
890 self.handle.expect( "mininet>" )
891 print "output = ", self.handle.before
892
893 # Determine ipaddress of the host-newSw interface
894 cmd = host + " ifconfig"
895 print "cmd10= ", cmd
896 self.handle.sendline( cmd )
897 self.handle.expect( "mininet>" )
898 print "ifconfig o/p = ", self.handle.before
899
900 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700901
902 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700903 main.log.error( self.name + ": TIMEOUT exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700906 except pexpect.EOF:
907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
909 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700910 except Exception:
911 main.log.exception( self.name + ": Uncaught exception!" )
912 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700913
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700914 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800915 """
916 Moves a host from one switch to another on the fly
917 Note: The intf between host and oldSw when detached
918 using detach(), will still show up in the 'net'
919 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700920 ( which is correct behavior since the interfaces
921 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800922 """
923 if self.handle:
924 try:
Jon Hall439c8912016-04-15 02:22:03 -0700925 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800926 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700927 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800928 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800929 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800930 response = self.execute( cmd=cmd,
931 prompt="mininet>",
932 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700933
kelvin-onlaba1484582015-02-02 15:46:20 -0800934 # Determine hostintf and Oldswitchintf
935 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800936 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800937 print "cmd2= ", cmd
938 self.handle.sendline( cmd )
939 self.handle.expect( "mininet>" )
940
shahshreya73537862015-02-11 15:15:24 -0800941 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700942 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800943 print "cmd3= ", cmd
944 self.handle.sendline( cmd )
945 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800946
947 cmd = "px macaddr = hintf.MAC()"
948 print "cmd3= ", cmd
949 self.handle.sendline( cmd )
950 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700951
kelvin-onlaba1484582015-02-02 15:46:20 -0800952 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700953 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800954 print "cmd4= ", cmd
955 self.handle.sendline( cmd )
956 self.handle.expect( "mininet>" )
957
958 # Add link between host-newSw
959 cmd = "py net.addLink(" + host + "," + newSw + ")"
960 print "cmd5= ", cmd
961 self.handle.sendline( cmd )
962 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700963
kelvin-onlaba1484582015-02-02 15:46:20 -0800964 # Determine hostintf and Newswitchintf
965 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800966 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800967 print "cmd6= ", cmd
968 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700969 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800970
971 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700972 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700973 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800974 self.handle.sendline( cmd )
975 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800976
977 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700978 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700979 print "cmd7 = ", cmd
980 self.handle.sendline( cmd )
981 self.handle.expect( "mininet>" )
982
983 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700984 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800985 print "cmd8 = ", cmd
986 self.handle.sendline( cmd )
987 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700988
Jon Hall439c8912016-04-15 02:22:03 -0700989 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700990 print "cmd9 =", cmd
991 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -0700992 print response
993 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700994 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700995 print ipAddressSearch.group( 1 )
996 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -0700997 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
998 print "cmd10 = ", cmd
999 self.handle.sendline( cmd )
1000 self.handle.expect( "mininet>" )
1001
kelvin-onlaba1484582015-02-02 15:46:20 -08001002 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -07001003 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001004 self.handle.sendline( cmd )
1005 self.handle.expect( "mininet>" )
1006 print "output = ", self.handle.before
1007
1008 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -08001009 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -07001010 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001011 self.handle.sendline( cmd )
1012 self.handle.expect( "mininet>" )
1013 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -07001014
kelvin-onlaba1484582015-02-02 15:46:20 -08001015 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001016 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001017 main.log.error( self.name + ": TIMEOUT exception found" )
1018 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001019 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08001020 except pexpect.EOF:
1021 main.log.error( self.name + ": EOF exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
1023 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001024 except Exception:
1025 main.log.exception( self.name + ": Uncaught exception!" )
1026 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -08001027
Jon Hall7eb38402015-01-08 17:19:54 -08001028 def changeIP( self, host, intf, newIP, newNetmask ):
1029 """
1030 Changes the ip address of a host on the fly
1031 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001032 if self.handle:
1033 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001034 cmd = host + " ifconfig " + intf + " " + \
1035 newIP + " " + 'netmask' + " " + newNetmask
1036 self.handle.sendline( cmd )
1037 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001038 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001039 main.log.info( "response = " + response )
1040 main.log.info(
1041 "Ip of host " +
1042 host +
1043 " changed to new IP " +
1044 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001045 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001046 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001047 main.log.error( self.name + ": TIMEOUT exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001049 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001050 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001051 main.log.error( self.name + ": EOF exception found" )
1052 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001053 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001054 except Exception:
1055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001056 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001057
Jon Hall7eb38402015-01-08 17:19:54 -08001058 def changeDefaultGateway( self, host, newGW ):
1059 """
1060 Changes the default gateway of a host
1061 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001062 if self.handle:
1063 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001064 cmd = host + " route add default gw " + newGW
1065 self.handle.sendline( cmd )
1066 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001067 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001068 main.log.info( "response = " + response )
1069 main.log.info(
1070 "Default gateway of host " +
1071 host +
1072 " changed to " +
1073 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001074 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001075 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001076 main.log.error( self.name + ": TIMEOUT exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001078 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001079 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001080 main.log.error( self.name + ": EOF exception found" )
1081 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001082 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001083 except Exception:
1084 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001085 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001086
Jon Hall7eb38402015-01-08 17:19:54 -08001087 def addStaticMACAddress( self, host, GW, macaddr ):
1088 """
Jon Hallefbd9792015-03-05 16:11:36 -08001089 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001090 if self.handle:
1091 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001092 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1093 cmd = host + " arp -s " + GW + " " + macaddr
1094 self.handle.sendline( cmd )
1095 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001096 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001097 main.log.info( "response = " + response )
1098 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001099 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001100 GW +
1101 " changed to " +
1102 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001103 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001104 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001105 main.log.error( self.name + ": TIMEOUT exception found" )
1106 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001107 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001108 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001109 main.log.error( self.name + ": EOF exception found" )
1110 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001111 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001112 except Exception:
1113 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001114 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001115
Jon Hall7eb38402015-01-08 17:19:54 -08001116 def verifyStaticGWandMAC( self, host ):
1117 """
1118 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001119 if self.handle:
1120 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001121 # h1 arp -an
1122 cmd = host + " arp -an "
1123 self.handle.sendline( cmd )
1124 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001125 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001126 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001127 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001128 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001129 main.log.error( self.name + ": TIMEOUT exception found" )
1130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001131 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001132 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 main.log.error( self.name + ": EOF exception found" )
1134 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001135 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001136 except Exception:
1137 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001138 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001139
Jon Hall7eb38402015-01-08 17:19:54 -08001140 def getMacAddress( self, host ):
1141 """
1142 Verifies the host's ip configured or not."""
1143 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001144 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001145 response = self.execute(
1146 cmd=host +
1147 " ifconfig",
1148 prompt="mininet>",
1149 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001150 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001151 main.log.error( self.name + ": EOF exception found" )
1152 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001153 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001154 except Exception:
1155 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001156 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001157
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001158 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 macAddressSearch = re.search( pattern, response, re.I )
1160 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001161 main.log.info(
1162 self.name +
1163 ": Mac-Address of Host " +
1164 host +
1165 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 macAddress )
1167 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001168 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001169 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001170
Jon Hall7eb38402015-01-08 17:19:54 -08001171 def getInterfaceMACAddress( self, host, interface ):
1172 """
1173 Return the IP address of the interface on the given host"""
1174 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001175 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001176 response = self.execute( cmd=host + " ifconfig " + interface,
1177 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001178 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001179 main.log.error( self.name + ": EOF exception found" )
1180 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001181 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001182 except Exception:
1183 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001184 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001185
1186 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001187 macAddressSearch = re.search( pattern, response, re.I )
1188 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001189 main.log.info( "No mac address found in %s" % response )
1190 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001192 main.log.info(
1193 "Mac-Address of " +
1194 host +
1195 ":" +
1196 interface +
1197 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 macAddress )
1199 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001200 else:
1201 main.log.error( "Connection failed to the host" )
1202
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001203 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001204 """
1205 Verifies the host's ip configured or not."""
1206 if self.handle:
1207 try:
1208 response = self.execute(
1209 cmd=host +
1210 " ifconfig",
1211 prompt="mininet>",
1212 timeout=10 )
1213 except pexpect.EOF:
1214 main.log.error( self.name + ": EOF exception found" )
1215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001216 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001217 except Exception:
1218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001219 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001220
sathishmad953462015-12-03 17:42:07 +05301221 pattern = ''
1222 if proto == 'IPV4':
1223 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1224 else:
Jon Hall439c8912016-04-15 02:22:03 -07001225 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001227 main.log.info(
1228 self.name +
1229 ": IP-Address of Host " +
1230 host +
1231 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 ipAddressSearch.group( 1 ) )
1233 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001234 else:
1235 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001236
Jon Hall7eb38402015-01-08 17:19:54 -08001237 def getSwitchDPID( self, switch ):
1238 """
1239 return the datapath ID of the switch"""
1240 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001241 cmd = "py %s.dpid" % switch
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()
Jon Hall28bf54b2014-12-17 16:25:44 -08001254 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001255 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001256 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001257 main.log.info(
1258 "Couldn't find DPID for switch %s, found: %s" %
1259 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001260 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001261 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001262 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001263 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001264
Jon Hall7eb38402015-01-08 17:19:54 -08001265 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001266 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001267 self.handle.sendline( "" )
1268 self.expect( "mininet>" )
1269 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001270 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001271 response = self.execute(
1272 cmd=cmd,
1273 prompt="mininet>",
1274 timeout=10 )
1275 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001276 response = self.handle.before
1277 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001278 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001279 main.log.error( self.name + ": TIMEOUT exception found" )
1280 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001281 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001282 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001283 main.log.error( self.name + ": EOF exception found" )
1284 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001285 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001286 except Exception:
1287 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001288 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001289
Jon Hall7eb38402015-01-08 17:19:54 -08001290 def getInterfaces( self, node ):
1291 """
1292 return information dict about interfaces connected to the node"""
1293 if self.handle:
1294 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001295 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001296 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001297 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001298 response = self.execute(
1299 cmd=cmd,
1300 prompt="mininet>",
1301 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001302 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001303 main.log.error( self.name + ": EOF exception found" )
1304 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001305 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001306 except Exception:
1307 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001308 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001309 return response
1310 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001311 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001312
Jon Hall7eb38402015-01-08 17:19:54 -08001313 def dump( self ):
1314 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001315 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001316 response = self.execute(
1317 cmd='dump',
1318 prompt='mininet>',
1319 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001320 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001321 main.log.error( self.name + ": EOF exception found" )
1322 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001323 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001324 except Exception:
1325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001326 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001327 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001328
Jon Hall7eb38402015-01-08 17:19:54 -08001329 def intfs( self ):
1330 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001331 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001332 response = self.execute(
1333 cmd='intfs',
1334 prompt='mininet>',
1335 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001336 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001337 main.log.error( self.name + ": EOF exception found" )
1338 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001339 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001340 except Exception:
1341 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001342 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001343 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001344
Jon Hall7eb38402015-01-08 17:19:54 -08001345 def net( self ):
1346 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001347 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001348 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001349 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 main.log.error( self.name + ": EOF exception found" )
1351 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001352 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001353 except Exception:
1354 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001355 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001356 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001357
Devin Lima7cfdbd2017-09-29 15:02:22 -07001358 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001359 main.log.info( self.name + ": List network links" )
1360 try:
1361 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001362 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001363 except pexpect.EOF:
1364 main.log.error( self.name + ": EOF exception found" )
1365 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001366 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001367 except Exception:
1368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001369 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001370 return response
1371
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001372 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001373 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001374 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001375
kelvin-onlab7cce9382015-07-17 10:21:03 -07001376 @parm:
1377 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1378 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001379 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001380 try:
1381 for host1 in hosts:
1382 for host2 in hosts:
1383 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001384 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1385 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001386 except Exception:
1387 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001388 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001389
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001390 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001391 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001392 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1393 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001394
kelvin-onlab7cce9382015-07-17 10:21:03 -07001395 @parm:
1396 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1397 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001398 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001399 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1400 try:
1401 # Setup the mininet command
1402 cmd1 = 'iperf ' + host1 + " " + host2
1403 self.handle.sendline( cmd1 )
1404 outcome = self.handle.expect( "mininet>", timeout )
1405 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001406
kelvin-onlab7cce9382015-07-17 10:21:03 -07001407 # checks if there are results in the mininet response
1408 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001409 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001410 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001411 response = response.split( "\r\n" )
1412 response = response[ len( response )-2 ]
1413 response = response.split( ": " )
1414 response = response[ len( response )-1 ]
1415 response = response.replace( "[", "" )
1416 response = response.replace( "]", "" )
1417 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001418
kelvin-onlab7cce9382015-07-17 10:21:03 -07001419 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001420 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001421
kelvin-onlab7cce9382015-07-17 10:21:03 -07001422 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001423 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001424 if len( bandwidth ) == 2:
1425 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001426 return main.TRUE
1427 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001428 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001429 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001430 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001431 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001432 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001433 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001434 main.log.error( self.name + ": TIMEOUT exception found" )
1435 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001436 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001437 # NOTE: Send ctrl-c to make sure iperf is done
1438 self.handle.sendline( "\x03" )
1439 self.handle.expect( "Interrupt" )
1440 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001441 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001442 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001443 main.log.error( self.name + ": EOF exception found" )
1444 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001445 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001446 except Exception:
1447 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001448 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001449
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001450 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001451 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1452 try:
1453 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001454 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001455 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001456 outcome1 = self.handle.expect( "mininet>" )
1457 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001458 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001459 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001460 response1 = self.handle.before
1461 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001462 print response1, response2
1463 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001464 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001465 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001466 return main.TRUE
1467 else:
1468 main.log.error( self.name + ": iperf test failed" )
1469 return main.FALSE
1470 except pexpect.TIMEOUT:
1471 main.log.error( self.name + ": TIMEOUT exception found" )
1472 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1473 self.handle.sendline( "\x03" )
1474 self.handle.expect( "Interrupt" )
1475 self.handle.expect( "mininet>" )
1476 return main.FALSE
1477 except pexpect.EOF:
1478 main.log.error( self.name + ": EOF exception found" )
1479 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001480 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001481 except Exception:
1482 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001483 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001484
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001485 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001486 '''
GlennRC61321f22015-07-16 13:36:54 -07001487 Runs the iperfudp function with a given set of hosts and specified
1488 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001489
GlennRC61321f22015-07-16 13:36:54 -07001490 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001491 bandwidth: the targeted bandwidth, in megabits ('M')
1492 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001493 try:
1494 for host1 in hosts:
1495 for host2 in hosts:
1496 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001497 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1498 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001499 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001500 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001501 return main.FALSE
1502 except Exception:
1503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001504 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001505
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001506 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001507 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001508 Creates an iperf UDP test with a specific bandwidth.
1509 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001510
kelvin-onlab7cce9382015-07-17 10:21:03 -07001511 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001512 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1513 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001514 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001515 try:
1516 # setup the mininet command
1517 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001518 self.handle.sendline( cmd )
1519 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001520 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001521
kelvin-onlab7cce9382015-07-17 10:21:03 -07001522 # check if there are in results in the mininet response
1523 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001524 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001525 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001526 response = response.split( "\r\n" )
1527 response = response[ len( response )-2 ]
1528 response = response.split( ": " )
1529 response = response[ len( response )-1 ]
1530 response = response.replace( "[", "" )
1531 response = response.replace( "]", "" )
1532 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001533
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001534 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001535
kelvin-onlab7cce9382015-07-17 10:21:03 -07001536 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001537 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001538 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001539 # if one entry is blank then something is wrong
1540 for item in mnBandwidth:
1541 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001542 main.log.error( self.name + ": Could not parse iperf output" )
1543 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001544 return main.FALSE
1545 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001546 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001547 return main.TRUE
1548 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001549 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001550 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001551
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001552 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001553 main.log.error( self.name + ": TIMEOUT exception found" )
1554 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001555 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001556 except pexpect.EOF:
1557 main.log.error( self.name + ": EOF exception found" )
1558 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001559 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001560 except Exception:
1561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001562 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001563
Jon Hall7eb38402015-01-08 17:19:54 -08001564 def nodes( self ):
1565 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001566 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001567 response = self.execute(
1568 cmd='nodes',
1569 prompt='mininet>',
1570 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001571 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001572 main.log.error( self.name + ": EOF exception found" )
1573 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001574 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001575 except Exception:
1576 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001577 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001578 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001579
Jon Hall7eb38402015-01-08 17:19:54 -08001580 def pingpair( self ):
1581 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001582 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001583 response = self.execute(
1584 cmd='pingpair',
1585 prompt='mininet>',
1586 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001587 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001588 main.log.error( self.name + ": EOF exception found" )
1589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001590 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001591 except Exception:
1592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001593 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001594
Jon Hall7eb38402015-01-08 17:19:54 -08001595 if re.search( ',\s0\%\spacket\sloss', response ):
1596 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001597 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001598 else:
alisone4121a92016-11-22 16:31:36 -08001599 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001600 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001601
Jon Hall7eb38402015-01-08 17:19:54 -08001602 def link( self, **linkargs ):
1603 """
GlennRCed771242016-01-13 17:02:47 -08001604 Bring link( s ) between two nodes up or down
1605 """
Jon Hall6094a362014-04-11 14:46:56 -07001606 try:
GlennRCed771242016-01-13 17:02:47 -08001607 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1608 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1609 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1610 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1611
1612 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1613 cmd = "link {} {} {}".format( end1, end2, option )
1614 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001615 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001616 response = self.handle.before
1617 main.log.info( response )
1618
1619 return main.TRUE
1620 except pexpect.TIMEOUT:
1621 main.log.exception( self.name + ": Command timed out" )
1622 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001623 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001624 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001625 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001626 except Exception:
1627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001628 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001629
pingping-lin8244a3b2015-09-16 13:36:56 -07001630 def switch( self, **switchargs ):
1631 """
1632 start/stop a switch
1633 """
1634 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1635 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1636 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1637 command = "switch " + str( sw ) + " " + str( option )
1638 main.log.info( command )
1639 try:
1640 self.handle.sendline( command )
1641 self.handle.expect( "mininet>" )
1642 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001643 main.log.error( self.name + ": TIMEOUT exception found" )
1644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001645 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001646 except pexpect.EOF:
1647 main.log.error( self.name + ": EOF exception found" )
1648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001649 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001650 return main.TRUE
1651
pingping-lin5bb663b2015-09-24 11:47:50 -07001652 def node( self, nodeName, commandStr ):
1653 """
1654 Carry out a command line on a given node
1655 @parm:
1656 nodeName: the node name in Mininet testbed
1657 commandStr: the command line will be carried out on the node
1658 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1659 """
1660 command = str( nodeName ) + " " + str( commandStr )
1661 main.log.info( command )
1662
1663 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001664 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001665 if re.search( "Unknown command", response ):
1666 main.log.warn( response )
1667 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001668 if re.search( "Permission denied", response ):
1669 main.log.warn( response )
1670 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001671 except pexpect.EOF:
1672 main.log.error( self.name + ": EOF exception found" )
1673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001674 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001675 main.log.info( " response is :" )
1676 main.log.info( response )
1677 return response
1678
Jon Hall7eb38402015-01-08 17:19:54 -08001679 def yank( self, **yankargs ):
1680 """
1681 yank a mininet switch interface to a host"""
1682 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001683 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001684 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1685 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001686 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001687 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001688 response = self.execute(
1689 cmd=command,
1690 prompt="mininet>",
1691 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001692 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001693 main.log.error( self.name + ": EOF exception found" )
1694 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001695 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001696 except Exception:
1697 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001698 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001699 return main.TRUE
1700
Jon Hall7eb38402015-01-08 17:19:54 -08001701 def plug( self, **plugargs ):
1702 """
1703 plug the yanked mininet switch interface to a switch"""
1704 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001705 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001706 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1707 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001708 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001709 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001710 response = self.execute(
1711 cmd=command,
1712 prompt="mininet>",
1713 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001714 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001715 main.log.error( self.name + ": EOF exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001717 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001718 except Exception:
1719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001720 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001721 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001722
Jon Hall7eb38402015-01-08 17:19:54 -08001723 def dpctl( self, **dpctlargs ):
1724 """
1725 Run dpctl command on all switches."""
1726 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001727 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001728 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1729 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1730 command = "dpctl " + cmd + " " + str( cmdargs )
1731 try:
1732 response = self.execute(
1733 cmd=command,
1734 prompt="mininet>",
1735 timeout=10 )
1736 except pexpect.EOF:
1737 main.log.error( self.name + ": EOF exception found" )
1738 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001739 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001740 except Exception:
1741 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001742 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001743 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001744
kelvin-onlabd3b64892015-01-20 13:26:24 -08001745 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001746 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001747 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001748 try:
1749 fileInput = path + '/lib/Mininet/INSTALL'
1750 version = super( Mininet, self ).getVersion()
1751 pattern = 'Mininet\s\w\.\w\.\w\w*'
1752 for line in open( fileInput, 'r' ).readlines():
1753 result = re.match( pattern, line )
1754 if result:
1755 version = result.group( 0 )
1756 return version
1757 except Exception:
1758 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001759 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001760
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001762 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001763 Parameters:
1764 sw: The name of an OVS switch. Example "s1"
1765 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001766 The output of the command from the mininet cli
1767 or main.FALSE on timeout"""
1768 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001769 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001770 response = self.execute(
1771 cmd=command,
1772 prompt="mininet>",
1773 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001774 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001775 return response
admin2a9548d2014-06-17 14:08:07 -07001776 else:
1777 return main.FALSE
1778 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001779 main.log.error( self.name + ": EOF exception found" )
1780 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001781 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001782 except Exception:
1783 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001784 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001785
Charles Chan029be652015-08-24 01:46:10 +08001786 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001787 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001788 Description:
1789 Assign switches to the controllers ( for ovs use only )
1790 Required:
1791 sw - Name of the switch. This can be a list or a string.
1792 ip - Ip addresses of controllers. This can be a list or a string.
1793 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001794 port - ONOS use port 6653, if no list of ports is passed, then
1795 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001796 ptcp - ptcp number, This can be a string or a list that has
1797 the same length as switch. This is optional and not required
1798 when using ovs switches.
1799 NOTE: If switches and ptcp are given in a list type they should have the
1800 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1801 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001802
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001803 Return:
1804 Returns main.TRUE if mininet correctly assigned switches to
1805 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001806 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001807 """
1808 assignResult = main.TRUE
1809 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001810 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001811 command = "sh ovs-vsctl set-controller "
1812 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001813 try:
1814 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001815 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001816 if isinstance( port, types.StringType ) or \
1817 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001818 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001819 elif isinstance( port, types.ListType ):
1820 main.log.error( self.name + ": Only one controller " +
1821 "assigned and a list of ports has" +
1822 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001823 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001824 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001825 main.log.error( self.name + ": Invalid controller port " +
1826 "number. Please specify correct " +
1827 "controller port" )
1828 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001829
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001830 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001831 if isinstance( port, types.StringType ) or \
1832 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001833 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001834 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1835 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001836 elif isinstance( port, types.ListType ):
1837 if ( len( ip ) != len( port ) ):
1838 main.log.error( self.name + ": Port list = " +
1839 str( len( port ) ) +
1840 "should be the same as controller" +
1841 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001842 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001843 else:
1844 onosIp = ""
1845 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001846 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1847 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001848 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001849 main.log.error( self.name + ": Invalid controller port " +
1850 "number. Please specify correct " +
1851 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001852 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001853 else:
1854 main.log.error( self.name + ": Invalid ip address" )
1855 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001856
1857 if isinstance( sw, types.StringType ):
1858 command += sw + " "
1859 if ptcp:
1860 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001861 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001862 elif isinstance( ptcp, types.ListType ):
1863 main.log.error( self.name + ": Only one switch is " +
1864 "being set and multiple PTCP is " +
1865 "being passed " )
1866 else:
1867 main.log.error( self.name + ": Invalid PTCP" )
1868 ptcp = ""
1869 command += onosIp
1870 commandList.append( command )
1871
1872 elif isinstance( sw, types.ListType ):
1873 if ptcp:
1874 if isinstance( ptcp, types.ListType ):
1875 if len( ptcp ) != len( sw ):
1876 main.log.error( self.name + ": PTCP length = " +
1877 str( len( ptcp ) ) +
1878 " is not the same as switch" +
1879 " length = " +
1880 str( len( sw ) ) )
1881 return main.FALSE
1882 else:
1883 for switch, ptcpNum in zip( sw, ptcp ):
1884 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001885 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001886 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001887 tempCmd += onosIp
1888 commandList.append( tempCmd )
1889 else:
1890 main.log.error( self.name + ": Invalid PTCP" )
1891 return main.FALSE
1892 else:
1893 for switch in sw:
1894 tempCmd = "sh ovs-vsctl set-controller "
1895 tempCmd += switch + " " + onosIp
1896 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001897 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001898 main.log.error( self.name + ": Invalid switch type " )
1899 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001900
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001901 for cmd in commandList:
1902 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001903 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001904 except pexpect.TIMEOUT:
1905 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1906 return main.FALSE
1907 except pexpect.EOF:
1908 main.log.error( self.name + ": EOF exception found" )
1909 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001910 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001911 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001912 except pexpect.EOF:
1913 main.log.error( self.name + ": EOF exception found" )
1914 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001915 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001916 except Exception:
1917 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001918 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001919
kelvin-onlabd3b64892015-01-20 13:26:24 -08001920 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001921 """
1922 Removes the controller target from sw"""
1923 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001924 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001925 response = self.execute(
1926 cmd=command,
1927 prompt="mininet>",
1928 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001929 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001930 main.log.error( self.name + ": EOF exception found" )
1931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001932 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001933 except Exception:
1934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001935 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001936 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001937 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001938
kelvin-onlabd3b64892015-01-20 13:26:24 -08001939 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001940 """
Jon Hallb1290e82014-11-18 16:17:48 -05001941 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001942 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001943 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001944 NOTE: cannot currently specify what type of switch
1945 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001946 sw = name of the new switch as a string
1947 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001948 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001949 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001950 """
1951 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001952 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001953 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001954 response = self.execute(
1955 cmd=command,
1956 prompt="mininet>",
1957 timeout=10 )
1958 if re.search( "already exists!", response ):
1959 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001960 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001961 elif re.search( "Error", response ):
1962 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001963 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001964 elif re.search( "usage:", response ):
1965 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001966 return main.FALSE
1967 else:
1968 return main.TRUE
1969 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001970 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001971 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001972 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001973 except Exception:
1974 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001975 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001976
kelvin-onlabd3b64892015-01-20 13:26:24 -08001977 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001978 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001979 delete a switch from the mininet topology
1980 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001981 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001982 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001983 sw = name of the switch as a string
1984 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001985 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001986 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001987 response = self.execute(
1988 cmd=command,
1989 prompt="mininet>",
1990 timeout=10 )
1991 if re.search( "no switch named", response ):
1992 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001993 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001994 elif re.search( "Error", response ):
1995 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001996 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001997 elif re.search( "usage:", response ):
1998 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001999 return main.FALSE
2000 else:
2001 return main.TRUE
2002 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002003 main.log.error( self.name + ": EOF exception found" )
2004 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002005 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002006 except Exception:
2007 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002008 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002009
You Wangdb8cd0a2016-05-26 15:19:45 -07002010 def getSwitchRandom( self, timeout=60, nonCut=True ):
2011 """
2012 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002013 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002014 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002015 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002016 it just randomly returns one switch from all current switches in
2017 Mininet.
2018 Returns the name of the chosen switch.
2019 """
2020 import random
2021 candidateSwitches = []
2022 try:
2023 if not nonCut:
2024 switches = self.getSwitches( timeout=timeout )
2025 assert len( switches ) != 0
2026 for switchName in switches.keys():
2027 candidateSwitches.append( switchName )
2028 else:
2029 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002030 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002031 return None
2032 self.graph.update( graphDict )
2033 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002034 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002035 return None
2036 elif len( candidateSwitches ) == 0:
2037 main.log.info( self.name + ": No candidate switch for deletion" )
2038 return None
2039 else:
2040 switch = random.sample( candidateSwitches, 1 )
2041 return switch[ 0 ]
2042 except KeyError:
2043 main.log.exception( self.name + ": KeyError exception found" )
2044 return None
2045 except AssertionError:
2046 main.log.exception( self.name + ": AssertionError exception found" )
2047 return None
2048 except Exception:
2049 main.log.exception( self.name + ": Uncaught exception" )
2050 return None
2051
2052 def delSwitchRandom( self, timeout=60, nonCut=True ):
2053 """
2054 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002055 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002056 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002057 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002058 otherwise it just randomly delete one switch from all current
2059 switches in Mininet.
2060 Returns the name of the deleted switch
2061 """
2062 try:
2063 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002064 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002065 return None
2066 else:
2067 deletionResult = self.delSwitch( switch )
2068 if deletionResult:
2069 return switch
2070 else:
2071 return None
2072 except Exception:
2073 main.log.exception( self.name + ": Uncaught exception" )
2074 return None
2075
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002077 """
2078 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002079 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002080 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002081 NOTE: cannot currently specify what type of link
2082 required params:
2083 node1 = the string node name of the first endpoint of the link
2084 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002085 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002086 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002087 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002088 response = self.execute(
2089 cmd=command,
2090 prompt="mininet>",
2091 timeout=10 )
2092 if re.search( "doesnt exist!", response ):
2093 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002094 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002095 elif re.search( "Error", response ):
2096 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002097 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002098 elif re.search( "usage:", response ):
2099 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002100 return main.FALSE
2101 else:
2102 return main.TRUE
2103 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002104 main.log.error( self.name + ": EOF exception found" )
2105 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002106 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002107 except Exception:
2108 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002109 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002110
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002112 """
2113 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002114 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002115 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002116 required params:
2117 node1 = the string node name of the first endpoint of the link
2118 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002119 returns: main.FALSE on an error, else main.TRUE
2120 """
Jon Hallffb386d2014-11-21 13:43:38 -08002121 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002122 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002123 response = self.execute(
2124 cmd=command,
2125 prompt="mininet>",
2126 timeout=10 )
2127 if re.search( "no node named", response ):
2128 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002129 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002130 elif re.search( "Error", response ):
2131 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002132 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002133 elif re.search( "usage:", response ):
2134 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002135 return main.FALSE
2136 else:
2137 return main.TRUE
2138 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002139 main.log.error( self.name + ": EOF exception found" )
2140 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002141 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002142 except Exception:
2143 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002144 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002145
You Wangdb8cd0a2016-05-26 15:19:45 -07002146 def getLinkRandom( self, timeout=60, nonCut=True ):
2147 """
2148 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002149 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002150 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002151 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002152 it just randomly returns one link from all current links in
2153 Mininet.
2154 Returns the link as a list, e.g. [ 's1', 's2' ]
2155 """
2156 import random
2157 candidateLinks = []
2158 try:
2159 if not nonCut:
2160 links = self.getLinks( timeout=timeout )
2161 assert len( links ) != 0
2162 for link in links:
2163 # Exclude host-switch link
2164 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2165 continue
2166 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2167 else:
2168 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002169 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002170 return None
2171 self.graph.update( graphDict )
2172 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002173 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002174 return None
2175 elif len( candidateLinks ) == 0:
2176 main.log.info( self.name + ": No candidate link for deletion" )
2177 return None
2178 else:
2179 link = random.sample( candidateLinks, 1 )
2180 return link[ 0 ]
2181 except KeyError:
2182 main.log.exception( self.name + ": KeyError exception found" )
2183 return None
2184 except AssertionError:
2185 main.log.exception( self.name + ": AssertionError exception found" )
2186 return None
2187 except Exception:
2188 main.log.exception( self.name + ": Uncaught exception" )
2189 return None
2190
2191 def delLinkRandom( self, timeout=60, nonCut=True ):
2192 """
2193 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002194 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002195 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002196 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002197 otherwise it just randomly delete one link from all current links
2198 in Mininet.
2199 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2200 """
2201 try:
2202 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002203 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002204 return None
2205 else:
2206 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2207 if deletionResult:
2208 return link
2209 else:
2210 return None
2211 except Exception:
2212 main.log.exception( self.name + ": Uncaught exception" )
2213 return None
2214
kelvin-onlabd3b64892015-01-20 13:26:24 -08002215 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002216 """
Jon Hallb1290e82014-11-18 16:17:48 -05002217 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002218 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002219 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002220 NOTE: cannot currently specify what type of host
2221 required params:
2222 hostname = the string hostname
2223 optional key-value params
2224 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002225 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002226 """
2227 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002228 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002229 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002230 response = self.execute(
2231 cmd=command,
2232 prompt="mininet>",
2233 timeout=10 )
2234 if re.search( "already exists!", response ):
2235 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002236 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002237 elif re.search( "doesnt exists!", response ):
2238 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002239 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002240 elif re.search( "Error", response ):
2241 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002242 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002243 elif re.search( "usage:", response ):
2244 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002245 return main.FALSE
2246 else:
2247 return main.TRUE
2248 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002249 main.log.error( self.name + ": EOF exception found" )
2250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002251 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002252 except Exception:
2253 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002254 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002255
kelvin-onlabd3b64892015-01-20 13:26:24 -08002256 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002257 """
2258 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002259 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002260 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002261 NOTE: this uses a custom mn function
2262 required params:
2263 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002264 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002265 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002266 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002267 response = self.execute(
2268 cmd=command,
2269 prompt="mininet>",
2270 timeout=10 )
2271 if re.search( "no host named", response ):
2272 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002273 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002274 elif re.search( "Error", response ):
2275 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002276 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002277 elif re.search( "usage:", response ):
2278 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002279 return main.FALSE
2280 else:
2281 return main.TRUE
2282 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002283 main.log.error( self.name + ": EOF exception found" )
2284 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002285 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002286 except Exception:
2287 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002288 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002289
Jon Hall7eb38402015-01-08 17:19:54 -08002290 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002291 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002292 Called at the end of the test to stop the mininet and
2293 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002294 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002295 try:
2296 self.handle.sendline( '' )
2297 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2298 timeout=2 )
2299 response = main.TRUE
2300 if i == 0:
2301 response = self.stopNet()
2302 elif i == 1:
2303 return main.TRUE
2304 # print "Disconnecting Mininet"
2305 if self.handle:
2306 self.handle.sendline( "exit" )
2307 self.handle.expect( "exit" )
2308 self.handle.expect( "(.*)" )
2309 else:
2310 main.log.error( "Connection failed to the host" )
2311 return response
2312 except pexpect.EOF:
2313 main.log.error( self.name + ": EOF exception found" )
2314 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002315 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002316 except Exception:
2317 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002318 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002319
Devin Lima7cfdbd2017-09-29 15:02:22 -07002320 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002321 """
Jon Hall21270ac2015-02-16 17:59:55 -08002322 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002323 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002324 main.FALSE if the pexpect handle does not exist.
2325
Jon Halld61331b2015-02-17 16:35:47 -08002326 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002327 """
Jon Halld61331b2015-02-17 16:35:47 -08002328 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002329 response = ''
2330 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002331 try:
Jon Halld80cc142015-07-06 13:36:05 -07002332 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002333 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002334 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002335 pexpect.EOF,
2336 pexpect.TIMEOUT ],
2337 timeout )
2338 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002339 main.log.info( "Exiting mininet.." )
2340 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002341 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002342 prompt=self.prompt,
2343 timeout=exitTimeout )
2344 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002345 self.handle.sendline( "sudo mn -c" )
2346 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002347
Jeremyd9e4eb12016-04-13 12:09:06 -07002348 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002349 main.log.info( " Mininet trying to exit while not " +
2350 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002351 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002352 elif i == 2:
2353 main.log.error( "Something went wrong exiting mininet" )
2354 elif i == 3: # timeout
2355 main.log.error( "Something went wrong exiting mininet " +
2356 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002357
Hari Krishnab35c6d02015-03-18 11:13:51 -07002358 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002359 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002360 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002361 self.handle.sendline(
2362 "sudo kill -9 \`ps -ef | grep \"" +
2363 fileName +
2364 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002365 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002366 main.log.error( self.name + ": TIMEOUT exception found" )
2367 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002368 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002369 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002370 main.log.error( self.name + ": EOF exception found" )
2371 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002372 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002373 except Exception:
2374 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002375 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002376 else:
2377 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002378 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002379 return response
2380
YPZhang26a139e2016-04-25 14:01:55 -07002381 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002382 """
2383 Description:
2384 Sends arp message from mininet host for hosts discovery
2385 Required:
2386 host - hosts name
2387 Optional:
2388 ip - ip address that does not exist in the network so there would
2389 be no reply.
2390 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002391 if ethDevice:
2392 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002393 cmd = srcHost + " arping -c1 "
2394 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002395 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 -07002396 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002397 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002398 if output:
2399 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002400 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002401 i = self.handle.expect( [ "mininet>", "arping: " ] )
2402 if i == 0:
2403 return main.TRUE
2404 elif i == 1:
2405 response = self.handle.before + self.handle.after
2406 self.handle.expect( "mininet>" )
2407 response += self.handle.before + self.handle.after
2408 main.log.warn( "Error sending arping, output was: " +
2409 response )
2410 return main.FALSE
2411 except pexpect.TIMEOUT:
2412 main.log.error( self.name + ": TIMEOUT exception found" )
2413 main.log.warn( self.handle.before )
2414 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002415 except pexpect.EOF:
2416 main.log.error( self.name + ": EOF exception found" )
2417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002418 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002419 except Exception:
2420 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002421 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002422
Jon Hall7eb38402015-01-08 17:19:54 -08002423 def decToHex( self, num ):
2424 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002425
Jon Hall7eb38402015-01-08 17:19:54 -08002426 def getSwitchFlowCount( self, switch ):
2427 """
2428 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002429 if self.handle:
2430 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2431 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002432 response = self.execute(
2433 cmd=cmd,
2434 prompt="mininet>",
2435 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002436 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002437 main.log.error( self.name + ": EOF exception found" )
2438 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002439 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002440 except Exception:
2441 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002442 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002443 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002444 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002445 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002446 main.log.info(
2447 "Couldn't find flows on switch %s, found: %s" %
2448 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002449 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002450 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002451 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002452 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002453
Jon Hall9ed8f372016-02-24 17:34:07 -08002454 def checkFlows( self, sw, dumpFormat=None ):
2455 if dumpFormat:
2456 command = "sh ovs-ofctl -F " + \
2457 dumpFormat + " dump-flows " + str( sw )
2458 else:
2459 command = "sh ovs-ofctl dump-flows " + str( sw )
2460 try:
2461 response = self.execute(
2462 cmd=command,
2463 prompt="mininet>",
2464 timeout=10 )
2465 return response
2466 except pexpect.EOF:
2467 main.log.error( self.name + ": EOF exception found" )
2468 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002469 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002470 except Exception:
2471 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002472 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002473
GlennRC68467eb2015-11-16 18:01:01 -08002474 def flowTableComp( self, flowTable1, flowTable2 ):
2475 # This function compares the selctors and treatments of each flow
2476 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002477 assert flowTable1, "flowTable1 is empty or None"
2478 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002479 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002480 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002481 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002482 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002483 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2484 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002485 for field in dFields:
2486 try:
2487 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002488 except KeyError:
2489 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002490 try:
2491 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002492 except KeyError:
2493 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002494 for i in range( len( flowTable1 ) ):
2495 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002496 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002497 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002498 returnValue = main.FALSE
2499 break
2500 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002501 except AssertionError:
2502 main.log.exception( "Nothing to compare" )
2503 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002504 except Exception:
2505 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002506 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002507
GlennRC528ad292015-11-12 10:38:18 -08002508 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002509 '''
GlennRC956ea742015-11-05 16:14:15 -08002510 Discription: Parses flows into json format.
2511 NOTE: this can parse any string thats separated with commas
2512 Arguments:
2513 Required:
2514 flows: a list of strings that represnt flows
2515 Optional:
2516 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2517 debug: prints out the final result
2518 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002519 '''
GlennRC528ad292015-11-12 10:38:18 -08002520 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002521 try:
2522 for flow in flowTable:
2523 jsonFlow = {}
2524 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002525 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002526 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002527 for i in range( len( parsedFlow ) ):
2528 item = parsedFlow[ i ]
2529 if item[ 0 ] == " ":
2530 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002531 # grab the selector and treatment from the parsed flow
2532 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002533 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002534 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002535 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002536 index = 0
2537 # parse the flags
2538 # NOTE: This only parses one flag
2539 flag = {}
2540 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002541 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002542 index += 1
2543 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002544 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002545 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002546 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002547 # the priority is stuck in the selecter so put it back
2548 # in the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002549 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002550 # parse selector
2551 criteria = []
2552 for item in sel:
2553 # this is the type of the packet e.g. "arp"
2554 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002555 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002556 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002557 field = item.split( "=" )
2558 criteria.append( { field[ 0 ]: field[ 1 ] } )
2559 selector = { "selector": { "criteria": sorted( criteria ) } }
2560 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002561 # get rid of the action part e.g. "action=output:2"
2562 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002563 treat = treat.split( "=" )
2564 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002565 # parse treatment
2566 action = []
2567 for item in treat:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002568 field = item.split( ":" )
2569 action.append( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002570 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002571 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002572 # parse the rest of the flow
2573 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002574 field = item.split( "=" )
2575 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002576 # add the treatment and the selector to the json flow
2577 jsonFlow.update( selector )
2578 jsonFlow.update( treatment )
2579 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002580
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002581 if debug:
2582 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002583
You Wang91c37cf2016-05-23 09:39:42 -07002584 # add the json flow to the json flow table
2585 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002586
You Wang91c37cf2016-05-23 09:39:42 -07002587 return jsonFlowTable
2588
2589 except IndexError:
2590 main.log.exception( self.name + ": IndexError found" )
2591 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002592 except pexpect.EOF:
2593 main.log.error( self.name + ": EOF exception found" )
2594 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002595 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002596 except Exception:
2597 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002598 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002599
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002600 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002601 '''
2602 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002603 Each element is a flow.
2604 Arguments:
2605 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002606 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002607 a list of switches.
2608 Optional:
2609 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2610 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002611 '''
GlennRC956ea742015-11-05 16:14:15 -08002612 try:
2613 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002614 if isinstance( sw, list ):
2615 switches.extend( sw )
2616 else:
2617 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002618
2619 flows = []
2620 for s in switches:
2621 cmd = "sh ovs-ofctl dump-flows " + s
2622
GlennRC528ad292015-11-12 10:38:18 -08002623 if "1.0" == version:
2624 cmd += " -F OpenFlow10-table_id"
2625 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002626 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002627
2628 main.log.info( "Sending: " + cmd )
2629 self.handle.sendline( cmd )
2630 self.handle.expect( "mininet>" )
2631 response = self.handle.before
2632 response = response.split( "\r\n" )
2633 # dump the first two elements and the last
2634 # the first element is the command that was sent
2635 # the second is the table header
2636 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002637 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002638 flows.extend( response )
2639
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002640 if debug:
2641 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002642
GlennRC528ad292015-11-12 10:38:18 -08002643 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002644
GlennRC956ea742015-11-05 16:14:15 -08002645 except pexpect.EOF:
2646 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002647 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002648 except Exception:
2649 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002650 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002651
2652 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002653 '''
GlennRC956ea742015-11-05 16:14:15 -08002654 Discription: Checks whether the ID provided matches a flow ID in Mininet
2655 Arguments:
2656 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002657 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002658 a list of switches.
2659 flowId: the flow ID in hex format. Can also be a list of IDs
2660 Optional:
2661 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2662 debug: prints out the final result
2663 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2664 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002665 '''
GlennRC956ea742015-11-05 16:14:15 -08002666 try:
2667 main.log.info( "Getting flows from Mininet" )
2668 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002669 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002670 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002671
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002672 if debug:
2673 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002674
2675 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002676 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002677 result = False
2678 for f in flows:
2679 if flowId in f.get( 'cookie' ):
2680 result = True
2681 break
2682 # flowId is a list
2683 else:
2684 result = True
2685 # Get flow IDs from Mininet
2686 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2687 # Save the IDs that are not in Mininet
2688 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2689
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002690 if debug:
2691 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002692
2693 # Print out the IDs that are not in Mininet
2694 if absentIds:
2695 main.log.warn( "Absent ids: {}".format( absentIds ) )
2696 result = False
2697
2698 return main.TRUE if result else main.FALSE
2699
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002700 except pexpect.EOF:
2701 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()
GlennRC956ea742015-11-05 16:14:15 -08002704 except Exception:
2705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002706 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002707
Charles Chan029be652015-08-24 01:46:10 +08002708 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002709 """
Jon Hallefbd9792015-03-05 16:11:36 -08002710 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002711 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002712 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002713 self.handle.sendline( "" )
2714 self.handle.expect( "mininet>" )
2715 self.handle.sendline(
2716 "sh sudo tcpdump -n -i " +
2717 intf +
2718 " " +
2719 port +
2720 " -w " +
2721 filename.strip() +
2722 " &" )
2723 self.handle.sendline( "" )
2724 i = self.handle.expect( [ 'No\ssuch\device',
2725 'listening\son',
2726 pexpect.TIMEOUT,
2727 "mininet>" ],
2728 timeout=10 )
2729 main.log.warn( self.handle.before + self.handle.after )
2730 self.handle.sendline( "" )
2731 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002732 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002733 main.log.error(
2734 self.name +
2735 ": tcpdump - No such device exists. " +
2736 "tcpdump attempted on: " +
2737 intf )
admin2a9548d2014-06-17 14:08:07 -07002738 return main.FALSE
2739 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002740 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002741 return main.TRUE
2742 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002743 main.log.error(
2744 self.name +
2745 ": tcpdump command timed out! Check interface name," +
2746 " given interface was: " +
2747 intf )
admin2a9548d2014-06-17 14:08:07 -07002748 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002749 elif i == 3:
2750 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002751 return main.TRUE
2752 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002753 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002754 return main.FALSE
2755 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002756 main.log.error( self.name + ": EOF exception found" )
2757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002758 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002759 except Exception:
2760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002761 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002762
kelvin-onlabd3b64892015-01-20 13:26:24 -08002763 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002764 """
2765 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002766 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002767 self.handle.sendline( "sh sudo pkill tcpdump" )
2768 self.handle.expect( "mininet>" )
2769 self.handle.sendline( "" )
2770 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002771 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002772 main.log.error( self.name + ": TIMEOUT exception found" )
2773 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002774 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002775 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002776 main.log.error( self.name + ": EOF exception found" )
2777 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002778 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002779 except Exception:
2780 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002781 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002782
Jon Halld80cc142015-07-06 13:36:05 -07002783 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002784 """
2785 Read ports from a Mininet switch.
2786
2787 Returns a json structure containing information about the
2788 ports of the given switch.
2789 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002790 try:
2791 response = self.getInterfaces( nodeName )
2792 # TODO: Sanity check on response. log if no such switch exists
2793 ports = []
2794 for line in response.split( "\n" ):
2795 if not line.startswith( "name=" ):
2796 continue
2797 portVars = {}
2798 for var in line.split( "," ):
2799 key, value = var.split( "=" )
2800 portVars[ key ] = value
2801 isUp = portVars.pop( 'enabled', "True" )
2802 isUp = "True" in isUp
2803 if verbose:
2804 main.log.info( "Reading switch port %s(%s)" %
2805 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2806 mac = portVars[ 'mac' ]
2807 if mac == 'None':
2808 mac = None
2809 ips = []
2810 ip = portVars[ 'ip' ]
2811 if ip == 'None':
2812 ip = None
2813 ips.append( ip )
2814 name = portVars[ 'name' ]
2815 if name == 'None':
2816 name = None
2817 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2818 if name == 'lo':
2819 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2820 else:
2821 portNo = re.search( portRe, name ).group( 'port' )
2822 ports.append( { 'of_port': portNo,
2823 'mac': str( mac ).replace( '\'', '' ),
2824 'name': name,
2825 'ips': ips,
2826 'enabled': isUp } )
2827 return ports
2828 except pexpect.EOF:
2829 main.log.error( self.name + ": EOF exception found" )
2830 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002831 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002832 except Exception:
2833 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002834 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002835
You Wangdb8cd0a2016-05-26 15:19:45 -07002836 def getOVSPorts( self, nodeName ):
2837 """
2838 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2839
2840 Returns a list of dictionaries containing information about each
2841 port of the given switch.
2842 """
2843 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2844 try:
2845 response = self.execute(
2846 cmd=command,
2847 prompt="mininet>",
2848 timeout=10 )
2849 ports = []
2850 if response:
2851 for line in response.split( "\n" ):
2852 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2853 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002854 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002855 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2856 result = re.search( pattern, line )
2857 if result:
2858 index = result.group( 'index' )
2859 name = result.group( 'name' )
2860 # This port number is extracted from port name
2861 port = result.group( 'port' )
2862 mac = result.group( 'mac' )
2863 ports.append( { 'index': index,
2864 'name': name,
2865 'port': port,
2866 'mac': mac } )
2867 return ports
2868 except pexpect.EOF:
2869 main.log.error( self.name + ": EOF exception found" )
2870 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002871 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002872 except Exception:
2873 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002874 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002875
Devin Lima7cfdbd2017-09-29 15:02:22 -07002876 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002877 """
2878 Read switches from Mininet.
2879
2880 Returns a dictionary whose keys are the switch names and the value is
2881 a dictionary containing information about the switch.
2882 """
Jon Halla22481b2015-07-28 17:46:01 -07002883 # NOTE: To support new Mininet switch classes, just append the new
2884 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002885
Jon Halla22481b2015-07-28 17:46:01 -07002886 # Regex patterns to parse 'dump' output
2887 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002888 # <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 -07002889 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002890 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2891 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2892 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002893 try:
2894 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2895 swRE = r"<(?P<class>" + switchClasses + r")" +\
2896 r"(?P<options>\{.*\})?\s" +\
2897 r"(?P<name>[^:]+)\:\s" +\
2898 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2899 r"\spid=(?P<pid>(\d)+)"
2900 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002901 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002902 output = {}
2903 dump = self.dump().split( "\n" )
2904 for line in dump:
2905 result = re.search( swRE, line, re.I )
2906 if result:
2907 name = result.group( 'name' )
2908 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2909 pid = result.group( 'pid' )
2910 swClass = result.group( 'class' )
2911 options = result.group( 'options' )
2912 if verbose:
2913 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2914 ports = self.getPorts( name )
2915 output[ name ] = { "dpid": dpid,
2916 "ports": ports,
2917 "swClass": swClass,
2918 "pid": pid,
2919 "options": options }
2920 return output
2921 except pexpect.EOF:
2922 main.log.error( self.name + ": EOF exception found" )
2923 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002924 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002925 except Exception:
2926 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002927 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002928
You Wang53dba1e2018-02-02 17:45:44 -08002929 def getHosts( self, verbose=False, updateTimeout=1000, hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ] ):
Jon Hallafa8a472015-06-12 14:02:42 -07002930 """
2931 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08002932 Optional:
2933 hostClass: it is used to match the class of the mininet host. It
2934 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07002935 Returns a dictionary whose keys are the host names and the value is
2936 a dictionary containing information about the host.
2937 """
2938 # Regex patterns to parse dump output
2939 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002940 # <Host h1: pid=12725>
2941 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2942 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2943 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002944 # NOTE: Does not correctly match hosts with multi-links
2945 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2946 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002947 try:
You Wang53dba1e2018-02-02 17:45:44 -08002948 if not isinstance( hostClass, types.ListType ):
2949 hostClass = [ str( hostClass ) ]
2950 classRE = "(" + "|".join([c for c in hostClass]) + ")"
2951 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002952 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
2953 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002954 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002955 # Get mininet dump
2956 dump = self.dump().split( "\n" )
2957 hosts = {}
2958 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08002959 result = re.search( hostRE, line )
2960 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002961 name = result.group( 'name' )
2962 interfaces = []
2963 response = self.getInterfaces( name )
2964 # Populate interface info
2965 for line in response.split( "\n" ):
2966 if line.startswith( "name=" ):
2967 portVars = {}
2968 for var in line.split( "," ):
2969 key, value = var.split( "=" )
2970 portVars[ key ] = value
2971 isUp = portVars.pop( 'enabled', "True" )
2972 isUp = "True" in isUp
2973 if verbose:
2974 main.log.info( "Reading host port %s(%s)" %
2975 ( portVars[ 'name' ],
2976 portVars[ 'mac' ] ) )
2977 mac = portVars[ 'mac' ]
2978 if mac == 'None':
2979 mac = None
2980 ips = []
2981 ip = portVars[ 'ip' ]
2982 if ip == 'None':
2983 ip = None
2984 ips.append( ip )
2985 intfName = portVars[ 'name' ]
2986 if name == 'None':
2987 name = None
2988 interfaces.append( {
2989 "name": intfName,
2990 "ips": ips,
2991 "mac": str( mac ),
2992 "isUp": isUp } )
2993 hosts[ name ] = { "interfaces": interfaces }
2994 return hosts
2995 except pexpect.EOF:
2996 main.log.error( self.name + ": EOF exception found" )
2997 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002998 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002999 except Exception:
3000 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003001 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003002
Devin Lima7cfdbd2017-09-29 15:02:22 -07003003 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003004 """
3005 Gathers information about current Mininet links. These links may not
3006 be up if one of the ports is down.
3007
3008 Returns a list of dictionaries with link endpoints.
3009
3010 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003011 { 'node1': str( node1 name )
3012 'node2': str( node2 name )
3013 'port1': str( port1 of_port )
3014 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003015 Note: The port number returned is the eth#, not necessarily the of_port
3016 number. In Mininet, for OVS switch, these should be the same. For
3017 hosts, this is just the eth#.
3018 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003019 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003020 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003021 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003022
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003023 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003024 # s1-eth3<->s2-eth1 (OK OK)
3025 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003026 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3027 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3028 links = []
3029 for line in response:
3030 match = re.search( linkRE, line )
3031 if match:
3032 node1 = match.group( 'node1' )
3033 node2 = match.group( 'node2' )
3034 port1 = match.group( 'port1' )
3035 port2 = match.group( 'port2' )
3036 links.append( { 'node1': node1,
3037 'node2': node2,
3038 'port1': port1,
3039 'port2': port2 } )
3040 return links
3041
3042 except pexpect.EOF:
3043 main.log.error( self.name + ": EOF exception found" )
3044 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003045 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003046 except Exception:
3047 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003048 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003049
3050 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003051 """
3052 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003053 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003054
Jon Hallafa8a472015-06-12 14:02:42 -07003055 Dependencies:
3056 1. numpy - "sudo pip install numpy"
3057 """
3058 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003059 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003060 try:
3061 mnDPIDs = []
3062 for swName, switch in switches.iteritems():
3063 mnDPIDs.append( switch[ 'dpid' ].lower() )
3064 mnDPIDs.sort()
3065 if switchesJson == "": # if rest call fails
3066 main.log.error(
3067 self.name +
3068 ".compareSwitches(): Empty JSON object given from ONOS" )
3069 return main.FALSE
3070 onos = switchesJson
3071 onosDPIDs = []
3072 for switch in onos:
3073 if switch[ 'available' ]:
3074 onosDPIDs.append(
3075 switch[ 'id' ].replace(
3076 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003077 '' ).replace(
3078 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003079 '' ).lower() )
3080 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003081
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003082 if mnDPIDs != onosDPIDs:
3083 switchResults = main.FALSE
3084 main.log.error( "Switches in MN but not in ONOS:" )
3085 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3086 main.log.error( str( list1 ) )
3087 main.log.error( "Switches in ONOS but not in MN:" )
3088 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3089 main.log.error( str( list2 ) )
3090 else: # list of dpid's match in onos and mn
3091 switchResults = main.TRUE
3092 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003093
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003094 # FIXME: this does not look for extra ports in ONOS, only checks that
3095 # ONOS has what is in MN
3096 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003097
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003098 # PORTS
3099 for name, mnSwitch in switches.iteritems():
3100 mnPorts = []
3101 onosPorts = []
3102 switchResult = main.TRUE
3103 for port in mnSwitch[ 'ports' ]:
3104 if port[ 'enabled' ]:
3105 mnPorts.append( int( port[ 'of_port' ] ) )
3106 for onosSwitch in portsJson:
3107 if onosSwitch[ 'device' ][ 'available' ]:
3108 if onosSwitch[ 'device' ][ 'id' ].replace(
3109 ':',
3110 '' ).replace(
3111 "of",
3112 '' ) == mnSwitch[ 'dpid' ]:
3113 for port in onosSwitch[ 'ports' ]:
3114 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003115 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003116 # onosPorts.append( 'local' )
3117 onosPorts.append( long( uint64( -2 ) ) )
3118 else:
3119 onosPorts.append( int( port[ 'port' ] ) )
3120 break
3121 mnPorts.sort( key=float )
3122 onosPorts.sort( key=float )
3123
3124 mnPortsLog = mnPorts
3125 onosPortsLog = onosPorts
3126 mnPorts = [ x for x in mnPorts ]
3127 onosPorts = [ x for x in onosPorts ]
3128
3129 # TODO: handle other reserved port numbers besides LOCAL
3130 # NOTE: Reserved ports
3131 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3132 # long( uint64( -2 ) )
3133 for mnPort in mnPortsLog:
3134 if mnPort in onosPorts:
3135 # don't set results to true here as this is just one of
3136 # many checks and it might override a failure
3137 mnPorts.remove( mnPort )
3138 onosPorts.remove( mnPort )
3139
3140 # NOTE: OVS reports this as down since there is no link
3141 # So ignoring these for now
3142 # TODO: Come up with a better way of handling these
3143 if 65534 in mnPorts:
3144 mnPorts.remove( 65534 )
3145 if long( uint64( -2 ) ) in onosPorts:
3146 onosPorts.remove( long( uint64( -2 ) ) )
3147 if len( mnPorts ): # the ports of this switch don't match
3148 switchResult = main.FALSE
3149 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3150 if len( onosPorts ): # the ports of this switch don't match
3151 switchResult = main.FALSE
3152 main.log.warn(
3153 "Ports in ONOS but not MN: " +
3154 str( onosPorts ) )
3155 if switchResult == main.FALSE:
3156 main.log.error(
3157 "The list of ports for switch %s(%s) does not match:" %
3158 ( name, mnSwitch[ 'dpid' ] ) )
3159 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3160 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3161 portsResults = portsResults and switchResult
3162 finalResults = finalResults and portsResults
3163 return finalResults
3164 except pexpect.EOF:
3165 main.log.error( self.name + ": EOF exception found" )
3166 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003167 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003168 except Exception:
3169 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003170 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003171
Jon Hallafa8a472015-06-12 14:02:42 -07003172 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003173 """
3174 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003175 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003176
Jon Hallafa8a472015-06-12 14:02:42 -07003177 """
Jon Hall7eb38402015-01-08 17:19:54 -08003178 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003179 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003180 try:
3181 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003182
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003183 mnLinks = []
3184 for l in links:
3185 try:
3186 node1 = switches[ l[ 'node1' ] ]
3187 node2 = switches[ l[ 'node2' ] ]
3188 enabled = True
3189 for port in node1[ 'ports' ]:
3190 if port[ 'of_port' ] == l[ 'port1' ]:
3191 enabled = enabled and port[ 'enabled' ]
3192 for port in node2[ 'ports' ]:
3193 if port[ 'of_port' ] == l[ 'port2' ]:
3194 enabled = enabled and port[ 'enabled' ]
3195 if enabled:
3196 mnLinks.append( l )
3197 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003198 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003199 if 2 * len( mnLinks ) == len( onos ):
3200 linkResults = main.TRUE
3201 else:
3202 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003203 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003204 "Mininet has " + str( len( mnLinks ) ) +
3205 " bidirectional links and ONOS has " +
3206 str( len( onos ) ) + " unidirectional links" )
3207
3208 # iterate through MN links and check if an ONOS link exists in
3209 # both directions
3210 for link in mnLinks:
3211 # TODO: Find a more efficient search method
3212 node1 = None
3213 port1 = None
3214 node2 = None
3215 port2 = None
3216 firstDir = main.FALSE
3217 secondDir = main.FALSE
3218 for swName, switch in switches.iteritems():
3219 if swName == link[ 'node1' ]:
3220 node1 = switch[ 'dpid' ]
3221 for port in switch[ 'ports' ]:
3222 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3223 port1 = port[ 'of_port' ]
3224 if node1 is not None and node2 is not None:
3225 break
3226 if swName == link[ 'node2' ]:
3227 node2 = switch[ 'dpid' ]
3228 for port in switch[ 'ports' ]:
3229 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3230 port2 = port[ 'of_port' ]
3231 if node1 is not None and node2 is not None:
3232 break
3233
3234 for onosLink in onos:
3235 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3236 ":", '' ).replace( "of", '' )
3237 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3238 ":", '' ).replace( "of", '' )
3239 onosPort1 = onosLink[ 'src' ][ 'port' ]
3240 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3241
3242 # check onos link from node1 to node2
3243 if str( onosNode1 ) == str( node1 ) and str(
3244 onosNode2 ) == str( node2 ):
3245 if int( onosPort1 ) == int( port1 ) and int(
3246 onosPort2 ) == int( port2 ):
3247 firstDir = main.TRUE
3248 else:
3249 main.log.warn(
3250 'The port numbers do not match for ' +
3251 str( link ) +
3252 ' between ONOS and MN. When checking ONOS for ' +
3253 'link %s/%s -> %s/%s' %
3254 ( node1, port1, node2, port2 ) +
3255 ' ONOS has the values %s/%s -> %s/%s' %
3256 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3257
3258 # check onos link from node2 to node1
3259 elif ( str( onosNode1 ) == str( node2 ) and
3260 str( onosNode2 ) == str( node1 ) ):
3261 if ( int( onosPort1 ) == int( port2 )
3262 and int( onosPort2 ) == int( port1 ) ):
3263 secondDir = main.TRUE
3264 else:
3265 main.log.warn(
3266 'The port numbers do not match for ' +
3267 str( link ) +
3268 ' between ONOS and MN. When checking ONOS for ' +
3269 'link %s/%s -> %s/%s' %
3270 ( node1, port1, node2, port2 ) +
3271 ' ONOS has the values %s/%s -> %s/%s' %
3272 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3273 else: # this is not the link you're looking for
3274 pass
3275 if not firstDir:
3276 main.log.error(
3277 'ONOS does not have the link %s/%s -> %s/%s' %
3278 ( node1, port1, node2, port2 ) )
3279 if not secondDir:
3280 main.log.error(
3281 'ONOS does not have the link %s/%s -> %s/%s' %
3282 ( node2, port2, node1, port1 ) )
3283 linkResults = linkResults and firstDir and secondDir
3284 return linkResults
3285 except pexpect.EOF:
3286 main.log.error( self.name + ": EOF exception found" )
3287 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003288 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003289 except Exception:
3290 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003291 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003292
Jon Hallafa8a472015-06-12 14:02:42 -07003293 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003294 """
Jon Hallafa8a472015-06-12 14:02:42 -07003295 Compare mn and onos Hosts.
3296 Since Mininet hosts are quiet, ONOS will only know of them when they
3297 speak. For this reason, we will only check that the hosts in ONOS
3298 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003299
Jon Hallafa8a472015-06-12 14:02:42 -07003300 Arguments:
3301 hostsJson: parsed json object from the onos hosts api
3302 Returns:
3303 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003304 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003305 try:
3306 hostResults = main.TRUE
3307 for onosHost in hostsJson:
3308 onosMAC = onosHost[ 'mac' ].lower()
3309 match = False
3310 for mnHost, info in hosts.iteritems():
3311 for mnIntf in info[ 'interfaces' ]:
3312 if onosMAC == mnIntf[ 'mac' ].lower():
3313 match = True
3314 for ip in mnIntf[ 'ips' ]:
3315 if ip in onosHost[ 'ipAddresses' ]:
3316 pass # all is well
3317 else:
3318 # misssing ip
3319 main.log.error( "ONOS host " +
3320 onosHost[ 'id' ] +
3321 " has a different IP(" +
3322 str( onosHost[ 'ipAddresses' ] ) +
3323 ") than the Mininet host(" +
3324 str( ip ) +
3325 ")." )
3326 output = json.dumps(
3327 onosHost,
3328 sort_keys=True,
3329 indent=4,
3330 separators=( ',', ': ' ) )
3331 main.log.info( output )
3332 hostResults = main.FALSE
3333 if not match:
3334 hostResults = main.FALSE
3335 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3336 "corresponding Mininet host." )
3337 output = json.dumps( onosHost,
3338 sort_keys=True,
3339 indent=4,
3340 separators=( ',', ': ' ) )
3341 main.log.info( output )
3342 return hostResults
3343 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003344 main.log.error( self.name + ": EOF exception found" )
3345 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003346 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003347 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003348 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003349 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003350
You Wang53dba1e2018-02-02 17:45:44 -08003351 def verifyHostIp( self, hostList=[], prefix="" ):
3352 """
3353 Description:
3354 Verify that all hosts have IP address assigned to them
3355 Optional:
3356 hostList: If specified, verifications only happen to the hosts
3357 in hostList
3358 prefix: at least one of the ip address assigned to the host
3359 needs to have the specified prefix
3360 Returns:
3361 main.TRUE if all hosts have specific IP address assigned;
3362 main.FALSE otherwise
3363 """
3364 try:
3365 hosts = self.getHosts()
3366 if not hostList:
3367 hostList = hosts.keys()
3368 for hostName in hosts.keys():
3369 if hostName not in hostList:
3370 continue
3371 ipList = []
3372 self.handle.sendline( str( hostName ) + " ip a" )
3373 self.handle.expect( "mininet>" )
3374 ipa = self.handle.before
3375 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3376 ipList += re.findall( ipv4Pattern, ipa )
3377 # It's tricky to make regex for IPv6 addresses and this one is simplified
3378 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})/'
3379 ipList += re.findall( ipv6Pattern, ipa )
3380 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3381 if not ipList:
3382 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3383 else:
3384 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3385 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3386 else:
3387 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3388 hostList.remove( hostName )
3389 return main.FALSE if hostList else main.TRUE
3390 except KeyError:
3391 main.log.exception( self.name + ": host data not as expected: " + hosts )
3392 return None
3393 except pexpect.EOF:
3394 main.log.error( self.name + ": EOF exception found" )
3395 main.log.error( self.name + ": " + self.handle.before )
3396 main.cleanAndExit()
3397 except Exception:
3398 main.log.exception( self.name + ": Uncaught exception" )
3399 return None
3400
Jon Hallafa8a472015-06-12 14:02:42 -07003401 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003402 """
3403 Returns a list of all hosts
3404 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003405 try:
3406 self.handle.sendline( "" )
3407 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003408
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003409 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3410 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003411
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003412 handlePy = self.handle.before
3413 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3414 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003415
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003416 self.handle.sendline( "" )
3417 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003418
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003419 hostStr = handlePy.replace( "]", "" )
3420 hostStr = hostStr.replace( "'", "" )
3421 hostStr = hostStr.replace( "[", "" )
3422 hostStr = hostStr.replace( " ", "" )
3423 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003424
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003425 return hostList
3426 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003427 main.log.error( self.name + ": TIMEOUT exception found" )
3428 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003429 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003430 except pexpect.EOF:
3431 main.log.error( self.name + ": EOF exception found" )
3432 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003433 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003434 except Exception:
3435 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003436 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003437
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003438 def getSwitch( self ):
3439 """
3440 Returns a list of all switches
3441 Again, don't ask question just use it...
3442 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003443 try:
3444 # get host list...
3445 hostList = self.getHosts()
3446 # Make host set
3447 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003448
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003449 # Getting all the nodes in mininet
3450 self.handle.sendline( "" )
3451 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003452
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003453 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3454 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003455
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003456 handlePy = self.handle.before
3457 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3458 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003459
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003460 self.handle.sendline( "" )
3461 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003462
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003463 nodesStr = handlePy.replace( "]", "" )
3464 nodesStr = nodesStr.replace( "'", "" )
3465 nodesStr = nodesStr.replace( "[", "" )
3466 nodesStr = nodesStr.replace( " ", "" )
3467 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003468
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003469 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003470 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003471 nodesSet.discard( 'c0' )
3472 nodesSet.discard( 'c1' )
3473 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003474
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003475 switchSet = nodesSet - hostSet
3476 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003477
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003478 return switchList
3479 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003480 main.log.error( self.name + ": TIMEOUT exception found" )
3481 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003482 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003483 except pexpect.EOF:
3484 main.log.error( self.name + ": EOF exception found" )
3485 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003486 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003487 except Exception:
3488 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003489 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003490
You Wangdb8cd0a2016-05-26 15:19:45 -07003491 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3492 """
3493 Return a dictionary which describes the latest Mininet topology data as a
3494 graph.
3495 An example of the dictionary:
3496 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3497 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3498 Each vertex should at least have an 'edges' attribute which describes the
3499 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003500 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003501 list of attributes.
3502 An example of the edges dictionary:
3503 'edges': { vertex2: { 'port': ..., 'weight': ... },
3504 vertex3: { 'port': ..., 'weight': ... } }
3505 If useId == True, dpid/mac will be used instead of names to identify
3506 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3507 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003508 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003509 in topology data.
3510 Note that link or switch that are brought down by 'link x x down' or 'switch
3511 x down' commands still show in the output of Mininet CLI commands such as
3512 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3513 recommended to use delLink() or delSwitch functions to simulate link/switch
3514 down, and addLink() or addSwitch to add them back.
3515 """
3516 graphDict = {}
3517 try:
3518 links = self.getLinks( timeout=timeout )
3519 portDict = {}
3520 if useId:
3521 switches = self.getSwitches()
3522 if includeHost:
3523 hosts = self.getHosts()
3524 for link in links:
3525 # FIXME: support 'includeHost' argument
3526 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3527 continue
3528 nodeName1 = link[ 'node1' ]
3529 nodeName2 = link[ 'node2' ]
3530 port1 = link[ 'port1' ]
3531 port2 = link[ 'port2' ]
3532 # Loop for two nodes
3533 for i in range( 2 ):
3534 # Get port index from OVS
3535 # The index extracted from port name may be inconsistent with ONOS
3536 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003537 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003538 portList = self.getOVSPorts( nodeName1 )
3539 if len( portList ) == 0:
3540 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3541 return None
3542 portDict[ nodeName1 ] = portList
3543 for port in portDict[ nodeName1 ]:
3544 if port[ 'port' ] == port1:
3545 portIndex = port[ 'index' ]
3546 break
3547 if portIndex == -1:
3548 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3549 return None
3550 if useId:
3551 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3552 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3553 else:
3554 node1 = nodeName1
3555 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003556 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003557 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003558 graphDict[ node1 ] = { 'edges': {},
3559 'dpid': switches[ nodeName1 ][ 'dpid' ],
3560 'name': nodeName1,
3561 'ports': switches[ nodeName1 ][ 'ports' ],
3562 'swClass': switches[ nodeName1 ][ 'swClass' ],
3563 'pid': switches[ nodeName1 ][ 'pid' ],
3564 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003565 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003566 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003567 else:
3568 # Assert node2 is not connected to any current links of node1
3569 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003570 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003571 # Swap two nodes/ports
3572 nodeName1, nodeName2 = nodeName2, nodeName1
3573 port1, port2 = port2, port1
3574 return graphDict
3575 except KeyError:
3576 main.log.exception( self.name + ": KeyError exception found" )
3577 return None
3578 except AssertionError:
3579 main.log.exception( self.name + ": AssertionError exception found" )
3580 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003581 except pexpect.EOF:
3582 main.log.error( self.name + ": EOF exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003585 except Exception:
3586 main.log.exception( self.name + ": Uncaught exception" )
3587 return None
3588
Devin Lima7cfdbd2017-09-29 15:02:22 -07003589 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003590 """
3591 updates the port address and status information for
3592 each port in mn"""
3593 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003594 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003595 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003596 self.handle.sendline( "" )
3597 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003598
Jon Hall7eb38402015-01-08 17:19:54 -08003599 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003600 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003601
Jon Hall7eb38402015-01-08 17:19:54 -08003602 self.handle.sendline( "" )
3603 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003604
Jon Hallb1290e82014-11-18 16:17:48 -05003605 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003606 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003607 main.log.error( self.name + ": TIMEOUT exception found" )
3608 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003609 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003610 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003611 main.log.error( self.name + ": EOF exception found" )
3612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003614 except Exception:
3615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003616 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003617
Jon Halld80cc142015-07-06 13:36:05 -07003618 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003619 """
3620 Add vlan tag to a host.
3621 Dependencies:
3622 This class depends on the "vlan" package
3623 $ sudo apt-get install vlan
3624 Configuration:
3625 Load the 8021q module into the kernel
3626 $sudo modprobe 8021q
3627
3628 To make this setup permanent:
3629 $ sudo su -c 'echo "8021q" >> /etc/modules'
3630 """
3631 if self.handle:
3632 try:
Jon Halld80cc142015-07-06 13:36:05 -07003633 # get the ip address of the host
3634 main.log.info( "Get the ip address of the host" )
3635 ipaddr = self.getIPAddress( host )
3636 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003637
Jon Halld80cc142015-07-06 13:36:05 -07003638 # remove IP from interface intf
3639 # Ex: h1 ifconfig h1-eth0 inet 0
3640 main.log.info( "Remove IP from interface " )
3641 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3642 self.handle.sendline( cmd2 )
3643 self.handle.expect( "mininet>" )
3644 response = self.handle.before
3645 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003646
Jon Halld80cc142015-07-06 13:36:05 -07003647 # create VLAN interface
3648 # Ex: h1 vconfig add h1-eth0 100
3649 main.log.info( "Create Vlan" )
3650 cmd3 = host + " vconfig add " + intf + " " + vlan
3651 self.handle.sendline( cmd3 )
3652 self.handle.expect( "mininet>" )
3653 response = self.handle.before
3654 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003655
Jon Halld80cc142015-07-06 13:36:05 -07003656 # assign the host's IP to the VLAN interface
3657 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3658 main.log.info( "Assign the host IP to the vlan interface" )
3659 vintf = intf + "." + vlan
3660 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3661 self.handle.sendline( cmd4 )
3662 self.handle.expect( "mininet>" )
3663 response = self.handle.before
3664 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003665
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003666 # update Mininet node variables
3667 main.log.info( "Update Mininet node variables" )
3668 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3669 self.handle.sendline( cmd5 )
3670 self.handle.expect( "mininet>" )
3671 response = self.handle.before
3672 main.log.info( "====> %s ", response )
3673
3674 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3675 self.handle.sendline( cmd6 )
3676 self.handle.expect( "mininet>" )
3677 response = self.handle.before
3678 main.log.info( "====> %s ", response )
3679
3680 return main.TRUE
3681 except pexpect.TIMEOUT:
3682 main.log.error( self.name + ": TIMEOUT exception found" )
3683 main.log.error( self.name + ": " + self.handle.before )
3684 main.cleanAndExit()
3685 except pexpect.EOF:
3686 main.log.error( self.name + ": EOF exception found" )
3687 main.log.error( self.name + ": " + self.handle.before )
3688 return main.FALSE
3689 except Exception:
3690 main.log.exception( self.name + ": Uncaught exception!" )
3691 return main.FALSE
3692
3693 def removeVLAN( self, host, intf ):
3694 """
3695 Remove vlan tag from a host.
3696 Dependencies:
3697 This class depends on the "vlan" package
3698 $ sudo apt-get install vlan
3699 Configuration:
3700 Load the 8021q module into the kernel
3701 $sudo modprobe 8021q
3702
3703 To make this setup permanent:
3704 $ sudo su -c 'echo "8021q" >> /etc/modules'
3705 """
3706 if self.handle:
3707 try:
3708 # get the ip address of the host
3709 main.log.info( "Get the ip address of the host" )
3710 ipaddr = self.getIPAddress( host )
3711
3712 # remove VLAN interface
3713 # Ex: h1 vconfig rem h1-eth0.100
3714 main.log.info( "Remove Vlan interface" )
3715 cmd2 = host + " vconfig rem " + intf
3716 self.handle.sendline( cmd2 )
3717 self.handle.expect( "mininet>" )
3718 response = self.handle.before
3719 main.log.info( "====> %s ", response )
3720
3721 # assign the host's IP to the original interface
3722 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3723 main.log.info( "Assign the host IP to the original interface" )
3724 original_intf = intf.split(".")[0]
3725 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3726 self.handle.sendline( cmd3 )
3727 self.handle.expect( "mininet>" )
3728 response = self.handle.before
3729 main.log.info( "====> %s ", response )
3730
3731 # update Mininet node variables
3732 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3733 self.handle.sendline( cmd4 )
3734 self.handle.expect( "mininet>" )
3735 response = self.handle.before
3736 main.log.info( "====> %s ", response )
3737
3738 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3739 self.handle.sendline( cmd5 )
3740 self.handle.expect( "mininet>" )
3741 response = self.handle.before
3742 main.log.info( "====> %s ", response )
3743
kaouthera3f13ca22015-05-05 15:01:41 -07003744 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003745 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003746 main.log.error( self.name + ": TIMEOUT exception found" )
3747 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003748 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003749 except pexpect.EOF:
3750 main.log.error( self.name + ": EOF exception found" )
3751 main.log.error( self.name + ": " + self.handle.before )
3752 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003753 except Exception:
3754 main.log.exception( self.name + ": Uncaught exception!" )
3755 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003756
Jon Hall892818c2015-10-20 17:58:34 -07003757 def createHostComponent( self, name ):
3758 """
3759 Creates a new mininet cli component with the same parameters as self.
3760 This new component is intended to be used to login to the hosts created
3761 by mininet.
3762
3763 Arguments:
3764 name - The string of the name of this component. The new component
3765 will be assigned to main.<name> .
3766 In addition, main.<name>.name = str( name )
3767 """
3768 try:
3769 # look to see if this component already exists
3770 getattr( main, name )
3771 except AttributeError:
3772 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003773 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3774 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003775 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003776 except pexpect.EOF:
3777 main.log.error( self.name + ": EOF exception found" )
3778 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003779 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003780 except Exception:
3781 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003782 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003783 else:
3784 # namespace is not clear!
3785 main.log.error( name + " component already exists!" )
3786 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003787 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003788
3789 def removeHostComponent( self, name ):
3790 """
3791 Remove host component
3792 Arguments:
3793 name - The string of the name of the component to delete.
3794 """
3795 try:
3796 # Get host component
3797 component = getattr( main, name )
3798 except AttributeError:
3799 main.log.error( "Component " + name + " does not exist." )
3800 return
3801 try:
3802 # Disconnect from component
3803 component.disconnect()
3804 # Delete component
3805 delattr( main, name )
3806 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003807 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003808 except pexpect.EOF:
3809 main.log.error( self.name + ": EOF exception found" )
3810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003811 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003812 except Exception:
3813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003814 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003815
3816 def startHostCli( self, host=None ):
3817 """
3818 Use the mininet m utility to connect to the host's cli
3819 """
3820 # These are fields that can be used by scapy packets. Initialized to None
3821 self.hostIp = None
3822 self.hostMac = None
3823 try:
3824 if not host:
3825 host = self.name
3826 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003827 self.handle.sendline( "cd" )
3828 self.handle.expect( self.hostPrompt )
3829 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003830 self.handle.expect( self.hostPrompt )
3831 return main.TRUE
3832 except pexpect.TIMEOUT:
3833 main.log.exception( self.name + ": Command timed out" )
3834 return main.FALSE
3835 except pexpect.EOF:
3836 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003837 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003838 except Exception:
3839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003840 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003841
YPZhang801d46d2016-08-08 13:26:28 -07003842 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003843 '''
3844
YPZhang801d46d2016-08-08 13:26:28 -07003845 Args:
3846 devicename: switch name
3847 intf: port name on switch
3848 status: up or down
3849
3850 Returns: boolean to show success change status
3851
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003852 '''
YPZhang801d46d2016-08-08 13:26:28 -07003853 if status == "down" or status == "up":
3854 try:
3855 cmd = devicename + " ifconfig " + intf + " " + status
3856 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003857 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003858 return main.TRUE
3859 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003860 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003861 return main.FALSE
3862 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003863 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003864 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003865 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003866 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003867 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003868 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003869 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003870 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003871 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003872 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003873 return main.FALSE
3874
3875
adminbae64d82013-08-01 10:50:15 -07003876if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003877 sys.modules[ __name__ ] = MininetCliDriver()