blob: 531e5ca860a09c7fd718fb26fa2023b9586c51c9 [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 Ronquillob27ce4c2017-07-17 12:41:28 -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 ):
Jon Hall7eb38402015-01-08 17:19:54 -080047 """
48 MininetCliDriver is the basic driver which will handle
49 the Mininet functions"""
50 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070051 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070052 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080053 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070054 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080055 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070056 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070057 # TODO: Refactor driver to use these everywhere
58 self.mnPrompt = "mininet>"
59 self.hostPrompt = "~#"
60 self.bashPrompt = "\$"
61 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070062 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070063
Jon Hall7eb38402015-01-08 17:19:54 -080064 def connect( self, **connectargs ):
65 """
66 Here the main is the TestON instance after creating
67 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080068 try:
69 for key in connectargs:
70 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070071 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080072 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070073 for key in self.options:
74 if key == "home":
75 self.home = self.options[ 'home' ]
76 break
77 if self.home is None or self.home == "":
78 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070079
80 try:
Jon Hall892818c2015-10-20 17:58:34 -070081 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070082 self.ip_address = os.getenv( str( self.ip_address ) )
83 else:
84 main.log.info( self.name +
85 ": Trying to connect to " +
86 self.ip_address )
87
88 except KeyError:
89 main.log.info( "Invalid host name," +
90 " connecting to local host instead" )
91 self.ip_address = 'localhost'
92 except Exception as inst:
93 main.log.error( "Uncaught exception: " + str( inst ) )
94
kelvin-onlaba1484582015-02-02 15:46:20 -080095 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070096 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080097 self ).connect(
98 user_name=self.user_name,
99 ip_address=self.ip_address,
100 port=None,
101 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800102
kelvin-onlaba1484582015-02-02 15:46:20 -0800103 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800104 main.log.info( "Connection successful to the host " +
105 self.user_name +
106 "@" +
107 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800108 return main.TRUE
109 else:
110 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800111 self.user_name +
112 "@" +
113 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800114 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800115 return main.FALSE
116 except pexpect.EOF:
117 main.log.error( self.name + ": EOF exception found" )
118 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700119 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800120 except Exception:
121 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700122 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800123
kelvin-onlab10e8d392015-06-03 13:53:45 -0700124 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800125 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700126 Description:
127 Starts Mininet accepts a topology(.py) file and/or an optional
128 argument, to start the mininet, as a parameter.
129 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700130 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700131 Options:
132 topoFile = file path for topology file (.py)
133 args = extra option added when starting the topology from the file
134 mnCmd = Mininet command use to start topology
135 Returns:
136 main.TRUE if the mininet starts successfully, main.FALSE
137 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800138 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700139 try:
140 if self.handle:
141 # make sure old networks are cleaned up
142 main.log.info( self.name +
143 ": Clearing any residual state or processes" )
144 self.handle.sendline( "sudo mn -c" )
145 i = self.handle.expect( [ 'password\sfor\s',
146 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800147 pexpect.EOF,
148 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700149 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800150 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700151 # Sudo asking for password
152 main.log.info( self.name + ": Sending sudo password" )
153 self.handle.sendline( self.pwd )
154 i = self.handle.expect( [ '%s:' % self.user,
Devin Limdc78e202017-06-09 18:30:07 -0700155 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700156 pexpect.EOF,
157 pexpect.TIMEOUT ],
158 timeout )
159 if i == 1:
160 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700161 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700162 main.log.error( self.name + ": Connection terminated" )
163 elif i == 3: # timeout
164 main.log.error( self.name + ": Something while cleaning " +
165 "Mininet took too long... " )
166 # Craft the string to start mininet
167 cmdString = "sudo "
168 if not mnCmd:
169 if topoFile is None or topoFile == '': # If no file is given
170 main.log.info( self.name + ": building fresh Mininet" )
171 cmdString += "mn "
172 if args is None or args == '':
173 # If no args given, use args from .topo file
174 args = self.options[ 'arg1' ] +\
175 " " + self.options[ 'arg2' ] +\
176 " --mac --controller " +\
177 self.options[ 'controller' ] + " " +\
178 self.options[ 'arg3' ]
179 else: # else only use given args
180 pass
181 # TODO: allow use of topo args and method args?
182 else: # Use given topology file
183 main.log.info(
184 "Starting Mininet from topo file " +
185 topoFile )
186 cmdString += "-E python " + topoFile + " "
187 if args is None:
188 args = ''
189 # TODO: allow use of args from .topo file?
190 cmdString += args
191 else:
192 main.log.info( "Starting Mininet topology using '" + mnCmd +
193 "' command" )
194 cmdString += mnCmd
195 # Send the command and check if network started
196 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700197 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700198 main.log.info( "Sending '" + cmdString + "' to " + self.name )
199 self.handle.sendline( cmdString )
200 while True:
201 i = self.handle.expect( [ 'mininet>',
202 'Exception',
203 '\*\*\*',
204 pexpect.EOF,
205 pexpect.TIMEOUT ],
206 timeout )
207 if i == 0:
208 main.log.info( self.name + ": Mininet built" )
209 return main.TRUE
210 elif i == 1:
211 response = str( self.handle.before +
212 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700213 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700214 response += str( self.handle.before +
215 self.handle.after )
216 main.log.error(
217 self.name +
218 ": Launching Mininet failed: " + response )
219 return main.FALSE
220 elif i == 2:
221 self.handle.expect( [ "\n",
222 pexpect.EOF,
223 pexpect.TIMEOUT ],
224 timeout )
225 main.log.info( self.handle.before )
226 elif i == 3:
227 main.log.error( self.name + ": Connection timeout" )
228 return main.FALSE
229 elif i == 4: # timeout
230 main.log.error(
231 self.name +
232 ": Something took too long... " )
233 return main.FALSE
234 # Why did we hit this part?
235 main.log.error( "startNet did not return correctly" )
236 return main.FASLE
237 else: # if no handle
238 main.log.error( self.name + ": Connection failed to the host " +
239 self.user_name + "@" + self.ip_address )
240 main.log.error( self.name + ": Failed to connect to the Mininet" )
241 return main.FALSE
242 except pexpect.TIMEOUT:
243 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
244 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700245 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700246 except pexpect.EOF:
247 main.log.error( self.name + ": EOF exception found" )
248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700249 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700250 except Exception:
251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700252 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800253
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800254 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700255 try:
256 if topoType == 'tree':
257 # In tree topology, if fanout arg is not given, by default it is 2
258 if fanout is None:
259 fanout = 2
260 k = 0
261 count = 0
262 while( k <= depth - 1 ):
263 count = count + pow( fanout, k )
264 k = k + 1
265 numSwitches = count
266 while( k <= depth - 2 ):
267 # depth-2 gives you only core links and not considering
268 # edge links as seen by ONOS. If all the links including
269 # edge links are required, do depth-1
270 count = count + pow( fanout, k )
271 k = k + 1
272 numLinks = count * fanout
273 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
274 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800275
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700276 elif topoType == 'linear':
277 # In linear topology, if fanout or numHostsPerSw is not given,
278 # by default it is 1
279 if fanout is None:
280 fanout = 1
281 numSwitches = depth
282 numHostsPerSw = fanout
283 totalNumHosts = numSwitches * numHostsPerSw
284 numLinks = totalNumHosts + ( numSwitches - 1 )
285 print "num_switches for %s(%d,%d) = %d and links=%d" %\
286 ( topoType, depth, fanout, numSwitches, numLinks )
287 topoDict = { "num_switches": int( numSwitches ),
288 "num_corelinks": int( numLinks ) }
289 return topoDict
290 except Exception:
291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700292 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400293
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700295 """
296 Calculate the number of switches and links in a topo."""
297 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700298 try:
299 argList = self.options[ 'arg1' ].split( "," )
300 topoArgList = argList[ 0 ].split( " " )
301 argList = map( int, argList[ 1: ] )
302 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700303
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700304 topoDict = self.numSwitchesNlinks( *topoArgList )
305 return topoDict
306 except Exception:
307 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700308 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400309
GlennRCf07c44a2015-09-18 13:33:46 -0700310 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800311 """
312 Verifies the reachability of the hosts using pingall command.
313 Optional parameter timeout allows you to specify how long to
314 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700315 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700316 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700317 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700318 ping
319 acceptableFailed - Set the number of acceptable failed pings for the
320 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800321 Returns:
322 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700323 otherwise main.FALSE
324 """
325 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700326 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700327 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700328 if self.handle:
329 main.log.info(
330 self.name +
331 ": Checking reachabilty to the hosts using pingall" )
332 response = ""
333 failedPings = 0
334 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700335 cmd = "pingall"
336 if protocol == "IPv6":
337 cmd = "py net.pingAll6()"
338 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700339 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700340 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700341 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700342 pexpect.EOF,
343 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700344 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700345 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700346 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700347 response += self.handle.before
348 break
349 elif i == 1:
350 response += self.handle.before + self.handle.after
351 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700352 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700353 returnValue = main.FALSE
354 if shortCircuit:
355 main.log.error( self.name +
356 ": Aborting pingall - "
357 + str( failedPings ) +
358 " pings failed" )
359 break
Jon Hall390696c2015-05-05 17:13:41 -0700360 if ( time.time() - startTime ) > timeout:
361 returnValue = main.FALSE
362 main.log.error( self.name +
363 ": Aborting pingall - " +
364 "Function took too long " )
365 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700366 elif i == 2:
367 main.log.error( self.name +
368 ": EOF exception found" )
369 main.log.error( self.name + ": " +
370 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700371 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700372 elif i == 3:
373 response += self.handle.before
374 main.log.error( self.name +
375 ": TIMEOUT exception found" )
376 main.log.error( self.name +
377 ": " +
378 str( response ) )
379 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800380 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700381 self.handle.expect( "Interrupt" )
382 self.handle.expect( "mininet>" )
383 break
384 pattern = "Results\:"
385 main.log.info( "Pingall output: " + str( response ) )
386 if re.search( pattern, response ):
387 main.log.info( self.name + ": Pingall finished with "
388 + str( failedPings ) + " failed pings" )
389 return returnValue
390 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700391 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800392 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700393 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700394 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700395 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700396 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700397 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700398 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700399 except pexpect.TIMEOUT:
400 if response:
401 main.log.info( "Pingall output: " + str( response ) )
402 main.log.error( self.name + ": pexpect.TIMEOUT found" )
403 return main.FALSE
404 except pexpect.EOF:
405 main.log.error( self.name + ": EOF exception found" )
406 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700407 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700408
Jon Hall7eb38402015-01-08 17:19:54 -0800409 def fpingHost( self, **pingParams ):
410 """
411 Uses the fping package for faster pinging...
412 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700413 try:
414 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
415 command = args[ "SRC" ] + \
416 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
417 self.handle.sendline( command )
418 self.handle.expect(
419 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
420 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
421 response = self.handle.before
422 if re.search( ":\s-", response ):
423 main.log.info( self.name + ": Ping fail" )
424 return main.FALSE
425 elif re.search( ":\s\d{1,2}\.\d\d", response ):
426 main.log.info( self.name + ": Ping good!" )
427 return main.TRUE
428 main.log.info( self.name + ": Install fping on mininet machine... " )
429 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700430 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700431 except Exception:
432 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700433 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700434
Jon Hallfbc828e2015-01-06 17:30:19 -0800435
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
463 pingResponse += str(str(host) + " -> ")
464
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 ):
GlennRCd10d3cc2015-09-24 12:47:16 -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"
GlennRC6d506272015-09-25 11:36:07 -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
GlennRC2cf7d952015-09-11 16:32:13 -0700514 pingResponse += str(str(host) + " -> ")
515
Hari Krishna9592fc82015-07-31 15:11:15 -0700516 for temp in pingList:
517 # Current host pings all other hosts specified
Jon Hall439c8912016-04-15 02:22:03 -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 ):
GlennRC2cf7d952015-09-11 16:32:13 -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"
GlennRC6d506272015-09-25 11:36:07 -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 )
550 wait = args['WAIT']
551 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
Hari Krishna012a1c12015-08-25 14:23:58 -0700591 FLOWLABEL and -I (src interface) will be added later after running some tests.
592 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 )
595 wait = args['WAIT']
596 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:
839 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
Jon Hall439c8912016-04-15 02:22:03 -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"
926 print "cmd9 =",cmd
927 response = self.execute( cmd = cmd, prompt="mininet>" ,timeout=10 )
928 print response
929 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700930 ipAddressSearch = re.search( pattern, response )
Jon Hall439c8912016-04-15 02:22:03 -0700931 print ipAddressSearch.group(1)
932 intf= host + "-eth" + str(ipAddressSearch.group(1))
933 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:
953 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:
983 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:
1012 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:
1041 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:
1065 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
sathishmad953462015-12-03 17:42:07 +05301139 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:
1215 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
GlennRC61321f22015-07-16 13:36:54 -07001308 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001309 '''
1310 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.
1315 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001316 try:
1317 for host1 in hosts:
1318 for host2 in hosts:
1319 if host1 != host2:
1320 if self.iperftcp(host1, host2, timeout) == main.FALSE:
1321 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
1322 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
1326 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001327 '''
1328 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.
1334 '''
1335 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:
Jon Hall892818c2015-10-20 17:58:34 -07001345 main.log.report(self.name + ": iperf test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001346 # parse the mn results
1347 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
1356 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
1359 # ['host1 to host2', 'host2 to host1"]
1360 if len(bandwidth) == 2:
1361 main.log.report(self.name + ": iperf test successful")
1362 return main.TRUE
1363 else:
1364 main.log.error(self.name + ": invalid iperf results")
1365 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
Jon Hall439c8912016-04-15 02:22:03 -07001386 def iperftcpipv6(self, host1="h1", host2="h2", timeout=50):
1387 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1388 try:
1389 IP1 = self.getIPAddress( host1, proto='IPV6' )
1390 cmd1 = host1 +' iperf -V -sD -B '+ str(IP1)
1391 self.handle.sendline( cmd1 )
1392 outcome1 = self.handle.expect( "mininet>")
1393 cmd2 = host2 +' iperf -V -c '+ str(IP1) +' -t 5'
1394 self.handle.sendline( cmd2 )
1395 outcome2 = self.handle.expect( "mininet>")
1396 response1 = self.handle.before
1397 response2 = self.handle.after
1398 print response1,response2
1399 pattern = "connected with "+ str(IP1)
1400 if pattern in response1:
1401 main.log.report(self.name + ": iperf test completed")
1402 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
GlennRC61321f22015-07-16 13:36:54 -07001421 def iperfudpAll(self, hosts, bandwidth="10M"):
1422 '''
1423 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:
1427 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:
1433 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1434 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1435 except TypeError:
1436 main.log.exception(self.name + ": Object not as expected")
1437 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
1442 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1443
kelvin-onlab7cce9382015-07-17 10:21:03 -07001444 '''
1445 Creates an iperf UDP test with a specific bandwidth.
1446 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001447
kelvin-onlab7cce9382015-07-17 10:21:03 -07001448 @param:
1449 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1450 '''
1451 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1452 try:
1453 # setup the mininet command
1454 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1455 self.handle.sendline(cmd)
1456 self.handle.expect("mininet>")
1457 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001458
kelvin-onlab7cce9382015-07-17 10:21:03 -07001459 # check if there are in results in the mininet response
1460 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001461 main.log.report(self.name + ": iperfudp test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001462 # parse the results
1463 response = response.split("\r\n")
1464 response = response[len(response)-2]
1465 response = response.split(": ")
1466 response = response[len(response)-1]
1467 response = response.replace("[", "")
1468 response = response.replace("]", "")
1469 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001470
kelvin-onlab7cce9382015-07-17 10:21:03 -07001471 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001472
kelvin-onlab7cce9382015-07-17 10:21:03 -07001473 # check to see if there are at least three entries
1474 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1475 if len(mnBandwidth) == 3:
1476 # if one entry is blank then something is wrong
1477 for item in mnBandwidth:
1478 if item == "":
1479 main.log.error(self.name + ": Could not parse iperf output")
1480 main.log.error(self.name + ": invalid iperfudp results")
1481 return main.FALSE
1482 # otherwise results are vaild
1483 main.log.report(self.name + ": iperfudp test successful")
1484 return main.TRUE
1485 else:
1486 main.log.error(self.name + ": invalid iperfudp results")
1487 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001488
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001489 except pexpect.TIMEOUT:
1490 main.log.error(self.name + ": TIMEOUT exception found")
1491 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001492 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001493 except pexpect.EOF:
1494 main.log.error( self.name + ": EOF exception found" )
1495 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001496 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001497 except Exception:
1498 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001499 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001500
Jon Hall7eb38402015-01-08 17:19:54 -08001501 def nodes( self ):
1502 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001503 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001504 response = self.execute(
1505 cmd='nodes',
1506 prompt='mininet>',
1507 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001508 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001509 main.log.error( self.name + ": EOF exception found" )
1510 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001511 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001512 except Exception:
1513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001514 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001515 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001516
Jon Hall7eb38402015-01-08 17:19:54 -08001517 def pingpair( self ):
1518 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001519 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001520 response = self.execute(
1521 cmd='pingpair',
1522 prompt='mininet>',
1523 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001524 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001525 main.log.error( self.name + ": EOF exception found" )
1526 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001527 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001528 except Exception:
1529 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001530 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001531
Jon Hall7eb38402015-01-08 17:19:54 -08001532 if re.search( ',\s0\%\spacket\sloss', response ):
1533 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001534 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001535 else:
alisone4121a92016-11-22 16:31:36 -08001536 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001537 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001538
Jon Hall7eb38402015-01-08 17:19:54 -08001539 def link( self, **linkargs ):
1540 """
GlennRCed771242016-01-13 17:02:47 -08001541 Bring link( s ) between two nodes up or down
1542 """
Jon Hall6094a362014-04-11 14:46:56 -07001543 try:
GlennRCed771242016-01-13 17:02:47 -08001544 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1545 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1546 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1547 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1548
1549 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1550 cmd = "link {} {} {}".format( end1, end2, option )
1551 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001552 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001553 response = self.handle.before
1554 main.log.info( response )
1555
1556 return main.TRUE
1557 except pexpect.TIMEOUT:
1558 main.log.exception( self.name + ": Command timed out" )
1559 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001560 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001561 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001562 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001563 except Exception:
1564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001565 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001566
pingping-lin8244a3b2015-09-16 13:36:56 -07001567 def switch( self, **switchargs ):
1568 """
1569 start/stop a switch
1570 """
1571 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1572 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1573 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1574 command = "switch " + str( sw ) + " " + str( option )
1575 main.log.info( command )
1576 try:
1577 self.handle.sendline( command )
1578 self.handle.expect( "mininet>" )
1579 except pexpect.TIMEOUT:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001580 main.log.error(self.name + ": TIMEOUT exception found")
1581 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001582 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001583 except pexpect.EOF:
1584 main.log.error( self.name + ": EOF exception found" )
1585 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001586 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001587 return main.TRUE
1588
pingping-lin5bb663b2015-09-24 11:47:50 -07001589 def node( self, nodeName, commandStr ):
1590 """
1591 Carry out a command line on a given node
1592 @parm:
1593 nodeName: the node name in Mininet testbed
1594 commandStr: the command line will be carried out on the node
1595 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1596 """
1597 command = str( nodeName ) + " " + str( commandStr )
1598 main.log.info( command )
1599
1600 try:
1601 response = self.execute( cmd = command, prompt = "mininet>" )
1602 if re.search( "Unknown command", response ):
1603 main.log.warn( response )
1604 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001605 if re.search( "Permission denied", response ):
1606 main.log.warn( response )
1607 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001608 except pexpect.EOF:
1609 main.log.error( self.name + ": EOF exception found" )
1610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001611 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001612 main.log.info( " response is :" )
1613 main.log.info( response )
1614 return response
1615
Jon Hall7eb38402015-01-08 17:19:54 -08001616 def yank( self, **yankargs ):
1617 """
1618 yank a mininet switch interface to a host"""
1619 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001620 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001621 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1622 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1623 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001624 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001625 response = self.execute(
1626 cmd=command,
1627 prompt="mininet>",
1628 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001629 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001630 main.log.error( self.name + ": EOF exception found" )
1631 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001632 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001633 except Exception:
1634 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001635 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001636 return main.TRUE
1637
Jon Hall7eb38402015-01-08 17:19:54 -08001638 def plug( self, **plugargs ):
1639 """
1640 plug the yanked mininet switch interface to a switch"""
1641 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001642 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001643 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1644 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1645 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001646 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001647 response = self.execute(
1648 cmd=command,
1649 prompt="mininet>",
1650 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001651 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001652 main.log.error( self.name + ": EOF exception found" )
1653 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001654 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001655 except Exception:
1656 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001657 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001658 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001659
Jon Hall7eb38402015-01-08 17:19:54 -08001660 def dpctl( self, **dpctlargs ):
1661 """
1662 Run dpctl command on all switches."""
1663 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001664 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001665 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1666 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1667 command = "dpctl " + cmd + " " + str( cmdargs )
1668 try:
1669 response = self.execute(
1670 cmd=command,
1671 prompt="mininet>",
1672 timeout=10 )
1673 except pexpect.EOF:
1674 main.log.error( self.name + ": EOF exception found" )
1675 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001676 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001677 except Exception:
1678 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001679 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001680 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001681
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001683 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001684 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001685 try:
1686 fileInput = path + '/lib/Mininet/INSTALL'
1687 version = super( Mininet, self ).getVersion()
1688 pattern = 'Mininet\s\w\.\w\.\w\w*'
1689 for line in open( fileInput, 'r' ).readlines():
1690 result = re.match( pattern, line )
1691 if result:
1692 version = result.group( 0 )
1693 return version
1694 except Exception:
1695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001696 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001697
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001699 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001700 Parameters:
1701 sw: The name of an OVS switch. Example "s1"
1702 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001703 The output of the command from the mininet cli
1704 or main.FALSE on timeout"""
1705 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001706 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001707 response = self.execute(
1708 cmd=command,
1709 prompt="mininet>",
1710 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001711 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001712 return response
admin2a9548d2014-06-17 14:08:07 -07001713 else:
1714 return main.FALSE
1715 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001716 main.log.error( self.name + ": EOF exception found" )
1717 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001718 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001719 except Exception:
1720 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001721 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001722
Charles Chan029be652015-08-24 01:46:10 +08001723 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001724 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001725 Description:
1726 Assign switches to the controllers ( for ovs use only )
1727 Required:
1728 sw - Name of the switch. This can be a list or a string.
1729 ip - Ip addresses of controllers. This can be a list or a string.
1730 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001731 port - ONOS use port 6653, if no list of ports is passed, then
1732 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001733 ptcp - ptcp number, This can be a string or a list that has
1734 the same length as switch. This is optional and not required
1735 when using ovs switches.
1736 NOTE: If switches and ptcp are given in a list type they should have the
1737 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1738 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001739
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001740 Return:
1741 Returns main.TRUE if mininet correctly assigned switches to
1742 controllers, otherwise it will return main.FALSE or an appropriate
1743 exception(s)
1744 """
1745 assignResult = main.TRUE
1746 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001747 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001748 command = "sh ovs-vsctl set-controller "
1749 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001750 try:
1751 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001752 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001753 if isinstance( port, types.StringType ) or \
1754 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001755 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001756 elif isinstance( port, types.ListType ):
1757 main.log.error( self.name + ": Only one controller " +
1758 "assigned and a list of ports has" +
1759 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001760 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001761 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001762 main.log.error( self.name + ": Invalid controller port " +
1763 "number. Please specify correct " +
1764 "controller port" )
1765 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001766
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001767 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001768 if isinstance( port, types.StringType ) or \
1769 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001770 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001771 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1772 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001773 elif isinstance( port, types.ListType ):
1774 if ( len( ip ) != len( port ) ):
1775 main.log.error( self.name + ": Port list = " +
1776 str( len( port ) ) +
1777 "should be the same as controller" +
1778 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001779 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001780 else:
1781 onosIp = ""
1782 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001783 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1784 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001785 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001786 main.log.error( self.name + ": Invalid controller port " +
1787 "number. Please specify correct " +
1788 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001789 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001790 else:
1791 main.log.error( self.name + ": Invalid ip address" )
1792 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001793
1794 if isinstance( sw, types.StringType ):
1795 command += sw + " "
1796 if ptcp:
1797 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001798 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001799 elif isinstance( ptcp, types.ListType ):
1800 main.log.error( self.name + ": Only one switch is " +
1801 "being set and multiple PTCP is " +
1802 "being passed " )
1803 else:
1804 main.log.error( self.name + ": Invalid PTCP" )
1805 ptcp = ""
1806 command += onosIp
1807 commandList.append( command )
1808
1809 elif isinstance( sw, types.ListType ):
1810 if ptcp:
1811 if isinstance( ptcp, types.ListType ):
1812 if len( ptcp ) != len( sw ):
1813 main.log.error( self.name + ": PTCP length = " +
1814 str( len( ptcp ) ) +
1815 " is not the same as switch" +
1816 " length = " +
1817 str( len( sw ) ) )
1818 return main.FALSE
1819 else:
1820 for switch, ptcpNum in zip( sw, ptcp ):
1821 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001822 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001823 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001824 tempCmd += onosIp
1825 commandList.append( tempCmd )
1826 else:
1827 main.log.error( self.name + ": Invalid PTCP" )
1828 return main.FALSE
1829 else:
1830 for switch in sw:
1831 tempCmd = "sh ovs-vsctl set-controller "
1832 tempCmd += switch + " " + onosIp
1833 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001834 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001835 main.log.error( self.name + ": Invalid switch type " )
1836 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001837
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001838 for cmd in commandList:
1839 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001840 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001841 except pexpect.TIMEOUT:
1842 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1843 return main.FALSE
1844 except pexpect.EOF:
1845 main.log.error( self.name + ": EOF exception found" )
1846 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001847 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001848 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001849 except pexpect.EOF:
1850 main.log.error( self.name + ": EOF exception found" )
1851 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001852 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001853 except Exception:
1854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001855 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001856
kelvin-onlabd3b64892015-01-20 13:26:24 -08001857 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001858 """
1859 Removes the controller target from sw"""
1860 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001861 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001862 response = self.execute(
1863 cmd=command,
1864 prompt="mininet>",
1865 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001866 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001867 main.log.error( self.name + ": EOF exception found" )
1868 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001869 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001870 except Exception:
1871 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001872 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001873 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001874 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001875
kelvin-onlabd3b64892015-01-20 13:26:24 -08001876 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001877 """
Jon Hallb1290e82014-11-18 16:17:48 -05001878 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001879 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001880 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001881 NOTE: cannot currently specify what type of switch
1882 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001883 sw = name of the new switch as a string
1884 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001885 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001886 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001887 """
1888 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001889 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001890 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001891 response = self.execute(
1892 cmd=command,
1893 prompt="mininet>",
1894 timeout=10 )
1895 if re.search( "already exists!", response ):
1896 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001897 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001898 elif re.search( "Error", response ):
1899 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001900 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001901 elif re.search( "usage:", response ):
1902 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001903 return main.FALSE
1904 else:
1905 return main.TRUE
1906 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001907 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001908 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001909 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001910 except Exception:
1911 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001912 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001913
kelvin-onlabd3b64892015-01-20 13:26:24 -08001914 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001915 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001916 delete a switch from the mininet topology
1917 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001918 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001919 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001920 sw = name of the switch as a string
1921 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001922 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001923 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001924 response = self.execute(
1925 cmd=command,
1926 prompt="mininet>",
1927 timeout=10 )
1928 if re.search( "no switch named", response ):
1929 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001930 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001931 elif re.search( "Error", response ):
1932 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001933 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001934 elif re.search( "usage:", response ):
1935 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001936 return main.FALSE
1937 else:
1938 return main.TRUE
1939 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001940 main.log.error( self.name + ": EOF exception found" )
1941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001942 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001943 except Exception:
1944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001945 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001946
You Wangdb8cd0a2016-05-26 15:19:45 -07001947 def getSwitchRandom( self, timeout=60, nonCut=True ):
1948 """
1949 Randomly get a switch from Mininet topology.
1950 If nonCut is True, it gets a list of non-cut switches (the deletion
1951 of a non-cut switch will not increase the number of connected
1952 components of a graph) and randomly returns one of them, otherwise
1953 it just randomly returns one switch from all current switches in
1954 Mininet.
1955 Returns the name of the chosen switch.
1956 """
1957 import random
1958 candidateSwitches = []
1959 try:
1960 if not nonCut:
1961 switches = self.getSwitches( timeout=timeout )
1962 assert len( switches ) != 0
1963 for switchName in switches.keys():
1964 candidateSwitches.append( switchName )
1965 else:
1966 graphDict = self.getGraphDict( timeout=timeout, useId=False )
1967 if graphDict == None:
1968 return None
1969 self.graph.update( graphDict )
1970 candidateSwitches = self.graph.getNonCutVertices()
1971 if candidateSwitches == None:
1972 return None
1973 elif len( candidateSwitches ) == 0:
1974 main.log.info( self.name + ": No candidate switch for deletion" )
1975 return None
1976 else:
1977 switch = random.sample( candidateSwitches, 1 )
1978 return switch[ 0 ]
1979 except KeyError:
1980 main.log.exception( self.name + ": KeyError exception found" )
1981 return None
1982 except AssertionError:
1983 main.log.exception( self.name + ": AssertionError exception found" )
1984 return None
1985 except Exception:
1986 main.log.exception( self.name + ": Uncaught exception" )
1987 return None
1988
1989 def delSwitchRandom( self, timeout=60, nonCut=True ):
1990 """
1991 Randomly delete a switch from Mininet topology.
1992 If nonCut is True, it gets a list of non-cut switches (the deletion
1993 of a non-cut switch will not increase the number of connected
1994 components of a graph) and randomly chooses one for deletion,
1995 otherwise it just randomly delete one switch from all current
1996 switches in Mininet.
1997 Returns the name of the deleted switch
1998 """
1999 try:
2000 switch = self.getSwitchRandom( timeout, nonCut )
2001 if switch == None:
2002 return None
2003 else:
2004 deletionResult = self.delSwitch( switch )
2005 if deletionResult:
2006 return switch
2007 else:
2008 return None
2009 except Exception:
2010 main.log.exception( self.name + ": Uncaught exception" )
2011 return None
2012
kelvin-onlabd3b64892015-01-20 13:26:24 -08002013 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002014 """
2015 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002016 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002017 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002018 NOTE: cannot currently specify what type of link
2019 required params:
2020 node1 = the string node name of the first endpoint of the link
2021 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002022 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002023 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002024 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002025 response = self.execute(
2026 cmd=command,
2027 prompt="mininet>",
2028 timeout=10 )
2029 if re.search( "doesnt exist!", response ):
2030 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002031 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002032 elif re.search( "Error", response ):
2033 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002034 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002035 elif re.search( "usage:", response ):
2036 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002037 return main.FALSE
2038 else:
2039 return main.TRUE
2040 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002041 main.log.error( self.name + ": EOF exception found" )
2042 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002043 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002044 except Exception:
2045 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002046 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002047
kelvin-onlabd3b64892015-01-20 13:26:24 -08002048 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002049 """
2050 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002051 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002052 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002053 required params:
2054 node1 = the string node name of the first endpoint of the link
2055 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002056 returns: main.FALSE on an error, else main.TRUE
2057 """
Jon Hallffb386d2014-11-21 13:43:38 -08002058 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002059 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002060 response = self.execute(
2061 cmd=command,
2062 prompt="mininet>",
2063 timeout=10 )
2064 if re.search( "no node named", response ):
2065 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002066 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002067 elif re.search( "Error", response ):
2068 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002069 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002070 elif re.search( "usage:", response ):
2071 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002072 return main.FALSE
2073 else:
2074 return main.TRUE
2075 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002076 main.log.error( self.name + ": EOF exception found" )
2077 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002078 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002079 except Exception:
2080 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002081 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002082
You Wangdb8cd0a2016-05-26 15:19:45 -07002083 def getLinkRandom( self, timeout=60, nonCut=True ):
2084 """
2085 Randomly get a link from Mininet topology.
2086 If nonCut is True, it gets a list of non-cut links (the deletion
2087 of a non-cut link will not increase the number of connected
2088 component of a graph) and randomly returns one of them, otherwise
2089 it just randomly returns one link from all current links in
2090 Mininet.
2091 Returns the link as a list, e.g. [ 's1', 's2' ]
2092 """
2093 import random
2094 candidateLinks = []
2095 try:
2096 if not nonCut:
2097 links = self.getLinks( timeout=timeout )
2098 assert len( links ) != 0
2099 for link in links:
2100 # Exclude host-switch link
2101 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2102 continue
2103 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2104 else:
2105 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2106 if graphDict == None:
2107 return None
2108 self.graph.update( graphDict )
2109 candidateLinks = self.graph.getNonCutEdges()
2110 if candidateLinks == None:
2111 return None
2112 elif len( candidateLinks ) == 0:
2113 main.log.info( self.name + ": No candidate link for deletion" )
2114 return None
2115 else:
2116 link = random.sample( candidateLinks, 1 )
2117 return link[ 0 ]
2118 except KeyError:
2119 main.log.exception( self.name + ": KeyError exception found" )
2120 return None
2121 except AssertionError:
2122 main.log.exception( self.name + ": AssertionError exception found" )
2123 return None
2124 except Exception:
2125 main.log.exception( self.name + ": Uncaught exception" )
2126 return None
2127
2128 def delLinkRandom( self, timeout=60, nonCut=True ):
2129 """
2130 Randomly delete a link from Mininet topology.
2131 If nonCut is True, it gets a list of non-cut links (the deletion
2132 of a non-cut link will not increase the number of connected
2133 component of a graph) and randomly chooses one for deletion,
2134 otherwise it just randomly delete one link from all current links
2135 in Mininet.
2136 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2137 """
2138 try:
2139 link = self.getLinkRandom( timeout, nonCut )
2140 if link == None:
2141 return None
2142 else:
2143 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2144 if deletionResult:
2145 return link
2146 else:
2147 return None
2148 except Exception:
2149 main.log.exception( self.name + ": Uncaught exception" )
2150 return None
2151
kelvin-onlabd3b64892015-01-20 13:26:24 -08002152 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002153 """
Jon Hallb1290e82014-11-18 16:17:48 -05002154 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002155 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002156 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002157 NOTE: cannot currently specify what type of host
2158 required params:
2159 hostname = the string hostname
2160 optional key-value params
2161 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002162 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002163 """
2164 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002165 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002166 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002167 response = self.execute(
2168 cmd=command,
2169 prompt="mininet>",
2170 timeout=10 )
2171 if re.search( "already exists!", response ):
2172 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002173 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002174 elif re.search( "doesnt exists!", response ):
2175 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002176 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002177 elif re.search( "Error", response ):
2178 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002179 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002180 elif re.search( "usage:", response ):
2181 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002182 return main.FALSE
2183 else:
2184 return main.TRUE
2185 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002186 main.log.error( self.name + ": EOF exception found" )
2187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002188 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002189 except Exception:
2190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002191 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002192
kelvin-onlabd3b64892015-01-20 13:26:24 -08002193 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002194 """
2195 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002196 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002197 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002198 NOTE: this uses a custom mn function
2199 required params:
2200 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002201 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002202 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002203 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002204 response = self.execute(
2205 cmd=command,
2206 prompt="mininet>",
2207 timeout=10 )
2208 if re.search( "no host named", response ):
2209 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002210 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002211 elif re.search( "Error", response ):
2212 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002213 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002214 elif re.search( "usage:", response ):
2215 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002216 return main.FALSE
2217 else:
2218 return main.TRUE
2219 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002220 main.log.error( self.name + ": EOF exception found" )
2221 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002222 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002223 except Exception:
2224 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002225 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002226
Jon Hall7eb38402015-01-08 17:19:54 -08002227 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002228 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002229 Called at the end of the test to stop the mininet and
2230 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002231 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002232 try:
2233 self.handle.sendline( '' )
2234 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2235 timeout=2 )
2236 response = main.TRUE
2237 if i == 0:
2238 response = self.stopNet()
2239 elif i == 1:
2240 return main.TRUE
2241 # print "Disconnecting Mininet"
2242 if self.handle:
2243 self.handle.sendline( "exit" )
2244 self.handle.expect( "exit" )
2245 self.handle.expect( "(.*)" )
2246 else:
2247 main.log.error( "Connection failed to the host" )
2248 return response
2249 except pexpect.EOF:
2250 main.log.error( self.name + ": EOF exception found" )
2251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002252 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002253 except Exception:
2254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002255 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002256
Jon Halld80cc142015-07-06 13:36:05 -07002257 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002258 """
Jon Hall21270ac2015-02-16 17:59:55 -08002259 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002260 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002261 main.FALSE if the pexpect handle does not exist.
2262
Jon Halld61331b2015-02-17 16:35:47 -08002263 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002264 """
Jon Halld61331b2015-02-17 16:35:47 -08002265 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002266 response = ''
2267 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002268 try:
Jon Halld80cc142015-07-06 13:36:05 -07002269 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002270 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002271 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002272 pexpect.EOF,
2273 pexpect.TIMEOUT ],
2274 timeout )
2275 if i == 0:
2276 main.log.info( "Exiting mininet..." )
Jeremyd9e4eb12016-04-13 12:09:06 -07002277 response = self.execute( cmd="exit",
2278 prompt="(.*)",
2279 timeout=120 )
2280 main.log.info( self.name + ": Stopped" )
2281 self.handle.sendline( "sudo mn -c" )
2282 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002283
Jeremyd9e4eb12016-04-13 12:09:06 -07002284 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002285 main.log.info( " Mininet trying to exit while not " +
2286 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002287 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002288 elif i == 2:
2289 main.log.error( "Something went wrong exiting mininet" )
2290 elif i == 3: # timeout
2291 main.log.error( "Something went wrong exiting mininet " +
2292 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002293
Hari Krishnab35c6d02015-03-18 11:13:51 -07002294 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002295 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002296 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002297 self.handle.sendline(
2298 "sudo kill -9 \`ps -ef | grep \"" +
2299 fileName +
2300 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002301 except pexpect.TIMEOUT:
2302 main.log.error(self.name + ": TIMEOUT exception found")
2303 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07002304 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002305 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002306 main.log.error( self.name + ": EOF exception found" )
2307 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002308 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002309 except Exception:
2310 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002311 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002312 else:
2313 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002314 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002315 return response
2316
YPZhang26a139e2016-04-25 14:01:55 -07002317 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002318 """
2319 Description:
2320 Sends arp message from mininet host for hosts discovery
2321 Required:
2322 host - hosts name
2323 Optional:
2324 ip - ip address that does not exist in the network so there would
2325 be no reply.
2326 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002327 if ethDevice:
2328 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002329 cmd = srcHost + " arping -c1 "
2330 if noResult:
2331 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
2332 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002333 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002334 if output:
2335 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002336 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002337 i = self.handle.expect( [ "mininet>", "arping: " ] )
2338 if i == 0:
2339 return main.TRUE
2340 elif i == 1:
2341 response = self.handle.before + self.handle.after
2342 self.handle.expect( "mininet>" )
2343 response += self.handle.before + self.handle.after
2344 main.log.warn( "Error sending arping, output was: " +
2345 response )
2346 return main.FALSE
2347 except pexpect.TIMEOUT:
2348 main.log.error( self.name + ": TIMEOUT exception found" )
2349 main.log.warn( self.handle.before )
2350 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002351 except pexpect.EOF:
2352 main.log.error( self.name + ": EOF exception found" )
2353 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002354 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002355 except Exception:
2356 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002357 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002358
Jon Hall7eb38402015-01-08 17:19:54 -08002359 def decToHex( self, num ):
2360 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002361
Jon Hall7eb38402015-01-08 17:19:54 -08002362 def getSwitchFlowCount( self, switch ):
2363 """
2364 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002365 if self.handle:
2366 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2367 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002368 response = self.execute(
2369 cmd=cmd,
2370 prompt="mininet>",
2371 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002372 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002373 main.log.error( self.name + ": EOF exception found" )
2374 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002375 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002376 except Exception:
2377 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002378 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002379 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002380 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002381 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002382 main.log.info(
2383 "Couldn't find flows on switch %s, found: %s" %
2384 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002385 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002386 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002387 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002388 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002389
Jon Hall9ed8f372016-02-24 17:34:07 -08002390 def checkFlows( self, sw, dumpFormat=None ):
2391 if dumpFormat:
2392 command = "sh ovs-ofctl -F " + \
2393 dumpFormat + " dump-flows " + str( sw )
2394 else:
2395 command = "sh ovs-ofctl dump-flows " + str( sw )
2396 try:
2397 response = self.execute(
2398 cmd=command,
2399 prompt="mininet>",
2400 timeout=10 )
2401 return response
2402 except pexpect.EOF:
2403 main.log.error( self.name + ": EOF exception found" )
2404 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002405 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002406 except Exception:
2407 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002408 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002409
GlennRC68467eb2015-11-16 18:01:01 -08002410 def flowTableComp( self, flowTable1, flowTable2 ):
2411 # This function compares the selctors and treatments of each flow
2412 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002413 assert flowTable1, "flowTable1 is empty or None"
2414 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002415 returnValue = main.TRUE
GlennRC68467eb2015-11-16 18:01:01 -08002416 if len(flowTable1) != len(flowTable2):
2417 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002418 returnValue = main.FALSE
GlennRCfa65fce2015-12-16 13:16:08 -08002419 dFields = ["n_bytes", "cookie", "n_packets", "duration"]
2420 for flow1, flow2 in zip(flowTable1, flowTable2):
Jon Hallacd1b182015-12-17 11:43:20 -08002421 for field in dFields:
2422 try:
2423 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002424 except KeyError:
2425 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002426 try:
2427 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002428 except KeyError:
2429 pass
GlennRC68467eb2015-11-16 18:01:01 -08002430 for i in range( len(flowTable1) ):
GlennRC17bbcf52015-12-14 17:31:50 -08002431 if flowTable1[i] not in flowTable2:
2432 main.log.warn( "Flow tables do not match:" )
2433 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[i] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002434 returnValue = main.FALSE
2435 break
2436 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002437 except AssertionError:
2438 main.log.exception( "Nothing to compare" )
2439 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002440 except Exception:
2441 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002442 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002443
GlennRC528ad292015-11-12 10:38:18 -08002444 def parseFlowTable( self, flowTable, version="", debug=True ):
GlennRC956ea742015-11-05 16:14:15 -08002445 '''
2446 Discription: Parses flows into json format.
2447 NOTE: this can parse any string thats separated with commas
2448 Arguments:
2449 Required:
2450 flows: a list of strings that represnt flows
2451 Optional:
2452 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2453 debug: prints out the final result
2454 returns: A list of flows in json format
2455 '''
GlennRC528ad292015-11-12 10:38:18 -08002456 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002457 try:
2458 for flow in flowTable:
2459 jsonFlow = {}
2460 # split up the fields of the flow
2461 parsedFlow = flow.split(", ")
2462 # get rid of any spaces in front of the field
2463 for i in range( len(parsedFlow) ):
2464 item = parsedFlow[i]
2465 if item[0] == " ":
2466 parsedFlow[i] = item[1:]
2467 # grab the selector and treatment from the parsed flow
2468 # the last element is the selector and the treatment
2469 temp = parsedFlow.pop(-1)
2470 # split up the selector and the treatment
2471 temp = temp.split(" ")
2472 index = 0
2473 # parse the flags
2474 # NOTE: This only parses one flag
2475 flag = {}
2476 if version == "1.3":
2477 flag = {"flag":[temp[index]]}
2478 index += 1
2479 # the first element is the selector and split it up
2480 sel = temp[index]
GlennRC528ad292015-11-12 10:38:18 -08002481 index += 1
You Wang91c37cf2016-05-23 09:39:42 -07002482 sel = sel.split(",")
2483 # the priority is stuck in the selecter so put it back
2484 # in the flow
2485 parsedFlow.append(sel.pop(0))
2486 # parse selector
2487 criteria = []
2488 for item in sel:
2489 # this is the type of the packet e.g. "arp"
2490 if "=" not in item:
2491 criteria.append( {"type":item} )
2492 else:
2493 field = item.split("=")
2494 criteria.append( {field[0]:field[1]} )
2495 selector = {"selector": {"criteria":sorted(criteria)} }
2496 treat = temp[index]
2497 # get rid of the action part e.g. "action=output:2"
2498 # we will add it back later
2499 treat = treat.split("=")
2500 treat.pop(0)
2501 # parse treatment
2502 action = []
2503 for item in treat:
2504 field = item.split(":")
2505 action.append( {field[0]:field[1]} )
2506 # create the treatment field and add the actions
2507 treatment = {"treatment": {"action":sorted(action)} }
2508 # parse the rest of the flow
2509 for item in parsedFlow:
GlennRC528ad292015-11-12 10:38:18 -08002510 field = item.split("=")
You Wang91c37cf2016-05-23 09:39:42 -07002511 jsonFlow.update( {field[0]:field[1]} )
2512 # add the treatment and the selector to the json flow
2513 jsonFlow.update( selector )
2514 jsonFlow.update( treatment )
2515 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002516
You Wang91c37cf2016-05-23 09:39:42 -07002517 if debug: 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
Jon Hall0a543792015-12-14 11:00:26 -08002535 def getFlowTable( self, sw, version="", debug=False):
GlennRC956ea742015-11-05 16:14:15 -08002536 '''
2537 Discription: Returns the flow table(s) on a switch or switches in a list.
2538 Each element is a flow.
2539 Arguments:
2540 Required:
2541 sw: The switch name ("s1") to retrive the flow table. Can also be
2542 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
2546 '''
2547 try:
2548 switches = []
2549 if type(sw) is list:
Jon Hallca7ac292015-11-11 09:28:12 -08002550 switches.extend(sw)
GlennRC956ea742015-11-05 16:14:15 -08002551 else: switches.append(sw)
2552
2553 flows = []
2554 for s in switches:
2555 cmd = "sh ovs-ofctl dump-flows " + s
2556
GlennRC528ad292015-11-12 10:38:18 -08002557 if "1.0" == version:
2558 cmd += " -F OpenFlow10-table_id"
2559 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002560 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002561
2562 main.log.info( "Sending: " + cmd )
2563 self.handle.sendline( cmd )
2564 self.handle.expect( "mininet>" )
2565 response = self.handle.before
2566 response = response.split( "\r\n" )
2567 # dump the first two elements and the last
2568 # the first element is the command that was sent
2569 # the second is the table header
2570 # the last element is empty
2571 response = response[2:-1]
2572 flows.extend( response )
2573
2574 if debug: print "Flows:\n{}\n\n".format(flows)
2575
GlennRC528ad292015-11-12 10:38:18 -08002576 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002577
GlennRC956ea742015-11-05 16:14:15 -08002578 except pexpect.EOF:
2579 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002580 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002581 except Exception:
2582 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002583 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002584
2585 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
2586 '''
2587 Discription: Checks whether the ID provided matches a flow ID in Mininet
2588 Arguments:
2589 Required:
2590 sw: The switch name ("s1") to retrive the flow table. Can also be
2591 a list of switches.
2592 flowId: the flow ID in hex format. Can also be a list of IDs
2593 Optional:
2594 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2595 debug: prints out the final result
2596 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2597 NOTE: prints out IDs that are not present
2598 '''
2599 try:
2600 main.log.info( "Getting flows from Mininet" )
2601 flows = self.getFlowTable( sw, version, debug )
You Wang083ae982016-05-25 09:31:09 -07002602 if flows == None:
2603 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002604
2605 if debug: print "flow ids:\n{}\n\n".format(flowId)
2606
2607 # Check flowId is a list or a string
2608 if type( flowId ) is str:
2609 result = False
2610 for f in flows:
2611 if flowId in f.get( 'cookie' ):
2612 result = True
2613 break
2614 # flowId is a list
2615 else:
2616 result = True
2617 # Get flow IDs from Mininet
2618 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2619 # Save the IDs that are not in Mininet
2620 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2621
2622 if debug: print "mn flow ids:\n{}\n\n".format(mnFlowIds)
2623
2624 # Print out the IDs that are not in Mininet
2625 if absentIds:
2626 main.log.warn( "Absent ids: {}".format( absentIds ) )
2627 result = False
2628
2629 return main.TRUE if result else main.FALSE
2630
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002631 except pexpect.EOF:
2632 main.log.error( self.name + ": EOF exception found" )
2633 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002634 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002635 except Exception:
2636 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002637 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002638
2639
Charles Chan029be652015-08-24 01:46:10 +08002640 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002641 """
Jon Hallefbd9792015-03-05 16:11:36 -08002642 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002643 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002644 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002645 self.handle.sendline( "" )
2646 self.handle.expect( "mininet>" )
2647 self.handle.sendline(
2648 "sh sudo tcpdump -n -i " +
2649 intf +
2650 " " +
2651 port +
2652 " -w " +
2653 filename.strip() +
2654 " &" )
2655 self.handle.sendline( "" )
2656 i = self.handle.expect( [ 'No\ssuch\device',
2657 'listening\son',
2658 pexpect.TIMEOUT,
2659 "mininet>" ],
2660 timeout=10 )
2661 main.log.warn( self.handle.before + self.handle.after )
2662 self.handle.sendline( "" )
2663 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002664 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002665 main.log.error(
2666 self.name +
2667 ": tcpdump - No such device exists. " +
2668 "tcpdump attempted on: " +
2669 intf )
admin2a9548d2014-06-17 14:08:07 -07002670 return main.FALSE
2671 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002672 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002673 return main.TRUE
2674 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002675 main.log.error(
2676 self.name +
2677 ": tcpdump command timed out! Check interface name," +
2678 " given interface was: " +
2679 intf )
admin2a9548d2014-06-17 14:08:07 -07002680 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002681 elif i == 3:
2682 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002683 return main.TRUE
2684 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002685 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002686 return main.FALSE
2687 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002690 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002691 except Exception:
2692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002693 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002694
kelvin-onlabd3b64892015-01-20 13:26:24 -08002695 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002696 """
2697 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002698 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002699 self.handle.sendline( "sh sudo pkill tcpdump" )
2700 self.handle.expect( "mininet>" )
2701 self.handle.sendline( "" )
2702 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002703 except pexpect.TIMEOUT:
2704 main.log.error(self.name + ": TIMEOUT exception found")
2705 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07002706 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002707 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002708 main.log.error( self.name + ": EOF exception found" )
2709 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002710 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002711 except Exception:
2712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002713 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002714
Jon Halld80cc142015-07-06 13:36:05 -07002715 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002716 """
2717 Read ports from a Mininet switch.
2718
2719 Returns a json structure containing information about the
2720 ports of the given switch.
2721 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002722 try:
2723 response = self.getInterfaces( nodeName )
2724 # TODO: Sanity check on response. log if no such switch exists
2725 ports = []
2726 for line in response.split( "\n" ):
2727 if not line.startswith( "name=" ):
2728 continue
2729 portVars = {}
2730 for var in line.split( "," ):
2731 key, value = var.split( "=" )
2732 portVars[ key ] = value
2733 isUp = portVars.pop( 'enabled', "True" )
2734 isUp = "True" in isUp
2735 if verbose:
2736 main.log.info( "Reading switch port %s(%s)" %
2737 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2738 mac = portVars[ 'mac' ]
2739 if mac == 'None':
2740 mac = None
2741 ips = []
2742 ip = portVars[ 'ip' ]
2743 if ip == 'None':
2744 ip = None
2745 ips.append( ip )
2746 name = portVars[ 'name' ]
2747 if name == 'None':
2748 name = None
2749 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2750 if name == 'lo':
2751 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2752 else:
2753 portNo = re.search( portRe, name ).group( 'port' )
2754 ports.append( { 'of_port': portNo,
2755 'mac': str( mac ).replace( '\'', '' ),
2756 'name': name,
2757 'ips': ips,
2758 'enabled': isUp } )
2759 return ports
2760 except pexpect.EOF:
2761 main.log.error( self.name + ": EOF exception found" )
2762 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002763 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002764 except Exception:
2765 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002766 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002767
You Wangdb8cd0a2016-05-26 15:19:45 -07002768 def getOVSPorts( self, nodeName ):
2769 """
2770 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2771
2772 Returns a list of dictionaries containing information about each
2773 port of the given switch.
2774 """
2775 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2776 try:
2777 response = self.execute(
2778 cmd=command,
2779 prompt="mininet>",
2780 timeout=10 )
2781 ports = []
2782 if response:
2783 for line in response.split( "\n" ):
2784 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2785 # Example port:
2786 # 1(s1-eth1): addr:ae:60:72:77:55:51
2787 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2788 result = re.search( pattern, line )
2789 if result:
2790 index = result.group( 'index' )
2791 name = result.group( 'name' )
2792 # This port number is extracted from port name
2793 port = result.group( 'port' )
2794 mac = result.group( 'mac' )
2795 ports.append( { 'index': index,
2796 'name': name,
2797 'port': port,
2798 'mac': mac } )
2799 return ports
2800 except pexpect.EOF:
2801 main.log.error( self.name + ": EOF exception found" )
2802 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002803 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002804 except Exception:
2805 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002806 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002807
Jon Halld80cc142015-07-06 13:36:05 -07002808 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002809 """
2810 Read switches from Mininet.
2811
2812 Returns a dictionary whose keys are the switch names and the value is
2813 a dictionary containing information about the switch.
2814 """
Jon Halla22481b2015-07-28 17:46:01 -07002815 # NOTE: To support new Mininet switch classes, just append the new
2816 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002817
Jon Halla22481b2015-07-28 17:46:01 -07002818 # Regex patterns to parse 'dump' output
2819 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002820 # <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 -07002821 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002822 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2823 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2824 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002825 try:
2826 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2827 swRE = r"<(?P<class>" + switchClasses + r")" +\
2828 r"(?P<options>\{.*\})?\s" +\
2829 r"(?P<name>[^:]+)\:\s" +\
2830 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2831 r"\spid=(?P<pid>(\d)+)"
2832 # Update mn port info
2833 self.update()
2834 output = {}
2835 dump = self.dump().split( "\n" )
2836 for line in dump:
2837 result = re.search( swRE, line, re.I )
2838 if result:
2839 name = result.group( 'name' )
2840 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2841 pid = result.group( 'pid' )
2842 swClass = result.group( 'class' )
2843 options = result.group( 'options' )
2844 if verbose:
2845 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2846 ports = self.getPorts( name )
2847 output[ name ] = { "dpid": dpid,
2848 "ports": ports,
2849 "swClass": swClass,
2850 "pid": pid,
2851 "options": options }
2852 return output
2853 except pexpect.EOF:
2854 main.log.error( self.name + ": EOF exception found" )
2855 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002856 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002857 except Exception:
2858 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002859 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002860
Jon Halld80cc142015-07-06 13:36:05 -07002861 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002862 """
2863 Read hosts from Mininet.
2864
2865 Returns a dictionary whose keys are the host names and the value is
2866 a dictionary containing information about the host.
2867 """
2868 # Regex patterns to parse dump output
2869 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002870 # <Host h1: pid=12725>
2871 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2872 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2873 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002874 # NOTE: Does not correctly match hosts with multi-links
2875 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2876 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002877 try:
2878 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
2879 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
2880 # update mn port info
2881 self.update()
2882 # Get mininet dump
2883 dump = self.dump().split( "\n" )
2884 hosts = {}
2885 for line in dump:
2886 if "Host" in line :
2887 result = re.search( hostRE, line )
2888 name = result.group( 'name' )
2889 interfaces = []
2890 response = self.getInterfaces( name )
2891 # Populate interface info
2892 for line in response.split( "\n" ):
2893 if line.startswith( "name=" ):
2894 portVars = {}
2895 for var in line.split( "," ):
2896 key, value = var.split( "=" )
2897 portVars[ key ] = value
2898 isUp = portVars.pop( 'enabled', "True" )
2899 isUp = "True" in isUp
2900 if verbose:
2901 main.log.info( "Reading host port %s(%s)" %
2902 ( portVars[ 'name' ],
2903 portVars[ 'mac' ] ) )
2904 mac = portVars[ 'mac' ]
2905 if mac == 'None':
2906 mac = None
2907 ips = []
2908 ip = portVars[ 'ip' ]
2909 if ip == 'None':
2910 ip = None
2911 ips.append( ip )
2912 intfName = portVars[ 'name' ]
2913 if name == 'None':
2914 name = None
2915 interfaces.append( {
2916 "name": intfName,
2917 "ips": ips,
2918 "mac": str( mac ),
2919 "isUp": isUp } )
2920 hosts[ name ] = { "interfaces": interfaces }
2921 return hosts
2922 except pexpect.EOF:
2923 main.log.error( self.name + ": EOF exception found" )
2924 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002925 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002926 except Exception:
2927 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002929
YPZhang81a7d4e2016-04-18 13:10:17 -07002930 def getLinks( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002931 """
2932 Gathers information about current Mininet links. These links may not
2933 be up if one of the ports is down.
2934
2935 Returns a list of dictionaries with link endpoints.
2936
2937 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002938 { 'node1': str( node1 name )
2939 'node2': str( node2 name )
2940 'port1': str( port1 of_port )
2941 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002942 Note: The port number returned is the eth#, not necessarily the of_port
2943 number. In Mininet, for OVS switch, these should be the same. For
2944 hosts, this is just the eth#.
2945 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002946 try:
2947 self.update()
2948 response = self.links(timeout=timeout).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07002949
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002950 # Examples:
2951 # s1-eth3<->s2-eth1 (OK OK)
2952 # s13-eth3<->h27-eth0 (OK OK)
2953 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2954 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2955 links = []
2956 for line in response:
2957 match = re.search( linkRE, line )
2958 if match:
2959 node1 = match.group( 'node1' )
2960 node2 = match.group( 'node2' )
2961 port1 = match.group( 'port1' )
2962 port2 = match.group( 'port2' )
2963 links.append( { 'node1': node1,
2964 'node2': node2,
2965 'port1': port1,
2966 'port2': port2 } )
2967 return links
2968
2969 except pexpect.EOF:
2970 main.log.error( self.name + ": EOF exception found" )
2971 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002972 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002973 except Exception:
2974 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002975 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002976
2977 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002978 """
2979 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002980 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002981
Jon Hallafa8a472015-06-12 14:02:42 -07002982 Dependencies:
2983 1. numpy - "sudo pip install numpy"
2984 """
2985 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002986 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002987 try:
2988 mnDPIDs = []
2989 for swName, switch in switches.iteritems():
2990 mnDPIDs.append( switch[ 'dpid' ].lower() )
2991 mnDPIDs.sort()
2992 if switchesJson == "": # if rest call fails
2993 main.log.error(
2994 self.name +
2995 ".compareSwitches(): Empty JSON object given from ONOS" )
2996 return main.FALSE
2997 onos = switchesJson
2998 onosDPIDs = []
2999 for switch in onos:
3000 if switch[ 'available' ]:
3001 onosDPIDs.append(
3002 switch[ 'id' ].replace(
3003 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003004 '' ).replace(
3005 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003006 '' ).lower() )
3007 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003008
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003009 if mnDPIDs != onosDPIDs:
3010 switchResults = main.FALSE
3011 main.log.error( "Switches in MN but not in ONOS:" )
3012 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3013 main.log.error( str( list1 ) )
3014 main.log.error( "Switches in ONOS but not in MN:" )
3015 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3016 main.log.error( str( list2 ) )
3017 else: # list of dpid's match in onos and mn
3018 switchResults = main.TRUE
3019 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003020
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003021 # FIXME: this does not look for extra ports in ONOS, only checks that
3022 # ONOS has what is in MN
3023 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003024
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003025 # PORTS
3026 for name, mnSwitch in switches.iteritems():
3027 mnPorts = []
3028 onosPorts = []
3029 switchResult = main.TRUE
3030 for port in mnSwitch[ 'ports' ]:
3031 if port[ 'enabled' ]:
3032 mnPorts.append( int( port[ 'of_port' ] ) )
3033 for onosSwitch in portsJson:
3034 if onosSwitch[ 'device' ][ 'available' ]:
3035 if onosSwitch[ 'device' ][ 'id' ].replace(
3036 ':',
3037 '' ).replace(
3038 "of",
3039 '' ) == mnSwitch[ 'dpid' ]:
3040 for port in onosSwitch[ 'ports' ]:
3041 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003042 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003043 # onosPorts.append( 'local' )
3044 onosPorts.append( long( uint64( -2 ) ) )
3045 else:
3046 onosPorts.append( int( port[ 'port' ] ) )
3047 break
3048 mnPorts.sort( key=float )
3049 onosPorts.sort( key=float )
3050
3051 mnPortsLog = mnPorts
3052 onosPortsLog = onosPorts
3053 mnPorts = [ x for x in mnPorts ]
3054 onosPorts = [ x for x in onosPorts ]
3055
3056 # TODO: handle other reserved port numbers besides LOCAL
3057 # NOTE: Reserved ports
3058 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3059 # long( uint64( -2 ) )
3060 for mnPort in mnPortsLog:
3061 if mnPort in onosPorts:
3062 # don't set results to true here as this is just one of
3063 # many checks and it might override a failure
3064 mnPorts.remove( mnPort )
3065 onosPorts.remove( mnPort )
3066
3067 # NOTE: OVS reports this as down since there is no link
3068 # So ignoring these for now
3069 # TODO: Come up with a better way of handling these
3070 if 65534 in mnPorts:
3071 mnPorts.remove( 65534 )
3072 if long( uint64( -2 ) ) in onosPorts:
3073 onosPorts.remove( long( uint64( -2 ) ) )
3074 if len( mnPorts ): # the ports of this switch don't match
3075 switchResult = main.FALSE
3076 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3077 if len( onosPorts ): # the ports of this switch don't match
3078 switchResult = main.FALSE
3079 main.log.warn(
3080 "Ports in ONOS but not MN: " +
3081 str( onosPorts ) )
3082 if switchResult == main.FALSE:
3083 main.log.error(
3084 "The list of ports for switch %s(%s) does not match:" %
3085 ( name, mnSwitch[ 'dpid' ] ) )
3086 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3087 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3088 portsResults = portsResults and switchResult
3089 finalResults = finalResults and portsResults
3090 return finalResults
3091 except pexpect.EOF:
3092 main.log.error( self.name + ": EOF exception found" )
3093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003094 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003095 except Exception:
3096 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003097 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003098
Jon Hallafa8a472015-06-12 14:02:42 -07003099 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003100 """
3101 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003102 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003103
Jon Hallafa8a472015-06-12 14:02:42 -07003104 """
Jon Hall7eb38402015-01-08 17:19:54 -08003105 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003106 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003107 try:
3108 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003109
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003110 mnLinks = []
3111 for l in links:
3112 try:
3113 node1 = switches[ l[ 'node1' ] ]
3114 node2 = switches[ l[ 'node2' ] ]
3115 enabled = True
3116 for port in node1[ 'ports' ]:
3117 if port[ 'of_port' ] == l[ 'port1' ]:
3118 enabled = enabled and port[ 'enabled' ]
3119 for port in node2[ 'ports' ]:
3120 if port[ 'of_port' ] == l[ 'port2' ]:
3121 enabled = enabled and port[ 'enabled' ]
3122 if enabled:
3123 mnLinks.append( l )
3124 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003125 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003126 if 2 * len( mnLinks ) == len( onos ):
3127 linkResults = main.TRUE
3128 else:
3129 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003130 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003131 "Mininet has " + str( len( mnLinks ) ) +
3132 " bidirectional links and ONOS has " +
3133 str( len( onos ) ) + " unidirectional links" )
3134
3135 # iterate through MN links and check if an ONOS link exists in
3136 # both directions
3137 for link in mnLinks:
3138 # TODO: Find a more efficient search method
3139 node1 = None
3140 port1 = None
3141 node2 = None
3142 port2 = None
3143 firstDir = main.FALSE
3144 secondDir = main.FALSE
3145 for swName, switch in switches.iteritems():
3146 if swName == link[ 'node1' ]:
3147 node1 = switch[ 'dpid' ]
3148 for port in switch[ 'ports' ]:
3149 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3150 port1 = port[ 'of_port' ]
3151 if node1 is not None and node2 is not None:
3152 break
3153 if swName == link[ 'node2' ]:
3154 node2 = switch[ 'dpid' ]
3155 for port in switch[ 'ports' ]:
3156 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3157 port2 = port[ 'of_port' ]
3158 if node1 is not None and node2 is not None:
3159 break
3160
3161 for onosLink in onos:
3162 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3163 ":", '' ).replace( "of", '' )
3164 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3165 ":", '' ).replace( "of", '' )
3166 onosPort1 = onosLink[ 'src' ][ 'port' ]
3167 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3168
3169 # check onos link from node1 to node2
3170 if str( onosNode1 ) == str( node1 ) and str(
3171 onosNode2 ) == str( node2 ):
3172 if int( onosPort1 ) == int( port1 ) and int(
3173 onosPort2 ) == int( port2 ):
3174 firstDir = main.TRUE
3175 else:
3176 main.log.warn(
3177 'The port numbers do not match for ' +
3178 str( link ) +
3179 ' between ONOS and MN. When checking ONOS for ' +
3180 'link %s/%s -> %s/%s' %
3181 ( node1, port1, node2, port2 ) +
3182 ' ONOS has the values %s/%s -> %s/%s' %
3183 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3184
3185 # check onos link from node2 to node1
3186 elif ( str( onosNode1 ) == str( node2 ) and
3187 str( onosNode2 ) == str( node1 ) ):
3188 if ( int( onosPort1 ) == int( port2 )
3189 and int( onosPort2 ) == int( port1 ) ):
3190 secondDir = main.TRUE
3191 else:
3192 main.log.warn(
3193 'The port numbers do not match for ' +
3194 str( link ) +
3195 ' between ONOS and MN. When checking ONOS for ' +
3196 'link %s/%s -> %s/%s' %
3197 ( node1, port1, node2, port2 ) +
3198 ' ONOS has the values %s/%s -> %s/%s' %
3199 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3200 else: # this is not the link you're looking for
3201 pass
3202 if not firstDir:
3203 main.log.error(
3204 'ONOS does not have the link %s/%s -> %s/%s' %
3205 ( node1, port1, node2, port2 ) )
3206 if not secondDir:
3207 main.log.error(
3208 'ONOS does not have the link %s/%s -> %s/%s' %
3209 ( node2, port2, node1, port1 ) )
3210 linkResults = linkResults and firstDir and secondDir
3211 return linkResults
3212 except pexpect.EOF:
3213 main.log.error( self.name + ": EOF exception found" )
3214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003215 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003216 except Exception:
3217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003219
Jon Hallafa8a472015-06-12 14:02:42 -07003220 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003221 """
Jon Hallafa8a472015-06-12 14:02:42 -07003222 Compare mn and onos Hosts.
3223 Since Mininet hosts are quiet, ONOS will only know of them when they
3224 speak. For this reason, we will only check that the hosts in ONOS
3225 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003226
Jon Hallafa8a472015-06-12 14:02:42 -07003227 Arguments:
3228 hostsJson: parsed json object from the onos hosts api
3229 Returns:
3230 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003231 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003232 try:
3233 hostResults = main.TRUE
3234 for onosHost in hostsJson:
3235 onosMAC = onosHost[ 'mac' ].lower()
3236 match = False
3237 for mnHost, info in hosts.iteritems():
3238 for mnIntf in info[ 'interfaces' ]:
3239 if onosMAC == mnIntf[ 'mac' ].lower():
3240 match = True
3241 for ip in mnIntf[ 'ips' ]:
3242 if ip in onosHost[ 'ipAddresses' ]:
3243 pass # all is well
3244 else:
3245 # misssing ip
3246 main.log.error( "ONOS host " +
3247 onosHost[ 'id' ] +
3248 " has a different IP(" +
3249 str( onosHost[ 'ipAddresses' ] ) +
3250 ") than the Mininet host(" +
3251 str( ip ) +
3252 ")." )
3253 output = json.dumps(
3254 onosHost,
3255 sort_keys=True,
3256 indent=4,
3257 separators=( ',', ': ' ) )
3258 main.log.info( output )
3259 hostResults = main.FALSE
3260 if not match:
3261 hostResults = main.FALSE
3262 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3263 "corresponding Mininet host." )
3264 output = json.dumps( onosHost,
3265 sort_keys=True,
3266 indent=4,
3267 separators=( ',', ': ' ) )
3268 main.log.info( output )
3269 return hostResults
3270 except pexpect.EOF:
3271 main.log.error(self.name + ": EOF exception found")
3272 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003273 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003274 except Exception:
3275 main.log.exception(self.name + ": Uncaught exception!")
Devin Lim44075962017-08-11 10:56:37 -07003276 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003277
Jon Hallafa8a472015-06-12 14:02:42 -07003278 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003279 """
3280 Returns a list of all hosts
3281 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003282 try:
3283 self.handle.sendline( "" )
3284 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003285
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003286 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3287 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003288
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003289 handlePy = self.handle.before
3290 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3291 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003292
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003293 self.handle.sendline( "" )
3294 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003295
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003296 hostStr = handlePy.replace( "]", "" )
3297 hostStr = hostStr.replace( "'", "" )
3298 hostStr = hostStr.replace( "[", "" )
3299 hostStr = hostStr.replace( " ", "" )
3300 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003301
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003302 return hostList
3303 except pexpect.TIMEOUT:
3304 main.log.error(self.name + ": TIMEOUT exception found")
3305 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003306 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003307 except pexpect.EOF:
3308 main.log.error( self.name + ": EOF exception found" )
3309 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003310 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003311 except Exception:
3312 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003313 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003314
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003315 def getSwitch( self ):
3316 """
3317 Returns a list of all switches
3318 Again, don't ask question just use it...
3319 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003320 try:
3321 # get host list...
3322 hostList = self.getHosts()
3323 # Make host set
3324 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003325
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003326 # Getting all the nodes in mininet
3327 self.handle.sendline( "" )
3328 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003329
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003330 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3331 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003332
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003333 handlePy = self.handle.before
3334 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3335 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003336
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003337 self.handle.sendline( "" )
3338 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003339
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003340 nodesStr = handlePy.replace( "]", "" )
3341 nodesStr = nodesStr.replace( "'", "" )
3342 nodesStr = nodesStr.replace( "[", "" )
3343 nodesStr = nodesStr.replace( " ", "" )
3344 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003345
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003346 nodesSet = set( nodesList )
3347 # discarding default controller(s) node
3348 nodesSet.discard( 'c0' )
3349 nodesSet.discard( 'c1' )
3350 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003351
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003352 switchSet = nodesSet - hostSet
3353 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003354
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003355 return switchList
3356 except pexpect.TIMEOUT:
3357 main.log.error(self.name + ": TIMEOUT exception found")
3358 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003359 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003360 except pexpect.EOF:
3361 main.log.error( self.name + ": EOF exception found" )
3362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003363 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003364 except Exception:
3365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003366 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003367
You Wangdb8cd0a2016-05-26 15:19:45 -07003368 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3369 """
3370 Return a dictionary which describes the latest Mininet topology data as a
3371 graph.
3372 An example of the dictionary:
3373 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3374 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3375 Each vertex should at least have an 'edges' attribute which describes the
3376 adjacency information. The value of 'edges' attribute is also represented by
3377 a dictionary, which maps each edge (identified by the neighbor vertex) to a
3378 list of attributes.
3379 An example of the edges dictionary:
3380 'edges': { vertex2: { 'port': ..., 'weight': ... },
3381 vertex3: { 'port': ..., 'weight': ... } }
3382 If useId == True, dpid/mac will be used instead of names to identify
3383 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3384 topology.
3385 If includeHost == True, all hosts (and host-switch links) will be included
3386 in topology data.
3387 Note that link or switch that are brought down by 'link x x down' or 'switch
3388 x down' commands still show in the output of Mininet CLI commands such as
3389 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3390 recommended to use delLink() or delSwitch functions to simulate link/switch
3391 down, and addLink() or addSwitch to add them back.
3392 """
3393 graphDict = {}
3394 try:
3395 links = self.getLinks( timeout=timeout )
3396 portDict = {}
3397 if useId:
3398 switches = self.getSwitches()
3399 if includeHost:
3400 hosts = self.getHosts()
3401 for link in links:
3402 # FIXME: support 'includeHost' argument
3403 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3404 continue
3405 nodeName1 = link[ 'node1' ]
3406 nodeName2 = link[ 'node2' ]
3407 port1 = link[ 'port1' ]
3408 port2 = link[ 'port2' ]
3409 # Loop for two nodes
3410 for i in range( 2 ):
3411 # Get port index from OVS
3412 # The index extracted from port name may be inconsistent with ONOS
3413 portIndex = -1
3414 if not nodeName1 in portDict.keys():
3415 portList = self.getOVSPorts( nodeName1 )
3416 if len( portList ) == 0:
3417 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3418 return None
3419 portDict[ nodeName1 ] = portList
3420 for port in portDict[ nodeName1 ]:
3421 if port[ 'port' ] == port1:
3422 portIndex = port[ 'index' ]
3423 break
3424 if portIndex == -1:
3425 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3426 return None
3427 if useId:
3428 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3429 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3430 else:
3431 node1 = nodeName1
3432 node2 = nodeName2
3433 if not node1 in graphDict.keys():
3434 if useId:
3435 graphDict[ node1 ] = { 'edges':{},
3436 'dpid':switches[ nodeName1 ][ 'dpid' ],
3437 'name':nodeName1,
3438 'ports':switches[ nodeName1 ][ 'ports' ],
3439 'swClass':switches[ nodeName1 ][ 'swClass' ],
3440 'pid':switches[ nodeName1 ][ 'pid' ],
3441 'options':switches[ nodeName1 ][ 'options' ] }
3442 else:
3443 graphDict[ node1 ] = { 'edges':{} }
3444 else:
3445 # Assert node2 is not connected to any current links of node1
3446 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
3447 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port':portIndex }
3448 # Swap two nodes/ports
3449 nodeName1, nodeName2 = nodeName2, nodeName1
3450 port1, port2 = port2, port1
3451 return graphDict
3452 except KeyError:
3453 main.log.exception( self.name + ": KeyError exception found" )
3454 return None
3455 except AssertionError:
3456 main.log.exception( self.name + ": AssertionError exception found" )
3457 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003458 except pexpect.EOF:
3459 main.log.error( self.name + ": EOF exception found" )
3460 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003461 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003462 except Exception:
3463 main.log.exception( self.name + ": Uncaught exception" )
3464 return None
3465
Jon Hall7eb38402015-01-08 17:19:54 -08003466 def update( self ):
3467 """
3468 updates the port address and status information for
3469 each port in mn"""
3470 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003471 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003472 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003473 self.handle.sendline( "" )
3474 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003475
Jon Hall7eb38402015-01-08 17:19:54 -08003476 self.handle.sendline( "update" )
3477 self.handle.expect( "update" )
3478 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003479
Jon Hall7eb38402015-01-08 17:19:54 -08003480 self.handle.sendline( "" )
3481 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003482
Jon Hallb1290e82014-11-18 16:17:48 -05003483 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003484 except pexpect.TIMEOUT:
3485 main.log.error(self.name + ": TIMEOUT exception found")
3486 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003487 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003488 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003489 main.log.error( self.name + ": EOF exception found" )
3490 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003491 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003492 except Exception:
3493 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003494 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003495
Jon Halld80cc142015-07-06 13:36:05 -07003496 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003497 """
3498 Add vlan tag to a host.
3499 Dependencies:
3500 This class depends on the "vlan" package
3501 $ sudo apt-get install vlan
3502 Configuration:
3503 Load the 8021q module into the kernel
3504 $sudo modprobe 8021q
3505
3506 To make this setup permanent:
3507 $ sudo su -c 'echo "8021q" >> /etc/modules'
3508 """
3509 if self.handle:
3510 try:
Jon Halld80cc142015-07-06 13:36:05 -07003511 # get the ip address of the host
3512 main.log.info( "Get the ip address of the host" )
3513 ipaddr = self.getIPAddress( host )
3514 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003515
Jon Halld80cc142015-07-06 13:36:05 -07003516 # remove IP from interface intf
3517 # Ex: h1 ifconfig h1-eth0 inet 0
3518 main.log.info( "Remove IP from interface " )
3519 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3520 self.handle.sendline( cmd2 )
3521 self.handle.expect( "mininet>" )
3522 response = self.handle.before
3523 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003524
Jon Halld80cc142015-07-06 13:36:05 -07003525 # create VLAN interface
3526 # Ex: h1 vconfig add h1-eth0 100
3527 main.log.info( "Create Vlan" )
3528 cmd3 = host + " vconfig add " + intf + " " + vlan
3529 self.handle.sendline( cmd3 )
3530 self.handle.expect( "mininet>" )
3531 response = self.handle.before
3532 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003533
Jon Halld80cc142015-07-06 13:36:05 -07003534 # assign the host's IP to the VLAN interface
3535 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3536 main.log.info( "Assign the host IP to the vlan interface" )
3537 vintf = intf + "." + vlan
3538 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3539 self.handle.sendline( cmd4 )
3540 self.handle.expect( "mininet>" )
3541 response = self.handle.before
3542 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003543
3544 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003545 except pexpect.TIMEOUT:
3546 main.log.error(self.name + ": TIMEOUT exception found")
3547 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003548 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003549 except pexpect.EOF:
3550 main.log.error( self.name + ": EOF exception found" )
3551 main.log.error( self.name + ": " + self.handle.before )
3552 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003553 except Exception:
3554 main.log.exception( self.name + ": Uncaught exception!" )
3555 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003556
Jon Hall892818c2015-10-20 17:58:34 -07003557 def createHostComponent( self, name ):
3558 """
3559 Creates a new mininet cli component with the same parameters as self.
3560 This new component is intended to be used to login to the hosts created
3561 by mininet.
3562
3563 Arguments:
3564 name - The string of the name of this component. The new component
3565 will be assigned to main.<name> .
3566 In addition, main.<name>.name = str( name )
3567 """
3568 try:
3569 # look to see if this component already exists
3570 getattr( main, name )
3571 except AttributeError:
3572 # namespace is clear, creating component
3573 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
3574 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
3575 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003576 except pexpect.EOF:
3577 main.log.error( self.name + ": EOF exception found" )
3578 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003579 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003580 except Exception:
3581 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003582 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003583 else:
3584 # namespace is not clear!
3585 main.log.error( name + " component already exists!" )
3586 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003587 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003588
3589 def removeHostComponent( self, name ):
3590 """
3591 Remove host component
3592 Arguments:
3593 name - The string of the name of the component to delete.
3594 """
3595 try:
3596 # Get host component
3597 component = getattr( main, name )
3598 except AttributeError:
3599 main.log.error( "Component " + name + " does not exist." )
3600 return
3601 try:
3602 # Disconnect from component
3603 component.disconnect()
3604 # Delete component
3605 delattr( main, name )
3606 # Delete component from ComponentDictionary
3607 del( main.componentDictionary[name] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003608 except pexpect.EOF:
3609 main.log.error( self.name + ": EOF exception found" )
3610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003611 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003612 except Exception:
3613 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003614 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003615
3616 def startHostCli( self, host=None ):
3617 """
3618 Use the mininet m utility to connect to the host's cli
3619 """
3620 # These are fields that can be used by scapy packets. Initialized to None
3621 self.hostIp = None
3622 self.hostMac = None
3623 try:
3624 if not host:
3625 host = self.name
3626 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003627 self.handle.sendline( "cd" )
3628 self.handle.expect( self.hostPrompt )
3629 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003630 self.handle.expect( self.hostPrompt )
3631 return main.TRUE
3632 except pexpect.TIMEOUT:
3633 main.log.exception( self.name + ": Command timed out" )
3634 return main.FALSE
3635 except pexpect.EOF:
3636 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003637 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003638 except Exception:
3639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003640 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003641
YPZhang801d46d2016-08-08 13:26:28 -07003642 def changeInterfaceStatus( self, devicename, intf, status ):
3643 '''
3644
3645 Args:
3646 devicename: switch name
3647 intf: port name on switch
3648 status: up or down
3649
3650 Returns: boolean to show success change status
3651
3652 '''
3653 if status == "down" or status == "up":
3654 try:
3655 cmd = devicename + " ifconfig " + intf + " " + status
3656 self.handle.sendline( cmd )
3657 self.handle.expect("mininet>")
3658 return main.TRUE
3659 except pexpect.TIMEOUT:
3660 main.log.exception(self.name + ": Command timed out")
3661 return main.FALSE
3662 except pexpect.EOF:
3663 main.log.exception(self.name + ": connection closed.")
Devin Lim44075962017-08-11 10:56:37 -07003664 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003665 except TypeError:
3666 main.log.exception(self.name + ": TypeError")
Devin Lim44075962017-08-11 10:56:37 -07003667 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003668 except Exception:
3669 main.log.exception(self.name + ": Uncaught exception!")
Devin Lim44075962017-08-11 10:56:37 -07003670 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003671 else:
3672 main.log.warn("Interface status should be up or down!")
3673 return main.FALSE
3674
3675
Jon Hall892818c2015-10-20 17:58:34 -07003676
adminbae64d82013-08-01 10:50:15 -07003677if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003678 sys.modules[ __name__ ] = MininetCliDriver()