blob: d5adc69f3f840d9356240712a1d50d23b4f94fc6 [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 Ronquillo23fb2162017-09-15 14:59:57 -07004Copyright 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
Jon Hall1ccf82c2014-10-15 14:55:16 -040041from math import pow
adminbae64d82013-08-01 10:50:15 -070042from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070043from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070044
Jon Hall7eb38402015-01-08 17:19:54 -080045
kelvin-onlab50907142015-04-01 13:37:45 -070046class MininetCliDriver( Emulator ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070047
Jon Hall7eb38402015-01-08 17:19:54 -080048 """
49 MininetCliDriver is the basic driver which will handle
50 the Mininet functions"""
51 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070052 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070053 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080054 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070055 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080056 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070057 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070058 # TODO: Refactor driver to use these everywhere
59 self.mnPrompt = "mininet>"
60 self.hostPrompt = "~#"
61 self.bashPrompt = "\$"
62 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070063 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070064
Jon Hall7eb38402015-01-08 17:19:54 -080065 def connect( self, **connectargs ):
66 """
67 Here the main is the TestON instance after creating
68 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080069 try:
70 for key in connectargs:
71 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070072 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080073 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070074 for key in self.options:
75 if key == "home":
76 self.home = self.options[ 'home' ]
77 break
78 if self.home is None or self.home == "":
79 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070080
81 try:
Jon Hall892818c2015-10-20 17:58:34 -070082 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070083 self.ip_address = os.getenv( str( self.ip_address ) )
84 else:
85 main.log.info( self.name +
86 ": Trying to connect to " +
87 self.ip_address )
88
89 except KeyError:
90 main.log.info( "Invalid host name," +
91 " connecting to local host instead" )
92 self.ip_address = 'localhost'
93 except Exception as inst:
94 main.log.error( "Uncaught exception: " + str( inst ) )
95
kelvin-onlaba1484582015-02-02 15:46:20 -080096 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070097 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080098 self ).connect(
99 user_name=self.user_name,
100 ip_address=self.ip_address,
101 port=None,
102 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800103
kelvin-onlaba1484582015-02-02 15:46:20 -0800104 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800105 main.log.info( "Connection successful to the host " +
106 self.user_name +
107 "@" +
108 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800109 return main.TRUE
110 else:
111 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800112 self.user_name +
113 "@" +
114 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800115 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800116 return main.FALSE
117 except pexpect.EOF:
118 main.log.error( self.name + ": EOF exception found" )
119 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700120 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800121 except Exception:
122 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700123 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800124
kelvin-onlab10e8d392015-06-03 13:53:45 -0700125 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800126 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700127 Description:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700128 Starts Mininet accepts a topology( .py ) file and/or an optional
kelvin-onlabf512e942015-06-08 19:42:59 -0700129 argument, to start the mininet, as a parameter.
130 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700131 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700132 Options:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700133 topoFile = file path for topology file ( .py )
kelvin-onlabf512e942015-06-08 19:42:59 -0700134 args = extra option added when starting the topology from the file
135 mnCmd = Mininet command use to start topology
136 Returns:
137 main.TRUE if the mininet starts successfully, main.FALSE
138 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800139 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700140 try:
141 if self.handle:
142 # make sure old networks are cleaned up
143 main.log.info( self.name +
144 ": Clearing any residual state or processes" )
145 self.handle.sendline( "sudo mn -c" )
146 i = self.handle.expect( [ 'password\sfor\s',
147 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800148 pexpect.EOF,
149 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700150 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800151 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700152 # Sudo asking for password
153 main.log.info( self.name + ": Sending sudo password" )
154 self.handle.sendline( self.pwd )
155 i = self.handle.expect( [ '%s:' % self.user,
Devin Limdc78e202017-06-09 18:30:07 -0700156 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700157 pexpect.EOF,
158 pexpect.TIMEOUT ],
159 timeout )
160 if i == 1:
161 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700162 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700163 main.log.error( self.name + ": Connection terminated" )
164 elif i == 3: # timeout
165 main.log.error( self.name + ": Something while cleaning " +
166 "Mininet took too long... " )
167 # Craft the string to start mininet
168 cmdString = "sudo "
169 if not mnCmd:
170 if topoFile is None or topoFile == '': # If no file is given
171 main.log.info( self.name + ": building fresh Mininet" )
172 cmdString += "mn "
173 if args is None or args == '':
174 # If no args given, use args from .topo file
175 args = self.options[ 'arg1' ] +\
176 " " + self.options[ 'arg2' ] +\
177 " --mac --controller " +\
178 self.options[ 'controller' ] + " " +\
179 self.options[ 'arg3' ]
180 else: # else only use given args
181 pass
182 # TODO: allow use of topo args and method args?
183 else: # Use given topology file
184 main.log.info(
185 "Starting Mininet from topo file " +
186 topoFile )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700187 cmdString += "-E python " + topoFile + " "
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700188 if args is None:
189 args = ''
190 # TODO: allow use of args from .topo file?
191 cmdString += args
192 else:
193 main.log.info( "Starting Mininet topology using '" + mnCmd +
194 "' command" )
195 cmdString += mnCmd
196 # Send the command and check if network started
197 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700198 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700199 main.log.info( "Sending '" + cmdString + "' to " + self.name )
200 self.handle.sendline( cmdString )
201 while True:
202 i = self.handle.expect( [ 'mininet>',
203 'Exception',
204 '\*\*\*',
205 pexpect.EOF,
206 pexpect.TIMEOUT ],
207 timeout )
208 if i == 0:
209 main.log.info( self.name + ": Mininet built" )
210 return main.TRUE
211 elif i == 1:
212 response = str( self.handle.before +
213 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700214 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700215 response += str( self.handle.before +
216 self.handle.after )
217 main.log.error(
218 self.name +
219 ": Launching Mininet failed: " + response )
220 return main.FALSE
221 elif i == 2:
222 self.handle.expect( [ "\n",
223 pexpect.EOF,
224 pexpect.TIMEOUT ],
225 timeout )
226 main.log.info( self.handle.before )
227 elif i == 3:
228 main.log.error( self.name + ": Connection timeout" )
229 return main.FALSE
230 elif i == 4: # timeout
231 main.log.error(
232 self.name +
233 ": Something took too long... " )
234 return main.FALSE
235 # Why did we hit this part?
236 main.log.error( "startNet did not return correctly" )
237 return main.FASLE
238 else: # if no handle
239 main.log.error( self.name + ": Connection failed to the host " +
240 self.user_name + "@" + self.ip_address )
241 main.log.error( self.name + ": Failed to connect to the Mininet" )
242 return main.FALSE
243 except pexpect.TIMEOUT:
244 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
245 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700246 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700247 except pexpect.EOF:
248 main.log.error( self.name + ": EOF exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700251 except Exception:
252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800254
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800255 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700256 try:
257 if topoType == 'tree':
258 # In tree topology, if fanout arg is not given, by default it is 2
259 if fanout is None:
260 fanout = 2
261 k = 0
262 count = 0
263 while( k <= depth - 1 ):
264 count = count + pow( fanout, k )
265 k = k + 1
266 numSwitches = count
267 while( k <= depth - 2 ):
268 # depth-2 gives you only core links and not considering
269 # edge links as seen by ONOS. If all the links including
270 # edge links are required, do depth-1
271 count = count + pow( fanout, k )
272 k = k + 1
273 numLinks = count * fanout
274 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
275 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800276
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700277 elif topoType == 'linear':
278 # In linear topology, if fanout or numHostsPerSw is not given,
279 # by default it is 1
280 if fanout is None:
281 fanout = 1
282 numSwitches = depth
283 numHostsPerSw = fanout
284 totalNumHosts = numSwitches * numHostsPerSw
285 numLinks = totalNumHosts + ( numSwitches - 1 )
286 print "num_switches for %s(%d,%d) = %d and links=%d" %\
287 ( topoType, depth, fanout, numSwitches, numLinks )
288 topoDict = { "num_switches": int( numSwitches ),
289 "num_corelinks": int( numLinks ) }
290 return topoDict
291 except Exception:
292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700293 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400294
kelvin-onlabd3b64892015-01-20 13:26:24 -0800295 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700296 """
297 Calculate the number of switches and links in a topo."""
298 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700299 try:
300 argList = self.options[ 'arg1' ].split( "," )
301 topoArgList = argList[ 0 ].split( " " )
302 argList = map( int, argList[ 1: ] )
303 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700304
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700305 topoDict = self.numSwitchesNlinks( *topoArgList )
306 return topoDict
307 except Exception:
308 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700309 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400310
GlennRCf07c44a2015-09-18 13:33:46 -0700311 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800312 """
313 Verifies the reachability of the hosts using pingall command.
314 Optional parameter timeout allows you to specify how long to
315 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700316 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700317 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700318 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700319 ping
320 acceptableFailed - Set the number of acceptable failed pings for the
321 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800322 Returns:
323 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700324 otherwise main.FALSE
325 """
326 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700327 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700328 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700329 if self.handle:
330 main.log.info(
331 self.name +
332 ": Checking reachabilty to the hosts using pingall" )
333 response = ""
334 failedPings = 0
335 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700336 cmd = "pingall"
337 if protocol == "IPv6":
338 cmd = "py net.pingAll6()"
339 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700340 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700341 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700342 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700343 pexpect.EOF,
344 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700345 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700346 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700347 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700348 response += self.handle.before
349 break
350 elif i == 1:
351 response += self.handle.before + self.handle.after
352 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700353 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700354 returnValue = main.FALSE
355 if shortCircuit:
356 main.log.error( self.name +
357 ": Aborting pingall - "
358 + str( failedPings ) +
359 " pings failed" )
360 break
Jon Hall390696c2015-05-05 17:13:41 -0700361 if ( time.time() - startTime ) > timeout:
362 returnValue = main.FALSE
363 main.log.error( self.name +
364 ": Aborting pingall - " +
365 "Function took too long " )
366 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700367 elif i == 2:
368 main.log.error( self.name +
369 ": EOF exception found" )
370 main.log.error( self.name + ": " +
371 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700372 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700373 elif i == 3:
374 response += self.handle.before
375 main.log.error( self.name +
376 ": TIMEOUT exception found" )
377 main.log.error( self.name +
378 ": " +
379 str( response ) )
380 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800381 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700382 self.handle.expect( "Interrupt" )
383 self.handle.expect( "mininet>" )
384 break
385 pattern = "Results\:"
386 main.log.info( "Pingall output: " + str( response ) )
387 if re.search( pattern, response ):
388 main.log.info( self.name + ": Pingall finished with "
389 + str( failedPings ) + " failed pings" )
390 return returnValue
391 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700392 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800393 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700394 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700395 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700396 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700397 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700398 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700399 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700400 except pexpect.TIMEOUT:
401 if response:
402 main.log.info( "Pingall output: " + str( response ) )
403 main.log.error( self.name + ": pexpect.TIMEOUT found" )
404 return main.FALSE
405 except pexpect.EOF:
406 main.log.error( self.name + ": EOF exception found" )
407 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700408 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700409
Jon Hall7eb38402015-01-08 17:19:54 -0800410 def fpingHost( self, **pingParams ):
411 """
412 Uses the fping package for faster pinging...
413 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700414 try:
415 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
416 command = args[ "SRC" ] + \
417 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
418 self.handle.sendline( command )
419 self.handle.expect(
420 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
421 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
422 response = self.handle.before
423 if re.search( ":\s-", response ):
424 main.log.info( self.name + ": Ping fail" )
425 return main.FALSE
426 elif re.search( ":\s\d{1,2}\.\d\d", response ):
427 main.log.info( self.name + ": Ping good!" )
428 return main.TRUE
429 main.log.info( self.name + ": Install fping on mininet machine... " )
430 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700431 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700432 except Exception:
433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700434 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700435
Jon Hall3b489db2015-10-05 14:38:37 -0700436 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400437 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700438 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700439
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400440 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700441 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700442
443 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400444 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700445
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400446 Returns main.FALSE if one or more of hosts specified
447 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700448 wait = int( wait )
449 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400450
451 try:
452 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700453
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400454 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700455 pingResponse = "IPv4 ping across specified hosts\n"
456 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400457 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700458 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400459 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700460 pingList = hostList[ :listIndex ] + \
461 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700462
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700463 pingResponse += str( str( host ) + " -> " )
GlennRCd10d3cc2015-09-24 12:47:16 -0700464
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400465 for temp in pingList:
466 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700467 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700468 self.handle.sendline( pingCmd )
469 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400470 response = self.handle.before
471 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700472 pingResponse += str( " h" + str( temp[ 1: ] ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400473 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700474 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400475 # One of the host to host pair is unreachable
476 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700477 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700478 pingResponse += "\n"
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700479 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700480 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700481 except pexpect.TIMEOUT:
482 main.log.exception( self.name + ": TIMEOUT exception" )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700483 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400484 except pexpect.EOF:
485 main.log.error( self.name + ": EOF exception found" )
486 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700487 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700488 except Exception:
489 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700490 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400491
Jon Hall3b489db2015-10-05 14:38:37 -0700492 def pingIpv6Hosts( self, hostList, prefix='1000::', wait=1 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700493 """
Jon Hall3b489db2015-10-05 14:38:37 -0700494 IPv6 ping all hosts in hostList. If no prefix passed this will use
495 default prefix of 1000::
Hari Krishna9592fc82015-07-31 15:11:15 -0700496
Jon Hall3b489db2015-10-05 14:38:37 -0700497 Returns main.TRUE if all hosts specified can reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700498
Jon Hall3b489db2015-10-05 14:38:37 -0700499 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700500 """
501 try:
502 main.log.info( "Testing reachability between specified IPv6 hosts" )
503 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700504 wait = int( wait )
505 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700506 pingResponse = "IPv6 Pingall output:\n"
507 failedPings = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700508 for host in hostList:
509 listIndex = hostList.index( host )
510 # List of hosts to ping other than itself
511 pingList = hostList[ :listIndex ] + \
512 hostList[ ( listIndex + 1 ): ]
513
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700514 pingResponse += str( str( host ) + " -> " )
GlennRC2cf7d952015-09-11 16:32:13 -0700515
Hari Krishna9592fc82015-07-31 15:11:15 -0700516 for temp in pingList:
517 # Current host pings all other hosts specified
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700518 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
Jon Hall934576d2015-10-09 10:12:22 -0700519 self.handle.sendline( pingCmd )
520 self.handle.expect( "mininet>", timeout=wait + 1 )
Hari Krishna9592fc82015-07-31 15:11:15 -0700521 response = self.handle.before
522 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700523 pingResponse += str( " h" + str( temp[ 1: ] ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700524 else:
GlennRC2cf7d952015-09-11 16:32:13 -0700525 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700526 # One of the host to host pair is unreachable
527 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700528 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700529 pingResponse += "\n"
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700530 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700531 return isReachable
532
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700533 except pexpect.TIMEOUT:
534 main.log.exception( self.name + ": TIMEOUT exception" )
535 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700536 except pexpect.EOF:
537 main.log.error( self.name + ": EOF exception found" )
538 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700539 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700540 except Exception:
541 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700542 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700543
Jon Hall7eb38402015-01-08 17:19:54 -0800544 def pingHost( self, **pingParams ):
545 """
Jon Hall3b489db2015-10-05 14:38:37 -0700546 Ping from one mininet host to another
547 Currently the only supported Params: SRC, TARGET, and WAIT
548 """
549 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700550 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700551 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800552 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700553 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700554 try:
Jon Hall61282e32015-03-19 11:34:11 -0700555 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800556 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700557 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
558 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700559 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800560 main.log.error(
561 self.name +
562 ": timeout when waiting for response from mininet" )
563 main.log.error( "response: " + str( self.handle.before ) )
564 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700565 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800566 main.log.error(
567 self.name +
568 ": timeout when waiting for response from mininet" )
569 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700570 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700571 if re.search( ',\s0\%\spacket\sloss', response ):
572 main.log.info( self.name + ": no packets lost, host is reachable" )
573 return main.TRUE
574 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800575 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700576 self.name +
577 ": PACKET LOST, HOST IS NOT REACHABLE" )
578 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800579 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800580 main.log.error( self.name + ": EOF exception found" )
581 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700582 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700583 except Exception:
584 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700585 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700586
587 def ping6pair( self, **pingParams ):
588 """
GlennRC2cf7d952015-09-11 16:32:13 -0700589 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700590 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700591 FLOWLABEL and -I ( src interface ) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700592 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
593 """
Jon Hall3b489db2015-10-05 14:38:37 -0700594 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700595 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700596 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530597 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700598 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700599 try:
600 main.log.info( "Sending: " + command )
601 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700602 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
603 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700604 if i == 1:
605 main.log.error(
606 self.name +
607 ": timeout when waiting for response from mininet" )
608 main.log.error( "response: " + str( self.handle.before ) )
609 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
610 if i == 1:
611 main.log.error(
612 self.name +
613 ": timeout when waiting for response from mininet" )
614 main.log.error( "response: " + str( self.handle.before ) )
615 response = self.handle.before
616 main.log.info( self.name + ": Ping Response: " + response )
617 if re.search( ',\s0\%\spacket\sloss', response ):
618 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700619 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700620 else:
alisone4121a92016-11-22 16:31:36 -0800621 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700622 self.name +
623 ": PACKET LOST, HOST IS NOT REACHABLE" )
624 return main.FALSE
625
626 except pexpect.EOF:
627 main.log.error( self.name + ": EOF exception found" )
628 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700629 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700630 except Exception:
631 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700632 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800633
You Wangdb927a52016-02-26 11:03:28 -0800634 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
635 """
636 Description:
637 Ping a set of destination host from host CLI.
638 Logging into a Mininet host CLI is required before calling this funtion.
639 Params:
640 dstIPList is a list of destination ip addresses
641 Returns:
642 main.TRUE if the destination host is reachable
643 main.FALSE otherwise
644 """
645 isReachable = main.TRUE
646 wait = int( wait )
647 cmd = "ping"
648 if IPv6:
649 cmd = cmd + "6"
650 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
651 try:
652 for dstIP in dstIPList:
653 pingCmd = cmd + " " + dstIP
654 self.handle.sendline( pingCmd )
655 i = self.handle.expect( [ self.hostPrompt,
656 '\*\*\* Unknown command: ' + pingCmd,
657 pexpect.TIMEOUT ],
658 timeout=wait + 1 )
659 if i == 0:
660 response = self.handle.before
661 if not re.search( ',\s0\%\spacket\sloss', response ):
662 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
663 isReachable = main.FALSE
664 elif i == 1:
665 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700666 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800667 elif i == 2:
668 main.log.error( self.name + ": timeout when waiting for response" )
669 isReachable = main.FALSE
670 else:
671 main.log.error( self.name + ": unknown response: " + self.handle.before )
672 isReachable = main.FALSE
673 except pexpect.TIMEOUT:
674 main.log.exception( self.name + ": TIMEOUT exception" )
675 isReachable = main.FALSE
676 except pexpect.EOF:
677 main.log.error( self.name + ": EOF exception found" )
678 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700679 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800680 except Exception:
681 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700682 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800683 return isReachable
684
Jon Hall7eb38402015-01-08 17:19:54 -0800685 def checkIP( self, host ):
686 """
687 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700688 try:
689 if self.handle:
690 try:
691 response = self.execute(
692 cmd=host +
693 " ifconfig",
694 prompt="mininet>",
695 timeout=10 )
696 except pexpect.EOF:
697 main.log.error( self.name + ": EOF exception found" )
698 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700699 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700700
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700701 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
702 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
703 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
704 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
705 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
706 "[0-9]|25[0-5]|[0-9]{1,2})"
707 # pattern = "inet addr:10.0.0.6"
708 if re.search( pattern, response ):
709 main.log.info( self.name + ": Host Ip configured properly" )
710 return main.TRUE
711 else:
712 main.log.error( self.name + ": Host IP not found" )
713 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700714 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700715 main.log.error( self.name + ": Connection failed to the host" )
716 except Exception:
717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700718 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800719
Jon Hall7eb38402015-01-08 17:19:54 -0800720 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800721 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700722 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800723 response = self.execute(
724 cmd="h1 /usr/sbin/sshd -D&",
725 prompt="mininet>",
726 timeout=10 )
727 response = self.execute(
728 cmd="h4 /usr/sbin/sshd -D&",
729 prompt="mininet>",
730 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700731 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 vars( self )[ key ] = connectargs[ key ]
733 response = self.execute(
734 cmd="xterm h1 h4 ",
735 prompt="mininet>",
736 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800737 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700740 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700741 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800742 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700743 if self.flag == 0:
744 self.flag = 1
745 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800746 else:
adminbae64d82013-08-01 10:50:15 -0700747 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800748
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700749 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700750 """
751 Moves a host from one switch to another on the fly
752 Note: The intf between host and oldSw when detached
753 using detach(), will still show up in the 'net'
754 cmd, because switch.detach() doesn't affect switch.intfs[]
755 ( which is correct behavior since the interfaces
756 haven't moved ).
757 """
758 if self.handle:
759 try:
760 # Bring link between oldSw-host down
761 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
762 "'," + "'down')"
763 print "cmd1= ", cmd
764 response = self.execute( cmd=cmd,
765 prompt="mininet>",
766 timeout=10 )
767
768 # Determine hostintf and Oldswitchintf
769 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
770 ")[0]"
771 print "cmd2= ", cmd
772 self.handle.sendline( cmd )
773 self.handle.expect( "mininet>" )
774
775 # Determine ip and mac address of the host-oldSw interface
776 cmd = "px ipaddr = hintf.IP()"
777 print "cmd3= ", cmd
778 self.handle.sendline( cmd )
779 self.handle.expect( "mininet>" )
780
781 cmd = "px macaddr = hintf.MAC()"
782 print "cmd3= ", cmd
783 self.handle.sendline( cmd )
784 self.handle.expect( "mininet>" )
785
786 # Detach interface between oldSw-host
787 cmd = "px " + oldSw + ".detach( sintf )"
788 print "cmd4= ", cmd
789 self.handle.sendline( cmd )
790 self.handle.expect( "mininet>" )
791
792 # Add link between host-newSw
793 cmd = "py net.addLink(" + host + "," + newSw + ")"
794 print "cmd5= ", cmd
795 self.handle.sendline( cmd )
796 self.handle.expect( "mininet>" )
797
798 # Determine hostintf and Newswitchintf
799 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
800 ")[0]"
801 print "cmd6= ", cmd
802 self.handle.sendline( cmd )
803 self.handle.expect( "mininet>" )
804
805 # Attach interface between newSw-host
806 cmd = "px " + newSw + ".attach( sintf )"
807 print "cmd3= ", cmd
808 self.handle.sendline( cmd )
809 self.handle.expect( "mininet>" )
810
811 # Set ipaddress of the host-newSw interface
812 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
813 print "cmd7 = ", cmd
814 self.handle.sendline( cmd )
815 self.handle.expect( "mininet>" )
816
817 # Set macaddress of the host-newSw interface
818 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
819 print "cmd8 = ", cmd
820 self.handle.sendline( cmd )
821 self.handle.expect( "mininet>" )
822
823 cmd = "net"
824 print "cmd9 = ", cmd
825 self.handle.sendline( cmd )
826 self.handle.expect( "mininet>" )
827 print "output = ", self.handle.before
828
829 # Determine ipaddress of the host-newSw interface
830 cmd = host + " ifconfig"
831 print "cmd10= ", cmd
832 self.handle.sendline( cmd )
833 self.handle.expect( "mininet>" )
834 print "ifconfig o/p = ", self.handle.before
835
836 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700837
838 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700839 main.log.error( self.name + ": TIMEOUT exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700841 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700842 except pexpect.EOF:
843 main.log.error( self.name + ": EOF exception found" )
844 main.log.error( self.name + ": " + self.handle.before )
845 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700846 except Exception:
847 main.log.exception( self.name + ": Uncaught exception!" )
848 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700849
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700850 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800851 """
852 Moves a host from one switch to another on the fly
853 Note: The intf between host and oldSw when detached
854 using detach(), will still show up in the 'net'
855 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700856 ( which is correct behavior since the interfaces
857 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800858 """
859 if self.handle:
860 try:
Jon Hall439c8912016-04-15 02:22:03 -0700861 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800862 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700863 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800864 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800865 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800866 response = self.execute( cmd=cmd,
867 prompt="mininet>",
868 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700869
kelvin-onlaba1484582015-02-02 15:46:20 -0800870 # Determine hostintf and Oldswitchintf
871 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800872 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800873 print "cmd2= ", cmd
874 self.handle.sendline( cmd )
875 self.handle.expect( "mininet>" )
876
shahshreya73537862015-02-11 15:15:24 -0800877 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700878 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800879 print "cmd3= ", cmd
880 self.handle.sendline( cmd )
881 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800882
883 cmd = "px macaddr = hintf.MAC()"
884 print "cmd3= ", cmd
885 self.handle.sendline( cmd )
886 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700887
kelvin-onlaba1484582015-02-02 15:46:20 -0800888 # Detach interface between oldSw-host
889 cmd = "px " + oldSw + ".detach( sintf )"
890 print "cmd4= ", cmd
891 self.handle.sendline( cmd )
892 self.handle.expect( "mininet>" )
893
894 # Add link between host-newSw
895 cmd = "py net.addLink(" + host + "," + newSw + ")"
896 print "cmd5= ", cmd
897 self.handle.sendline( cmd )
898 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700899
kelvin-onlaba1484582015-02-02 15:46:20 -0800900 # Determine hostintf and Newswitchintf
901 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800902 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800903 print "cmd6= ", cmd
904 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700905 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800906
907 # Attach interface between newSw-host
908 cmd = "px " + newSw + ".attach( sintf )"
Jon Hall439c8912016-04-15 02:22:03 -0700909 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800910 self.handle.sendline( cmd )
911 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800912
913 # Set macaddress of the host-newSw interface
914 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700915 print "cmd7 = ", cmd
916 self.handle.sendline( cmd )
917 self.handle.expect( "mininet>" )
918
919 # Set ipaddress of the host-newSw interface
920 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800921 print "cmd8 = ", cmd
922 self.handle.sendline( cmd )
923 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700924
Jon Hall439c8912016-04-15 02:22:03 -0700925 cmd = host + " ifconfig"
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700926 print "cmd9 =", cmd
927 response = self.execute( cmd=cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -0700928 print response
929 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700930 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700931 print ipAddressSearch.group( 1 )
932 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -0700933 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
934 print "cmd10 = ", cmd
935 self.handle.sendline( cmd )
936 self.handle.expect( "mininet>" )
937
kelvin-onlaba1484582015-02-02 15:46:20 -0800938 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700939 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800940 self.handle.sendline( cmd )
941 self.handle.expect( "mininet>" )
942 print "output = ", self.handle.before
943
944 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800945 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700946 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800947 self.handle.sendline( cmd )
948 self.handle.expect( "mininet>" )
949 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700950
kelvin-onlaba1484582015-02-02 15:46:20 -0800951 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700952 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700953 main.log.error( self.name + ": TIMEOUT exception found" )
954 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700955 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800956 except pexpect.EOF:
957 main.log.error( self.name + ": EOF exception found" )
958 main.log.error( self.name + ": " + self.handle.before )
959 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700960 except Exception:
961 main.log.exception( self.name + ": Uncaught exception!" )
962 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800963
Jon Hall7eb38402015-01-08 17:19:54 -0800964 def changeIP( self, host, intf, newIP, newNetmask ):
965 """
966 Changes the ip address of a host on the fly
967 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800968 if self.handle:
969 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800970 cmd = host + " ifconfig " + intf + " " + \
971 newIP + " " + 'netmask' + " " + newNetmask
972 self.handle.sendline( cmd )
973 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800974 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800975 main.log.info( "response = " + response )
976 main.log.info(
977 "Ip of host " +
978 host +
979 " changed to new IP " +
980 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800981 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700982 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700983 main.log.error( self.name + ": TIMEOUT exception found" )
984 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800986 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800989 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700990 except Exception:
991 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700992 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800993
Jon Hall7eb38402015-01-08 17:19:54 -0800994 def changeDefaultGateway( self, host, newGW ):
995 """
996 Changes the default gateway of a host
997 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800998 if self.handle:
999 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001000 cmd = host + " route add default gw " + newGW
1001 self.handle.sendline( cmd )
1002 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001003 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001004 main.log.info( "response = " + response )
1005 main.log.info(
1006 "Default gateway of host " +
1007 host +
1008 " changed to " +
1009 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001010 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001011 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001012 main.log.error( self.name + ": TIMEOUT exception found" )
1013 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001014 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001015 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001016 main.log.error( self.name + ": EOF exception found" )
1017 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001018 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001019 except Exception:
1020 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001021 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001022
Jon Hall7eb38402015-01-08 17:19:54 -08001023 def addStaticMACAddress( self, host, GW, macaddr ):
1024 """
Jon Hallefbd9792015-03-05 16:11:36 -08001025 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001026 if self.handle:
1027 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001028 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1029 cmd = host + " arp -s " + GW + " " + macaddr
1030 self.handle.sendline( cmd )
1031 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001032 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001033 main.log.info( "response = " + response )
1034 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001035 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001036 GW +
1037 " changed to " +
1038 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001039 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001040 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001041 main.log.error( self.name + ": TIMEOUT exception found" )
1042 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001044 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001047 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001048 except Exception:
1049 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001050 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001051
Jon Hall7eb38402015-01-08 17:19:54 -08001052 def verifyStaticGWandMAC( self, host ):
1053 """
1054 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001055 if self.handle:
1056 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001057 # h1 arp -an
1058 cmd = host + " arp -an "
1059 self.handle.sendline( cmd )
1060 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001061 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001062 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001063 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001064 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001065 main.log.error( self.name + ": TIMEOUT exception found" )
1066 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001067 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001068 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001069 main.log.error( self.name + ": EOF exception found" )
1070 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001071 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001072 except Exception:
1073 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001074 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001075
Jon Hall7eb38402015-01-08 17:19:54 -08001076 def getMacAddress( self, host ):
1077 """
1078 Verifies the host's ip configured or not."""
1079 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001080 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001081 response = self.execute(
1082 cmd=host +
1083 " ifconfig",
1084 prompt="mininet>",
1085 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001086 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001087 main.log.error( self.name + ": EOF exception found" )
1088 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001089 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001090 except Exception:
1091 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001092 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001093
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001094 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 macAddressSearch = re.search( pattern, response, re.I )
1096 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001097 main.log.info(
1098 self.name +
1099 ": Mac-Address of Host " +
1100 host +
1101 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 macAddress )
1103 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001104 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001105 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001106
Jon Hall7eb38402015-01-08 17:19:54 -08001107 def getInterfaceMACAddress( self, host, interface ):
1108 """
1109 Return the IP address of the interface on the given host"""
1110 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001111 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001112 response = self.execute( cmd=host + " ifconfig " + interface,
1113 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001114 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001115 main.log.error( self.name + ": EOF exception found" )
1116 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001117 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001118 except Exception:
1119 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001120 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001121
1122 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 macAddressSearch = re.search( pattern, response, re.I )
1124 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001125 main.log.info( "No mac address found in %s" % response )
1126 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001128 main.log.info(
1129 "Mac-Address of " +
1130 host +
1131 ":" +
1132 interface +
1133 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 macAddress )
1135 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001136 else:
1137 main.log.error( "Connection failed to the host" )
1138
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001139 def getIPAddress( self, host, proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001140 """
1141 Verifies the host's ip configured or not."""
1142 if self.handle:
1143 try:
1144 response = self.execute(
1145 cmd=host +
1146 " ifconfig",
1147 prompt="mininet>",
1148 timeout=10 )
1149 except pexpect.EOF:
1150 main.log.error( self.name + ": EOF exception found" )
1151 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001153 except Exception:
1154 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001155 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001156
sathishmad953462015-12-03 17:42:07 +05301157 pattern = ''
1158 if proto == 'IPV4':
1159 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1160 else:
Jon Hall439c8912016-04-15 02:22:03 -07001161 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001163 main.log.info(
1164 self.name +
1165 ": IP-Address of Host " +
1166 host +
1167 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 ipAddressSearch.group( 1 ) )
1169 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001170 else:
1171 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001172
Jon Hall7eb38402015-01-08 17:19:54 -08001173 def getSwitchDPID( self, switch ):
1174 """
1175 return the datapath ID of the switch"""
1176 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001177 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001178 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001179 response = self.execute(
1180 cmd=cmd,
1181 prompt="mininet>",
1182 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001183 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001184 main.log.error( self.name + ": EOF exception found" )
1185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001186 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001187 except Exception:
1188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001189 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001190 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001191 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001192 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001193 main.log.info(
1194 "Couldn't find DPID for switch %s, found: %s" %
1195 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001196 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001197 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001198 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001199 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001200
Jon Hall7eb38402015-01-08 17:19:54 -08001201 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001202 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001203 self.handle.sendline( "" )
1204 self.expect( "mininet>" )
1205 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001206 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001207 response = self.execute(
1208 cmd=cmd,
1209 prompt="mininet>",
1210 timeout=10 )
1211 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001212 response = self.handle.before
1213 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001214 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001215 main.log.error( self.name + ": TIMEOUT exception found" )
1216 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001217 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001218 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001219 main.log.error( self.name + ": EOF exception found" )
1220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001221 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001222 except Exception:
1223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001224 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001225
Jon Hall7eb38402015-01-08 17:19:54 -08001226 def getInterfaces( self, node ):
1227 """
1228 return information dict about interfaces connected to the node"""
1229 if self.handle:
1230 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001231 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001232 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001233 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001234 response = self.execute(
1235 cmd=cmd,
1236 prompt="mininet>",
1237 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001238 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001239 main.log.error( self.name + ": EOF exception found" )
1240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001241 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001242 except Exception:
1243 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001244 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001245 return response
1246 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001247 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001248
Jon Hall7eb38402015-01-08 17:19:54 -08001249 def dump( self ):
1250 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001251 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001252 response = self.execute(
1253 cmd='dump',
1254 prompt='mininet>',
1255 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001256 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001257 main.log.error( self.name + ": EOF exception found" )
1258 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001259 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001260 except Exception:
1261 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001262 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001263 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001264
Jon Hall7eb38402015-01-08 17:19:54 -08001265 def intfs( self ):
1266 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001267 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001268 response = self.execute(
1269 cmd='intfs',
1270 prompt='mininet>',
1271 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001272 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001273 main.log.error( self.name + ": EOF exception found" )
1274 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001275 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001276 except Exception:
1277 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001278 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001279 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001280
Jon Hall7eb38402015-01-08 17:19:54 -08001281 def net( self ):
1282 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001283 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001284 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001285 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001286 main.log.error( self.name + ": EOF exception found" )
1287 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001288 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001289 except Exception:
1290 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001291 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001292 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001293
YPZhang81a7d4e2016-04-18 13:10:17 -07001294 def links( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001295 main.log.info( self.name + ": List network links" )
1296 try:
1297 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001298 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001299 except pexpect.EOF:
1300 main.log.error( self.name + ": EOF exception found" )
1301 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001302 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001303 except Exception:
1304 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001305 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001306 return response
1307
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001308 def iperftcpAll( self, hosts, timeout=6 ):
1309 """
kelvin-onlab7cce9382015-07-17 10:21:03 -07001310 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001311
kelvin-onlab7cce9382015-07-17 10:21:03 -07001312 @parm:
1313 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1314 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001315 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001316 try:
1317 for host1 in hosts:
1318 for host2 in hosts:
1319 if host1 != host2:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001320 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1321 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001322 except Exception:
1323 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001324 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001325
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001326 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
1327 """
kelvin-onlab7cce9382015-07-17 10:21:03 -07001328 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1329 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001330
kelvin-onlab7cce9382015-07-17 10:21:03 -07001331 @parm:
1332 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1333 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001334 """
kelvin-onlab7cce9382015-07-17 10:21:03 -07001335 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1336 try:
1337 # Setup the mininet command
1338 cmd1 = 'iperf ' + host1 + " " + host2
1339 self.handle.sendline( cmd1 )
1340 outcome = self.handle.expect( "mininet>", timeout )
1341 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001342
kelvin-onlab7cce9382015-07-17 10:21:03 -07001343 # checks if there are results in the mininet response
1344 if "Results:" in response:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001345 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001346 # parse the mn results
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001347 response = response.split( "\r\n" )
1348 response = response[ len( response ) - 2 ]
1349 response = response.split( ": " )
1350 response = response[ len( response ) - 1 ]
1351 response = response.replace( "[", "" )
1352 response = response.replace( "]", "" )
1353 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001354
kelvin-onlab7cce9382015-07-17 10:21:03 -07001355 # this is the bandwith two and from the two hosts
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001356 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001357
kelvin-onlab7cce9382015-07-17 10:21:03 -07001358 # there should be two elements in the bandwidth list
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001359 # [ 'host1 to host2', 'host2 to host1" ]
1360 if len( bandwidth ) == 2:
1361 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001362 return main.TRUE
1363 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001364 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001365 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001366 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001367 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001368 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001369 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001370 main.log.error( self.name + ": TIMEOUT exception found" )
1371 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001372 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001373 # NOTE: Send ctrl-c to make sure iperf is done
1374 self.handle.sendline( "\x03" )
1375 self.handle.expect( "Interrupt" )
1376 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001377 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001378 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001379 main.log.error( self.name + ": EOF exception found" )
1380 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001381 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001382 except Exception:
1383 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001384 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001385
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001386 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001387 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1388 try:
1389 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001390 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001391 self.handle.sendline( cmd1 )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001392 outcome1 = self.handle.expect( "mininet>" )
1393 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001394 self.handle.sendline( cmd2 )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001395 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001396 response1 = self.handle.before
1397 response2 = self.handle.after
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001398 print response1, response2
1399 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001400 if pattern in response1:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001401 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001402 return main.TRUE
1403 else:
1404 main.log.error( self.name + ": iperf test failed" )
1405 return main.FALSE
1406 except pexpect.TIMEOUT:
1407 main.log.error( self.name + ": TIMEOUT exception found" )
1408 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1409 self.handle.sendline( "\x03" )
1410 self.handle.expect( "Interrupt" )
1411 self.handle.expect( "mininet>" )
1412 return main.FALSE
1413 except pexpect.EOF:
1414 main.log.error( self.name + ": EOF exception found" )
1415 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001416 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001417 except Exception:
1418 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001419 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001420
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001421 def iperfudpAll( self, hosts, bandwidth="10M" ):
1422 """
GlennRC61321f22015-07-16 13:36:54 -07001423 Runs the iperfudp function with a given set of hosts and specified
1424 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001425
GlennRC61321f22015-07-16 13:36:54 -07001426 @param:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001427 bandwidth: the targeted bandwidth, in megabits ( 'M' )
1428 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001429 try:
1430 for host1 in hosts:
1431 for host2 in hosts:
1432 if host1 != host2:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001433 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1434 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001435 except TypeError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001436 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001437 return main.FALSE
1438 except Exception:
1439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001440 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001441
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001442 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
1443 """
kelvin-onlab7cce9382015-07-17 10:21:03 -07001444 Creates an iperf UDP test with a specific bandwidth.
1445 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001446
kelvin-onlab7cce9382015-07-17 10:21:03 -07001447 @param:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001448 bandwidth: the targeted bandwidth, in megabits ( 'M' ), to run the test
1449 """
1450 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001451 try:
1452 # setup the mininet command
1453 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001454 self.handle.sendline( cmd )
1455 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001456 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001457
kelvin-onlab7cce9382015-07-17 10:21:03 -07001458 # check if there are in results in the mininet response
1459 if "Results:" in response:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001460 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001461 # parse the results
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001462 response = response.split( "\r\n" )
1463 response = response[ len( response ) - 2 ]
1464 response = response.split( ": " )
1465 response = response[ len( response ) - 1 ]
1466 response = response.replace( "[", "" )
1467 response = response.replace( "]", "" )
1468 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001469
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001470 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001471
kelvin-onlab7cce9382015-07-17 10:21:03 -07001472 # check to see if there are at least three entries
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001473 # [ 'bandwidth', 'host1 to host2', 'host2 to host1' ]
1474 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001475 # if one entry is blank then something is wrong
1476 for item in mnBandwidth:
1477 if item == "":
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001478 main.log.error( self.name + ": Could not parse iperf output" )
1479 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001480 return main.FALSE
1481 # otherwise results are vaild
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001482 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001483 return main.TRUE
1484 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001485 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001486 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001487
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001488 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001489 main.log.error( self.name + ": TIMEOUT exception found" )
1490 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001491 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001492 except pexpect.EOF:
1493 main.log.error( self.name + ": EOF exception found" )
1494 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001495 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001496 except Exception:
1497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001498 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001499
Jon Hall7eb38402015-01-08 17:19:54 -08001500 def nodes( self ):
1501 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001502 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001503 response = self.execute(
1504 cmd='nodes',
1505 prompt='mininet>',
1506 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001507 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001508 main.log.error( self.name + ": EOF exception found" )
1509 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001510 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001511 except Exception:
1512 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001513 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001514 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001515
Jon Hall7eb38402015-01-08 17:19:54 -08001516 def pingpair( self ):
1517 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001518 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001519 response = self.execute(
1520 cmd='pingpair',
1521 prompt='mininet>',
1522 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001523 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001524 main.log.error( self.name + ": EOF exception found" )
1525 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001526 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001527 except Exception:
1528 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001529 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001530
Jon Hall7eb38402015-01-08 17:19:54 -08001531 if re.search( ',\s0\%\spacket\sloss', response ):
1532 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001533 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001534 else:
alisone4121a92016-11-22 16:31:36 -08001535 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001536 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001537
Jon Hall7eb38402015-01-08 17:19:54 -08001538 def link( self, **linkargs ):
1539 """
GlennRCed771242016-01-13 17:02:47 -08001540 Bring link( s ) between two nodes up or down
1541 """
Jon Hall6094a362014-04-11 14:46:56 -07001542 try:
GlennRCed771242016-01-13 17:02:47 -08001543 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1544 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1545 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1546 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1547
1548 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1549 cmd = "link {} {} {}".format( end1, end2, option )
1550 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001551 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001552 response = self.handle.before
1553 main.log.info( response )
1554
1555 return main.TRUE
1556 except pexpect.TIMEOUT:
1557 main.log.exception( self.name + ": Command timed out" )
1558 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001559 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001560 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001561 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001562 except Exception:
1563 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001564 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001565
pingping-lin8244a3b2015-09-16 13:36:56 -07001566 def switch( self, **switchargs ):
1567 """
1568 start/stop a switch
1569 """
1570 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1571 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1572 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1573 command = "switch " + str( sw ) + " " + str( option )
1574 main.log.info( command )
1575 try:
1576 self.handle.sendline( command )
1577 self.handle.expect( "mininet>" )
1578 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001579 main.log.error( self.name + ": TIMEOUT exception found" )
1580 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001581 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001582 except pexpect.EOF:
1583 main.log.error( self.name + ": EOF exception found" )
1584 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001585 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001586 return main.TRUE
1587
pingping-lin5bb663b2015-09-24 11:47:50 -07001588 def node( self, nodeName, commandStr ):
1589 """
1590 Carry out a command line on a given node
1591 @parm:
1592 nodeName: the node name in Mininet testbed
1593 commandStr: the command line will be carried out on the node
1594 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1595 """
1596 command = str( nodeName ) + " " + str( commandStr )
1597 main.log.info( command )
1598
1599 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001600 response = self.execute( cmd=command, prompt="mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001601 if re.search( "Unknown command", response ):
1602 main.log.warn( response )
1603 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001604 if re.search( "Permission denied", response ):
1605 main.log.warn( response )
1606 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001607 except pexpect.EOF:
1608 main.log.error( self.name + ": EOF exception found" )
1609 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001610 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001611 main.log.info( " response is :" )
1612 main.log.info( response )
1613 return response
1614
Jon Hall7eb38402015-01-08 17:19:54 -08001615 def yank( self, **yankargs ):
1616 """
1617 yank a mininet switch interface to a host"""
1618 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001619 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001620 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1621 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1622 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001623 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001624 response = self.execute(
1625 cmd=command,
1626 prompt="mininet>",
1627 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001628 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001629 main.log.error( self.name + ": EOF exception found" )
1630 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001631 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001632 except Exception:
1633 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001634 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001635 return main.TRUE
1636
Jon Hall7eb38402015-01-08 17:19:54 -08001637 def plug( self, **plugargs ):
1638 """
1639 plug the yanked mininet switch interface to a switch"""
1640 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001641 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001642 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1643 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1644 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001645 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001646 response = self.execute(
1647 cmd=command,
1648 prompt="mininet>",
1649 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001650 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001651 main.log.error( self.name + ": EOF exception found" )
1652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001653 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001654 except Exception:
1655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001656 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001657 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001658
Jon Hall7eb38402015-01-08 17:19:54 -08001659 def dpctl( self, **dpctlargs ):
1660 """
1661 Run dpctl command on all switches."""
1662 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001663 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001664 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1665 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1666 command = "dpctl " + cmd + " " + str( cmdargs )
1667 try:
1668 response = self.execute(
1669 cmd=command,
1670 prompt="mininet>",
1671 timeout=10 )
1672 except pexpect.EOF:
1673 main.log.error( self.name + ": EOF exception found" )
1674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001675 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001676 except Exception:
1677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001678 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001679 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001680
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001682 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001683 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001684 try:
1685 fileInput = path + '/lib/Mininet/INSTALL'
1686 version = super( Mininet, self ).getVersion()
1687 pattern = 'Mininet\s\w\.\w\.\w\w*'
1688 for line in open( fileInput, 'r' ).readlines():
1689 result = re.match( pattern, line )
1690 if result:
1691 version = result.group( 0 )
1692 return version
1693 except Exception:
1694 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001695 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001696
kelvin-onlabd3b64892015-01-20 13:26:24 -08001697 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001698 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001699 Parameters:
1700 sw: The name of an OVS switch. Example "s1"
1701 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001702 The output of the command from the mininet cli
1703 or main.FALSE on timeout"""
1704 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001705 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001706 response = self.execute(
1707 cmd=command,
1708 prompt="mininet>",
1709 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001710 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001711 return response
admin2a9548d2014-06-17 14:08:07 -07001712 else:
1713 return main.FALSE
1714 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
Charles Chan029be652015-08-24 01:46:10 +08001722 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001723 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001724 Description:
1725 Assign switches to the controllers ( for ovs use only )
1726 Required:
1727 sw - Name of the switch. This can be a list or a string.
1728 ip - Ip addresses of controllers. This can be a list or a string.
1729 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001730 port - ONOS use port 6653, if no list of ports is passed, then
1731 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001732 ptcp - ptcp number, This can be a string or a list that has
1733 the same length as switch. This is optional and not required
1734 when using ovs switches.
1735 NOTE: If switches and ptcp are given in a list type they should have the
1736 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1737 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001738
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001739 Return:
1740 Returns main.TRUE if mininet correctly assigned switches to
1741 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001742 exception( s )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001743 """
1744 assignResult = main.TRUE
1745 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001746 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001747 command = "sh ovs-vsctl set-controller "
1748 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001749 try:
1750 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001751 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001752 if isinstance( port, types.StringType ) or \
1753 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001754 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001755 elif isinstance( port, types.ListType ):
1756 main.log.error( self.name + ": Only one controller " +
1757 "assigned and a list of ports has" +
1758 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001759 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001760 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001761 main.log.error( self.name + ": Invalid controller port " +
1762 "number. Please specify correct " +
1763 "controller port" )
1764 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001765
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001766 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001767 if isinstance( port, types.StringType ) or \
1768 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001769 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001770 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1771 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001772 elif isinstance( port, types.ListType ):
1773 if ( len( ip ) != len( port ) ):
1774 main.log.error( self.name + ": Port list = " +
1775 str( len( port ) ) +
1776 "should be the same as controller" +
1777 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001778 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001779 else:
1780 onosIp = ""
1781 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001782 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1783 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001784 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001785 main.log.error( self.name + ": Invalid controller port " +
1786 "number. Please specify correct " +
1787 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001788 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001789 else:
1790 main.log.error( self.name + ": Invalid ip address" )
1791 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001792
1793 if isinstance( sw, types.StringType ):
1794 command += sw + " "
1795 if ptcp:
1796 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001797 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001798 elif isinstance( ptcp, types.ListType ):
1799 main.log.error( self.name + ": Only one switch is " +
1800 "being set and multiple PTCP is " +
1801 "being passed " )
1802 else:
1803 main.log.error( self.name + ": Invalid PTCP" )
1804 ptcp = ""
1805 command += onosIp
1806 commandList.append( command )
1807
1808 elif isinstance( sw, types.ListType ):
1809 if ptcp:
1810 if isinstance( ptcp, types.ListType ):
1811 if len( ptcp ) != len( sw ):
1812 main.log.error( self.name + ": PTCP length = " +
1813 str( len( ptcp ) ) +
1814 " is not the same as switch" +
1815 " length = " +
1816 str( len( sw ) ) )
1817 return main.FALSE
1818 else:
1819 for switch, ptcpNum in zip( sw, ptcp ):
1820 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001821 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001822 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001823 tempCmd += onosIp
1824 commandList.append( tempCmd )
1825 else:
1826 main.log.error( self.name + ": Invalid PTCP" )
1827 return main.FALSE
1828 else:
1829 for switch in sw:
1830 tempCmd = "sh ovs-vsctl set-controller "
1831 tempCmd += switch + " " + onosIp
1832 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001833 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001834 main.log.error( self.name + ": Invalid switch type " )
1835 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001836
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001837 for cmd in commandList:
1838 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001839 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001840 except pexpect.TIMEOUT:
1841 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1842 return main.FALSE
1843 except pexpect.EOF:
1844 main.log.error( self.name + ": EOF exception found" )
1845 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001846 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001847 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001848 except pexpect.EOF:
1849 main.log.error( self.name + ": EOF exception found" )
1850 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001851 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001852 except Exception:
1853 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001854 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001855
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001857 """
1858 Removes the controller target from sw"""
1859 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001860 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001861 response = self.execute(
1862 cmd=command,
1863 prompt="mininet>",
1864 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001865 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001866 main.log.error( self.name + ": EOF exception found" )
1867 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001868 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001869 except Exception:
1870 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001871 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001872 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001873 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001874
kelvin-onlabd3b64892015-01-20 13:26:24 -08001875 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001876 """
Jon Hallb1290e82014-11-18 16:17:48 -05001877 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001878 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001879 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001880 NOTE: cannot currently specify what type of switch
1881 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001882 sw = name of the new switch as a string
1883 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001884 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001885 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001886 """
1887 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001888 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001889 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001890 response = self.execute(
1891 cmd=command,
1892 prompt="mininet>",
1893 timeout=10 )
1894 if re.search( "already exists!", response ):
1895 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001896 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001897 elif re.search( "Error", response ):
1898 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001899 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001900 elif re.search( "usage:", response ):
1901 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001902 return main.FALSE
1903 else:
1904 return main.TRUE
1905 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001906 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001908 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001909 except Exception:
1910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001911 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001912
kelvin-onlabd3b64892015-01-20 13:26:24 -08001913 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001914 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001915 delete a switch from the mininet topology
1916 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001917 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001918 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001919 sw = name of the switch as a string
1920 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001921 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001922 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001923 response = self.execute(
1924 cmd=command,
1925 prompt="mininet>",
1926 timeout=10 )
1927 if re.search( "no switch named", response ):
1928 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001929 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001930 elif re.search( "Error", response ):
1931 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001932 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001933 elif re.search( "usage:", response ):
1934 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001935 return main.FALSE
1936 else:
1937 return main.TRUE
1938 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001939 main.log.error( self.name + ": EOF exception found" )
1940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001941 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001942 except Exception:
1943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001944 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001945
You Wangdb8cd0a2016-05-26 15:19:45 -07001946 def getSwitchRandom( self, timeout=60, nonCut=True ):
1947 """
1948 Randomly get a switch from Mininet topology.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001949 If nonCut is True, it gets a list of non-cut switches ( the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001950 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001951 components of a graph ) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07001952 it just randomly returns one switch from all current switches in
1953 Mininet.
1954 Returns the name of the chosen switch.
1955 """
1956 import random
1957 candidateSwitches = []
1958 try:
1959 if not nonCut:
1960 switches = self.getSwitches( timeout=timeout )
1961 assert len( switches ) != 0
1962 for switchName in switches.keys():
1963 candidateSwitches.append( switchName )
1964 else:
1965 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001966 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001967 return None
1968 self.graph.update( graphDict )
1969 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001970 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001971 return None
1972 elif len( candidateSwitches ) == 0:
1973 main.log.info( self.name + ": No candidate switch for deletion" )
1974 return None
1975 else:
1976 switch = random.sample( candidateSwitches, 1 )
1977 return switch[ 0 ]
1978 except KeyError:
1979 main.log.exception( self.name + ": KeyError exception found" )
1980 return None
1981 except AssertionError:
1982 main.log.exception( self.name + ": AssertionError exception found" )
1983 return None
1984 except Exception:
1985 main.log.exception( self.name + ": Uncaught exception" )
1986 return None
1987
1988 def delSwitchRandom( self, timeout=60, nonCut=True ):
1989 """
1990 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001991 If nonCut is True, it gets a list of non-cut switches ( the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001992 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001993 components of a graph ) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07001994 otherwise it just randomly delete one switch from all current
1995 switches in Mininet.
1996 Returns the name of the deleted switch
1997 """
1998 try:
1999 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002000 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002001 return None
2002 else:
2003 deletionResult = self.delSwitch( switch )
2004 if deletionResult:
2005 return switch
2006 else:
2007 return None
2008 except Exception:
2009 main.log.exception( self.name + ": Uncaught exception" )
2010 return None
2011
kelvin-onlabd3b64892015-01-20 13:26:24 -08002012 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002013 """
2014 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002015 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002016 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002017 NOTE: cannot currently specify what type of link
2018 required params:
2019 node1 = the string node name of the first endpoint of the link
2020 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002021 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002022 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002023 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002024 response = self.execute(
2025 cmd=command,
2026 prompt="mininet>",
2027 timeout=10 )
2028 if re.search( "doesnt exist!", response ):
2029 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002030 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002031 elif re.search( "Error", response ):
2032 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002033 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002034 elif re.search( "usage:", response ):
2035 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002036 return main.FALSE
2037 else:
2038 return main.TRUE
2039 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002040 main.log.error( self.name + ": EOF exception found" )
2041 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002042 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002043 except Exception:
2044 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002045 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002046
kelvin-onlabd3b64892015-01-20 13:26:24 -08002047 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002048 """
2049 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002050 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002051 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002052 required params:
2053 node1 = the string node name of the first endpoint of the link
2054 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002055 returns: main.FALSE on an error, else main.TRUE
2056 """
Jon Hallffb386d2014-11-21 13:43:38 -08002057 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002058 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002059 response = self.execute(
2060 cmd=command,
2061 prompt="mininet>",
2062 timeout=10 )
2063 if re.search( "no node named", response ):
2064 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002065 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002066 elif re.search( "Error", response ):
2067 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002068 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002069 elif re.search( "usage:", response ):
2070 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002071 return main.FALSE
2072 else:
2073 return main.TRUE
2074 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002075 main.log.error( self.name + ": EOF exception found" )
2076 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002077 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002078 except Exception:
2079 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002080 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002081
You Wangdb8cd0a2016-05-26 15:19:45 -07002082 def getLinkRandom( self, timeout=60, nonCut=True ):
2083 """
2084 Randomly get a link from Mininet topology.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002085 If nonCut is True, it gets a list of non-cut links ( the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002086 of a non-cut link will not increase the number of connected
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002087 component of a graph ) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002088 it just randomly returns one link from all current links in
2089 Mininet.
2090 Returns the link as a list, e.g. [ 's1', 's2' ]
2091 """
2092 import random
2093 candidateLinks = []
2094 try:
2095 if not nonCut:
2096 links = self.getLinks( timeout=timeout )
2097 assert len( links ) != 0
2098 for link in links:
2099 # Exclude host-switch link
2100 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2101 continue
2102 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2103 else:
2104 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002105 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002106 return None
2107 self.graph.update( graphDict )
2108 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002109 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002110 return None
2111 elif len( candidateLinks ) == 0:
2112 main.log.info( self.name + ": No candidate link for deletion" )
2113 return None
2114 else:
2115 link = random.sample( candidateLinks, 1 )
2116 return link[ 0 ]
2117 except KeyError:
2118 main.log.exception( self.name + ": KeyError exception found" )
2119 return None
2120 except AssertionError:
2121 main.log.exception( self.name + ": AssertionError exception found" )
2122 return None
2123 except Exception:
2124 main.log.exception( self.name + ": Uncaught exception" )
2125 return None
2126
2127 def delLinkRandom( self, timeout=60, nonCut=True ):
2128 """
2129 Randomly delete a link from Mininet topology.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002130 If nonCut is True, it gets a list of non-cut links ( the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002131 of a non-cut link will not increase the number of connected
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002132 component of a graph ) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002133 otherwise it just randomly delete one link from all current links
2134 in Mininet.
2135 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2136 """
2137 try:
2138 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002139 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002140 return None
2141 else:
2142 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2143 if deletionResult:
2144 return link
2145 else:
2146 return None
2147 except Exception:
2148 main.log.exception( self.name + ": Uncaught exception" )
2149 return None
2150
kelvin-onlabd3b64892015-01-20 13:26:24 -08002151 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002152 """
Jon Hallb1290e82014-11-18 16:17:48 -05002153 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002154 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002155 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002156 NOTE: cannot currently specify what type of host
2157 required params:
2158 hostname = the string hostname
2159 optional key-value params
2160 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002161 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002162 """
2163 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002164 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002165 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002166 response = self.execute(
2167 cmd=command,
2168 prompt="mininet>",
2169 timeout=10 )
2170 if re.search( "already exists!", response ):
2171 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002172 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002173 elif re.search( "doesnt exists!", response ):
2174 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002175 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002176 elif re.search( "Error", response ):
2177 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002178 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002179 elif re.search( "usage:", response ):
2180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002181 return main.FALSE
2182 else:
2183 return main.TRUE
2184 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002185 main.log.error( self.name + ": EOF exception found" )
2186 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002187 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002188 except Exception:
2189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002190 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002191
kelvin-onlabd3b64892015-01-20 13:26:24 -08002192 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002193 """
2194 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002195 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002196 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002197 NOTE: this uses a custom mn function
2198 required params:
2199 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002200 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002201 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002202 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002203 response = self.execute(
2204 cmd=command,
2205 prompt="mininet>",
2206 timeout=10 )
2207 if re.search( "no host named", response ):
2208 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002209 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002210 elif re.search( "Error", response ):
2211 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002212 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002213 elif re.search( "usage:", response ):
2214 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002215 return main.FALSE
2216 else:
2217 return main.TRUE
2218 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002219 main.log.error( self.name + ": EOF exception found" )
2220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002221 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002222 except Exception:
2223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002224 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002225
Jon Hall7eb38402015-01-08 17:19:54 -08002226 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002227 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002228 Called at the end of the test to stop the mininet and
2229 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002230 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002231 try:
2232 self.handle.sendline( '' )
2233 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2234 timeout=2 )
2235 response = main.TRUE
2236 if i == 0:
2237 response = self.stopNet()
2238 elif i == 1:
2239 return main.TRUE
2240 # print "Disconnecting Mininet"
2241 if self.handle:
2242 self.handle.sendline( "exit" )
2243 self.handle.expect( "exit" )
2244 self.handle.expect( "(.*)" )
2245 else:
2246 main.log.error( "Connection failed to the host" )
2247 return response
2248 except pexpect.EOF:
2249 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()
kelvin-onlaba1484582015-02-02 15:46:20 -08002255
Jon Halld80cc142015-07-06 13:36:05 -07002256 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002257 """
Jon Hall21270ac2015-02-16 17:59:55 -08002258 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002259 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002260 main.FALSE if the pexpect handle does not exist.
2261
Jon Halld61331b2015-02-17 16:35:47 -08002262 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002263 """
Jon Halld61331b2015-02-17 16:35:47 -08002264 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002265 response = ''
2266 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002267 try:
Jon Halld80cc142015-07-06 13:36:05 -07002268 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002269 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002270 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002271 pexpect.EOF,
2272 pexpect.TIMEOUT ],
2273 timeout )
2274 if i == 0:
2275 main.log.info( "Exiting mininet..." )
Jeremyd9e4eb12016-04-13 12:09:06 -07002276 response = self.execute( cmd="exit",
2277 prompt="(.*)",
2278 timeout=120 )
2279 main.log.info( self.name + ": Stopped" )
2280 self.handle.sendline( "sudo mn -c" )
2281 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002282
Jeremyd9e4eb12016-04-13 12:09:06 -07002283 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002284 main.log.info( " Mininet trying to exit while not " +
2285 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002286 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002287 elif i == 2:
2288 main.log.error( "Something went wrong exiting mininet" )
2289 elif i == 3: # timeout
2290 main.log.error( "Something went wrong exiting mininet " +
2291 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002292
Hari Krishnab35c6d02015-03-18 11:13:51 -07002293 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002294 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002295 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002296 self.handle.sendline(
2297 "sudo kill -9 \`ps -ef | grep \"" +
2298 fileName +
2299 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002300 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002301 main.log.error( self.name + ": TIMEOUT exception found" )
2302 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002303 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002304 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002305 main.log.error( self.name + ": EOF exception found" )
2306 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002307 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002308 except Exception:
2309 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002310 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002311 else:
2312 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002313 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002314 return response
2315
YPZhang26a139e2016-04-25 14:01:55 -07002316 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002317 """
2318 Description:
2319 Sends arp message from mininet host for hosts discovery
2320 Required:
2321 host - hosts name
2322 Optional:
2323 ip - ip address that does not exist in the network so there would
2324 be no reply.
2325 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002326 if ethDevice:
2327 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002328 cmd = srcHost + " arping -c1 "
2329 if noResult:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002330 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 -07002331 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002332 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002333 if output:
2334 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002335 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002336 i = self.handle.expect( [ "mininet>", "arping: " ] )
2337 if i == 0:
2338 return main.TRUE
2339 elif i == 1:
2340 response = self.handle.before + self.handle.after
2341 self.handle.expect( "mininet>" )
2342 response += self.handle.before + self.handle.after
2343 main.log.warn( "Error sending arping, output was: " +
2344 response )
2345 return main.FALSE
2346 except pexpect.TIMEOUT:
2347 main.log.error( self.name + ": TIMEOUT exception found" )
2348 main.log.warn( self.handle.before )
2349 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002350 except pexpect.EOF:
2351 main.log.error( self.name + ": EOF exception found" )
2352 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002353 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002354 except Exception:
2355 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002356 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002357
Jon Hall7eb38402015-01-08 17:19:54 -08002358 def decToHex( self, num ):
2359 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002360
Jon Hall7eb38402015-01-08 17:19:54 -08002361 def getSwitchFlowCount( self, switch ):
2362 """
2363 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002364 if self.handle:
2365 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2366 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002367 response = self.execute(
2368 cmd=cmd,
2369 prompt="mininet>",
2370 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002371 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002372 main.log.error( self.name + ": EOF exception found" )
2373 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002374 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002375 except Exception:
2376 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002377 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002378 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002379 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002380 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002381 main.log.info(
2382 "Couldn't find flows on switch %s, found: %s" %
2383 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002384 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002385 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002386 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002387 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002388
Jon Hall9ed8f372016-02-24 17:34:07 -08002389 def checkFlows( self, sw, dumpFormat=None ):
2390 if dumpFormat:
2391 command = "sh ovs-ofctl -F " + \
2392 dumpFormat + " dump-flows " + str( sw )
2393 else:
2394 command = "sh ovs-ofctl dump-flows " + str( sw )
2395 try:
2396 response = self.execute(
2397 cmd=command,
2398 prompt="mininet>",
2399 timeout=10 )
2400 return response
2401 except pexpect.EOF:
2402 main.log.error( self.name + ": EOF exception found" )
2403 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002404 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002405 except Exception:
2406 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002407 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002408
GlennRC68467eb2015-11-16 18:01:01 -08002409 def flowTableComp( self, flowTable1, flowTable2 ):
2410 # This function compares the selctors and treatments of each flow
2411 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002412 assert flowTable1, "flowTable1 is empty or None"
2413 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002414 returnValue = main.TRUE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002415 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002416 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002417 returnValue = main.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002418 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2419 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002420 for field in dFields:
2421 try:
2422 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002423 except KeyError:
2424 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002425 try:
2426 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002427 except KeyError:
2428 pass
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002429 for i in range( len( flowTable1 ) ):
2430 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002431 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002432 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002433 returnValue = main.FALSE
2434 break
2435 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002436 except AssertionError:
2437 main.log.exception( "Nothing to compare" )
2438 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002439 except Exception:
2440 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002441 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002442
GlennRC528ad292015-11-12 10:38:18 -08002443 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002444 """
GlennRC956ea742015-11-05 16:14:15 -08002445 Discription: Parses flows into json format.
2446 NOTE: this can parse any string thats separated with commas
2447 Arguments:
2448 Required:
2449 flows: a list of strings that represnt flows
2450 Optional:
2451 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2452 debug: prints out the final result
2453 returns: A list of flows in json format
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002454 """
GlennRC528ad292015-11-12 10:38:18 -08002455 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002456 try:
2457 for flow in flowTable:
2458 jsonFlow = {}
2459 # split up the fields of the flow
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002460 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002461 # get rid of any spaces in front of the field
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002462 for i in range( len( parsedFlow ) ):
2463 item = parsedFlow[ i ]
2464 if item[ 0 ] == " ":
2465 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002466 # grab the selector and treatment from the parsed flow
2467 # the last element is the selector and the treatment
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002468 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002469 # split up the selector and the treatment
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002470 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002471 index = 0
2472 # parse the flags
2473 # NOTE: This only parses one flag
2474 flag = {}
2475 if version == "1.3":
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002476 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002477 index += 1
2478 # the first element is the selector and split it up
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002479 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002480 index += 1
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002481 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002482 # the priority is stuck in the selecter so put it back
2483 # in the flow
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002484 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002485 # parse selector
2486 criteria = []
2487 for item in sel:
2488 # this is the type of the packet e.g. "arp"
2489 if "=" not in item:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002490 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002491 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002492 field = item.split( "=" )
2493 criteria.append( { field[ 0 ]: field[ 1 ] } )
2494 selector = { "selector": { "criteria": sorted( criteria ) } }
2495 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002496 # get rid of the action part e.g. "action=output:2"
2497 # we will add it back later
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002498 treat = treat.split( "=" )
2499 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002500 # parse treatment
2501 action = []
2502 for item in treat:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002503 field = item.split( ":" )
2504 action.append( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002505 # create the treatment field and add the actions
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002506 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002507 # parse the rest of the flow
2508 for item in parsedFlow:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002509 field = item.split( "=" )
2510 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002511 # add the treatment and the selector to the json flow
2512 jsonFlow.update( selector )
2513 jsonFlow.update( treatment )
2514 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002515
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002516 if debug:
2517 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002518
You Wang91c37cf2016-05-23 09:39:42 -07002519 # add the json flow to the json flow table
2520 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002521
You Wang91c37cf2016-05-23 09:39:42 -07002522 return jsonFlowTable
2523
2524 except IndexError:
2525 main.log.exception( self.name + ": IndexError found" )
2526 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002527 except pexpect.EOF:
2528 main.log.error( self.name + ": EOF exception found" )
2529 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002530 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002531 except Exception:
2532 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002533 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002534
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002535 def getFlowTable( self, sw, version="", debug=False ):
2536 """
2537 Discription: Returns the flow table( s ) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002538 Each element is a flow.
2539 Arguments:
2540 Required:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002541 sw: The switch name ( "s1" ) to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002542 a list of switches.
2543 Optional:
2544 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2545 debug: prints out the final result
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002546 """
GlennRC956ea742015-11-05 16:14:15 -08002547 try:
2548 switches = []
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002549 if isinstance( sw, list ):
2550 switches.extend( sw )
2551 else:
2552 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002553
2554 flows = []
2555 for s in switches:
2556 cmd = "sh ovs-ofctl dump-flows " + s
2557
GlennRC528ad292015-11-12 10:38:18 -08002558 if "1.0" == version:
2559 cmd += " -F OpenFlow10-table_id"
2560 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002561 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002562
2563 main.log.info( "Sending: " + cmd )
2564 self.handle.sendline( cmd )
2565 self.handle.expect( "mininet>" )
2566 response = self.handle.before
2567 response = response.split( "\r\n" )
2568 # dump the first two elements and the last
2569 # the first element is the command that was sent
2570 # the second is the table header
2571 # the last element is empty
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002572 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002573 flows.extend( response )
2574
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002575 if debug:
2576 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002577
GlennRC528ad292015-11-12 10:38:18 -08002578 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002579
GlennRC956ea742015-11-05 16:14:15 -08002580 except pexpect.EOF:
2581 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002582 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002583 except Exception:
2584 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002585 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002586
2587 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002588 """
GlennRC956ea742015-11-05 16:14:15 -08002589 Discription: Checks whether the ID provided matches a flow ID in Mininet
2590 Arguments:
2591 Required:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002592 sw: The switch name ( "s1" ) to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002593 a list of switches.
2594 flowId: the flow ID in hex format. Can also be a list of IDs
2595 Optional:
2596 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2597 debug: prints out the final result
2598 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2599 NOTE: prints out IDs that are not present
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002600 """
GlennRC956ea742015-11-05 16:14:15 -08002601 try:
2602 main.log.info( "Getting flows from Mininet" )
2603 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002604 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002605 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002606
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002607 if debug:
2608 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002609
2610 # Check flowId is a list or a string
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002611 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002612 result = False
2613 for f in flows:
2614 if flowId in f.get( 'cookie' ):
2615 result = True
2616 break
2617 # flowId is a list
2618 else:
2619 result = True
2620 # Get flow IDs from Mininet
2621 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2622 # Save the IDs that are not in Mininet
2623 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2624
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002625 if debug:
2626 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002627
2628 # Print out the IDs that are not in Mininet
2629 if absentIds:
2630 main.log.warn( "Absent ids: {}".format( absentIds ) )
2631 result = False
2632
2633 return main.TRUE if result else main.FALSE
2634
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002635 except pexpect.EOF:
2636 main.log.error( self.name + ": EOF exception found" )
2637 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002638 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002639 except Exception:
2640 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002641 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002642
Charles Chan029be652015-08-24 01:46:10 +08002643 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002644 """
Jon Hallefbd9792015-03-05 16:11:36 -08002645 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002646 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002647 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002648 self.handle.sendline( "" )
2649 self.handle.expect( "mininet>" )
2650 self.handle.sendline(
2651 "sh sudo tcpdump -n -i " +
2652 intf +
2653 " " +
2654 port +
2655 " -w " +
2656 filename.strip() +
2657 " &" )
2658 self.handle.sendline( "" )
2659 i = self.handle.expect( [ 'No\ssuch\device',
2660 'listening\son',
2661 pexpect.TIMEOUT,
2662 "mininet>" ],
2663 timeout=10 )
2664 main.log.warn( self.handle.before + self.handle.after )
2665 self.handle.sendline( "" )
2666 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002667 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002668 main.log.error(
2669 self.name +
2670 ": tcpdump - No such device exists. " +
2671 "tcpdump attempted on: " +
2672 intf )
admin2a9548d2014-06-17 14:08:07 -07002673 return main.FALSE
2674 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002675 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002676 return main.TRUE
2677 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002678 main.log.error(
2679 self.name +
2680 ": tcpdump command timed out! Check interface name," +
2681 " given interface was: " +
2682 intf )
admin2a9548d2014-06-17 14:08:07 -07002683 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002684 elif i == 3:
2685 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002686 return main.TRUE
2687 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002688 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002689 return main.FALSE
2690 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002691 main.log.error( self.name + ": EOF exception found" )
2692 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002693 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002694 except Exception:
2695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002696 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002697
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002699 """
2700 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002701 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002702 self.handle.sendline( "sh sudo pkill tcpdump" )
2703 self.handle.expect( "mininet>" )
2704 self.handle.sendline( "" )
2705 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002706 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002707 main.log.error( self.name + ": TIMEOUT exception found" )
2708 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002709 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002710 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002711 main.log.error( self.name + ": EOF exception found" )
2712 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002713 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002714 except Exception:
2715 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002716 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002717
Jon Halld80cc142015-07-06 13:36:05 -07002718 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002719 """
2720 Read ports from a Mininet switch.
2721
2722 Returns a json structure containing information about the
2723 ports of the given switch.
2724 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002725 try:
2726 response = self.getInterfaces( nodeName )
2727 # TODO: Sanity check on response. log if no such switch exists
2728 ports = []
2729 for line in response.split( "\n" ):
2730 if not line.startswith( "name=" ):
2731 continue
2732 portVars = {}
2733 for var in line.split( "," ):
2734 key, value = var.split( "=" )
2735 portVars[ key ] = value
2736 isUp = portVars.pop( 'enabled', "True" )
2737 isUp = "True" in isUp
2738 if verbose:
2739 main.log.info( "Reading switch port %s(%s)" %
2740 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2741 mac = portVars[ 'mac' ]
2742 if mac == 'None':
2743 mac = None
2744 ips = []
2745 ip = portVars[ 'ip' ]
2746 if ip == 'None':
2747 ip = None
2748 ips.append( ip )
2749 name = portVars[ 'name' ]
2750 if name == 'None':
2751 name = None
2752 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2753 if name == 'lo':
2754 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2755 else:
2756 portNo = re.search( portRe, name ).group( 'port' )
2757 ports.append( { 'of_port': portNo,
2758 'mac': str( mac ).replace( '\'', '' ),
2759 'name': name,
2760 'ips': ips,
2761 'enabled': isUp } )
2762 return ports
2763 except pexpect.EOF:
2764 main.log.error( self.name + ": EOF exception found" )
2765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002766 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002767 except Exception:
2768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002770
You Wangdb8cd0a2016-05-26 15:19:45 -07002771 def getOVSPorts( self, nodeName ):
2772 """
2773 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2774
2775 Returns a list of dictionaries containing information about each
2776 port of the given switch.
2777 """
2778 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2779 try:
2780 response = self.execute(
2781 cmd=command,
2782 prompt="mininet>",
2783 timeout=10 )
2784 ports = []
2785 if response:
2786 for line in response.split( "\n" ):
2787 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2788 # Example port:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002789 # 1( s1-eth1 ): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002790 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2791 result = re.search( pattern, line )
2792 if result:
2793 index = result.group( 'index' )
2794 name = result.group( 'name' )
2795 # This port number is extracted from port name
2796 port = result.group( 'port' )
2797 mac = result.group( 'mac' )
2798 ports.append( { 'index': index,
2799 'name': name,
2800 'port': port,
2801 'mac': mac } )
2802 return ports
2803 except pexpect.EOF:
2804 main.log.error( self.name + ": EOF exception found" )
2805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002806 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002807 except Exception:
2808 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002809 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002810
Jon Halld80cc142015-07-06 13:36:05 -07002811 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002812 """
2813 Read switches from Mininet.
2814
2815 Returns a dictionary whose keys are the switch names and the value is
2816 a dictionary containing information about the switch.
2817 """
Jon Halla22481b2015-07-28 17:46:01 -07002818 # NOTE: To support new Mininet switch classes, just append the new
2819 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002820
Jon Halla22481b2015-07-28 17:46:01 -07002821 # Regex patterns to parse 'dump' output
2822 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002823 # <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 -07002824 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002825 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2826 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2827 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002828 try:
2829 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2830 swRE = r"<(?P<class>" + switchClasses + r")" +\
2831 r"(?P<options>\{.*\})?\s" +\
2832 r"(?P<name>[^:]+)\:\s" +\
2833 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2834 r"\spid=(?P<pid>(\d)+)"
2835 # Update mn port info
2836 self.update()
2837 output = {}
2838 dump = self.dump().split( "\n" )
2839 for line in dump:
2840 result = re.search( swRE, line, re.I )
2841 if result:
2842 name = result.group( 'name' )
2843 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2844 pid = result.group( 'pid' )
2845 swClass = result.group( 'class' )
2846 options = result.group( 'options' )
2847 if verbose:
2848 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2849 ports = self.getPorts( name )
2850 output[ name ] = { "dpid": dpid,
2851 "ports": ports,
2852 "swClass": swClass,
2853 "pid": pid,
2854 "options": options }
2855 return output
2856 except pexpect.EOF:
2857 main.log.error( self.name + ": EOF exception found" )
2858 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002859 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002860 except Exception:
2861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002862 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002863
Jon Halld80cc142015-07-06 13:36:05 -07002864 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002865 """
2866 Read hosts from Mininet.
2867
2868 Returns a dictionary whose keys are the host names and the value is
2869 a dictionary containing information about the host.
2870 """
2871 # Regex patterns to parse dump output
2872 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002873 # <Host h1: pid=12725>
2874 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2875 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2876 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002877 # NOTE: Does not correctly match hosts with multi-links
2878 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2879 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002880 try:
2881 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
2882 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
2883 # update mn port info
2884 self.update()
2885 # Get mininet dump
2886 dump = self.dump().split( "\n" )
2887 hosts = {}
2888 for line in dump:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002889 if "Host" in line:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002890 result = re.search( hostRE, line )
2891 name = result.group( 'name' )
2892 interfaces = []
2893 response = self.getInterfaces( name )
2894 # Populate interface info
2895 for line in response.split( "\n" ):
2896 if line.startswith( "name=" ):
2897 portVars = {}
2898 for var in line.split( "," ):
2899 key, value = var.split( "=" )
2900 portVars[ key ] = value
2901 isUp = portVars.pop( 'enabled', "True" )
2902 isUp = "True" in isUp
2903 if verbose:
2904 main.log.info( "Reading host port %s(%s)" %
2905 ( portVars[ 'name' ],
2906 portVars[ 'mac' ] ) )
2907 mac = portVars[ 'mac' ]
2908 if mac == 'None':
2909 mac = None
2910 ips = []
2911 ip = portVars[ 'ip' ]
2912 if ip == 'None':
2913 ip = None
2914 ips.append( ip )
2915 intfName = portVars[ 'name' ]
2916 if name == 'None':
2917 name = None
2918 interfaces.append( {
2919 "name": intfName,
2920 "ips": ips,
2921 "mac": str( mac ),
2922 "isUp": isUp } )
2923 hosts[ name ] = { "interfaces": interfaces }
2924 return hosts
2925 except pexpect.EOF:
2926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002929 except Exception:
2930 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002932
YPZhang81a7d4e2016-04-18 13:10:17 -07002933 def getLinks( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002934 """
2935 Gathers information about current Mininet links. These links may not
2936 be up if one of the ports is down.
2937
2938 Returns a list of dictionaries with link endpoints.
2939
2940 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002941 { 'node1': str( node1 name )
2942 'node2': str( node2 name )
2943 'port1': str( port1 of_port )
2944 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002945 Note: The port number returned is the eth#, not necessarily the of_port
2946 number. In Mininet, for OVS switch, these should be the same. For
2947 hosts, this is just the eth#.
2948 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002949 try:
2950 self.update()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002951 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07002952
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002953 # Examples:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002954 # s1-eth3<->s2-eth1 ( OK OK )
2955 # s13-eth3<->h27-eth0 ( OK OK )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002956 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2957 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2958 links = []
2959 for line in response:
2960 match = re.search( linkRE, line )
2961 if match:
2962 node1 = match.group( 'node1' )
2963 node2 = match.group( 'node2' )
2964 port1 = match.group( 'port1' )
2965 port2 = match.group( 'port2' )
2966 links.append( { 'node1': node1,
2967 'node2': node2,
2968 'port1': port1,
2969 'port2': port2 } )
2970 return links
2971
2972 except pexpect.EOF:
2973 main.log.error( self.name + ": EOF exception found" )
2974 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002975 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002976 except Exception:
2977 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002978 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002979
2980 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002981 """
2982 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002983 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002984
Jon Hallafa8a472015-06-12 14:02:42 -07002985 Dependencies:
2986 1. numpy - "sudo pip install numpy"
2987 """
2988 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002989 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002990 try:
2991 mnDPIDs = []
2992 for swName, switch in switches.iteritems():
2993 mnDPIDs.append( switch[ 'dpid' ].lower() )
2994 mnDPIDs.sort()
2995 if switchesJson == "": # if rest call fails
2996 main.log.error(
2997 self.name +
2998 ".compareSwitches(): Empty JSON object given from ONOS" )
2999 return main.FALSE
3000 onos = switchesJson
3001 onosDPIDs = []
3002 for switch in onos:
3003 if switch[ 'available' ]:
3004 onosDPIDs.append(
3005 switch[ 'id' ].replace(
3006 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003007 '' ).replace(
3008 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003009 '' ).lower() )
3010 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003011
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003012 if mnDPIDs != onosDPIDs:
3013 switchResults = main.FALSE
3014 main.log.error( "Switches in MN but not in ONOS:" )
3015 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3016 main.log.error( str( list1 ) )
3017 main.log.error( "Switches in ONOS but not in MN:" )
3018 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3019 main.log.error( str( list2 ) )
3020 else: # list of dpid's match in onos and mn
3021 switchResults = main.TRUE
3022 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003023
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003024 # FIXME: this does not look for extra ports in ONOS, only checks that
3025 # ONOS has what is in MN
3026 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003027
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003028 # PORTS
3029 for name, mnSwitch in switches.iteritems():
3030 mnPorts = []
3031 onosPorts = []
3032 switchResult = main.TRUE
3033 for port in mnSwitch[ 'ports' ]:
3034 if port[ 'enabled' ]:
3035 mnPorts.append( int( port[ 'of_port' ] ) )
3036 for onosSwitch in portsJson:
3037 if onosSwitch[ 'device' ][ 'available' ]:
3038 if onosSwitch[ 'device' ][ 'id' ].replace(
3039 ':',
3040 '' ).replace(
3041 "of",
3042 '' ) == mnSwitch[ 'dpid' ]:
3043 for port in onosSwitch[ 'ports' ]:
3044 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003045 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003046 # onosPorts.append( 'local' )
3047 onosPorts.append( long( uint64( -2 ) ) )
3048 else:
3049 onosPorts.append( int( port[ 'port' ] ) )
3050 break
3051 mnPorts.sort( key=float )
3052 onosPorts.sort( key=float )
3053
3054 mnPortsLog = mnPorts
3055 onosPortsLog = onosPorts
3056 mnPorts = [ x for x in mnPorts ]
3057 onosPorts = [ x for x in onosPorts ]
3058
3059 # TODO: handle other reserved port numbers besides LOCAL
3060 # NOTE: Reserved ports
3061 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3062 # long( uint64( -2 ) )
3063 for mnPort in mnPortsLog:
3064 if mnPort in onosPorts:
3065 # don't set results to true here as this is just one of
3066 # many checks and it might override a failure
3067 mnPorts.remove( mnPort )
3068 onosPorts.remove( mnPort )
3069
3070 # NOTE: OVS reports this as down since there is no link
3071 # So ignoring these for now
3072 # TODO: Come up with a better way of handling these
3073 if 65534 in mnPorts:
3074 mnPorts.remove( 65534 )
3075 if long( uint64( -2 ) ) in onosPorts:
3076 onosPorts.remove( long( uint64( -2 ) ) )
3077 if len( mnPorts ): # the ports of this switch don't match
3078 switchResult = main.FALSE
3079 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3080 if len( onosPorts ): # the ports of this switch don't match
3081 switchResult = main.FALSE
3082 main.log.warn(
3083 "Ports in ONOS but not MN: " +
3084 str( onosPorts ) )
3085 if switchResult == main.FALSE:
3086 main.log.error(
3087 "The list of ports for switch %s(%s) does not match:" %
3088 ( name, mnSwitch[ 'dpid' ] ) )
3089 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3090 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3091 portsResults = portsResults and switchResult
3092 finalResults = finalResults and portsResults
3093 return finalResults
3094 except pexpect.EOF:
3095 main.log.error( self.name + ": EOF exception found" )
3096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003097 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003098 except Exception:
3099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003100 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003101
Jon Hallafa8a472015-06-12 14:02:42 -07003102 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003103 """
3104 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003105 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003106
Jon Hallafa8a472015-06-12 14:02:42 -07003107 """
Jon Hall7eb38402015-01-08 17:19:54 -08003108 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003109 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003110 try:
3111 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003112
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003113 mnLinks = []
3114 for l in links:
3115 try:
3116 node1 = switches[ l[ 'node1' ] ]
3117 node2 = switches[ l[ 'node2' ] ]
3118 enabled = True
3119 for port in node1[ 'ports' ]:
3120 if port[ 'of_port' ] == l[ 'port1' ]:
3121 enabled = enabled and port[ 'enabled' ]
3122 for port in node2[ 'ports' ]:
3123 if port[ 'of_port' ] == l[ 'port2' ]:
3124 enabled = enabled and port[ 'enabled' ]
3125 if enabled:
3126 mnLinks.append( l )
3127 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003128 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003129 if 2 * len( mnLinks ) == len( onos ):
3130 linkResults = main.TRUE
3131 else:
3132 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003133 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003134 "Mininet has " + str( len( mnLinks ) ) +
3135 " bidirectional links and ONOS has " +
3136 str( len( onos ) ) + " unidirectional links" )
3137
3138 # iterate through MN links and check if an ONOS link exists in
3139 # both directions
3140 for link in mnLinks:
3141 # TODO: Find a more efficient search method
3142 node1 = None
3143 port1 = None
3144 node2 = None
3145 port2 = None
3146 firstDir = main.FALSE
3147 secondDir = main.FALSE
3148 for swName, switch in switches.iteritems():
3149 if swName == link[ 'node1' ]:
3150 node1 = switch[ 'dpid' ]
3151 for port in switch[ 'ports' ]:
3152 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3153 port1 = port[ 'of_port' ]
3154 if node1 is not None and node2 is not None:
3155 break
3156 if swName == link[ 'node2' ]:
3157 node2 = switch[ 'dpid' ]
3158 for port in switch[ 'ports' ]:
3159 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3160 port2 = port[ 'of_port' ]
3161 if node1 is not None and node2 is not None:
3162 break
3163
3164 for onosLink in onos:
3165 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3166 ":", '' ).replace( "of", '' )
3167 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3168 ":", '' ).replace( "of", '' )
3169 onosPort1 = onosLink[ 'src' ][ 'port' ]
3170 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3171
3172 # check onos link from node1 to node2
3173 if str( onosNode1 ) == str( node1 ) and str(
3174 onosNode2 ) == str( node2 ):
3175 if int( onosPort1 ) == int( port1 ) and int(
3176 onosPort2 ) == int( port2 ):
3177 firstDir = main.TRUE
3178 else:
3179 main.log.warn(
3180 'The port numbers do not match for ' +
3181 str( link ) +
3182 ' between ONOS and MN. When checking ONOS for ' +
3183 'link %s/%s -> %s/%s' %
3184 ( node1, port1, node2, port2 ) +
3185 ' ONOS has the values %s/%s -> %s/%s' %
3186 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3187
3188 # check onos link from node2 to node1
3189 elif ( str( onosNode1 ) == str( node2 ) and
3190 str( onosNode2 ) == str( node1 ) ):
3191 if ( int( onosPort1 ) == int( port2 )
3192 and int( onosPort2 ) == int( port1 ) ):
3193 secondDir = main.TRUE
3194 else:
3195 main.log.warn(
3196 'The port numbers do not match for ' +
3197 str( link ) +
3198 ' between ONOS and MN. When checking ONOS for ' +
3199 'link %s/%s -> %s/%s' %
3200 ( node1, port1, node2, port2 ) +
3201 ' ONOS has the values %s/%s -> %s/%s' %
3202 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3203 else: # this is not the link you're looking for
3204 pass
3205 if not firstDir:
3206 main.log.error(
3207 'ONOS does not have the link %s/%s -> %s/%s' %
3208 ( node1, port1, node2, port2 ) )
3209 if not secondDir:
3210 main.log.error(
3211 'ONOS does not have the link %s/%s -> %s/%s' %
3212 ( node2, port2, node1, port1 ) )
3213 linkResults = linkResults and firstDir and secondDir
3214 return linkResults
3215 except pexpect.EOF:
3216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003219 except Exception:
3220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003221 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003222
Jon Hallafa8a472015-06-12 14:02:42 -07003223 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003224 """
Jon Hallafa8a472015-06-12 14:02:42 -07003225 Compare mn and onos Hosts.
3226 Since Mininet hosts are quiet, ONOS will only know of them when they
3227 speak. For this reason, we will only check that the hosts in ONOS
3228 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003229
Jon Hallafa8a472015-06-12 14:02:42 -07003230 Arguments:
3231 hostsJson: parsed json object from the onos hosts api
3232 Returns:
3233 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003234 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003235 try:
3236 hostResults = main.TRUE
3237 for onosHost in hostsJson:
3238 onosMAC = onosHost[ 'mac' ].lower()
3239 match = False
3240 for mnHost, info in hosts.iteritems():
3241 for mnIntf in info[ 'interfaces' ]:
3242 if onosMAC == mnIntf[ 'mac' ].lower():
3243 match = True
3244 for ip in mnIntf[ 'ips' ]:
3245 if ip in onosHost[ 'ipAddresses' ]:
3246 pass # all is well
3247 else:
3248 # misssing ip
3249 main.log.error( "ONOS host " +
3250 onosHost[ 'id' ] +
3251 " has a different IP(" +
3252 str( onosHost[ 'ipAddresses' ] ) +
3253 ") than the Mininet host(" +
3254 str( ip ) +
3255 ")." )
3256 output = json.dumps(
3257 onosHost,
3258 sort_keys=True,
3259 indent=4,
3260 separators=( ',', ': ' ) )
3261 main.log.info( output )
3262 hostResults = main.FALSE
3263 if not match:
3264 hostResults = main.FALSE
3265 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3266 "corresponding Mininet host." )
3267 output = json.dumps( onosHost,
3268 sort_keys=True,
3269 indent=4,
3270 separators=( ',', ': ' ) )
3271 main.log.info( output )
3272 return hostResults
3273 except pexpect.EOF:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003274 main.log.error( self.name + ": EOF exception found" )
3275 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003276 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003277 except Exception:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003278 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003279 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003280
Jon Hallafa8a472015-06-12 14:02:42 -07003281 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003282 """
3283 Returns a list of all hosts
3284 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003285 try:
3286 self.handle.sendline( "" )
3287 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003288
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003289 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3290 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003291
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003292 handlePy = self.handle.before
3293 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3294 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003295
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003296 self.handle.sendline( "" )
3297 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003298
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003299 hostStr = handlePy.replace( "]", "" )
3300 hostStr = hostStr.replace( "'", "" )
3301 hostStr = hostStr.replace( "[", "" )
3302 hostStr = hostStr.replace( " ", "" )
3303 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003304
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003305 return hostList
3306 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003307 main.log.error( self.name + ": TIMEOUT exception found" )
3308 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003309 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003310 except pexpect.EOF:
3311 main.log.error( self.name + ": EOF exception found" )
3312 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003313 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003314 except Exception:
3315 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003316 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003317
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003318 def getSwitch( self ):
3319 """
3320 Returns a list of all switches
3321 Again, don't ask question just use it...
3322 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003323 try:
3324 # get host list...
3325 hostList = self.getHosts()
3326 # Make host set
3327 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003328
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003329 # Getting all the nodes in mininet
3330 self.handle.sendline( "" )
3331 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003332
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003333 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3334 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003335
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003336 handlePy = self.handle.before
3337 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3338 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003339
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003340 self.handle.sendline( "" )
3341 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003342
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003343 nodesStr = handlePy.replace( "]", "" )
3344 nodesStr = nodesStr.replace( "'", "" )
3345 nodesStr = nodesStr.replace( "[", "" )
3346 nodesStr = nodesStr.replace( " ", "" )
3347 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003348
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003349 nodesSet = set( nodesList )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003350 # discarding default controller( s ) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003351 nodesSet.discard( 'c0' )
3352 nodesSet.discard( 'c1' )
3353 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003354
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003355 switchSet = nodesSet - hostSet
3356 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003357
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003358 return switchList
3359 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003360 main.log.error( self.name + ": TIMEOUT exception found" )
3361 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003362 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003363 except pexpect.EOF:
3364 main.log.error( self.name + ": EOF exception found" )
3365 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003366 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003367 except Exception:
3368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003369 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003370
You Wangdb8cd0a2016-05-26 15:19:45 -07003371 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3372 """
3373 Return a dictionary which describes the latest Mininet topology data as a
3374 graph.
3375 An example of the dictionary:
3376 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3377 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3378 Each vertex should at least have an 'edges' attribute which describes the
3379 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003380 a dictionary, which maps each edge ( identified by the neighbor vertex ) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003381 list of attributes.
3382 An example of the edges dictionary:
3383 'edges': { vertex2: { 'port': ..., 'weight': ... },
3384 vertex3: { 'port': ..., 'weight': ... } }
3385 If useId == True, dpid/mac will be used instead of names to identify
3386 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3387 topology.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003388 If includeHost == True, all hosts ( and host-switch links ) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003389 in topology data.
3390 Note that link or switch that are brought down by 'link x x down' or 'switch
3391 x down' commands still show in the output of Mininet CLI commands such as
3392 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3393 recommended to use delLink() or delSwitch functions to simulate link/switch
3394 down, and addLink() or addSwitch to add them back.
3395 """
3396 graphDict = {}
3397 try:
3398 links = self.getLinks( timeout=timeout )
3399 portDict = {}
3400 if useId:
3401 switches = self.getSwitches()
3402 if includeHost:
3403 hosts = self.getHosts()
3404 for link in links:
3405 # FIXME: support 'includeHost' argument
3406 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3407 continue
3408 nodeName1 = link[ 'node1' ]
3409 nodeName2 = link[ 'node2' ]
3410 port1 = link[ 'port1' ]
3411 port2 = link[ 'port2' ]
3412 # Loop for two nodes
3413 for i in range( 2 ):
3414 # Get port index from OVS
3415 # The index extracted from port name may be inconsistent with ONOS
3416 portIndex = -1
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003417 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003418 portList = self.getOVSPorts( nodeName1 )
3419 if len( portList ) == 0:
3420 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3421 return None
3422 portDict[ nodeName1 ] = portList
3423 for port in portDict[ nodeName1 ]:
3424 if port[ 'port' ] == port1:
3425 portIndex = port[ 'index' ]
3426 break
3427 if portIndex == -1:
3428 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3429 return None
3430 if useId:
3431 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3432 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3433 else:
3434 node1 = nodeName1
3435 node2 = nodeName2
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003436 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003437 if useId:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003438 graphDict[ node1 ] = { 'edges': {},
3439 'dpid': switches[ nodeName1 ][ 'dpid' ],
3440 'name': nodeName1,
3441 'ports': switches[ nodeName1 ][ 'ports' ],
3442 'swClass': switches[ nodeName1 ][ 'swClass' ],
3443 'pid': switches[ nodeName1 ][ 'pid' ],
3444 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003445 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003446 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003447 else:
3448 # Assert node2 is not connected to any current links of node1
3449 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003450 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003451 # Swap two nodes/ports
3452 nodeName1, nodeName2 = nodeName2, nodeName1
3453 port1, port2 = port2, port1
3454 return graphDict
3455 except KeyError:
3456 main.log.exception( self.name + ": KeyError exception found" )
3457 return None
3458 except AssertionError:
3459 main.log.exception( self.name + ": AssertionError exception found" )
3460 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003461 except pexpect.EOF:
3462 main.log.error( self.name + ": EOF exception found" )
3463 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003464 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003465 except Exception:
3466 main.log.exception( self.name + ": Uncaught exception" )
3467 return None
3468
Jon Hall7eb38402015-01-08 17:19:54 -08003469 def update( self ):
3470 """
3471 updates the port address and status information for
3472 each port in mn"""
3473 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003474 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003475 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003476 self.handle.sendline( "" )
3477 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003478
Jon Hall7eb38402015-01-08 17:19:54 -08003479 self.handle.sendline( "update" )
3480 self.handle.expect( "update" )
3481 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003482
Jon Hall7eb38402015-01-08 17:19:54 -08003483 self.handle.sendline( "" )
3484 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003485
Jon Hallb1290e82014-11-18 16:17:48 -05003486 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003487 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003488 main.log.error( self.name + ": TIMEOUT exception found" )
3489 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003490 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003491 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003492 main.log.error( self.name + ": EOF exception found" )
3493 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003494 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003495 except Exception:
3496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003497 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003498
Jon Halld80cc142015-07-06 13:36:05 -07003499 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003500 """
3501 Add vlan tag to a host.
3502 Dependencies:
3503 This class depends on the "vlan" package
3504 $ sudo apt-get install vlan
3505 Configuration:
3506 Load the 8021q module into the kernel
3507 $sudo modprobe 8021q
3508
3509 To make this setup permanent:
3510 $ sudo su -c 'echo "8021q" >> /etc/modules'
3511 """
3512 if self.handle:
3513 try:
Jon Halld80cc142015-07-06 13:36:05 -07003514 # get the ip address of the host
3515 main.log.info( "Get the ip address of the host" )
3516 ipaddr = self.getIPAddress( host )
3517 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003518
Jon Halld80cc142015-07-06 13:36:05 -07003519 # remove IP from interface intf
3520 # Ex: h1 ifconfig h1-eth0 inet 0
3521 main.log.info( "Remove IP from interface " )
3522 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3523 self.handle.sendline( cmd2 )
3524 self.handle.expect( "mininet>" )
3525 response = self.handle.before
3526 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003527
Jon Halld80cc142015-07-06 13:36:05 -07003528 # create VLAN interface
3529 # Ex: h1 vconfig add h1-eth0 100
3530 main.log.info( "Create Vlan" )
3531 cmd3 = host + " vconfig add " + intf + " " + vlan
3532 self.handle.sendline( cmd3 )
3533 self.handle.expect( "mininet>" )
3534 response = self.handle.before
3535 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003536
Jon Halld80cc142015-07-06 13:36:05 -07003537 # assign the host's IP to the VLAN interface
3538 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3539 main.log.info( "Assign the host IP to the vlan interface" )
3540 vintf = intf + "." + vlan
3541 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3542 self.handle.sendline( cmd4 )
3543 self.handle.expect( "mininet>" )
3544 response = self.handle.before
3545 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003546
3547 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003548 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003549 main.log.error( self.name + ": TIMEOUT exception found" )
3550 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003551 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003552 except pexpect.EOF:
3553 main.log.error( self.name + ": EOF exception found" )
3554 main.log.error( self.name + ": " + self.handle.before )
3555 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003556 except Exception:
3557 main.log.exception( self.name + ": Uncaught exception!" )
3558 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003559
Jon Hall892818c2015-10-20 17:58:34 -07003560 def createHostComponent( self, name ):
3561 """
3562 Creates a new mininet cli component with the same parameters as self.
3563 This new component is intended to be used to login to the hosts created
3564 by mininet.
3565
3566 Arguments:
3567 name - The string of the name of this component. The new component
3568 will be assigned to main.<name> .
3569 In addition, main.<name>.name = str( name )
3570 """
3571 try:
3572 # look to see if this component already exists
3573 getattr( main, name )
3574 except AttributeError:
3575 # namespace is clear, creating component
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003576 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3577 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003578 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003579 except pexpect.EOF:
3580 main.log.error( self.name + ": EOF exception found" )
3581 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003582 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003583 except Exception:
3584 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003585 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003586 else:
3587 # namespace is not clear!
3588 main.log.error( name + " component already exists!" )
3589 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003591
3592 def removeHostComponent( self, name ):
3593 """
3594 Remove host component
3595 Arguments:
3596 name - The string of the name of the component to delete.
3597 """
3598 try:
3599 # Get host component
3600 component = getattr( main, name )
3601 except AttributeError:
3602 main.log.error( "Component " + name + " does not exist." )
3603 return
3604 try:
3605 # Disconnect from component
3606 component.disconnect()
3607 # Delete component
3608 delattr( main, name )
3609 # Delete component from ComponentDictionary
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003610 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003611 except pexpect.EOF:
3612 main.log.error( self.name + ": EOF exception found" )
3613 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003614 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003615 except Exception:
3616 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003617 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003618
3619 def startHostCli( self, host=None ):
3620 """
3621 Use the mininet m utility to connect to the host's cli
3622 """
3623 # These are fields that can be used by scapy packets. Initialized to None
3624 self.hostIp = None
3625 self.hostMac = None
3626 try:
3627 if not host:
3628 host = self.name
3629 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003630 self.handle.sendline( "cd" )
3631 self.handle.expect( self.hostPrompt )
3632 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003633 self.handle.expect( self.hostPrompt )
3634 return main.TRUE
3635 except pexpect.TIMEOUT:
3636 main.log.exception( self.name + ": Command timed out" )
3637 return main.FALSE
3638 except pexpect.EOF:
3639 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003640 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003641 except Exception:
3642 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003643 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003644
YPZhang801d46d2016-08-08 13:26:28 -07003645 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003646 """
YPZhang801d46d2016-08-08 13:26:28 -07003647 Args:
3648 devicename: switch name
3649 intf: port name on switch
3650 status: up or down
3651
3652 Returns: boolean to show success change status
3653
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003654 """
YPZhang801d46d2016-08-08 13:26:28 -07003655 if status == "down" or status == "up":
3656 try:
3657 cmd = devicename + " ifconfig " + intf + " " + status
3658 self.handle.sendline( cmd )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003659 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003660 return main.TRUE
3661 except pexpect.TIMEOUT:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003662 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003663 return main.FALSE
3664 except pexpect.EOF:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003665 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003666 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003667 except TypeError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003668 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003669 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003670 except Exception:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003671 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003672 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003673 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003674 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003675 return main.FALSE
3676
3677
adminbae64d82013-08-01 10:50:15 -07003678if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003679 sys.modules[ __name__ ] = MininetCliDriver()