blob: a0a64e9dcd8f5170d7eb2f2c0ea7b4ba244605d4 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004Copyright 2012 Open Networking Foundation (ONF)
adminbae64d82013-08-01 10:50:15 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
Jon Hall7eb38402015-01-08 17:19:54 -080010TestON is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070014
Jon Hall7eb38402015-01-08 17:19:54 -080015TestON is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070019
Jon Hall7eb38402015-01-08 17:19:54 -080020You should have received a copy of the GNU General Public License
21along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
Jon Hallbe6dfc42015-01-12 17:37:25 -080023MininetCliDriver is the basic driver which will handle the Mininet functions
24
25Some functions rely on a modified version of Mininet. These functions
26should all be noted in the comments. To get this MN version run these commands
27from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080028 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080030 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git pull
32
Jon Hall272a4db2015-01-12 17:43:48 -080033
34 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080035changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070036import pexpect
adminbae64d82013-08-01 10:50:15 -070037import re
38import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070039import types
kelvin-onlaba4074292015-07-09 15:19:49 -070040import os
Devin Lima7cfdbd2017-09-29 15:02:22 -070041import time
Jon Hall1ccf82c2014-10-15 14:55:16 -040042from math import pow
adminbae64d82013-08-01 10:50:15 -070043from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070044from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
kelvin-onlab50907142015-04-01 13:37:45 -070047class MininetCliDriver( Emulator ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -070048
Jon Hall7eb38402015-01-08 17:19:54 -080049 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070053 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070056 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080057 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070058 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070059 # TODO: Refactor driver to use these everywhere
60 self.mnPrompt = "mininet>"
61 self.hostPrompt = "~#"
62 self.bashPrompt = "\$"
63 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070064 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070065
Jon Hall7eb38402015-01-08 17:19:54 -080066 def connect( self, **connectargs ):
67 """
68 Here the main is the TestON instance after creating
69 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080070 try:
71 for key in connectargs:
72 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070073 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080074 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070075 for key in self.options:
76 if key == "home":
77 self.home = self.options[ 'home' ]
78 break
79 if self.home is None or self.home == "":
80 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070081
82 try:
Jon Hall892818c2015-10-20 17:58:34 -070083 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070084 self.ip_address = os.getenv( str( self.ip_address ) )
85 else:
86 main.log.info( self.name +
87 ": Trying to connect to " +
88 self.ip_address )
89
90 except KeyError:
91 main.log.info( "Invalid host name," +
92 " connecting to local host instead" )
93 self.ip_address = 'localhost'
94 except Exception as inst:
95 main.log.error( "Uncaught exception: " + str( inst ) )
96
kelvin-onlaba1484582015-02-02 15:46:20 -080097 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070098 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080099 self ).connect(
100 user_name=self.user_name,
101 ip_address=self.ip_address,
102 port=None,
103 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800104
kelvin-onlaba1484582015-02-02 15:46:20 -0800105 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800106 main.log.info( "Connection successful to the host " +
107 self.user_name +
108 "@" +
109 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800110 return main.TRUE
111 else:
112 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800113 self.user_name +
114 "@" +
115 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800116 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800117 return main.FALSE
118 except pexpect.EOF:
119 main.log.error( self.name + ": EOF exception found" )
120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700121 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800122 except Exception:
123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700124 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800125
kelvin-onlab10e8d392015-06-03 13:53:45 -0700126 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800127 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700128 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000129 Starts Mininet accepts a topology(.py) file and/or an optional
kelvin-onlabf512e942015-06-08 19:42:59 -0700130 argument, to start the mininet, as a parameter.
131 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700132 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700133 Options:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000134 topoFile = file path for topology file (.py)
kelvin-onlabf512e942015-06-08 19:42:59 -0700135 args = extra option added when starting the topology from the file
136 mnCmd = Mininet command use to start topology
137 Returns:
138 main.TRUE if the mininet starts successfully, main.FALSE
139 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800140 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700141 try:
142 if self.handle:
143 # make sure old networks are cleaned up
144 main.log.info( self.name +
145 ": Clearing any residual state or processes" )
146 self.handle.sendline( "sudo mn -c" )
147 i = self.handle.expect( [ 'password\sfor\s',
148 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800149 pexpect.EOF,
150 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700151 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800152 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700153 # Sudo asking for password
154 main.log.info( self.name + ": Sending sudo password" )
155 self.handle.sendline( self.pwd )
Jon Hall173f2a02018-01-11 13:56:37 -0800156 i = self.handle.expect( [ '%s:' % self.user_name,
Devin Limdc78e202017-06-09 18:30:07 -0700157 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700158 pexpect.EOF,
159 pexpect.TIMEOUT ],
160 timeout )
161 if i == 1:
162 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700163 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700164 main.log.error( self.name + ": Connection terminated" )
165 elif i == 3: # timeout
166 main.log.error( self.name + ": Something while cleaning " +
167 "Mininet took too long... " )
168 # Craft the string to start mininet
169 cmdString = "sudo "
170 if not mnCmd:
171 if topoFile is None or topoFile == '': # If no file is given
172 main.log.info( self.name + ": building fresh Mininet" )
173 cmdString += "mn "
174 if args is None or args == '':
175 # If no args given, use args from .topo file
176 args = self.options[ 'arg1' ] +\
177 " " + self.options[ 'arg2' ] +\
178 " --mac --controller " +\
179 self.options[ 'controller' ] + " " +\
180 self.options[ 'arg3' ]
181 else: # else only use given args
182 pass
183 # TODO: allow use of topo args and method args?
184 else: # Use given topology file
185 main.log.info(
186 "Starting Mininet from topo file " +
187 topoFile )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700188 cmdString += "-E python " + topoFile + " "
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700189 if args is None:
190 args = ''
191 # TODO: allow use of args from .topo file?
192 cmdString += args
193 else:
194 main.log.info( "Starting Mininet topology using '" + mnCmd +
195 "' command" )
196 cmdString += mnCmd
197 # Send the command and check if network started
198 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700199 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700200 main.log.info( "Sending '" + cmdString + "' to " + self.name )
201 self.handle.sendline( cmdString )
Devin Lima7cfdbd2017-09-29 15:02:22 -0700202 startTime = time.time()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700203 while True:
204 i = self.handle.expect( [ 'mininet>',
Jon Hallbc743112018-04-18 11:09:01 -0700205 'Exception|Error',
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700206 '\*\*\*',
207 pexpect.EOF,
Jon Hallab611372018-02-21 15:26:05 -0800208 pexpect.TIMEOUT,
209 "No such file or directory"],
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700210 timeout )
211 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -0700212 main.log.info( self.name + ": Mininet built\nTime Took : " + str( time.time() - startTime ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700213 return main.TRUE
214 elif i == 1:
215 response = str( self.handle.before +
216 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700217 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700218 response += str( self.handle.before +
219 self.handle.after )
220 main.log.error(
221 self.name +
222 ": Launching Mininet failed: " + response )
223 return main.FALSE
224 elif i == 2:
225 self.handle.expect( [ "\n",
226 pexpect.EOF,
227 pexpect.TIMEOUT ],
228 timeout )
229 main.log.info( self.handle.before )
230 elif i == 3:
231 main.log.error( self.name + ": Connection timeout" )
232 return main.FALSE
233 elif i == 4: # timeout
234 main.log.error(
235 self.name +
236 ": Something took too long... " )
Jon Hallbc743112018-04-18 11:09:01 -0700237 main.log.debug( self.handle.before + self.handle.after )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700238 return main.FALSE
Jon Hallab611372018-02-21 15:26:05 -0800239 elif i == 5:
240 main.log.error( self.name + ": " + self.handle.before + self.handle.after )
241 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700242 # Why did we hit this part?
243 main.log.error( "startNet did not return correctly" )
244 return main.FASLE
245 else: # if no handle
246 main.log.error( self.name + ": Connection failed to the host " +
247 self.user_name + "@" + self.ip_address )
248 main.log.error( self.name + ": Failed to connect to the Mininet" )
249 return main.FALSE
250 except pexpect.TIMEOUT:
251 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
252 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700253 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700254 except pexpect.EOF:
255 main.log.error( self.name + ": EOF exception found" )
256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700257 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700258 except Exception:
259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700260 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800261
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800262 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700263 try:
264 if topoType == 'tree':
265 # In tree topology, if fanout arg is not given, by default it is 2
266 if fanout is None:
267 fanout = 2
268 k = 0
269 count = 0
270 while( k <= depth - 1 ):
271 count = count + pow( fanout, k )
272 k = k + 1
273 numSwitches = count
274 while( k <= depth - 2 ):
275 # depth-2 gives you only core links and not considering
276 # edge links as seen by ONOS. If all the links including
277 # edge links are required, do depth-1
278 count = count + pow( fanout, k )
279 k = k + 1
280 numLinks = count * fanout
281 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
282 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800283
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700284 elif topoType == 'linear':
285 # In linear topology, if fanout or numHostsPerSw is not given,
286 # by default it is 1
287 if fanout is None:
288 fanout = 1
289 numSwitches = depth
290 numHostsPerSw = fanout
291 totalNumHosts = numSwitches * numHostsPerSw
292 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hallab611372018-02-21 15:26:05 -0800293 main.log.debug( "num_switches for %s(%d,%d) = %d and links=%d" %
294 ( topoType, depth, fanout, numSwitches, numLinks ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700295 topoDict = { "num_switches": int( numSwitches ),
296 "num_corelinks": int( numLinks ) }
297 return topoDict
298 except Exception:
299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700300 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400301
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700303 """
304 Calculate the number of switches and links in a topo."""
305 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700306 try:
307 argList = self.options[ 'arg1' ].split( "," )
308 topoArgList = argList[ 0 ].split( " " )
309 argList = map( int, argList[ 1: ] )
310 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700311
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700312 topoDict = self.numSwitchesNlinks( *topoArgList )
313 return topoDict
314 except Exception:
315 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700316 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400317
GlennRCf07c44a2015-09-18 13:33:46 -0700318 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800319 """
320 Verifies the reachability of the hosts using pingall command.
321 Optional parameter timeout allows you to specify how long to
322 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700323 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700324 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700325 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700326 ping
327 acceptableFailed - Set the number of acceptable failed pings for the
328 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800329 Returns:
330 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700331 otherwise main.FALSE
332 """
333 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700334 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700335 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700336 if self.handle:
337 main.log.info(
338 self.name +
339 ": Checking reachabilty to the hosts using pingall" )
340 response = ""
341 failedPings = 0
342 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700343 cmd = "pingall"
344 if protocol == "IPv6":
345 cmd = "py net.pingAll6()"
346 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700347 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700348 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700349 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700350 pexpect.EOF,
351 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700352 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700353 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700354 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700355 response += self.handle.before
356 break
357 elif i == 1:
358 response += self.handle.before + self.handle.after
359 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700360 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700361 returnValue = main.FALSE
362 if shortCircuit:
363 main.log.error( self.name +
364 ": Aborting pingall - "
365 + str( failedPings ) +
366 " pings failed" )
367 break
Jon Hall390696c2015-05-05 17:13:41 -0700368 if ( time.time() - startTime ) > timeout:
369 returnValue = main.FALSE
370 main.log.error( self.name +
371 ": Aborting pingall - " +
372 "Function took too long " )
373 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700374 elif i == 2:
375 main.log.error( self.name +
376 ": EOF exception found" )
377 main.log.error( self.name + ": " +
378 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700379 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700380 elif i == 3:
381 response += self.handle.before
382 main.log.error( self.name +
383 ": TIMEOUT exception found" )
384 main.log.error( self.name +
385 ": " +
386 str( response ) )
387 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800388 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700389 self.handle.expect( "Interrupt" )
390 self.handle.expect( "mininet>" )
391 break
392 pattern = "Results\:"
393 main.log.info( "Pingall output: " + str( response ) )
394 if re.search( pattern, response ):
395 main.log.info( self.name + ": Pingall finished with "
396 + str( failedPings ) + " failed pings" )
397 return returnValue
398 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700399 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800400 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700401 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700402 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700403 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700404 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700405 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700406 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700407 except pexpect.TIMEOUT:
408 if response:
409 main.log.info( "Pingall output: " + str( response ) )
410 main.log.error( self.name + ": pexpect.TIMEOUT found" )
411 return main.FALSE
412 except pexpect.EOF:
413 main.log.error( self.name + ": EOF exception found" )
414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700416
Jon Hall7eb38402015-01-08 17:19:54 -0800417 def fpingHost( self, **pingParams ):
418 """
419 Uses the fping package for faster pinging...
420 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700421 try:
422 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
423 command = args[ "SRC" ] + \
424 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
425 self.handle.sendline( command )
426 self.handle.expect(
427 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
428 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
429 response = self.handle.before
430 if re.search( ":\s-", response ):
431 main.log.info( self.name + ": Ping fail" )
432 return main.FALSE
433 elif re.search( ":\s\d{1,2}\.\d\d", response ):
434 main.log.info( self.name + ": Ping good!" )
435 return main.TRUE
436 main.log.info( self.name + ": Install fping on mininet machine... " )
437 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700438 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700439 except Exception:
440 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700441 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700442
Jon Hall3b489db2015-10-05 14:38:37 -0700443 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400444 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700445 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700446
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400447 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700448 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700449
450 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400451 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700452
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400453 Returns main.FALSE if one or more of hosts specified
454 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700455 wait = int( wait )
456 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400457
458 try:
459 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700460
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400461 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700462 pingResponse = "IPv4 ping across specified hosts\n"
463 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400464 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700465 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400466 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700467 pingList = hostList[ :listIndex ] + \
468 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700469
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700470 pingResponse += str( str( host ) + " -> " )
GlennRCd10d3cc2015-09-24 12:47:16 -0700471
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400472 for temp in pingList:
473 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700474 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700475 self.handle.sendline( pingCmd )
Jon Halla604fd42018-05-04 14:27:27 -0700476 self.handle.expect( "mininet>", timeout=wait + 5 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400477 response = self.handle.before
478 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700479 pingResponse += str( " h" + str( temp[ 1: ] ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400480 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700481 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400482 # One of the host to host pair is unreachable
483 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700484 failedPings += 1
You Wang11f9ead2018-03-21 14:34:59 -0700485 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
GlennRCd10d3cc2015-09-24 12:47:16 -0700486 pingResponse += "\n"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700487 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700488 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700489 except pexpect.TIMEOUT:
490 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800491 response = self.handle.before
492 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700493 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800494 self.handle.expect( "Interrupt" )
495 response += self.handle.before + self.handle.after
496 self.handle.expect( "mininet>" )
497 response += self.handle.before + self.handle.after
498 main.log.debug( response )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700499 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400500 except pexpect.EOF:
501 main.log.error( self.name + ": EOF exception found" )
502 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700503 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700504 except Exception:
505 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700506 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400507
You Wangf19d9f42018-02-23 16:34:19 -0800508 def pingIpv6Hosts( self, hostList, wait=1, acceptableFailed=0 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700509 """
You Wangf19d9f42018-02-23 16:34:19 -0800510 IPv6 ping all hosts in hostList.
511
512 acceptableFailed: max number of acceptable failed pings
Hari Krishna9592fc82015-07-31 15:11:15 -0700513
Jon Hall3b489db2015-10-05 14:38:37 -0700514 Returns main.TRUE if all hosts specified can reach each other
Jon Hall3b489db2015-10-05 14:38:37 -0700515 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700516 """
517 try:
518 main.log.info( "Testing reachability between specified IPv6 hosts" )
519 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700520 wait = int( wait )
521 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700522 pingResponse = "IPv6 Pingall output:\n"
You Wangf19d9f42018-02-23 16:34:19 -0800523 failedPingsTotal = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700524 for host in hostList:
525 listIndex = hostList.index( host )
526 # List of hosts to ping other than itself
527 pingList = hostList[ :listIndex ] + \
528 hostList[ ( listIndex + 1 ): ]
529
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700530 pingResponse += str( str( host ) + " -> " )
GlennRC2cf7d952015-09-11 16:32:13 -0700531
Hari Krishna9592fc82015-07-31 15:11:15 -0700532 for temp in pingList:
533 # Current host pings all other hosts specified
You Wangf19d9f42018-02-23 16:34:19 -0800534 failedPings = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700535 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
You Wangf19d9f42018-02-23 16:34:19 -0800536 while failedPings <= acceptableFailed:
537 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
538 self.handle.sendline( pingCmd )
Jon Halla604fd42018-05-04 14:27:27 -0700539 self.handle.expect( "mininet>", timeout=wait + 5 )
You Wangf19d9f42018-02-23 16:34:19 -0800540 response = self.handle.before
541 if re.search( ',\s0\%\spacket\sloss', response ):
You Wangba231e72018-03-01 13:18:21 -0800542 pingResponse += " " + str( temp )
543 break
544 else:
545 failedPings += 1
546 time.sleep(1)
547 if failedPings > acceptableFailed:
548 # One of the host to host pair is unreachable
549 pingResponse += " X"
550 isReachable = main.FALSE
551 failedPingsTotal += 1
You Wang11f9ead2018-03-21 14:34:59 -0700552 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
You Wangba231e72018-03-01 13:18:21 -0800553 pingResponse += "\n"
554 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
555 return isReachable
556
557 except pexpect.TIMEOUT:
558 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800559 response = self.handle.before
560 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700561 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800562 self.handle.expect( "Interrupt" )
563 response += self.handle.before + self.handle.after
564 self.handle.expect( "mininet>" )
565 response += self.handle.before + self.handle.after
566 main.log.debug( response )
You Wangba231e72018-03-01 13:18:21 -0800567 return main.FALSE
568 except pexpect.EOF:
569 main.log.error( self.name + ": EOF exception found" )
570 main.log.error( self.name + ": " + self.handle.before )
571 main.cleanAndExit()
572 except Exception:
573 main.log.exception( self.name + ": Uncaught exception!" )
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700574
575 main.cleanAndExit()
576
You Wang48381752018-05-07 13:50:57 -0700577 def discoverHosts( self, hostList=[], wait=1, dstIp="6.6.6.6", dstIp6="1020::3fe" ):
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700578 '''
You Wang48381752018-05-07 13:50:57 -0700579 Hosts in hostList will do a single ping to a non-existent address for ONOS to
580 discover them. A host will use ping/ping6 to send echo requests depending on if
581 it has IPv4/IPv6 addresses configured.
582 Optional:
583 hostList: a list of names of the hosts that need to be discovered. If not
584 specified mininet will send ping from all the hosts
585 wait: timeout for IPv4/IPv6 echo requests
586 dstIp: destination address used by IPv4 hosts
587 dstIp6: destination address used by IPv6 hosts
588 Returns:
589 main.TRUE if all ping packets were successfully sent. Otherwise main.FALSE
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700590 '''
591 try:
You Wang48381752018-05-07 13:50:57 -0700592 if not hostList:
593 hosts = self.getHosts( getInterfaces=False )
594 hostList = hosts.keys()
595 discoveryResult = main.TRUE
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700596 for host in hostList:
You Wang48381752018-05-07 13:50:57 -0700597 cmd = ""
598 if self.getIPAddress( host ):
599 cmd = "{} ping -c 1 -i 1 -W {} {}".format( host, wait, dstIp )
600 main.log.debug( "Sending IPv4 probe ping from host {}".format( host ) )
601 elif self.getIPAddress( host, proto='IPV6' ):
602 cmd = "{} ping6 -c 1 -i 1 -W {} {}".format( host, wait, dstIp6 )
603 main.log.debug( "Sending IPv6 probe ping from host {}".format( host ) )
604 else:
605 main.log.warn( "No IP addresses configured on host {}, skipping discovery".format( host ) )
606 discoveryResult = main.FALSE
607 if cmd:
You Wang547893e2018-05-08 13:34:59 -0700608 self.handle.sendline( "{} ip neigh flush all".format( host ) )
Jon Halla604fd42018-05-04 14:27:27 -0700609 self.handle.expect( "mininet>" )
You Wang48381752018-05-07 13:50:57 -0700610 self.handle.sendline( cmd )
Jon Halla604fd42018-05-04 14:27:27 -0700611 self.handle.expect( "mininet>", timeout=wait + 5 )
You Wang48381752018-05-07 13:50:57 -0700612 return discoveryResult
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700613 except pexpect.TIMEOUT:
614 main.log.exception( self.name + ": TIMEOUT exception" )
615 response = self.handle.before
616 # NOTE: Send ctrl-c to make sure command is stopped
617 self.handle.send( "\x03" )
618 self.handle.expect( "Interrupt" )
619 response += self.handle.before + self.handle.after
620 self.handle.expect( "mininet>" )
621 response += self.handle.before + self.handle.after
622 main.log.debug( response )
623 return main.FALSE
624 except pexpect.EOF:
625 main.log.error( self.name + ": EOF exception found" )
626 main.log.error( self.name + ": " + self.handle.before )
627 main.cleanAndExit()
628 except Exception:
629 main.log.exception( self.name + ": Uncaught exception!" )
You Wangba231e72018-03-01 13:18:21 -0800630 main.cleanAndExit()
631
632 def pingallHostsUnidirectional( self, srcList, dstList, ipv6=False, wait=1, acceptableFailed=0 ):
633 """
634 Verify ping from each host in srcList to each host in dstList
635
636 acceptableFailed: max number of acceptable failed pings
637
638 Returns main.TRUE if all src hosts can reach all dst hosts
639 Returns main.FALSE if one or more of src hosts cannot reach one or more of dst hosts
640 """
641 try:
642 main.log.info( "Verifying ping from each src host to each dst host" )
643 isReachable = main.TRUE
644 wait = int( wait )
645 cmd = " ping" + ("6" if ipv6 else "") + " -c 1 -i 1 -W " + str( wait ) + " "
646 pingResponse = "Ping output:\n"
647 failedPingsTotal = 0
648 for host in srcList:
649 pingResponse += str( str( host ) + " -> " )
650 for temp in dstList:
651 failedPings = 0
You Wang5da39c82018-04-26 22:55:08 -0700652 dstIP = self.getIPAddress( temp, proto='IPV6' if ipv6 else 'IPV4' )
653 assert dstIP, "Not able to get IP address of host {}".format( temp )
654 pingCmd = str( host ) + cmd + str( dstIP )
You Wangba231e72018-03-01 13:18:21 -0800655 while failedPings <= acceptableFailed:
656 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
657 self.handle.sendline( pingCmd )
Jon Halla604fd42018-05-04 14:27:27 -0700658 self.handle.expect( "mininet>", timeout=wait + 5 )
You Wangba231e72018-03-01 13:18:21 -0800659 response = self.handle.before
660 if re.search( ',\s0\%\spacket\sloss', response ):
661 pingResponse += " " + str( temp )
You Wangf19d9f42018-02-23 16:34:19 -0800662 break
663 else:
664 failedPings += 1
665 time.sleep(1)
666 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700667 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800668 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700669 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800670 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700671 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800672 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700673 return isReachable
You Wang5da39c82018-04-26 22:55:08 -0700674 except AssertionError:
675 main.log.exception( "" )
676 return main.FALSE
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700677 except pexpect.TIMEOUT:
678 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800679 response = self.handle.before
680 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700681 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800682 self.handle.expect( "Interrupt" )
683 response += self.handle.before + self.handle.after
684 self.handle.expect( "mininet>" )
685 response += self.handle.before + self.handle.after
686 main.log.debug( response )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700687 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700688 except pexpect.EOF:
689 main.log.error( self.name + ": EOF exception found" )
690 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700691 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700692 except Exception:
693 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700694 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700695
Jon Hall7eb38402015-01-08 17:19:54 -0800696 def pingHost( self, **pingParams ):
697 """
Jon Hall3b489db2015-10-05 14:38:37 -0700698 Ping from one mininet host to another
699 Currently the only supported Params: SRC, TARGET, and WAIT
700 """
701 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700702 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700703 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800704 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700705 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700706 try:
Jon Hall61282e32015-03-19 11:34:11 -0700707 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800708 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700709 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
Jon Halla604fd42018-05-04 14:27:27 -0700710 timeout=wait + 5 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700711 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800712 main.log.error(
713 self.name +
714 ": timeout when waiting for response from mininet" )
715 main.log.error( "response: " + str( self.handle.before ) )
716 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700717 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800718 main.log.error(
719 self.name +
720 ": timeout when waiting for response from mininet" )
721 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700722 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700723 if re.search( ',\s0\%\spacket\sloss', response ):
724 main.log.info( self.name + ": no packets lost, host is reachable" )
725 return main.TRUE
726 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800727 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700728 self.name +
729 ": PACKET LOST, HOST IS NOT REACHABLE" )
730 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800731 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700738
739 def ping6pair( self, **pingParams ):
740 """
GlennRC2cf7d952015-09-11 16:32:13 -0700741 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700742 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000743 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700744 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
745 """
Jon Hall3b489db2015-10-05 14:38:37 -0700746 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700747 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700748 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530749 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700750 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700751 try:
752 main.log.info( "Sending: " + command )
753 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700754 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
Jon Halla604fd42018-05-04 14:27:27 -0700755 timeout=wait + 5 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700756 if i == 1:
757 main.log.error(
758 self.name +
759 ": timeout when waiting for response from mininet" )
760 main.log.error( "response: " + str( self.handle.before ) )
761 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
762 if i == 1:
763 main.log.error(
764 self.name +
765 ": timeout when waiting for response from mininet" )
766 main.log.error( "response: " + str( self.handle.before ) )
767 response = self.handle.before
768 main.log.info( self.name + ": Ping Response: " + response )
769 if re.search( ',\s0\%\spacket\sloss', response ):
770 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700771 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700772 else:
alisone4121a92016-11-22 16:31:36 -0800773 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700774 self.name +
775 ": PACKET LOST, HOST IS NOT REACHABLE" )
776 return main.FALSE
Hari Krishna012a1c12015-08-25 14:23:58 -0700777 except pexpect.EOF:
778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700780 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700781 except Exception:
782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700783 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800784
You Wangdb927a52016-02-26 11:03:28 -0800785 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
786 """
787 Description:
788 Ping a set of destination host from host CLI.
789 Logging into a Mininet host CLI is required before calling this funtion.
790 Params:
791 dstIPList is a list of destination ip addresses
792 Returns:
793 main.TRUE if the destination host is reachable
794 main.FALSE otherwise
795 """
796 isReachable = main.TRUE
797 wait = int( wait )
798 cmd = "ping"
799 if IPv6:
800 cmd = cmd + "6"
801 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
802 try:
803 for dstIP in dstIPList:
804 pingCmd = cmd + " " + dstIP
805 self.handle.sendline( pingCmd )
806 i = self.handle.expect( [ self.hostPrompt,
807 '\*\*\* Unknown command: ' + pingCmd,
808 pexpect.TIMEOUT ],
Jon Halla604fd42018-05-04 14:27:27 -0700809 timeout=wait + 5 )
You Wang5da39c82018-04-26 22:55:08 -0700810 # For some reason we need to send something
811 # Otherwise ping results won't be read by handle
812 self.handle.sendline( "" )
813 self.handle.expect( self.hostPrompt )
You Wangdb927a52016-02-26 11:03:28 -0800814 if i == 0:
815 response = self.handle.before
816 if not re.search( ',\s0\%\spacket\sloss', response ):
817 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
818 isReachable = main.FALSE
819 elif i == 1:
820 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800822 elif i == 2:
823 main.log.error( self.name + ": timeout when waiting for response" )
824 isReachable = main.FALSE
825 else:
826 main.log.error( self.name + ": unknown response: " + self.handle.before )
827 isReachable = main.FALSE
828 except pexpect.TIMEOUT:
829 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800830 response = self.handle.before
831 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700832 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800833 self.handle.expect( "Interrupt" )
834 response += self.handle.before + self.handle.after
835 self.handle.expect( "mininet>" )
836 response += self.handle.before + self.handle.after
837 main.log.debug( response )
You Wangdb927a52016-02-26 11:03:28 -0800838 isReachable = main.FALSE
839 except pexpect.EOF:
840 main.log.error( self.name + ": EOF exception found" )
841 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700842 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800843 except Exception:
844 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700845 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800846 return isReachable
847
Jon Hall7eb38402015-01-08 17:19:54 -0800848 def checkIP( self, host ):
849 """
850 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700851 try:
852 if self.handle:
853 try:
854 response = self.execute(
855 cmd=host +
856 " ifconfig",
857 prompt="mininet>",
858 timeout=10 )
859 except pexpect.EOF:
860 main.log.error( self.name + ": EOF exception found" )
861 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700862 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700863
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700864 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
865 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
866 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
867 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
868 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
869 "[0-9]|25[0-5]|[0-9]{1,2})"
870 # pattern = "inet addr:10.0.0.6"
871 if re.search( pattern, response ):
872 main.log.info( self.name + ": Host Ip configured properly" )
873 return main.TRUE
874 else:
875 main.log.error( self.name + ": Host IP not found" )
876 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700877 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700878 main.log.error( self.name + ": Connection failed to the host" )
879 except Exception:
880 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700881 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800882
Jon Hall7eb38402015-01-08 17:19:54 -0800883 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800884 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700885 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800886 response = self.execute(
887 cmd="h1 /usr/sbin/sshd -D&",
888 prompt="mininet>",
889 timeout=10 )
890 response = self.execute(
891 cmd="h4 /usr/sbin/sshd -D&",
892 prompt="mininet>",
893 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700894 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800895 vars( self )[ key ] = connectargs[ key ]
896 response = self.execute(
897 cmd="xterm h1 h4 ",
898 prompt="mininet>",
899 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800900 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700903 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700904 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800905 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700906 if self.flag == 0:
907 self.flag = 1
908 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800909 else:
adminbae64d82013-08-01 10:50:15 -0700910 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800911
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700912 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700913 """
914 Moves a host from one switch to another on the fly
915 Note: The intf between host and oldSw when detached
916 using detach(), will still show up in the 'net'
917 cmd, because switch.detach() doesn't affect switch.intfs[]
918 ( which is correct behavior since the interfaces
919 haven't moved ).
920 """
921 if self.handle:
922 try:
923 # Bring link between oldSw-host down
924 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
925 "'," + "'down')"
926 print "cmd1= ", cmd
927 response = self.execute( cmd=cmd,
928 prompt="mininet>",
929 timeout=10 )
930
931 # Determine hostintf and Oldswitchintf
932 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
933 ")[0]"
934 print "cmd2= ", cmd
935 self.handle.sendline( cmd )
936 self.handle.expect( "mininet>" )
937
938 # Determine ip and mac address of the host-oldSw interface
939 cmd = "px ipaddr = hintf.IP()"
940 print "cmd3= ", cmd
941 self.handle.sendline( cmd )
942 self.handle.expect( "mininet>" )
943
944 cmd = "px macaddr = hintf.MAC()"
945 print "cmd3= ", cmd
946 self.handle.sendline( cmd )
947 self.handle.expect( "mininet>" )
948
949 # Detach interface between oldSw-host
950 cmd = "px " + oldSw + ".detach( sintf )"
951 print "cmd4= ", cmd
952 self.handle.sendline( cmd )
953 self.handle.expect( "mininet>" )
954
955 # Add link between host-newSw
956 cmd = "py net.addLink(" + host + "," + newSw + ")"
957 print "cmd5= ", cmd
958 self.handle.sendline( cmd )
959 self.handle.expect( "mininet>" )
960
961 # Determine hostintf and Newswitchintf
962 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
963 ")[0]"
964 print "cmd6= ", cmd
965 self.handle.sendline( cmd )
966 self.handle.expect( "mininet>" )
967
968 # Attach interface between newSw-host
969 cmd = "px " + newSw + ".attach( sintf )"
970 print "cmd3= ", cmd
971 self.handle.sendline( cmd )
972 self.handle.expect( "mininet>" )
973
974 # Set ipaddress of the host-newSw interface
975 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
976 print "cmd7 = ", cmd
977 self.handle.sendline( cmd )
978 self.handle.expect( "mininet>" )
979
980 # Set macaddress of the host-newSw interface
981 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
982 print "cmd8 = ", cmd
983 self.handle.sendline( cmd )
984 self.handle.expect( "mininet>" )
985
986 cmd = "net"
987 print "cmd9 = ", cmd
988 self.handle.sendline( cmd )
989 self.handle.expect( "mininet>" )
990 print "output = ", self.handle.before
991
992 # Determine ipaddress of the host-newSw interface
993 cmd = host + " ifconfig"
994 print "cmd10= ", cmd
995 self.handle.sendline( cmd )
996 self.handle.expect( "mininet>" )
997 print "ifconfig o/p = ", self.handle.before
998
999 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001000
1001 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001002 main.log.error( self.name + ": TIMEOUT exception found" )
1003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001004 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -07001005 except pexpect.EOF:
1006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
1008 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001009 except Exception:
1010 main.log.exception( self.name + ": Uncaught exception!" )
1011 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -07001012
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001013 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001014 """
1015 Moves a host from one switch to another on the fly
1016 Note: The intf between host and oldSw when detached
1017 using detach(), will still show up in the 'net'
1018 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -07001019 ( which is correct behavior since the interfaces
1020 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -08001021 """
1022 if self.handle:
1023 try:
Jon Hall439c8912016-04-15 02:22:03 -07001024 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -08001025 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -07001026 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -08001027 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -08001028 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -08001029 response = self.execute( cmd=cmd,
1030 prompt="mininet>",
1031 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -07001032
kelvin-onlaba1484582015-02-02 15:46:20 -08001033 # Determine hostintf and Oldswitchintf
1034 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -08001035 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -08001036 print "cmd2= ", cmd
1037 self.handle.sendline( cmd )
1038 self.handle.expect( "mininet>" )
1039
shahshreya73537862015-02-11 15:15:24 -08001040 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001041 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -08001042 print "cmd3= ", cmd
1043 self.handle.sendline( cmd )
1044 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -08001045
1046 cmd = "px macaddr = hintf.MAC()"
1047 print "cmd3= ", cmd
1048 self.handle.sendline( cmd )
1049 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001050
kelvin-onlaba1484582015-02-02 15:46:20 -08001051 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001052 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -08001053 print "cmd4= ", cmd
1054 self.handle.sendline( cmd )
1055 self.handle.expect( "mininet>" )
1056
1057 # Add link between host-newSw
1058 cmd = "py net.addLink(" + host + "," + newSw + ")"
1059 print "cmd5= ", cmd
1060 self.handle.sendline( cmd )
1061 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001062
kelvin-onlaba1484582015-02-02 15:46:20 -08001063 # Determine hostintf and Newswitchintf
1064 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -08001065 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -08001066 print "cmd6= ", cmd
1067 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -07001068 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001069
1070 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001071 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001072 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001073 self.handle.sendline( cmd )
1074 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -08001075
1076 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001077 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001078 print "cmd7 = ", cmd
1079 self.handle.sendline( cmd )
1080 self.handle.expect( "mininet>" )
1081
1082 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001083 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -08001084 print "cmd8 = ", cmd
1085 self.handle.sendline( cmd )
1086 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001087
Jon Hall439c8912016-04-15 02:22:03 -07001088 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001089 print "cmd9 =", cmd
1090 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -07001091 print response
1092 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -07001093 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001094 print ipAddressSearch.group( 1 )
1095 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -07001096 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
1097 print "cmd10 = ", cmd
1098 self.handle.sendline( cmd )
1099 self.handle.expect( "mininet>" )
1100
kelvin-onlaba1484582015-02-02 15:46:20 -08001101 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -07001102 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001103 self.handle.sendline( cmd )
1104 self.handle.expect( "mininet>" )
1105 print "output = ", self.handle.before
1106
1107 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -08001108 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -07001109 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001110 self.handle.sendline( cmd )
1111 self.handle.expect( "mininet>" )
1112 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -07001113
kelvin-onlaba1484582015-02-02 15:46:20 -08001114 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001115 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001116 main.log.error( self.name + ": TIMEOUT exception found" )
1117 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001118 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08001119 except pexpect.EOF:
1120 main.log.error( self.name + ": EOF exception found" )
1121 main.log.error( self.name + ": " + self.handle.before )
1122 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001123 except Exception:
1124 main.log.exception( self.name + ": Uncaught exception!" )
1125 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -08001126
Jon Hall7eb38402015-01-08 17:19:54 -08001127 def changeIP( self, host, intf, newIP, newNetmask ):
1128 """
1129 Changes the ip address of a host on the fly
1130 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001131 if self.handle:
1132 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 cmd = host + " ifconfig " + intf + " " + \
1134 newIP + " " + 'netmask' + " " + newNetmask
1135 self.handle.sendline( cmd )
1136 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001137 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001138 main.log.info( "response = " + response )
1139 main.log.info(
1140 "Ip of host " +
1141 host +
1142 " changed to new IP " +
1143 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001144 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001145 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001146 main.log.error( self.name + ": TIMEOUT exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001148 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001149 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001150 main.log.error( self.name + ": EOF exception found" )
1151 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001152 return main.FALSE
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()
shahshreyae6c7cf42014-11-26 16:39:01 -08001156
Jon Hall7eb38402015-01-08 17:19:54 -08001157 def changeDefaultGateway( self, host, newGW ):
1158 """
1159 Changes the default gateway of a host
1160 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001161 if self.handle:
1162 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001163 cmd = host + " route add default gw " + newGW
1164 self.handle.sendline( cmd )
1165 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001166 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001167 main.log.info( "response = " + response )
1168 main.log.info(
1169 "Default gateway of host " +
1170 host +
1171 " changed to " +
1172 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001173 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001174 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001175 main.log.error( self.name + ": TIMEOUT exception found" )
1176 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001177 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001178 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001179 main.log.error( self.name + ": EOF exception found" )
1180 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001181 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001182 except Exception:
1183 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001184 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001185
You Wange24d6272018-03-27 21:18:50 -07001186 def addRoute( self, host, dstIP, interface, ipv6=False ):
1187 """
1188 Add a route to host
1189 Ex: h1 route add -host 224.2.0.1 h1-eth0
1190 """
1191 if self.handle:
1192 try:
1193 cmd = str( host )
1194 if ipv6:
1195 cmd += " route -A inet6 add "
1196 else:
1197 cmd += " route add -host "
1198 cmd += str( dstIP ) + " " + str( interface )
1199 self.handle.sendline( cmd )
1200 self.handle.expect( "mininet>" )
1201 response = self.handle.before
1202 main.log.debug( "response = " + response )
1203 return main.TRUE
1204 except pexpect.TIMEOUT:
1205 main.log.error( self.name + ": TIMEOUT exception found" )
1206 main.log.error( self.name + ": " + self.handle.before )
1207 main.cleanAndExit()
1208 except pexpect.EOF:
1209 main.log.error( self.name + ": EOF exception found" )
1210 main.log.error( self.name + ": " + self.handle.before )
1211 return main.FALSE
1212 except Exception:
1213 main.log.exception( self.name + ": Uncaught exception!" )
1214 main.cleanAndExit()
1215
Jon Hall7eb38402015-01-08 17:19:54 -08001216 def addStaticMACAddress( self, host, GW, macaddr ):
1217 """
Jon Hallefbd9792015-03-05 16:11:36 -08001218 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001219 if self.handle:
1220 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001221 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1222 cmd = host + " arp -s " + GW + " " + macaddr
1223 self.handle.sendline( cmd )
1224 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001225 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001226 main.log.info( "response = " + response )
1227 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001228 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001229 GW +
1230 " changed to " +
1231 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001232 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001233 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001234 main.log.error( self.name + ": TIMEOUT exception found" )
1235 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001236 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001237 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001238 main.log.error( self.name + ": EOF exception found" )
1239 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001240 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001241 except Exception:
1242 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001243 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001244
Jon Hall7eb38402015-01-08 17:19:54 -08001245 def verifyStaticGWandMAC( self, host ):
1246 """
1247 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001248 if self.handle:
1249 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001250 # h1 arp -an
1251 cmd = host + " arp -an "
1252 self.handle.sendline( cmd )
1253 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001254 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001255 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001256 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001257 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001258 main.log.error( self.name + ": TIMEOUT exception found" )
1259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001260 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001261 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001262 main.log.error( self.name + ": EOF exception found" )
1263 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001264 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001265 except Exception:
1266 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001267 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001268
Jon Hall7eb38402015-01-08 17:19:54 -08001269 def getMacAddress( self, host ):
1270 """
1271 Verifies the host's ip configured or not."""
1272 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001273 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001274 response = self.execute(
1275 cmd=host +
1276 " ifconfig",
1277 prompt="mininet>",
1278 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001279 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001280 main.log.error( self.name + ": EOF exception found" )
1281 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001282 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001283 except Exception:
1284 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001285 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001286
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001287 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 macAddressSearch = re.search( pattern, response, re.I )
1289 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001290 main.log.info(
1291 self.name +
1292 ": Mac-Address of Host " +
1293 host +
1294 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 macAddress )
1296 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001297 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001298 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001299
Jon Hall7eb38402015-01-08 17:19:54 -08001300 def getInterfaceMACAddress( self, host, interface ):
1301 """
1302 Return the IP address of the interface on the given host"""
1303 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001304 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001305 response = self.execute( cmd=host + " ifconfig " + interface,
1306 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001307 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001308 main.log.error( self.name + ": EOF exception found" )
1309 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001310 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001311 except Exception:
1312 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001313 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001314
1315 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001316 macAddressSearch = re.search( pattern, response, re.I )
1317 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001318 main.log.info( "No mac address found in %s" % response )
1319 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001320 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001321 main.log.info(
1322 "Mac-Address of " +
1323 host +
1324 ":" +
1325 interface +
1326 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001327 macAddress )
1328 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001329 else:
1330 main.log.error( "Connection failed to the host" )
1331
You Wang5da39c82018-04-26 22:55:08 -07001332 def getIPAddress( self, host, proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001333 """
1334 Verifies the host's ip configured or not."""
1335 if self.handle:
1336 try:
1337 response = self.execute(
1338 cmd=host +
1339 " ifconfig",
1340 prompt="mininet>",
1341 timeout=10 )
1342 except pexpect.EOF:
1343 main.log.error( self.name + ": EOF exception found" )
1344 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001345 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001346 except Exception:
1347 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001348 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001349
sathishmad953462015-12-03 17:42:07 +05301350 pattern = ''
1351 if proto == 'IPV4':
You Wang5da39c82018-04-26 22:55:08 -07001352 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)\s\sBcast"
sathishmad953462015-12-03 17:42:07 +05301353 else:
Jon Hall439c8912016-04-15 02:22:03 -07001354 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 ipAddressSearch = re.search( pattern, response )
Jon Hall3c910162018-03-07 14:42:16 -08001356 if not ipAddressSearch:
1357 return None
Jon Hall7eb38402015-01-08 17:19:54 -08001358 main.log.info(
1359 self.name +
1360 ": IP-Address of Host " +
1361 host +
1362 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 ipAddressSearch.group( 1 ) )
1364 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001365 else:
1366 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001367
Jon Hall7eb38402015-01-08 17:19:54 -08001368 def getSwitchDPID( self, switch ):
1369 """
1370 return the datapath ID of the switch"""
1371 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001372 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001373 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001374 response = self.execute(
1375 cmd=cmd,
1376 prompt="mininet>",
1377 timeout=10 )
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()
Jon Hall28bf54b2014-12-17 16:25:44 -08001385 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001386 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001387 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001388 main.log.info(
1389 "Couldn't find DPID for switch %s, found: %s" %
1390 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001391 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001392 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001393 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001394 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001395
Jon Hall7eb38402015-01-08 17:19:54 -08001396 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001397 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001398 self.handle.sendline( "" )
1399 self.expect( "mininet>" )
1400 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001401 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001402 response = self.execute(
1403 cmd=cmd,
1404 prompt="mininet>",
1405 timeout=10 )
1406 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001407 response = self.handle.before
1408 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001409 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001410 main.log.error( self.name + ": TIMEOUT exception found" )
1411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001412 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001413 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001414 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()
admin2580a0e2014-07-29 11:24:34 -07001420
Jon Hall7eb38402015-01-08 17:19:54 -08001421 def getInterfaces( self, node ):
1422 """
1423 return information dict about interfaces connected to the node"""
1424 if self.handle:
1425 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001426 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001427 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001428 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 response = self.execute(
1430 cmd=cmd,
1431 prompt="mininet>",
1432 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001433 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001434 main.log.error( self.name + ": EOF exception found" )
1435 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001436 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001437 except Exception:
1438 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001439 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001440 return response
1441 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001442 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001443
Jon Hall7eb38402015-01-08 17:19:54 -08001444 def dump( self ):
1445 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001446 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001447 response = self.execute(
1448 cmd='dump',
1449 prompt='mininet>',
1450 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001451 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001452 main.log.error( self.name + ": EOF exception found" )
1453 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001454 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001455 except Exception:
1456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001457 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001458 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001459
Jon Hall7eb38402015-01-08 17:19:54 -08001460 def intfs( self ):
1461 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001462 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001463 response = self.execute(
1464 cmd='intfs',
1465 prompt='mininet>',
1466 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001467 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001468 main.log.error( self.name + ": EOF exception found" )
1469 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001470 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001471 except Exception:
1472 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001473 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001474 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001475
Jon Hall7eb38402015-01-08 17:19:54 -08001476 def net( self ):
1477 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001478 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001479 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001480 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001481 main.log.error( self.name + ": EOF exception found" )
1482 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001483 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001484 except Exception:
1485 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001486 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001487 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001488
Devin Lima7cfdbd2017-09-29 15:02:22 -07001489 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001490 main.log.info( self.name + ": List network links" )
1491 try:
1492 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001493 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001494 except pexpect.EOF:
1495 main.log.error( self.name + ": EOF exception found" )
1496 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001497 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001498 except Exception:
1499 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001500 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001501 return response
1502
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001503 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001504 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001505 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001506
kelvin-onlab7cce9382015-07-17 10:21:03 -07001507 @parm:
1508 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1509 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001510 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001511 try:
1512 for host1 in hosts:
1513 for host2 in hosts:
1514 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001515 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1516 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001517 except Exception:
1518 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001519 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001520
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001521 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001522 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001523 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1524 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001525
kelvin-onlab7cce9382015-07-17 10:21:03 -07001526 @parm:
1527 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1528 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001529 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001530 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1531 try:
1532 # Setup the mininet command
1533 cmd1 = 'iperf ' + host1 + " " + host2
1534 self.handle.sendline( cmd1 )
1535 outcome = self.handle.expect( "mininet>", timeout )
1536 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001537
kelvin-onlab7cce9382015-07-17 10:21:03 -07001538 # checks if there are results in the mininet response
1539 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001540 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001541 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001542 response = response.split( "\r\n" )
1543 response = response[ len( response )-2 ]
1544 response = response.split( ": " )
1545 response = response[ len( response )-1 ]
1546 response = response.replace( "[", "" )
1547 response = response.replace( "]", "" )
1548 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001549
kelvin-onlab7cce9382015-07-17 10:21:03 -07001550 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001551 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001552
kelvin-onlab7cce9382015-07-17 10:21:03 -07001553 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001554 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001555 if len( bandwidth ) == 2:
1556 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001557 return main.TRUE
1558 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001559 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001560 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001561 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001562 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001563 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001564 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001565 main.log.error( self.name + ": TIMEOUT exception found" )
1566 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001567 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001568 # NOTE: Send ctrl-c to make sure iperf is done
Jon Hall2c5ac942018-03-23 11:26:54 -07001569 self.handle.send( "\x03" )
Jon Hall3b489db2015-10-05 14:38:37 -07001570 self.handle.expect( "Interrupt" )
1571 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001572 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001573 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001576 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001577 except Exception:
1578 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001579 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001580
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001581 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001582 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1583 try:
1584 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001585 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001586 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001587 outcome1 = self.handle.expect( "mininet>" )
1588 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001589 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001590 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001591 response1 = self.handle.before
1592 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001593 print response1, response2
1594 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001595 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001596 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001597 return main.TRUE
1598 else:
1599 main.log.error( self.name + ": iperf test failed" )
1600 return main.FALSE
1601 except pexpect.TIMEOUT:
1602 main.log.error( self.name + ": TIMEOUT exception found" )
1603 main.log.error( self.name + " response: " + repr( self.handle.before ) )
Jon Hall2c5ac942018-03-23 11:26:54 -07001604 self.handle.send( "\x03" )
Jon Hall439c8912016-04-15 02:22:03 -07001605 self.handle.expect( "Interrupt" )
1606 self.handle.expect( "mininet>" )
1607 return main.FALSE
1608 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()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001612 except Exception:
1613 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001614 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001615
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001616 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001617 '''
GlennRC61321f22015-07-16 13:36:54 -07001618 Runs the iperfudp function with a given set of hosts and specified
1619 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001620
GlennRC61321f22015-07-16 13:36:54 -07001621 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001622 bandwidth: the targeted bandwidth, in megabits ('M')
1623 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001624 try:
1625 for host1 in hosts:
1626 for host2 in hosts:
1627 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001628 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1629 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001630 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001631 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001632 return main.FALSE
1633 except Exception:
1634 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001635 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001636
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001637 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001638 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001639 Creates an iperf UDP test with a specific bandwidth.
1640 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001641
kelvin-onlab7cce9382015-07-17 10:21:03 -07001642 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001643 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1644 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001645 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001646 try:
1647 # setup the mininet command
1648 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001649 self.handle.sendline( cmd )
1650 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001651 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001652
kelvin-onlab7cce9382015-07-17 10:21:03 -07001653 # check if there are in results in the mininet response
1654 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001655 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001656 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001657 response = response.split( "\r\n" )
1658 response = response[ len( response )-2 ]
1659 response = response.split( ": " )
1660 response = response[ len( response )-1 ]
1661 response = response.replace( "[", "" )
1662 response = response.replace( "]", "" )
1663 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001664
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001665 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001666
kelvin-onlab7cce9382015-07-17 10:21:03 -07001667 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001668 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001669 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001670 # if one entry is blank then something is wrong
1671 for item in mnBandwidth:
1672 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001673 main.log.error( self.name + ": Could not parse iperf output" )
1674 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001675 return main.FALSE
1676 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001677 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001678 return main.TRUE
1679 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001680 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001681 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001682
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001683 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001684 main.log.error( self.name + ": TIMEOUT exception found" )
1685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001686 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001687 except pexpect.EOF:
1688 main.log.error( self.name + ": EOF exception found" )
1689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001690 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001691 except Exception:
1692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001693 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001694
Jon Hall7eb38402015-01-08 17:19:54 -08001695 def nodes( self ):
1696 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001697 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001698 response = self.execute(
1699 cmd='nodes',
1700 prompt='mininet>',
1701 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001702 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001703 main.log.error( self.name + ": EOF exception found" )
1704 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001705 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001706 except Exception:
1707 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001708 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001709 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001710
Jon Hall7eb38402015-01-08 17:19:54 -08001711 def pingpair( self ):
1712 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001713 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001714 response = self.execute(
1715 cmd='pingpair',
1716 prompt='mininet>',
1717 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001718 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001719 main.log.error( self.name + ": EOF exception found" )
1720 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001721 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001722 except Exception:
1723 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001724 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001725
Jon Hall7eb38402015-01-08 17:19:54 -08001726 if re.search( ',\s0\%\spacket\sloss', response ):
1727 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001728 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001729 else:
alisone4121a92016-11-22 16:31:36 -08001730 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001731 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001732
Jon Hall7eb38402015-01-08 17:19:54 -08001733 def link( self, **linkargs ):
1734 """
GlennRCed771242016-01-13 17:02:47 -08001735 Bring link( s ) between two nodes up or down
1736 """
Jon Hall6094a362014-04-11 14:46:56 -07001737 try:
GlennRCed771242016-01-13 17:02:47 -08001738 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1739 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1740 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1741 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1742
1743 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1744 cmd = "link {} {} {}".format( end1, end2, option )
1745 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001746 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001747 response = self.handle.before
1748 main.log.info( response )
Jon Hallab611372018-02-21 15:26:05 -08001749 if "not in network" in response:
1750 main.log.error( self.name + ": Could not find one of the endpoints of the link" )
1751 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08001752 return main.TRUE
1753 except pexpect.TIMEOUT:
1754 main.log.exception( self.name + ": Command timed out" )
1755 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001756 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001757 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001758 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001759 except Exception:
1760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001761 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001762
pingping-lin8244a3b2015-09-16 13:36:56 -07001763 def switch( self, **switchargs ):
1764 """
1765 start/stop a switch
1766 """
1767 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1768 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1769 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1770 command = "switch " + str( sw ) + " " + str( option )
1771 main.log.info( command )
1772 try:
1773 self.handle.sendline( command )
1774 self.handle.expect( "mininet>" )
1775 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001776 main.log.error( self.name + ": TIMEOUT exception found" )
1777 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001778 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001779 except pexpect.EOF:
1780 main.log.error( self.name + ": EOF exception found" )
1781 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001782 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001783 return main.TRUE
1784
pingping-lin5bb663b2015-09-24 11:47:50 -07001785 def node( self, nodeName, commandStr ):
1786 """
1787 Carry out a command line on a given node
1788 @parm:
1789 nodeName: the node name in Mininet testbed
1790 commandStr: the command line will be carried out on the node
1791 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1792 """
1793 command = str( nodeName ) + " " + str( commandStr )
1794 main.log.info( command )
1795
1796 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001797 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001798 if re.search( "Unknown command", response ):
1799 main.log.warn( response )
1800 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001801 if re.search( "Permission denied", response ):
1802 main.log.warn( response )
1803 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001804 except pexpect.EOF:
1805 main.log.error( self.name + ": EOF exception found" )
1806 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001807 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001808 main.log.info( " response is :" )
1809 main.log.info( response )
1810 return response
1811
Jon Hall7eb38402015-01-08 17:19:54 -08001812 def yank( self, **yankargs ):
1813 """
1814 yank a mininet switch interface to a host"""
1815 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001816 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001817 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1818 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001819 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001820 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001821 response = self.execute(
1822 cmd=command,
1823 prompt="mininet>",
1824 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001825 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001826 main.log.error( self.name + ": EOF exception found" )
1827 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001828 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001829 except Exception:
1830 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001831 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001832 return main.TRUE
1833
Jon Hall7eb38402015-01-08 17:19:54 -08001834 def plug( self, **plugargs ):
1835 """
1836 plug the yanked mininet switch interface to a switch"""
1837 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001838 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001839 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1840 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001841 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001842 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001843 response = self.execute(
1844 cmd=command,
1845 prompt="mininet>",
1846 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001847 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001848 main.log.error( self.name + ": EOF exception found" )
1849 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001850 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001851 except Exception:
1852 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001853 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001854 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001855
Jon Hall7eb38402015-01-08 17:19:54 -08001856 def dpctl( self, **dpctlargs ):
1857 """
1858 Run dpctl command on all switches."""
1859 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001860 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001861 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1862 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1863 command = "dpctl " + cmd + " " + str( cmdargs )
1864 try:
1865 response = self.execute(
1866 cmd=command,
1867 prompt="mininet>",
1868 timeout=10 )
1869 except pexpect.EOF:
1870 main.log.error( self.name + ": EOF exception found" )
1871 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001872 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001873 except Exception:
1874 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001875 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001876 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001877
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001879 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001880 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001881 try:
1882 fileInput = path + '/lib/Mininet/INSTALL'
1883 version = super( Mininet, self ).getVersion()
1884 pattern = 'Mininet\s\w\.\w\.\w\w*'
1885 for line in open( fileInput, 'r' ).readlines():
1886 result = re.match( pattern, line )
1887 if result:
1888 version = result.group( 0 )
1889 return version
1890 except Exception:
1891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001892 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001893
kelvin-onlabd3b64892015-01-20 13:26:24 -08001894 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001895 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001896 Parameters:
1897 sw: The name of an OVS switch. Example "s1"
1898 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001899 The output of the command from the mininet cli
1900 or main.FALSE on timeout"""
1901 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001902 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001903 response = self.execute(
1904 cmd=command,
1905 prompt="mininet>",
1906 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001907 if response:
Jon Hallab611372018-02-21 15:26:05 -08001908 if "no bridge named" in response:
1909 main.log.error( self.name + ": Error in getSwController: " +
1910 self.handle.before )
1911 return main.FALSE
1912 else:
1913 return response
admin2a9548d2014-06-17 14:08:07 -07001914 else:
1915 return main.FALSE
1916 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001917 main.log.error( self.name + ": EOF exception found" )
1918 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001919 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001920 except Exception:
1921 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001922 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001923
Charles Chan029be652015-08-24 01:46:10 +08001924 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001925 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001926 Description:
1927 Assign switches to the controllers ( for ovs use only )
1928 Required:
1929 sw - Name of the switch. This can be a list or a string.
1930 ip - Ip addresses of controllers. This can be a list or a string.
1931 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001932 port - ONOS use port 6653, if no list of ports is passed, then
1933 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001934 ptcp - ptcp number, This can be a string or a list that has
1935 the same length as switch. This is optional and not required
1936 when using ovs switches.
1937 NOTE: If switches and ptcp are given in a list type they should have the
1938 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1939 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001940
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001941 Return:
1942 Returns main.TRUE if mininet correctly assigned switches to
1943 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001944 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001945 """
1946 assignResult = main.TRUE
1947 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001948 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001949 command = "sh ovs-vsctl set-controller "
1950 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001951 try:
1952 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001953 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001954 if isinstance( port, types.StringType ) or \
1955 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001956 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001957 elif isinstance( port, types.ListType ):
1958 main.log.error( self.name + ": Only one controller " +
1959 "assigned and a list of ports has" +
1960 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001961 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001962 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001963 main.log.error( self.name + ": Invalid controller port " +
1964 "number. Please specify correct " +
1965 "controller port" )
1966 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001967
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001968 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001969 if isinstance( port, types.StringType ) or \
1970 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001971 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001972 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1973 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001974 elif isinstance( port, types.ListType ):
1975 if ( len( ip ) != len( port ) ):
1976 main.log.error( self.name + ": Port list = " +
1977 str( len( port ) ) +
1978 "should be the same as controller" +
1979 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001980 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001981 else:
1982 onosIp = ""
1983 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001984 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1985 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001986 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001987 main.log.error( self.name + ": Invalid controller port " +
1988 "number. Please specify correct " +
1989 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001990 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001991 else:
1992 main.log.error( self.name + ": Invalid ip address" )
1993 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001994
1995 if isinstance( sw, types.StringType ):
1996 command += sw + " "
1997 if ptcp:
1998 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001999 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002000 elif isinstance( ptcp, types.ListType ):
2001 main.log.error( self.name + ": Only one switch is " +
2002 "being set and multiple PTCP is " +
2003 "being passed " )
2004 else:
2005 main.log.error( self.name + ": Invalid PTCP" )
2006 ptcp = ""
2007 command += onosIp
2008 commandList.append( command )
2009
2010 elif isinstance( sw, types.ListType ):
2011 if ptcp:
2012 if isinstance( ptcp, types.ListType ):
2013 if len( ptcp ) != len( sw ):
2014 main.log.error( self.name + ": PTCP length = " +
2015 str( len( ptcp ) ) +
2016 " is not the same as switch" +
2017 " length = " +
2018 str( len( sw ) ) )
2019 return main.FALSE
2020 else:
2021 for switch, ptcpNum in zip( sw, ptcp ):
2022 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07002023 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07002024 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002025 tempCmd += onosIp
2026 commandList.append( tempCmd )
2027 else:
2028 main.log.error( self.name + ": Invalid PTCP" )
2029 return main.FALSE
2030 else:
2031 for switch in sw:
2032 tempCmd = "sh ovs-vsctl set-controller "
2033 tempCmd += switch + " " + onosIp
2034 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002035 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002036 main.log.error( self.name + ": Invalid switch type " )
2037 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002038
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002039 for cmd in commandList:
2040 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002041 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
Jon Hallab611372018-02-21 15:26:05 -08002042 if "no bridge named" in self.handle.before:
2043 main.log.error( self.name + ": Error in assignSwController: " +
2044 self.handle.before )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002045 except pexpect.TIMEOUT:
2046 main.log.error( self.name + ": pexpect.TIMEOUT found" )
2047 return main.FALSE
2048 except pexpect.EOF:
2049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002051 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002052 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002053 except pexpect.EOF:
2054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002056 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07002057 except Exception:
2058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002059 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07002060
kelvin-onlabd3b64892015-01-20 13:26:24 -08002061 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002062 """
2063 Removes the controller target from sw"""
2064 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07002065 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002066 response = self.execute(
2067 cmd=command,
2068 prompt="mininet>",
2069 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08002070 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002071 main.log.error( self.name + ": EOF exception found" )
2072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002073 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002074 except Exception:
2075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002076 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002077 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002078 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07002079
kelvin-onlabd3b64892015-01-20 13:26:24 -08002080 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002081 """
Jon Hallb1290e82014-11-18 16:17:48 -05002082 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002083 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002084 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002085 NOTE: cannot currently specify what type of switch
2086 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002087 sw = name of the new switch as a string
2088 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05002089 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08002090 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002091 """
2092 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002093 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05002094 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002095 response = self.execute(
2096 cmd=command,
2097 prompt="mininet>",
2098 timeout=10 )
2099 if re.search( "already exists!", response ):
2100 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002101 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002102 elif re.search( "Error", response ):
2103 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002104 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002105 elif re.search( "usage:", response ):
2106 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002107 return main.FALSE
2108 else:
2109 return main.TRUE
2110 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002111 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07002112 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002113 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002114 except Exception:
2115 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002116 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002117
kelvin-onlabd3b64892015-01-20 13:26:24 -08002118 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002119 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002120 delete a switch from the mininet topology
2121 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002122 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002123 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002124 sw = name of the switch as a string
2125 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002126 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002127 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002128 response = self.execute(
2129 cmd=command,
2130 prompt="mininet>",
2131 timeout=10 )
2132 if re.search( "no switch named", response ):
2133 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002134 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002135 elif re.search( "Error", response ):
2136 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002137 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002138 elif re.search( "usage:", response ):
2139 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002140 return main.FALSE
2141 else:
2142 return main.TRUE
2143 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002144 main.log.error( self.name + ": EOF exception found" )
2145 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002146 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002147 except Exception:
2148 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002149 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002150
You Wangdb8cd0a2016-05-26 15:19:45 -07002151 def getSwitchRandom( self, timeout=60, nonCut=True ):
2152 """
2153 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002154 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002155 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002156 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002157 it just randomly returns one switch from all current switches in
2158 Mininet.
2159 Returns the name of the chosen switch.
2160 """
2161 import random
2162 candidateSwitches = []
2163 try:
2164 if not nonCut:
2165 switches = self.getSwitches( timeout=timeout )
2166 assert len( switches ) != 0
2167 for switchName in switches.keys():
2168 candidateSwitches.append( switchName )
2169 else:
2170 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002171 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002172 return None
2173 self.graph.update( graphDict )
2174 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002175 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002176 return None
2177 elif len( candidateSwitches ) == 0:
2178 main.log.info( self.name + ": No candidate switch for deletion" )
2179 return None
2180 else:
2181 switch = random.sample( candidateSwitches, 1 )
2182 return switch[ 0 ]
2183 except KeyError:
2184 main.log.exception( self.name + ": KeyError exception found" )
2185 return None
2186 except AssertionError:
2187 main.log.exception( self.name + ": AssertionError exception found" )
2188 return None
2189 except Exception:
2190 main.log.exception( self.name + ": Uncaught exception" )
2191 return None
2192
2193 def delSwitchRandom( self, timeout=60, nonCut=True ):
2194 """
2195 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002196 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002197 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002198 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002199 otherwise it just randomly delete one switch from all current
2200 switches in Mininet.
2201 Returns the name of the deleted switch
2202 """
2203 try:
2204 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002205 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002206 return None
2207 else:
2208 deletionResult = self.delSwitch( switch )
2209 if deletionResult:
2210 return switch
2211 else:
2212 return None
2213 except Exception:
2214 main.log.exception( self.name + ": Uncaught exception" )
2215 return None
2216
kelvin-onlabd3b64892015-01-20 13:26:24 -08002217 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002218 """
2219 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002220 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002221 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002222 NOTE: cannot currently specify what type of link
2223 required params:
2224 node1 = the string node name of the first endpoint of the link
2225 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002226 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002227 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002228 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002229 response = self.execute(
2230 cmd=command,
2231 prompt="mininet>",
2232 timeout=10 )
2233 if re.search( "doesnt exist!", response ):
2234 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002235 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002236 elif re.search( "Error", response ):
2237 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002238 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002239 elif re.search( "usage:", response ):
2240 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002241 return main.FALSE
2242 else:
2243 return main.TRUE
2244 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002245 main.log.error( self.name + ": EOF exception found" )
2246 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002247 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002248 except Exception:
2249 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002250 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002251
kelvin-onlabd3b64892015-01-20 13:26:24 -08002252 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002253 """
2254 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002255 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002256 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002257 required params:
2258 node1 = the string node name of the first endpoint of the link
2259 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002260 returns: main.FALSE on an error, else main.TRUE
2261 """
Jon Hallffb386d2014-11-21 13:43:38 -08002262 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002263 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002264 response = self.execute(
2265 cmd=command,
2266 prompt="mininet>",
2267 timeout=10 )
2268 if re.search( "no node named", response ):
2269 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002270 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002271 elif re.search( "Error", response ):
2272 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002273 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002274 elif re.search( "usage:", response ):
2275 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002276 return main.FALSE
2277 else:
2278 return main.TRUE
2279 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002280 main.log.error( self.name + ": EOF exception found" )
2281 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002282 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002283 except Exception:
2284 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002285 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002286
You Wangdb8cd0a2016-05-26 15:19:45 -07002287 def getLinkRandom( self, timeout=60, nonCut=True ):
2288 """
2289 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002290 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002291 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002292 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002293 it just randomly returns one link from all current links in
2294 Mininet.
2295 Returns the link as a list, e.g. [ 's1', 's2' ]
2296 """
2297 import random
2298 candidateLinks = []
2299 try:
2300 if not nonCut:
2301 links = self.getLinks( timeout=timeout )
2302 assert len( links ) != 0
2303 for link in links:
2304 # Exclude host-switch link
2305 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2306 continue
2307 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2308 else:
2309 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002310 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002311 return None
2312 self.graph.update( graphDict )
2313 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002314 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002315 return None
2316 elif len( candidateLinks ) == 0:
2317 main.log.info( self.name + ": No candidate link for deletion" )
2318 return None
2319 else:
2320 link = random.sample( candidateLinks, 1 )
2321 return link[ 0 ]
2322 except KeyError:
2323 main.log.exception( self.name + ": KeyError exception found" )
2324 return None
2325 except AssertionError:
2326 main.log.exception( self.name + ": AssertionError exception found" )
2327 return None
2328 except Exception:
2329 main.log.exception( self.name + ": Uncaught exception" )
2330 return None
2331
2332 def delLinkRandom( self, timeout=60, nonCut=True ):
2333 """
2334 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002335 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002336 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002337 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002338 otherwise it just randomly delete one link from all current links
2339 in Mininet.
2340 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2341 """
2342 try:
2343 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002344 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002345 return None
2346 else:
2347 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2348 if deletionResult:
2349 return link
2350 else:
2351 return None
2352 except Exception:
2353 main.log.exception( self.name + ": Uncaught exception" )
2354 return None
2355
kelvin-onlabd3b64892015-01-20 13:26:24 -08002356 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002357 """
Jon Hallb1290e82014-11-18 16:17:48 -05002358 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002359 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002360 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002361 NOTE: cannot currently specify what type of host
2362 required params:
2363 hostname = the string hostname
2364 optional key-value params
2365 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002366 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002367 """
2368 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002369 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002370 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002371 response = self.execute(
2372 cmd=command,
2373 prompt="mininet>",
2374 timeout=10 )
2375 if re.search( "already exists!", response ):
2376 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002377 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002378 elif re.search( "doesnt exists!", response ):
2379 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002380 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002381 elif re.search( "Error", response ):
2382 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002383 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002384 elif re.search( "usage:", response ):
2385 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002386 return main.FALSE
2387 else:
2388 return main.TRUE
2389 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002390 main.log.error( self.name + ": EOF exception found" )
2391 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002392 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002393 except Exception:
2394 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002395 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002396
kelvin-onlabd3b64892015-01-20 13:26:24 -08002397 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002398 """
2399 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002400 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002401 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002402 NOTE: this uses a custom mn function
2403 required params:
2404 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002405 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002406 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002407 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002408 response = self.execute(
2409 cmd=command,
2410 prompt="mininet>",
2411 timeout=10 )
2412 if re.search( "no host named", response ):
2413 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002414 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002415 elif re.search( "Error", response ):
2416 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002417 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002418 elif re.search( "usage:", response ):
2419 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002420 return main.FALSE
2421 else:
2422 return main.TRUE
2423 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002424 main.log.error( self.name + ": EOF exception found" )
2425 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002426 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002427 except Exception:
2428 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002429 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002430
Jon Hall7eb38402015-01-08 17:19:54 -08002431 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002432 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002433 Called at the end of the test to stop the mininet and
2434 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002435 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002436 try:
2437 self.handle.sendline( '' )
You Wangd66de192018-04-30 17:30:12 -07002438 i = self.handle.expect( [ 'mininet>', self.hostPrompt, pexpect.EOF, pexpect.TIMEOUT ],
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002439 timeout=2 )
2440 response = main.TRUE
2441 if i == 0:
2442 response = self.stopNet()
You Wangd66de192018-04-30 17:30:12 -07002443 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002444 return main.TRUE
2445 # print "Disconnecting Mininet"
2446 if self.handle:
2447 self.handle.sendline( "exit" )
2448 self.handle.expect( "exit" )
2449 self.handle.expect( "(.*)" )
2450 else:
2451 main.log.error( "Connection failed to the host" )
2452 return response
2453 except pexpect.EOF:
2454 main.log.error( self.name + ": EOF exception found" )
2455 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002456 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002457 except Exception:
2458 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002459 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002460
Devin Lima7cfdbd2017-09-29 15:02:22 -07002461 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002462 """
Jon Hall21270ac2015-02-16 17:59:55 -08002463 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002464 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002465 main.FALSE if the pexpect handle does not exist.
2466
Jon Halld61331b2015-02-17 16:35:47 -08002467 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002468 """
Jon Halld61331b2015-02-17 16:35:47 -08002469 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002470 response = ''
2471 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002472 try:
Jon Halld80cc142015-07-06 13:36:05 -07002473 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002474 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002475 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002476 pexpect.EOF,
2477 pexpect.TIMEOUT ],
2478 timeout )
2479 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002480 main.log.info( "Exiting mininet.." )
2481 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002482 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002483 prompt=self.prompt,
2484 timeout=exitTimeout )
2485 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002486 self.handle.sendline( "sudo mn -c" )
2487 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002488
Jeremyd9e4eb12016-04-13 12:09:06 -07002489 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002490 main.log.info( " Mininet trying to exit while not " +
2491 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002492 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002493 elif i == 2:
2494 main.log.error( "Something went wrong exiting mininet" )
2495 elif i == 3: # timeout
2496 main.log.error( "Something went wrong exiting mininet " +
2497 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002498
You Wang18db8592018-04-02 13:52:03 -07002499 self.handle.sendline( "" )
2500 self.handle.expect( self.prompt )
2501 self.handle.sendline( "sudo killall -9 dhclient dhcpd zebra bgpd" )
2502
Hari Krishnab35c6d02015-03-18 11:13:51 -07002503 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002504 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002505 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002506 self.handle.sendline(
2507 "sudo kill -9 \`ps -ef | grep \"" +
2508 fileName +
2509 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002510 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002511 main.log.error( self.name + ": TIMEOUT exception found" )
2512 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002513 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002514 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002515 main.log.error( self.name + ": EOF exception found" )
2516 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002517 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002518 except Exception:
2519 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002520 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002521 else:
2522 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002523 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002524 return response
2525
YPZhang26a139e2016-04-25 14:01:55 -07002526 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002527 """
2528 Description:
2529 Sends arp message from mininet host for hosts discovery
2530 Required:
2531 host - hosts name
2532 Optional:
2533 ip - ip address that does not exist in the network so there would
2534 be no reply.
2535 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002536 if ethDevice:
2537 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002538 cmd = srcHost + " arping -c1 "
2539 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002540 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
YPZhang26a139e2016-04-25 14:01:55 -07002541 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002542 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002543 if output:
2544 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002545 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002546 i = self.handle.expect( [ "mininet>", "arping: " ] )
2547 if i == 0:
2548 return main.TRUE
2549 elif i == 1:
2550 response = self.handle.before + self.handle.after
2551 self.handle.expect( "mininet>" )
2552 response += self.handle.before + self.handle.after
2553 main.log.warn( "Error sending arping, output was: " +
2554 response )
2555 return main.FALSE
2556 except pexpect.TIMEOUT:
2557 main.log.error( self.name + ": TIMEOUT exception found" )
2558 main.log.warn( self.handle.before )
2559 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002560 except pexpect.EOF:
2561 main.log.error( self.name + ": EOF exception found" )
2562 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002563 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002564 except Exception:
2565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002566 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002567
Jon Hall7eb38402015-01-08 17:19:54 -08002568 def decToHex( self, num ):
2569 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002570
Jon Hall7eb38402015-01-08 17:19:54 -08002571 def getSwitchFlowCount( self, switch ):
2572 """
2573 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002574 if self.handle:
2575 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2576 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002577 response = self.execute(
2578 cmd=cmd,
2579 prompt="mininet>",
2580 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002581 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002582 main.log.error( self.name + ": EOF exception found" )
2583 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002584 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002585 except Exception:
2586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002587 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002588 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002589 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002590 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002591 main.log.info(
2592 "Couldn't find flows on switch %s, found: %s" %
2593 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002594 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002595 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002596 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002597 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002598
Jon Hall9ed8f372016-02-24 17:34:07 -08002599 def checkFlows( self, sw, dumpFormat=None ):
2600 if dumpFormat:
2601 command = "sh ovs-ofctl -F " + \
2602 dumpFormat + " dump-flows " + str( sw )
2603 else:
2604 command = "sh ovs-ofctl dump-flows " + str( sw )
2605 try:
2606 response = self.execute(
2607 cmd=command,
2608 prompt="mininet>",
2609 timeout=10 )
2610 return response
2611 except pexpect.EOF:
2612 main.log.error( self.name + ": EOF exception found" )
2613 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002614 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002615 except Exception:
2616 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002617 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002618
GlennRC68467eb2015-11-16 18:01:01 -08002619 def flowTableComp( self, flowTable1, flowTable2 ):
2620 # This function compares the selctors and treatments of each flow
2621 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002622 assert flowTable1, "flowTable1 is empty or None"
2623 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002624 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002625 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002626 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002627 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002628 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2629 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002630 for field in dFields:
2631 try:
2632 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002633 except KeyError:
2634 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002635 try:
2636 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002637 except KeyError:
2638 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002639 for i in range( len( flowTable1 ) ):
2640 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002641 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002642 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002643 returnValue = main.FALSE
2644 break
2645 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002646 except AssertionError:
2647 main.log.exception( "Nothing to compare" )
2648 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002649 except Exception:
2650 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002651 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002652
GlennRC528ad292015-11-12 10:38:18 -08002653 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002654 '''
GlennRC956ea742015-11-05 16:14:15 -08002655 Discription: Parses flows into json format.
2656 NOTE: this can parse any string thats separated with commas
2657 Arguments:
2658 Required:
2659 flows: a list of strings that represnt flows
2660 Optional:
2661 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2662 debug: prints out the final result
2663 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002664 '''
GlennRC528ad292015-11-12 10:38:18 -08002665 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002666 try:
2667 for flow in flowTable:
2668 jsonFlow = {}
2669 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002670 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002671 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002672 for i in range( len( parsedFlow ) ):
2673 item = parsedFlow[ i ]
2674 if item[ 0 ] == " ":
2675 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002676 # grab the selector and treatment from the parsed flow
2677 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002678 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002679 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002680 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002681 index = 0
2682 # parse the flags
2683 # NOTE: This only parses one flag
2684 flag = {}
2685 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002686 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002687 index += 1
2688 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002689 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002690 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002691 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002692 # the priority is stuck in the selecter so put it back
2693 # in the flow
Jon Hallab611372018-02-21 15:26:05 -08002694 if 'priority' in sel[0]:
2695 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002696 # parse selector
2697 criteria = []
2698 for item in sel:
2699 # this is the type of the packet e.g. "arp"
2700 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002701 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002702 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002703 field = item.split( "=" )
2704 criteria.append( { field[ 0 ]: field[ 1 ] } )
2705 selector = { "selector": { "criteria": sorted( criteria ) } }
2706 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002707 # get rid of the action part e.g. "action=output:2"
2708 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002709 treat = treat.split( "=" )
2710 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002711 # parse treatment
2712 action = []
2713 for item in treat:
Jon Hallab611372018-02-21 15:26:05 -08002714 if ":" in item:
2715 field = item.split( ":" )
2716 action.append( { field[ 0 ]: field[ 1 ] } )
2717 else:
2718 main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
2719 item ) )
You Wang91c37cf2016-05-23 09:39:42 -07002720 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002721 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002722 # parse the rest of the flow
2723 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002724 field = item.split( "=" )
2725 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002726 # add the treatment and the selector to the json flow
2727 jsonFlow.update( selector )
2728 jsonFlow.update( treatment )
2729 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002730
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002731 if debug:
2732 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002733
You Wang91c37cf2016-05-23 09:39:42 -07002734 # add the json flow to the json flow table
2735 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002736
You Wang91c37cf2016-05-23 09:39:42 -07002737 return jsonFlowTable
2738
2739 except IndexError:
2740 main.log.exception( self.name + ": IndexError found" )
2741 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002742 except pexpect.EOF:
2743 main.log.error( self.name + ": EOF exception found" )
2744 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002745 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002746 except Exception:
2747 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002748 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002749
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002750 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002751 '''
2752 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002753 Each element is a flow.
2754 Arguments:
2755 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002756 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002757 a list of switches.
2758 Optional:
2759 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2760 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002761 '''
GlennRC956ea742015-11-05 16:14:15 -08002762 try:
2763 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002764 if isinstance( sw, list ):
2765 switches.extend( sw )
2766 else:
2767 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002768
2769 flows = []
2770 for s in switches:
2771 cmd = "sh ovs-ofctl dump-flows " + s
2772
GlennRC528ad292015-11-12 10:38:18 -08002773 if "1.0" == version:
2774 cmd += " -F OpenFlow10-table_id"
2775 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002776 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002777
2778 main.log.info( "Sending: " + cmd )
2779 self.handle.sendline( cmd )
2780 self.handle.expect( "mininet>" )
2781 response = self.handle.before
2782 response = response.split( "\r\n" )
2783 # dump the first two elements and the last
2784 # the first element is the command that was sent
2785 # the second is the table header
2786 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002787 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002788 flows.extend( response )
2789
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002790 if debug:
2791 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002792
GlennRC528ad292015-11-12 10:38:18 -08002793 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002794
GlennRC956ea742015-11-05 16:14:15 -08002795 except pexpect.EOF:
2796 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002797 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002798 except Exception:
2799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002800 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002801
2802 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002803 '''
GlennRC956ea742015-11-05 16:14:15 -08002804 Discription: Checks whether the ID provided matches a flow ID in Mininet
2805 Arguments:
2806 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002807 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002808 a list of switches.
2809 flowId: the flow ID in hex format. Can also be a list of IDs
2810 Optional:
2811 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2812 debug: prints out the final result
2813 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2814 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002815 '''
GlennRC956ea742015-11-05 16:14:15 -08002816 try:
2817 main.log.info( "Getting flows from Mininet" )
2818 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002819 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002820 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002821
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002822 if debug:
2823 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002824
2825 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002826 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002827 result = False
2828 for f in flows:
2829 if flowId in f.get( 'cookie' ):
2830 result = True
2831 break
2832 # flowId is a list
2833 else:
2834 result = True
2835 # Get flow IDs from Mininet
2836 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2837 # Save the IDs that are not in Mininet
2838 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2839
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002840 if debug:
2841 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002842
2843 # Print out the IDs that are not in Mininet
2844 if absentIds:
2845 main.log.warn( "Absent ids: {}".format( absentIds ) )
2846 result = False
2847
2848 return main.TRUE if result else main.FALSE
2849
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002850 except pexpect.EOF:
2851 main.log.error( self.name + ": EOF exception found" )
2852 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002853 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002854 except Exception:
2855 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002856 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002857
Charles Chan029be652015-08-24 01:46:10 +08002858 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002859 """
Jon Hallefbd9792015-03-05 16:11:36 -08002860 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002861 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002862 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002863 self.handle.sendline( "" )
2864 self.handle.expect( "mininet>" )
2865 self.handle.sendline(
2866 "sh sudo tcpdump -n -i " +
2867 intf +
2868 " " +
2869 port +
2870 " -w " +
2871 filename.strip() +
2872 " &" )
2873 self.handle.sendline( "" )
2874 i = self.handle.expect( [ 'No\ssuch\device',
2875 'listening\son',
2876 pexpect.TIMEOUT,
2877 "mininet>" ],
2878 timeout=10 )
2879 main.log.warn( self.handle.before + self.handle.after )
2880 self.handle.sendline( "" )
2881 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002882 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002883 main.log.error(
2884 self.name +
2885 ": tcpdump - No such device exists. " +
2886 "tcpdump attempted on: " +
2887 intf )
admin2a9548d2014-06-17 14:08:07 -07002888 return main.FALSE
2889 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002890 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002891 return main.TRUE
2892 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002893 main.log.error(
2894 self.name +
2895 ": tcpdump command timed out! Check interface name," +
2896 " given interface was: " +
2897 intf )
admin2a9548d2014-06-17 14:08:07 -07002898 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002899 elif i == 3:
2900 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002901 return main.TRUE
2902 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002903 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002904 return main.FALSE
2905 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002906 main.log.error( self.name + ": EOF exception found" )
2907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002908 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002909 except Exception:
2910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002911 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002912
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002914 """
2915 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002916 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002917 self.handle.sendline( "sh sudo pkill tcpdump" )
2918 self.handle.expect( "mininet>" )
2919 self.handle.sendline( "" )
2920 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002921 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002922 main.log.error( self.name + ": TIMEOUT exception found" )
2923 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002924 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002925 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002929 except Exception:
2930 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002932
Jon Halld80cc142015-07-06 13:36:05 -07002933 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002934 """
2935 Read ports from a Mininet switch.
2936
2937 Returns a json structure containing information about the
2938 ports of the given switch.
2939 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002940 try:
2941 response = self.getInterfaces( nodeName )
2942 # TODO: Sanity check on response. log if no such switch exists
2943 ports = []
2944 for line in response.split( "\n" ):
2945 if not line.startswith( "name=" ):
2946 continue
2947 portVars = {}
2948 for var in line.split( "," ):
2949 key, value = var.split( "=" )
2950 portVars[ key ] = value
2951 isUp = portVars.pop( 'enabled', "True" )
2952 isUp = "True" in isUp
2953 if verbose:
2954 main.log.info( "Reading switch port %s(%s)" %
2955 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2956 mac = portVars[ 'mac' ]
2957 if mac == 'None':
2958 mac = None
2959 ips = []
2960 ip = portVars[ 'ip' ]
2961 if ip == 'None':
2962 ip = None
2963 ips.append( ip )
2964 name = portVars[ 'name' ]
2965 if name == 'None':
2966 name = None
2967 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2968 if name == 'lo':
2969 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2970 else:
2971 portNo = re.search( portRe, name ).group( 'port' )
2972 ports.append( { 'of_port': portNo,
2973 'mac': str( mac ).replace( '\'', '' ),
2974 'name': name,
2975 'ips': ips,
2976 'enabled': isUp } )
2977 return ports
2978 except pexpect.EOF:
2979 main.log.error( self.name + ": EOF exception found" )
2980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002981 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002982 except Exception:
2983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002984 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002985
You Wangdb8cd0a2016-05-26 15:19:45 -07002986 def getOVSPorts( self, nodeName ):
2987 """
2988 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2989
2990 Returns a list of dictionaries containing information about each
2991 port of the given switch.
2992 """
2993 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2994 try:
2995 response = self.execute(
2996 cmd=command,
2997 prompt="mininet>",
2998 timeout=10 )
2999 ports = []
3000 if response:
3001 for line in response.split( "\n" ):
3002 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
3003 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003004 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07003005 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
3006 result = re.search( pattern, line )
3007 if result:
3008 index = result.group( 'index' )
3009 name = result.group( 'name' )
3010 # This port number is extracted from port name
3011 port = result.group( 'port' )
3012 mac = result.group( 'mac' )
3013 ports.append( { 'index': index,
3014 'name': name,
3015 'port': port,
3016 'mac': mac } )
3017 return ports
3018 except pexpect.EOF:
3019 main.log.error( self.name + ": EOF exception found" )
3020 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003021 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003022 except Exception:
3023 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003024 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003025
Devin Lima7cfdbd2017-09-29 15:02:22 -07003026 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003027 """
3028 Read switches from Mininet.
3029
3030 Returns a dictionary whose keys are the switch names and the value is
3031 a dictionary containing information about the switch.
3032 """
Jon Halla22481b2015-07-28 17:46:01 -07003033 # NOTE: To support new Mininet switch classes, just append the new
3034 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07003035
Jon Halla22481b2015-07-28 17:46:01 -07003036 # Regex patterns to parse 'dump' output
3037 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07003038 # <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 -07003039 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07003040 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
3041 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
3042 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003043 try:
3044 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
3045 swRE = r"<(?P<class>" + switchClasses + r")" +\
3046 r"(?P<options>\{.*\})?\s" +\
3047 r"(?P<name>[^:]+)\:\s" +\
3048 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
3049 r"\spid=(?P<pid>(\d)+)"
3050 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07003051 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003052 output = {}
3053 dump = self.dump().split( "\n" )
3054 for line in dump:
3055 result = re.search( swRE, line, re.I )
3056 if result:
3057 name = result.group( 'name' )
3058 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
3059 pid = result.group( 'pid' )
3060 swClass = result.group( 'class' )
3061 options = result.group( 'options' )
3062 if verbose:
3063 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
3064 ports = self.getPorts( name )
3065 output[ name ] = { "dpid": dpid,
3066 "ports": ports,
3067 "swClass": swClass,
3068 "pid": pid,
3069 "options": options }
3070 return output
3071 except pexpect.EOF:
3072 main.log.error( self.name + ": EOF exception found" )
3073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003074 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003075 except Exception:
3076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003077 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003078
You Wangd66de192018-04-30 17:30:12 -07003079 def getHosts( self, verbose=False, update=True, updateTimeout=1000,
Jon Hallab611372018-02-21 15:26:05 -08003080 hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
3081 getInterfaces=True ):
Jon Hallafa8a472015-06-12 14:02:42 -07003082 """
3083 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08003084 Optional:
3085 hostClass: it is used to match the class of the mininet host. It
3086 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07003087 Returns a dictionary whose keys are the host names and the value is
3088 a dictionary containing information about the host.
3089 """
3090 # Regex patterns to parse dump output
3091 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07003092 # <Host h1: pid=12725>
3093 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3094 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3095 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003096 # NOTE: Does not correctly match hosts with multi-links
3097 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3098 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003099 try:
You Wang53dba1e2018-02-02 17:45:44 -08003100 if not isinstance( hostClass, types.ListType ):
3101 hostClass = [ str( hostClass ) ]
3102 classRE = "(" + "|".join([c for c in hostClass]) + ")"
Jon Hallab611372018-02-21 15:26:05 -08003103 ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
3104 ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
3105 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
You Wangd66de192018-04-30 17:30:12 -07003106 if update:
3107 # update mn port info
3108 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003109 # Get mininet dump
3110 dump = self.dump().split( "\n" )
3111 hosts = {}
3112 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08003113 result = re.search( hostRE, line )
3114 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003115 name = result.group( 'name' )
3116 interfaces = []
You Wang79f5c5b2018-03-14 11:10:44 -07003117 if getInterfaces:
3118 response = self.getInterfaces( name )
3119 # Populate interface info
3120 for line in response.split( "\n" ):
3121 if line.startswith( "name=" ):
3122 portVars = {}
3123 for var in line.split( "," ):
3124 key, value = var.split( "=" )
3125 portVars[ key ] = value
3126 isUp = portVars.pop( 'enabled', "True" )
3127 isUp = "True" in isUp
3128 if verbose:
3129 main.log.info( "Reading host port %s(%s)" %
3130 ( portVars[ 'name' ],
3131 portVars[ 'mac' ] ) )
3132 mac = portVars[ 'mac' ]
3133 if mac == 'None':
3134 mac = None
3135 ips = []
3136 ip = portVars[ 'ip' ]
3137 if ip == 'None':
3138 ip = None
3139 ips.append( ip )
3140 intfName = portVars[ 'name' ]
3141 if name == 'None':
3142 name = None
3143 interfaces.append( {
3144 "name": intfName,
3145 "ips": ips,
3146 "mac": str( mac ),
3147 "isUp": isUp } )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003148 hosts[ name ] = { "interfaces": interfaces }
3149 return hosts
3150 except pexpect.EOF:
3151 main.log.error( self.name + ": EOF exception found" )
3152 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003153 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003154 except Exception:
3155 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003156 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003157
Devin Lima7cfdbd2017-09-29 15:02:22 -07003158 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003159 """
3160 Gathers information about current Mininet links. These links may not
3161 be up if one of the ports is down.
3162
3163 Returns a list of dictionaries with link endpoints.
3164
3165 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003166 { 'node1': str( node1 name )
3167 'node2': str( node2 name )
3168 'port1': str( port1 of_port )
3169 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003170 Note: The port number returned is the eth#, not necessarily the of_port
3171 number. In Mininet, for OVS switch, these should be the same. For
3172 hosts, this is just the eth#.
3173 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003174 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003175 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003176 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003177
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003178 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003179 # s1-eth3<->s2-eth1 (OK OK)
3180 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003181 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3182 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3183 links = []
3184 for line in response:
3185 match = re.search( linkRE, line )
3186 if match:
3187 node1 = match.group( 'node1' )
3188 node2 = match.group( 'node2' )
3189 port1 = match.group( 'port1' )
3190 port2 = match.group( 'port2' )
3191 links.append( { 'node1': node1,
3192 'node2': node2,
3193 'port1': port1,
3194 'port2': port2 } )
3195 return links
3196
3197 except pexpect.EOF:
3198 main.log.error( self.name + ": EOF exception found" )
3199 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003200 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003201 except Exception:
3202 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003203 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003204
3205 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003206 """
3207 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003208 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003209
Jon Hallafa8a472015-06-12 14:02:42 -07003210 Dependencies:
3211 1. numpy - "sudo pip install numpy"
3212 """
3213 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003214 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003215 try:
3216 mnDPIDs = []
3217 for swName, switch in switches.iteritems():
3218 mnDPIDs.append( switch[ 'dpid' ].lower() )
3219 mnDPIDs.sort()
3220 if switchesJson == "": # if rest call fails
3221 main.log.error(
3222 self.name +
3223 ".compareSwitches(): Empty JSON object given from ONOS" )
3224 return main.FALSE
3225 onos = switchesJson
3226 onosDPIDs = []
3227 for switch in onos:
3228 if switch[ 'available' ]:
3229 onosDPIDs.append(
3230 switch[ 'id' ].replace(
3231 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003232 '' ).replace(
3233 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003234 '' ).lower() )
3235 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003236
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003237 if mnDPIDs != onosDPIDs:
3238 switchResults = main.FALSE
3239 main.log.error( "Switches in MN but not in ONOS:" )
3240 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3241 main.log.error( str( list1 ) )
3242 main.log.error( "Switches in ONOS but not in MN:" )
3243 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3244 main.log.error( str( list2 ) )
3245 else: # list of dpid's match in onos and mn
3246 switchResults = main.TRUE
3247 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003248
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003249 # FIXME: this does not look for extra ports in ONOS, only checks that
3250 # ONOS has what is in MN
3251 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003252
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003253 # PORTS
3254 for name, mnSwitch in switches.iteritems():
3255 mnPorts = []
3256 onosPorts = []
3257 switchResult = main.TRUE
3258 for port in mnSwitch[ 'ports' ]:
3259 if port[ 'enabled' ]:
3260 mnPorts.append( int( port[ 'of_port' ] ) )
3261 for onosSwitch in portsJson:
3262 if onosSwitch[ 'device' ][ 'available' ]:
3263 if onosSwitch[ 'device' ][ 'id' ].replace(
3264 ':',
3265 '' ).replace(
3266 "of",
3267 '' ) == mnSwitch[ 'dpid' ]:
3268 for port in onosSwitch[ 'ports' ]:
3269 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003270 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003271 # onosPorts.append( 'local' )
3272 onosPorts.append( long( uint64( -2 ) ) )
3273 else:
3274 onosPorts.append( int( port[ 'port' ] ) )
3275 break
3276 mnPorts.sort( key=float )
3277 onosPorts.sort( key=float )
3278
3279 mnPortsLog = mnPorts
3280 onosPortsLog = onosPorts
3281 mnPorts = [ x for x in mnPorts ]
3282 onosPorts = [ x for x in onosPorts ]
3283
3284 # TODO: handle other reserved port numbers besides LOCAL
3285 # NOTE: Reserved ports
3286 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3287 # long( uint64( -2 ) )
3288 for mnPort in mnPortsLog:
3289 if mnPort in onosPorts:
3290 # don't set results to true here as this is just one of
3291 # many checks and it might override a failure
3292 mnPorts.remove( mnPort )
3293 onosPorts.remove( mnPort )
3294
3295 # NOTE: OVS reports this as down since there is no link
3296 # So ignoring these for now
3297 # TODO: Come up with a better way of handling these
3298 if 65534 in mnPorts:
3299 mnPorts.remove( 65534 )
3300 if long( uint64( -2 ) ) in onosPorts:
3301 onosPorts.remove( long( uint64( -2 ) ) )
3302 if len( mnPorts ): # the ports of this switch don't match
3303 switchResult = main.FALSE
3304 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3305 if len( onosPorts ): # the ports of this switch don't match
3306 switchResult = main.FALSE
3307 main.log.warn(
3308 "Ports in ONOS but not MN: " +
3309 str( onosPorts ) )
3310 if switchResult == main.FALSE:
3311 main.log.error(
3312 "The list of ports for switch %s(%s) does not match:" %
3313 ( name, mnSwitch[ 'dpid' ] ) )
3314 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3315 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3316 portsResults = portsResults and switchResult
3317 finalResults = finalResults and portsResults
3318 return finalResults
3319 except pexpect.EOF:
3320 main.log.error( self.name + ": EOF exception found" )
3321 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003322 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003323 except Exception:
3324 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003325 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003326
Jon Hallafa8a472015-06-12 14:02:42 -07003327 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003328 """
3329 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003330 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003331
Jon Hallafa8a472015-06-12 14:02:42 -07003332 """
Jon Hall7eb38402015-01-08 17:19:54 -08003333 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003334 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003335 try:
3336 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003337
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003338 mnLinks = []
3339 for l in links:
3340 try:
3341 node1 = switches[ l[ 'node1' ] ]
3342 node2 = switches[ l[ 'node2' ] ]
3343 enabled = True
3344 for port in node1[ 'ports' ]:
3345 if port[ 'of_port' ] == l[ 'port1' ]:
3346 enabled = enabled and port[ 'enabled' ]
3347 for port in node2[ 'ports' ]:
3348 if port[ 'of_port' ] == l[ 'port2' ]:
3349 enabled = enabled and port[ 'enabled' ]
3350 if enabled:
3351 mnLinks.append( l )
3352 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003353 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003354 if 2 * len( mnLinks ) == len( onos ):
3355 linkResults = main.TRUE
3356 else:
3357 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003358 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003359 "Mininet has " + str( len( mnLinks ) ) +
3360 " bidirectional links and ONOS has " +
3361 str( len( onos ) ) + " unidirectional links" )
3362
3363 # iterate through MN links and check if an ONOS link exists in
3364 # both directions
3365 for link in mnLinks:
3366 # TODO: Find a more efficient search method
3367 node1 = None
3368 port1 = None
3369 node2 = None
3370 port2 = None
3371 firstDir = main.FALSE
3372 secondDir = main.FALSE
3373 for swName, switch in switches.iteritems():
3374 if swName == link[ 'node1' ]:
3375 node1 = switch[ 'dpid' ]
3376 for port in switch[ 'ports' ]:
3377 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3378 port1 = port[ 'of_port' ]
3379 if node1 is not None and node2 is not None:
3380 break
3381 if swName == link[ 'node2' ]:
3382 node2 = switch[ 'dpid' ]
3383 for port in switch[ 'ports' ]:
3384 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3385 port2 = port[ 'of_port' ]
3386 if node1 is not None and node2 is not None:
3387 break
3388
3389 for onosLink in onos:
3390 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3391 ":", '' ).replace( "of", '' )
3392 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3393 ":", '' ).replace( "of", '' )
3394 onosPort1 = onosLink[ 'src' ][ 'port' ]
3395 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3396
3397 # check onos link from node1 to node2
3398 if str( onosNode1 ) == str( node1 ) and str(
3399 onosNode2 ) == str( node2 ):
3400 if int( onosPort1 ) == int( port1 ) and int(
3401 onosPort2 ) == int( port2 ):
3402 firstDir = main.TRUE
3403 else:
Jon Hallab611372018-02-21 15:26:05 -08003404 # The right switches, but wrong ports, could be
3405 # another link between these devices, or onos
3406 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003407 main.log.warn(
3408 'The port numbers do not match for ' +
3409 str( link ) +
3410 ' between ONOS and MN. When checking ONOS for ' +
3411 'link %s/%s -> %s/%s' %
3412 ( node1, port1, node2, port2 ) +
3413 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003414 ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
3415 '. This could be another link between these devices' +
3416 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003417
3418 # check onos link from node2 to node1
3419 elif ( str( onosNode1 ) == str( node2 ) and
3420 str( onosNode2 ) == str( node1 ) ):
3421 if ( int( onosPort1 ) == int( port2 )
3422 and int( onosPort2 ) == int( port1 ) ):
3423 secondDir = main.TRUE
3424 else:
Jon Hallab611372018-02-21 15:26:05 -08003425 # The right switches, but wrong ports, could be
3426 # another link between these devices, or onos
3427 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003428 main.log.warn(
3429 'The port numbers do not match for ' +
3430 str( link ) +
3431 ' between ONOS and MN. When checking ONOS for ' +
3432 'link %s/%s -> %s/%s' %
3433 ( node1, port1, node2, port2 ) +
3434 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003435 ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
3436 '. This could be another link between these devices' +
3437 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003438 else: # this is not the link you're looking for
3439 pass
3440 if not firstDir:
3441 main.log.error(
3442 'ONOS does not have the link %s/%s -> %s/%s' %
3443 ( node1, port1, node2, port2 ) )
3444 if not secondDir:
3445 main.log.error(
3446 'ONOS does not have the link %s/%s -> %s/%s' %
3447 ( node2, port2, node1, port1 ) )
3448 linkResults = linkResults and firstDir and secondDir
3449 return linkResults
3450 except pexpect.EOF:
3451 main.log.error( self.name + ": EOF exception found" )
3452 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003453 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003454 except Exception:
3455 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003456 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003457
Jon Hallafa8a472015-06-12 14:02:42 -07003458 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003459 """
Jon Hallafa8a472015-06-12 14:02:42 -07003460 Compare mn and onos Hosts.
3461 Since Mininet hosts are quiet, ONOS will only know of them when they
3462 speak. For this reason, we will only check that the hosts in ONOS
3463 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003464
Jon Hallafa8a472015-06-12 14:02:42 -07003465 Arguments:
3466 hostsJson: parsed json object from the onos hosts api
3467 Returns:
3468 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003469 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003470 try:
3471 hostResults = main.TRUE
3472 for onosHost in hostsJson:
3473 onosMAC = onosHost[ 'mac' ].lower()
3474 match = False
3475 for mnHost, info in hosts.iteritems():
3476 for mnIntf in info[ 'interfaces' ]:
3477 if onosMAC == mnIntf[ 'mac' ].lower():
3478 match = True
3479 for ip in mnIntf[ 'ips' ]:
3480 if ip in onosHost[ 'ipAddresses' ]:
3481 pass # all is well
3482 else:
3483 # misssing ip
3484 main.log.error( "ONOS host " +
3485 onosHost[ 'id' ] +
3486 " has a different IP(" +
3487 str( onosHost[ 'ipAddresses' ] ) +
3488 ") than the Mininet host(" +
3489 str( ip ) +
3490 ")." )
3491 output = json.dumps(
3492 onosHost,
3493 sort_keys=True,
3494 indent=4,
3495 separators=( ',', ': ' ) )
3496 main.log.info( output )
3497 hostResults = main.FALSE
3498 if not match:
3499 hostResults = main.FALSE
3500 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3501 "corresponding Mininet host." )
3502 output = json.dumps( onosHost,
3503 sort_keys=True,
3504 indent=4,
3505 separators=( ',', ': ' ) )
3506 main.log.info( output )
3507 return hostResults
3508 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003511 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003512 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003514 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003515
You Wangd66de192018-04-30 17:30:12 -07003516 def verifyHostIp( self, hostList=[], prefix="", update=True ):
You Wang53dba1e2018-02-02 17:45:44 -08003517 """
3518 Description:
3519 Verify that all hosts have IP address assigned to them
3520 Optional:
3521 hostList: If specified, verifications only happen to the hosts
3522 in hostList
3523 prefix: at least one of the ip address assigned to the host
3524 needs to have the specified prefix
You Wangd66de192018-04-30 17:30:12 -07003525 update: Update Mininet information if True
You Wang53dba1e2018-02-02 17:45:44 -08003526 Returns:
3527 main.TRUE if all hosts have specific IP address assigned;
3528 main.FALSE otherwise
3529 """
3530 try:
You Wangd66de192018-04-30 17:30:12 -07003531 hosts = self.getHosts( update=update, getInterfaces=False )
You Wang53dba1e2018-02-02 17:45:44 -08003532 if not hostList:
3533 hostList = hosts.keys()
3534 for hostName in hosts.keys():
3535 if hostName not in hostList:
3536 continue
3537 ipList = []
3538 self.handle.sendline( str( hostName ) + " ip a" )
3539 self.handle.expect( "mininet>" )
3540 ipa = self.handle.before
3541 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3542 ipList += re.findall( ipv4Pattern, ipa )
3543 # It's tricky to make regex for IPv6 addresses and this one is simplified
3544 ipv6Pattern = r'inet6 ((?:[0-9a-fA-F]{1,4})?(?:[:0-9a-fA-F]{1,4}){1,7}(?:::)?(?:[:0-9a-fA-F]{1,4}){1,7})/'
3545 ipList += re.findall( ipv6Pattern, ipa )
3546 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3547 if not ipList:
3548 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3549 else:
3550 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3551 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3552 else:
3553 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3554 hostList.remove( hostName )
3555 return main.FALSE if hostList else main.TRUE
3556 except KeyError:
3557 main.log.exception( self.name + ": host data not as expected: " + hosts )
3558 return None
3559 except pexpect.EOF:
3560 main.log.error( self.name + ": EOF exception found" )
3561 main.log.error( self.name + ": " + self.handle.before )
3562 main.cleanAndExit()
3563 except Exception:
3564 main.log.exception( self.name + ": Uncaught exception" )
3565 return None
3566
Jon Hallafa8a472015-06-12 14:02:42 -07003567 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003568 """
3569 Returns a list of all hosts
3570 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003571 try:
3572 self.handle.sendline( "" )
3573 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003574
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003575 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3576 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003577
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003578 handlePy = self.handle.before
3579 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3580 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003581
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003582 self.handle.sendline( "" )
3583 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003584
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003585 hostStr = handlePy.replace( "]", "" )
3586 hostStr = hostStr.replace( "'", "" )
3587 hostStr = hostStr.replace( "[", "" )
3588 hostStr = hostStr.replace( " ", "" )
3589 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003590
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003591 return hostList
3592 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003593 main.log.error( self.name + ": TIMEOUT exception found" )
3594 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003595 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003596 except pexpect.EOF:
3597 main.log.error( self.name + ": EOF exception found" )
3598 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003599 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003600 except Exception:
3601 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003602 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003603
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003604 def getSwitch( self ):
3605 """
3606 Returns a list of all switches
3607 Again, don't ask question just use it...
3608 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003609 try:
3610 # get host list...
3611 hostList = self.getHosts()
3612 # Make host set
3613 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003614
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003615 # Getting all the nodes in mininet
3616 self.handle.sendline( "" )
3617 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003618
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003619 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3620 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003621
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003622 handlePy = self.handle.before
3623 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3624 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003625
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003626 self.handle.sendline( "" )
3627 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003628
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003629 nodesStr = handlePy.replace( "]", "" )
3630 nodesStr = nodesStr.replace( "'", "" )
3631 nodesStr = nodesStr.replace( "[", "" )
3632 nodesStr = nodesStr.replace( " ", "" )
3633 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003634
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003635 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003636 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003637 nodesSet.discard( 'c0' )
3638 nodesSet.discard( 'c1' )
3639 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003640
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003641 switchSet = nodesSet - hostSet
3642 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003643
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003644 return switchList
3645 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003646 main.log.error( self.name + ": TIMEOUT exception found" )
3647 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003648 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003649 except pexpect.EOF:
3650 main.log.error( self.name + ": EOF exception found" )
3651 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003652 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003653 except Exception:
3654 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003655 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003656
You Wangdb8cd0a2016-05-26 15:19:45 -07003657 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3658 """
3659 Return a dictionary which describes the latest Mininet topology data as a
3660 graph.
3661 An example of the dictionary:
3662 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3663 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3664 Each vertex should at least have an 'edges' attribute which describes the
3665 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003666 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003667 list of attributes.
3668 An example of the edges dictionary:
3669 'edges': { vertex2: { 'port': ..., 'weight': ... },
3670 vertex3: { 'port': ..., 'weight': ... } }
3671 If useId == True, dpid/mac will be used instead of names to identify
3672 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3673 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003674 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003675 in topology data.
3676 Note that link or switch that are brought down by 'link x x down' or 'switch
3677 x down' commands still show in the output of Mininet CLI commands such as
3678 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3679 recommended to use delLink() or delSwitch functions to simulate link/switch
3680 down, and addLink() or addSwitch to add them back.
3681 """
3682 graphDict = {}
3683 try:
3684 links = self.getLinks( timeout=timeout )
3685 portDict = {}
3686 if useId:
3687 switches = self.getSwitches()
3688 if includeHost:
3689 hosts = self.getHosts()
3690 for link in links:
3691 # FIXME: support 'includeHost' argument
3692 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3693 continue
3694 nodeName1 = link[ 'node1' ]
3695 nodeName2 = link[ 'node2' ]
3696 port1 = link[ 'port1' ]
3697 port2 = link[ 'port2' ]
3698 # Loop for two nodes
3699 for i in range( 2 ):
3700 # Get port index from OVS
3701 # The index extracted from port name may be inconsistent with ONOS
3702 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003703 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003704 portList = self.getOVSPorts( nodeName1 )
3705 if len( portList ) == 0:
3706 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3707 return None
3708 portDict[ nodeName1 ] = portList
3709 for port in portDict[ nodeName1 ]:
3710 if port[ 'port' ] == port1:
3711 portIndex = port[ 'index' ]
3712 break
3713 if portIndex == -1:
3714 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3715 return None
3716 if useId:
3717 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3718 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3719 else:
3720 node1 = nodeName1
3721 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003722 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003723 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003724 graphDict[ node1 ] = { 'edges': {},
3725 'dpid': switches[ nodeName1 ][ 'dpid' ],
3726 'name': nodeName1,
3727 'ports': switches[ nodeName1 ][ 'ports' ],
3728 'swClass': switches[ nodeName1 ][ 'swClass' ],
3729 'pid': switches[ nodeName1 ][ 'pid' ],
3730 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003731 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003732 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003733 else:
3734 # Assert node2 is not connected to any current links of node1
3735 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003736 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003737 # Swap two nodes/ports
3738 nodeName1, nodeName2 = nodeName2, nodeName1
3739 port1, port2 = port2, port1
3740 return graphDict
3741 except KeyError:
3742 main.log.exception( self.name + ": KeyError exception found" )
3743 return None
3744 except AssertionError:
3745 main.log.exception( self.name + ": AssertionError exception found" )
3746 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003747 except pexpect.EOF:
3748 main.log.error( self.name + ": EOF exception found" )
3749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003750 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003751 except Exception:
3752 main.log.exception( self.name + ": Uncaught exception" )
3753 return None
3754
Devin Lima7cfdbd2017-09-29 15:02:22 -07003755 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003756 """
3757 updates the port address and status information for
3758 each port in mn"""
3759 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003760 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003761 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003762 self.handle.sendline( "" )
3763 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003764
Jon Hall7eb38402015-01-08 17:19:54 -08003765 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003766 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003767
Jon Hall7eb38402015-01-08 17:19:54 -08003768 self.handle.sendline( "" )
3769 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003770
Jon Hallb1290e82014-11-18 16:17:48 -05003771 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003772 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003773 main.log.error( self.name + ": TIMEOUT exception found" )
3774 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003775 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003776 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003777 main.log.error( self.name + ": EOF exception found" )
3778 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003779 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003780 except Exception:
3781 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003782 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003783
Jon Halld80cc142015-07-06 13:36:05 -07003784 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003785 """
3786 Add vlan tag to a host.
3787 Dependencies:
3788 This class depends on the "vlan" package
3789 $ sudo apt-get install vlan
3790 Configuration:
3791 Load the 8021q module into the kernel
3792 $sudo modprobe 8021q
3793
3794 To make this setup permanent:
3795 $ sudo su -c 'echo "8021q" >> /etc/modules'
3796 """
3797 if self.handle:
3798 try:
Jon Halld80cc142015-07-06 13:36:05 -07003799 # get the ip address of the host
3800 main.log.info( "Get the ip address of the host" )
3801 ipaddr = self.getIPAddress( host )
3802 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003803
Jon Halld80cc142015-07-06 13:36:05 -07003804 # remove IP from interface intf
3805 # Ex: h1 ifconfig h1-eth0 inet 0
3806 main.log.info( "Remove IP from interface " )
3807 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3808 self.handle.sendline( cmd2 )
3809 self.handle.expect( "mininet>" )
3810 response = self.handle.before
3811 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003812
Jon Halld80cc142015-07-06 13:36:05 -07003813 # create VLAN interface
3814 # Ex: h1 vconfig add h1-eth0 100
3815 main.log.info( "Create Vlan" )
3816 cmd3 = host + " vconfig add " + intf + " " + vlan
3817 self.handle.sendline( cmd3 )
3818 self.handle.expect( "mininet>" )
3819 response = self.handle.before
3820 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003821
Jon Halld80cc142015-07-06 13:36:05 -07003822 # assign the host's IP to the VLAN interface
3823 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3824 main.log.info( "Assign the host IP to the vlan interface" )
3825 vintf = intf + "." + vlan
3826 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3827 self.handle.sendline( cmd4 )
3828 self.handle.expect( "mininet>" )
3829 response = self.handle.before
3830 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003831
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003832 # update Mininet node variables
3833 main.log.info( "Update Mininet node variables" )
3834 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3835 self.handle.sendline( cmd5 )
3836 self.handle.expect( "mininet>" )
3837 response = self.handle.before
3838 main.log.info( "====> %s ", response )
3839
3840 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3841 self.handle.sendline( cmd6 )
3842 self.handle.expect( "mininet>" )
3843 response = self.handle.before
3844 main.log.info( "====> %s ", response )
3845
3846 return main.TRUE
3847 except pexpect.TIMEOUT:
3848 main.log.error( self.name + ": TIMEOUT exception found" )
3849 main.log.error( self.name + ": " + self.handle.before )
3850 main.cleanAndExit()
3851 except pexpect.EOF:
3852 main.log.error( self.name + ": EOF exception found" )
3853 main.log.error( self.name + ": " + self.handle.before )
3854 return main.FALSE
3855 except Exception:
3856 main.log.exception( self.name + ": Uncaught exception!" )
3857 return main.FALSE
3858
3859 def removeVLAN( self, host, intf ):
3860 """
3861 Remove vlan tag from a host.
3862 Dependencies:
3863 This class depends on the "vlan" package
3864 $ sudo apt-get install vlan
3865 Configuration:
3866 Load the 8021q module into the kernel
3867 $sudo modprobe 8021q
3868
3869 To make this setup permanent:
3870 $ sudo su -c 'echo "8021q" >> /etc/modules'
3871 """
3872 if self.handle:
3873 try:
3874 # get the ip address of the host
3875 main.log.info( "Get the ip address of the host" )
3876 ipaddr = self.getIPAddress( host )
3877
3878 # remove VLAN interface
3879 # Ex: h1 vconfig rem h1-eth0.100
3880 main.log.info( "Remove Vlan interface" )
3881 cmd2 = host + " vconfig rem " + intf
3882 self.handle.sendline( cmd2 )
3883 self.handle.expect( "mininet>" )
3884 response = self.handle.before
3885 main.log.info( "====> %s ", response )
3886
3887 # assign the host's IP to the original interface
3888 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3889 main.log.info( "Assign the host IP to the original interface" )
3890 original_intf = intf.split(".")[0]
3891 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3892 self.handle.sendline( cmd3 )
3893 self.handle.expect( "mininet>" )
3894 response = self.handle.before
3895 main.log.info( "====> %s ", response )
3896
3897 # update Mininet node variables
3898 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3899 self.handle.sendline( cmd4 )
3900 self.handle.expect( "mininet>" )
3901 response = self.handle.before
3902 main.log.info( "====> %s ", response )
3903
3904 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3905 self.handle.sendline( cmd5 )
3906 self.handle.expect( "mininet>" )
3907 response = self.handle.before
3908 main.log.info( "====> %s ", response )
3909
kaouthera3f13ca22015-05-05 15:01:41 -07003910 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003911 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003912 main.log.error( self.name + ": TIMEOUT exception found" )
3913 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003914 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003915 except pexpect.EOF:
3916 main.log.error( self.name + ": EOF exception found" )
3917 main.log.error( self.name + ": " + self.handle.before )
3918 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003919 except Exception:
3920 main.log.exception( self.name + ": Uncaught exception!" )
3921 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003922
Jon Hall892818c2015-10-20 17:58:34 -07003923 def createHostComponent( self, name ):
3924 """
3925 Creates a new mininet cli component with the same parameters as self.
3926 This new component is intended to be used to login to the hosts created
3927 by mininet.
3928
3929 Arguments:
3930 name - The string of the name of this component. The new component
3931 will be assigned to main.<name> .
3932 In addition, main.<name>.name = str( name )
3933 """
3934 try:
3935 # look to see if this component already exists
3936 getattr( main, name )
3937 except AttributeError:
3938 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003939 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3940 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003941 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003942 except pexpect.EOF:
3943 main.log.error( self.name + ": EOF exception found" )
3944 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003945 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003946 except Exception:
3947 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003948 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003949 else:
3950 # namespace is not clear!
3951 main.log.error( name + " component already exists!" )
3952 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003953 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003954
3955 def removeHostComponent( self, name ):
3956 """
3957 Remove host component
3958 Arguments:
3959 name - The string of the name of the component to delete.
3960 """
3961 try:
3962 # Get host component
3963 component = getattr( main, name )
3964 except AttributeError:
3965 main.log.error( "Component " + name + " does not exist." )
3966 return
3967 try:
3968 # Disconnect from component
3969 component.disconnect()
3970 # Delete component
3971 delattr( main, name )
3972 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003973 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003974 except pexpect.EOF:
3975 main.log.error( self.name + ": EOF exception found" )
3976 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003977 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003978 except Exception:
3979 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003980 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003981
3982 def startHostCli( self, host=None ):
3983 """
3984 Use the mininet m utility to connect to the host's cli
3985 """
3986 # These are fields that can be used by scapy packets. Initialized to None
3987 self.hostIp = None
3988 self.hostMac = None
3989 try:
3990 if not host:
3991 host = self.name
3992 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003993 self.handle.sendline( "cd" )
3994 self.handle.expect( self.hostPrompt )
3995 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003996 self.handle.expect( self.hostPrompt )
3997 return main.TRUE
3998 except pexpect.TIMEOUT:
3999 main.log.exception( self.name + ": Command timed out" )
4000 return main.FALSE
4001 except pexpect.EOF:
4002 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07004003 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07004004 except Exception:
4005 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004006 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07004007
YPZhang801d46d2016-08-08 13:26:28 -07004008 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004009 '''
4010
YPZhang801d46d2016-08-08 13:26:28 -07004011 Args:
4012 devicename: switch name
4013 intf: port name on switch
4014 status: up or down
4015
4016 Returns: boolean to show success change status
4017
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004018 '''
YPZhang801d46d2016-08-08 13:26:28 -07004019 if status == "down" or status == "up":
4020 try:
4021 cmd = devicename + " ifconfig " + intf + " " + status
4022 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004023 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07004024 return main.TRUE
4025 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004026 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07004027 return main.FALSE
4028 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004029 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07004030 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07004031 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004032 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07004033 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07004034 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004035 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004036 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07004037 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004038 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07004039 return main.FALSE
4040
4041
adminbae64d82013-08-01 10:50:15 -07004042if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07004043 sys.modules[ __name__ ] = MininetCliDriver()