blob: d69fbebcc0fc93f0d869c032556b54d68f483566 [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 ):
Jon Hall7eb38402015-01-08 17:19:54 -080048 """
49 MininetCliDriver is the basic driver which will handle
50 the Mininet functions"""
51 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070052 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070053 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080054 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070055 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080056 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070057 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070058 # TODO: Refactor driver to use these everywhere
59 self.mnPrompt = "mininet>"
60 self.hostPrompt = "~#"
61 self.bashPrompt = "\$"
62 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070063 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070064
Jon Hall7eb38402015-01-08 17:19:54 -080065 def connect( self, **connectargs ):
66 """
67 Here the main is the TestON instance after creating
68 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080069 try:
70 for key in connectargs:
71 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070072 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080073 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070074 for key in self.options:
75 if key == "home":
76 self.home = self.options[ 'home' ]
77 break
78 if self.home is None or self.home == "":
79 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070080
81 try:
Jon Hall892818c2015-10-20 17:58:34 -070082 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070083 self.ip_address = os.getenv( str( self.ip_address ) )
84 else:
85 main.log.info( self.name +
86 ": Trying to connect to " +
87 self.ip_address )
88
89 except KeyError:
90 main.log.info( "Invalid host name," +
91 " connecting to local host instead" )
92 self.ip_address = 'localhost'
93 except Exception as inst:
94 main.log.error( "Uncaught exception: " + str( inst ) )
95
kelvin-onlaba1484582015-02-02 15:46:20 -080096 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070097 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080098 self ).connect(
99 user_name=self.user_name,
100 ip_address=self.ip_address,
101 port=None,
102 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800103
kelvin-onlaba1484582015-02-02 15:46:20 -0800104 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800105 main.log.info( "Connection successful to the host " +
106 self.user_name +
107 "@" +
108 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800109 return main.TRUE
110 else:
111 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800112 self.user_name +
113 "@" +
114 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800115 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800116 return main.FALSE
117 except pexpect.EOF:
118 main.log.error( self.name + ": EOF exception found" )
119 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700120 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800121 except Exception:
122 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700123 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800124
kelvin-onlab10e8d392015-06-03 13:53:45 -0700125 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800126 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700127 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000128 Starts Mininet accepts a topology(.py) file and/or an optional
kelvin-onlabf512e942015-06-08 19:42:59 -0700129 argument, to start the mininet, as a parameter.
130 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700131 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700132 Options:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000133 topoFile = file path for topology file (.py)
kelvin-onlabf512e942015-06-08 19:42:59 -0700134 args = extra option added when starting the topology from the file
135 mnCmd = Mininet command use to start topology
136 Returns:
137 main.TRUE if the mininet starts successfully, main.FALSE
138 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800139 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700140 try:
141 if self.handle:
142 # make sure old networks are cleaned up
143 main.log.info( self.name +
144 ": Clearing any residual state or processes" )
145 self.handle.sendline( "sudo mn -c" )
146 i = self.handle.expect( [ 'password\sfor\s',
147 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800148 pexpect.EOF,
149 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700150 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800151 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700152 # Sudo asking for password
153 main.log.info( self.name + ": Sending sudo password" )
154 self.handle.sendline( self.pwd )
155 i = self.handle.expect( [ '%s:' % self.user,
Devin Limdc78e202017-06-09 18:30:07 -0700156 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700157 pexpect.EOF,
158 pexpect.TIMEOUT ],
159 timeout )
160 if i == 1:
161 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700162 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700163 main.log.error( self.name + ": Connection terminated" )
164 elif i == 3: # timeout
165 main.log.error( self.name + ": Something while cleaning " +
166 "Mininet took too long... " )
167 # Craft the string to start mininet
168 cmdString = "sudo "
169 if not mnCmd:
170 if topoFile is None or topoFile == '': # If no file is given
171 main.log.info( self.name + ": building fresh Mininet" )
172 cmdString += "mn "
173 if args is None or args == '':
174 # If no args given, use args from .topo file
175 args = self.options[ 'arg1' ] +\
176 " " + self.options[ 'arg2' ] +\
177 " --mac --controller " +\
178 self.options[ 'controller' ] + " " +\
179 self.options[ 'arg3' ]
180 else: # else only use given args
181 pass
182 # TODO: allow use of topo args and method args?
183 else: # Use given topology file
184 main.log.info(
185 "Starting Mininet from topo file " +
186 topoFile )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000187 cmdString += "-E python " + topoFile + " "
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700188 if args is None:
189 args = ''
190 # TODO: allow use of args from .topo file?
191 cmdString += args
192 else:
193 main.log.info( "Starting Mininet topology using '" + mnCmd +
194 "' command" )
195 cmdString += mnCmd
196 # Send the command and check if network started
197 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700198 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700199 main.log.info( "Sending '" + cmdString + "' to " + self.name )
200 self.handle.sendline( cmdString )
Devin Lima7cfdbd2017-09-29 15:02:22 -0700201 startTime = time.time()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700202 while True:
203 i = self.handle.expect( [ 'mininet>',
204 'Exception',
205 '\*\*\*',
206 pexpect.EOF,
207 pexpect.TIMEOUT ],
208 timeout )
209 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -0700210 main.log.info( self.name + ": Mininet built\nTime Took : " + str( time.time() - startTime ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700211 return main.TRUE
212 elif i == 1:
213 response = str( self.handle.before +
214 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700215 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700216 response += str( self.handle.before +
217 self.handle.after )
218 main.log.error(
219 self.name +
220 ": Launching Mininet failed: " + response )
221 return main.FALSE
222 elif i == 2:
223 self.handle.expect( [ "\n",
224 pexpect.EOF,
225 pexpect.TIMEOUT ],
226 timeout )
227 main.log.info( self.handle.before )
228 elif i == 3:
229 main.log.error( self.name + ": Connection timeout" )
230 return main.FALSE
231 elif i == 4: # timeout
232 main.log.error(
233 self.name +
234 ": Something took too long... " )
235 return main.FALSE
236 # Why did we hit this part?
237 main.log.error( "startNet did not return correctly" )
238 return main.FASLE
239 else: # if no handle
240 main.log.error( self.name + ": Connection failed to the host " +
241 self.user_name + "@" + self.ip_address )
242 main.log.error( self.name + ": Failed to connect to the Mininet" )
243 return main.FALSE
244 except pexpect.TIMEOUT:
245 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
246 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700247 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700248 except pexpect.EOF:
249 main.log.error( self.name + ": EOF exception found" )
250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700251 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700252 except Exception:
253 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700254 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800255
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800256 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700257 try:
258 if topoType == 'tree':
259 # In tree topology, if fanout arg is not given, by default it is 2
260 if fanout is None:
261 fanout = 2
262 k = 0
263 count = 0
264 while( k <= depth - 1 ):
265 count = count + pow( fanout, k )
266 k = k + 1
267 numSwitches = count
268 while( k <= depth - 2 ):
269 # depth-2 gives you only core links and not considering
270 # edge links as seen by ONOS. If all the links including
271 # edge links are required, do depth-1
272 count = count + pow( fanout, k )
273 k = k + 1
274 numLinks = count * fanout
275 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
276 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800277
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700278 elif topoType == 'linear':
279 # In linear topology, if fanout or numHostsPerSw is not given,
280 # by default it is 1
281 if fanout is None:
282 fanout = 1
283 numSwitches = depth
284 numHostsPerSw = fanout
285 totalNumHosts = numSwitches * numHostsPerSw
286 numLinks = totalNumHosts + ( numSwitches - 1 )
287 print "num_switches for %s(%d,%d) = %d and links=%d" %\
288 ( topoType, depth, fanout, numSwitches, numLinks )
289 topoDict = { "num_switches": int( numSwitches ),
290 "num_corelinks": int( numLinks ) }
291 return topoDict
292 except Exception:
293 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700294 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400295
kelvin-onlabd3b64892015-01-20 13:26:24 -0800296 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700297 """
298 Calculate the number of switches and links in a topo."""
299 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700300 try:
301 argList = self.options[ 'arg1' ].split( "," )
302 topoArgList = argList[ 0 ].split( " " )
303 argList = map( int, argList[ 1: ] )
304 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700305
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700306 topoDict = self.numSwitchesNlinks( *topoArgList )
307 return topoDict
308 except Exception:
309 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700310 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400311
GlennRCf07c44a2015-09-18 13:33:46 -0700312 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800313 """
314 Verifies the reachability of the hosts using pingall command.
315 Optional parameter timeout allows you to specify how long to
316 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700317 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700318 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700319 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700320 ping
321 acceptableFailed - Set the number of acceptable failed pings for the
322 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800323 Returns:
324 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700325 otherwise main.FALSE
326 """
327 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700328 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700329 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700330 if self.handle:
331 main.log.info(
332 self.name +
333 ": Checking reachabilty to the hosts using pingall" )
334 response = ""
335 failedPings = 0
336 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700337 cmd = "pingall"
338 if protocol == "IPv6":
339 cmd = "py net.pingAll6()"
340 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700341 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700342 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700343 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700344 pexpect.EOF,
345 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700346 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700347 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700348 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700349 response += self.handle.before
350 break
351 elif i == 1:
352 response += self.handle.before + self.handle.after
353 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700354 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700355 returnValue = main.FALSE
356 if shortCircuit:
357 main.log.error( self.name +
358 ": Aborting pingall - "
359 + str( failedPings ) +
360 " pings failed" )
361 break
Jon Hall390696c2015-05-05 17:13:41 -0700362 if ( time.time() - startTime ) > timeout:
363 returnValue = main.FALSE
364 main.log.error( self.name +
365 ": Aborting pingall - " +
366 "Function took too long " )
367 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700368 elif i == 2:
369 main.log.error( self.name +
370 ": EOF exception found" )
371 main.log.error( self.name + ": " +
372 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700373 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700374 elif i == 3:
375 response += self.handle.before
376 main.log.error( self.name +
377 ": TIMEOUT exception found" )
378 main.log.error( self.name +
379 ": " +
380 str( response ) )
381 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800382 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700383 self.handle.expect( "Interrupt" )
384 self.handle.expect( "mininet>" )
385 break
386 pattern = "Results\:"
387 main.log.info( "Pingall output: " + str( response ) )
388 if re.search( pattern, response ):
389 main.log.info( self.name + ": Pingall finished with "
390 + str( failedPings ) + " failed pings" )
391 return returnValue
392 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700393 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800394 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700395 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700396 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700397 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700398 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700399 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700400 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700401 except pexpect.TIMEOUT:
402 if response:
403 main.log.info( "Pingall output: " + str( response ) )
404 main.log.error( self.name + ": pexpect.TIMEOUT found" )
405 return main.FALSE
406 except pexpect.EOF:
407 main.log.error( self.name + ": EOF exception found" )
408 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700409 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700410
Jon Hall7eb38402015-01-08 17:19:54 -0800411 def fpingHost( self, **pingParams ):
412 """
413 Uses the fping package for faster pinging...
414 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700415 try:
416 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
417 command = args[ "SRC" ] + \
418 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
419 self.handle.sendline( command )
420 self.handle.expect(
421 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
422 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
423 response = self.handle.before
424 if re.search( ":\s-", response ):
425 main.log.info( self.name + ": Ping fail" )
426 return main.FALSE
427 elif re.search( ":\s\d{1,2}\.\d\d", response ):
428 main.log.info( self.name + ": Ping good!" )
429 return main.TRUE
430 main.log.info( self.name + ": Install fping on mininet machine... " )
431 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700432 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700433 except Exception:
434 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700435 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700436
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000437
Jon Hall3b489db2015-10-05 14:38:37 -0700438 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400439 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700440 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700441
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400442 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700443 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700444
445 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400446 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700447
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400448 Returns main.FALSE if one or more of hosts specified
449 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700450 wait = int( wait )
451 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400452
453 try:
454 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700455
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400456 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700457 pingResponse = "IPv4 ping across specified hosts\n"
458 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400459 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700460 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400461 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700462 pingList = hostList[ :listIndex ] + \
463 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700464
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000465 pingResponse += str(str(host) + " -> ")
GlennRCd10d3cc2015-09-24 12:47:16 -0700466
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400467 for temp in pingList:
468 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700469 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700470 self.handle.sendline( pingCmd )
471 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400472 response = self.handle.before
473 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000474 pingResponse += str(" h" + str( temp[1:] ))
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400475 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700476 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400477 # One of the host to host pair is unreachable
478 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700479 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700480 pingResponse += "\n"
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000481 main.log.info( pingResponse + "Failed pings: " + str(failedPings) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700482 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700483 except pexpect.TIMEOUT:
484 main.log.exception( self.name + ": TIMEOUT exception" )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700485 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400486 except pexpect.EOF:
487 main.log.error( self.name + ": EOF exception found" )
488 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700489 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700490 except Exception:
491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400493
Jon Hall3b489db2015-10-05 14:38:37 -0700494 def pingIpv6Hosts( self, hostList, prefix='1000::', wait=1 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700495 """
Jon Hall3b489db2015-10-05 14:38:37 -0700496 IPv6 ping all hosts in hostList. If no prefix passed this will use
497 default prefix of 1000::
Hari Krishna9592fc82015-07-31 15:11:15 -0700498
Jon Hall3b489db2015-10-05 14:38:37 -0700499 Returns main.TRUE if all hosts specified can reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700500
Jon Hall3b489db2015-10-05 14:38:37 -0700501 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700502 """
503 try:
504 main.log.info( "Testing reachability between specified IPv6 hosts" )
505 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700506 wait = int( wait )
507 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700508 pingResponse = "IPv6 Pingall output:\n"
509 failedPings = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700510 for host in hostList:
511 listIndex = hostList.index( host )
512 # List of hosts to ping other than itself
513 pingList = hostList[ :listIndex ] + \
514 hostList[ ( listIndex + 1 ): ]
515
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000516 pingResponse += str(str(host) + " -> ")
GlennRC2cf7d952015-09-11 16:32:13 -0700517
Hari Krishna9592fc82015-07-31 15:11:15 -0700518 for temp in pingList:
519 # Current host pings all other hosts specified
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000520 pingCmd = str( host ) + cmd + str( self.getIPAddress(temp,proto='IPv6') )
Jon Hall934576d2015-10-09 10:12:22 -0700521 self.handle.sendline( pingCmd )
522 self.handle.expect( "mininet>", timeout=wait + 1 )
Hari Krishna9592fc82015-07-31 15:11:15 -0700523 response = self.handle.before
524 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000525 pingResponse += str(" h" + str( temp[1:] ))
Hari Krishna9592fc82015-07-31 15:11:15 -0700526 else:
GlennRC2cf7d952015-09-11 16:32:13 -0700527 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700528 # One of the host to host pair is unreachable
529 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700530 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700531 pingResponse += "\n"
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000532 main.log.info( pingResponse + "Failed pings: " + str(failedPings) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700533 return isReachable
534
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700535 except pexpect.TIMEOUT:
536 main.log.exception( self.name + ": TIMEOUT exception" )
537 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700538 except pexpect.EOF:
539 main.log.error( self.name + ": EOF exception found" )
540 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700541 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700542 except Exception:
543 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700544 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700545
Jon Hall7eb38402015-01-08 17:19:54 -0800546 def pingHost( self, **pingParams ):
547 """
Jon Hall3b489db2015-10-05 14:38:37 -0700548 Ping from one mininet host to another
549 Currently the only supported Params: SRC, TARGET, and WAIT
550 """
551 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000552 wait = args['WAIT']
Jon Hall3b489db2015-10-05 14:38:37 -0700553 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800554 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700555 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700556 try:
Jon Hall61282e32015-03-19 11:34:11 -0700557 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800558 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700559 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
560 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700561 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800562 main.log.error(
563 self.name +
564 ": timeout when waiting for response from mininet" )
565 main.log.error( "response: " + str( self.handle.before ) )
566 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700567 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800568 main.log.error(
569 self.name +
570 ": timeout when waiting for response from mininet" )
571 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700572 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700573 if re.search( ',\s0\%\spacket\sloss', response ):
574 main.log.info( self.name + ": no packets lost, host is reachable" )
575 return main.TRUE
576 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800577 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700578 self.name +
579 ": PACKET LOST, HOST IS NOT REACHABLE" )
580 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800581 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800582 main.log.error( self.name + ": EOF exception found" )
583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700584 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700585 except Exception:
586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700587 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700588
589 def ping6pair( self, **pingParams ):
590 """
GlennRC2cf7d952015-09-11 16:32:13 -0700591 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700592 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000593 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700594 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
595 """
Jon Hall3b489db2015-10-05 14:38:37 -0700596 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000597 wait = args['WAIT']
Jon Hall3b489db2015-10-05 14:38:37 -0700598 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530599 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700600 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700601 try:
602 main.log.info( "Sending: " + command )
603 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700604 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
605 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700606 if i == 1:
607 main.log.error(
608 self.name +
609 ": timeout when waiting for response from mininet" )
610 main.log.error( "response: " + str( self.handle.before ) )
611 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
612 if i == 1:
613 main.log.error(
614 self.name +
615 ": timeout when waiting for response from mininet" )
616 main.log.error( "response: " + str( self.handle.before ) )
617 response = self.handle.before
618 main.log.info( self.name + ": Ping Response: " + response )
619 if re.search( ',\s0\%\spacket\sloss', response ):
620 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700621 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700622 else:
alisone4121a92016-11-22 16:31:36 -0800623 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700624 self.name +
625 ": PACKET LOST, HOST IS NOT REACHABLE" )
626 return main.FALSE
627
628 except pexpect.EOF:
629 main.log.error( self.name + ": EOF exception found" )
630 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700631 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700632 except Exception:
633 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700634 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800635
You Wangdb927a52016-02-26 11:03:28 -0800636 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
637 """
638 Description:
639 Ping a set of destination host from host CLI.
640 Logging into a Mininet host CLI is required before calling this funtion.
641 Params:
642 dstIPList is a list of destination ip addresses
643 Returns:
644 main.TRUE if the destination host is reachable
645 main.FALSE otherwise
646 """
647 isReachable = main.TRUE
648 wait = int( wait )
649 cmd = "ping"
650 if IPv6:
651 cmd = cmd + "6"
652 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
653 try:
654 for dstIP in dstIPList:
655 pingCmd = cmd + " " + dstIP
656 self.handle.sendline( pingCmd )
657 i = self.handle.expect( [ self.hostPrompt,
658 '\*\*\* Unknown command: ' + pingCmd,
659 pexpect.TIMEOUT ],
660 timeout=wait + 1 )
661 if i == 0:
662 response = self.handle.before
663 if not re.search( ',\s0\%\spacket\sloss', response ):
664 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
665 isReachable = main.FALSE
666 elif i == 1:
667 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700668 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800669 elif i == 2:
670 main.log.error( self.name + ": timeout when waiting for response" )
671 isReachable = main.FALSE
672 else:
673 main.log.error( self.name + ": unknown response: " + self.handle.before )
674 isReachable = main.FALSE
675 except pexpect.TIMEOUT:
676 main.log.exception( self.name + ": TIMEOUT exception" )
677 isReachable = main.FALSE
678 except pexpect.EOF:
679 main.log.error( self.name + ": EOF exception found" )
680 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700681 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800682 except Exception:
683 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700684 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800685 return isReachable
686
Jon Hall7eb38402015-01-08 17:19:54 -0800687 def checkIP( self, host ):
688 """
689 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700690 try:
691 if self.handle:
692 try:
693 response = self.execute(
694 cmd=host +
695 " ifconfig",
696 prompt="mininet>",
697 timeout=10 )
698 except pexpect.EOF:
699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700701 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700702
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700703 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
704 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
705 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
706 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
707 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
708 "[0-9]|25[0-5]|[0-9]{1,2})"
709 # pattern = "inet addr:10.0.0.6"
710 if re.search( pattern, response ):
711 main.log.info( self.name + ": Host Ip configured properly" )
712 return main.TRUE
713 else:
714 main.log.error( self.name + ": Host IP not found" )
715 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700716 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700717 main.log.error( self.name + ": Connection failed to the host" )
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700720 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800721
Jon Hall7eb38402015-01-08 17:19:54 -0800722 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800723 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700724 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800725 response = self.execute(
726 cmd="h1 /usr/sbin/sshd -D&",
727 prompt="mininet>",
728 timeout=10 )
729 response = self.execute(
730 cmd="h4 /usr/sbin/sshd -D&",
731 prompt="mininet>",
732 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700733 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800734 vars( self )[ key ] = connectargs[ key ]
735 response = self.execute(
736 cmd="xterm h1 h4 ",
737 prompt="mininet>",
738 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800739 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.error( self.name + ": EOF exception found" )
741 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700742 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700743 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800744 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700745 if self.flag == 0:
746 self.flag = 1
747 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800748 else:
adminbae64d82013-08-01 10:50:15 -0700749 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800750
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700751 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700752 """
753 Moves a host from one switch to another on the fly
754 Note: The intf between host and oldSw when detached
755 using detach(), will still show up in the 'net'
756 cmd, because switch.detach() doesn't affect switch.intfs[]
757 ( which is correct behavior since the interfaces
758 haven't moved ).
759 """
760 if self.handle:
761 try:
762 # Bring link between oldSw-host down
763 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
764 "'," + "'down')"
765 print "cmd1= ", cmd
766 response = self.execute( cmd=cmd,
767 prompt="mininet>",
768 timeout=10 )
769
770 # Determine hostintf and Oldswitchintf
771 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
772 ")[0]"
773 print "cmd2= ", cmd
774 self.handle.sendline( cmd )
775 self.handle.expect( "mininet>" )
776
777 # Determine ip and mac address of the host-oldSw interface
778 cmd = "px ipaddr = hintf.IP()"
779 print "cmd3= ", cmd
780 self.handle.sendline( cmd )
781 self.handle.expect( "mininet>" )
782
783 cmd = "px macaddr = hintf.MAC()"
784 print "cmd3= ", cmd
785 self.handle.sendline( cmd )
786 self.handle.expect( "mininet>" )
787
788 # Detach interface between oldSw-host
789 cmd = "px " + oldSw + ".detach( sintf )"
790 print "cmd4= ", cmd
791 self.handle.sendline( cmd )
792 self.handle.expect( "mininet>" )
793
794 # Add link between host-newSw
795 cmd = "py net.addLink(" + host + "," + newSw + ")"
796 print "cmd5= ", cmd
797 self.handle.sendline( cmd )
798 self.handle.expect( "mininet>" )
799
800 # Determine hostintf and Newswitchintf
801 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
802 ")[0]"
803 print "cmd6= ", cmd
804 self.handle.sendline( cmd )
805 self.handle.expect( "mininet>" )
806
807 # Attach interface between newSw-host
808 cmd = "px " + newSw + ".attach( sintf )"
809 print "cmd3= ", cmd
810 self.handle.sendline( cmd )
811 self.handle.expect( "mininet>" )
812
813 # Set ipaddress of the host-newSw interface
814 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
815 print "cmd7 = ", cmd
816 self.handle.sendline( cmd )
817 self.handle.expect( "mininet>" )
818
819 # Set macaddress of the host-newSw interface
820 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
821 print "cmd8 = ", cmd
822 self.handle.sendline( cmd )
823 self.handle.expect( "mininet>" )
824
825 cmd = "net"
826 print "cmd9 = ", cmd
827 self.handle.sendline( cmd )
828 self.handle.expect( "mininet>" )
829 print "output = ", self.handle.before
830
831 # Determine ipaddress of the host-newSw interface
832 cmd = host + " ifconfig"
833 print "cmd10= ", cmd
834 self.handle.sendline( cmd )
835 self.handle.expect( "mininet>" )
836 print "ifconfig o/p = ", self.handle.before
837
838 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700839
840 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000841 main.log.error(self.name + ": TIMEOUT exception found")
842 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -0700843 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700844 except pexpect.EOF:
845 main.log.error( self.name + ": EOF exception found" )
846 main.log.error( self.name + ": " + self.handle.before )
847 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700848 except Exception:
849 main.log.exception( self.name + ": Uncaught exception!" )
850 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700851
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700852 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800853 """
854 Moves a host from one switch to another on the fly
855 Note: The intf between host and oldSw when detached
856 using detach(), will still show up in the 'net'
857 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700858 ( which is correct behavior since the interfaces
859 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800860 """
861 if self.handle:
862 try:
Jon Hall439c8912016-04-15 02:22:03 -0700863 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800864 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700865 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800866 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800867 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800868 response = self.execute( cmd=cmd,
869 prompt="mininet>",
870 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700871
kelvin-onlaba1484582015-02-02 15:46:20 -0800872 # Determine hostintf and Oldswitchintf
873 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800874 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800875 print "cmd2= ", cmd
876 self.handle.sendline( cmd )
877 self.handle.expect( "mininet>" )
878
shahshreya73537862015-02-11 15:15:24 -0800879 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000880 cmd = "px ipaddr = " + str(IP)
kelvin-onlaba1484582015-02-02 15:46:20 -0800881 print "cmd3= ", cmd
882 self.handle.sendline( cmd )
883 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800884
885 cmd = "px macaddr = hintf.MAC()"
886 print "cmd3= ", cmd
887 self.handle.sendline( cmd )
888 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700889
kelvin-onlaba1484582015-02-02 15:46:20 -0800890 # Detach interface between oldSw-host
891 cmd = "px " + oldSw + ".detach( sintf )"
892 print "cmd4= ", cmd
893 self.handle.sendline( cmd )
894 self.handle.expect( "mininet>" )
895
896 # Add link between host-newSw
897 cmd = "py net.addLink(" + host + "," + newSw + ")"
898 print "cmd5= ", cmd
899 self.handle.sendline( cmd )
900 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700901
kelvin-onlaba1484582015-02-02 15:46:20 -0800902 # Determine hostintf and Newswitchintf
903 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800904 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800905 print "cmd6= ", cmd
906 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700907 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800908
909 # Attach interface between newSw-host
910 cmd = "px " + newSw + ".attach( sintf )"
Jon Hall439c8912016-04-15 02:22:03 -0700911 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800912 self.handle.sendline( cmd )
913 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800914
915 # Set macaddress of the host-newSw interface
916 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700917 print "cmd7 = ", cmd
918 self.handle.sendline( cmd )
919 self.handle.expect( "mininet>" )
920
921 # Set ipaddress of the host-newSw interface
922 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800923 print "cmd8 = ", cmd
924 self.handle.sendline( cmd )
925 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700926
Jon Hall439c8912016-04-15 02:22:03 -0700927 cmd = host + " ifconfig"
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000928 print "cmd9 =",cmd
929 response = self.execute( cmd = cmd, prompt="mininet>" ,timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -0700930 print response
931 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700932 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000933 print ipAddressSearch.group(1)
934 intf= host + "-eth" + str(ipAddressSearch.group(1))
Jon Hall439c8912016-04-15 02:22:03 -0700935 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
936 print "cmd10 = ", cmd
937 self.handle.sendline( cmd )
938 self.handle.expect( "mininet>" )
939
kelvin-onlaba1484582015-02-02 15:46:20 -0800940 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700941 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800942 self.handle.sendline( cmd )
943 self.handle.expect( "mininet>" )
944 print "output = ", self.handle.before
945
946 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800947 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700948 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800949 self.handle.sendline( cmd )
950 self.handle.expect( "mininet>" )
951 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700952
kelvin-onlaba1484582015-02-02 15:46:20 -0800953 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700954 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000955 main.log.error(self.name + ": TIMEOUT exception found")
956 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -0700957 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800958 except pexpect.EOF:
959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
961 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700962 except Exception:
963 main.log.exception( self.name + ": Uncaught exception!" )
964 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800965
Jon Hall7eb38402015-01-08 17:19:54 -0800966 def changeIP( self, host, intf, newIP, newNetmask ):
967 """
968 Changes the ip address of a host on the fly
969 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800970 if self.handle:
971 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800972 cmd = host + " ifconfig " + intf + " " + \
973 newIP + " " + 'netmask' + " " + newNetmask
974 self.handle.sendline( cmd )
975 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800976 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800977 main.log.info( "response = " + response )
978 main.log.info(
979 "Ip of host " +
980 host +
981 " changed to new IP " +
982 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800983 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700984 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000985 main.log.error(self.name + ": TIMEOUT exception found")
986 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -0700987 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800988 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800989 main.log.error( self.name + ": EOF exception found" )
990 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800991 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700992 except Exception:
993 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700994 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -0800995
Jon Hall7eb38402015-01-08 17:19:54 -0800996 def changeDefaultGateway( self, host, newGW ):
997 """
998 Changes the default gateway of a host
999 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001000 if self.handle:
1001 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001002 cmd = host + " route add default gw " + newGW
1003 self.handle.sendline( cmd )
1004 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001005 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001006 main.log.info( "response = " + response )
1007 main.log.info(
1008 "Default gateway of host " +
1009 host +
1010 " changed to " +
1011 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001012 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001013 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001014 main.log.error(self.name + ": TIMEOUT exception found")
1015 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001016 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001017 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001018 main.log.error( self.name + ": EOF exception found" )
1019 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001020 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001021 except Exception:
1022 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001023 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001024
Jon Hall7eb38402015-01-08 17:19:54 -08001025 def addStaticMACAddress( self, host, GW, macaddr ):
1026 """
Jon Hallefbd9792015-03-05 16:11:36 -08001027 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001028 if self.handle:
1029 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001030 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1031 cmd = host + " arp -s " + GW + " " + macaddr
1032 self.handle.sendline( cmd )
1033 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001034 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001035 main.log.info( "response = " + response )
1036 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001037 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001038 GW +
1039 " changed to " +
1040 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001041 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001042 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001043 main.log.error(self.name + ": TIMEOUT exception found")
1044 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001045 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001046 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001047 main.log.error( self.name + ": EOF exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001049 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001050 except Exception:
1051 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001052 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001053
Jon Hall7eb38402015-01-08 17:19:54 -08001054 def verifyStaticGWandMAC( self, host ):
1055 """
1056 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001057 if self.handle:
1058 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001059 # h1 arp -an
1060 cmd = host + " arp -an "
1061 self.handle.sendline( cmd )
1062 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001063 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001064 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001065 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001066 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001067 main.log.error(self.name + ": TIMEOUT exception found")
1068 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001069 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001070 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001073 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001074 except Exception:
1075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001077
Jon Hall7eb38402015-01-08 17:19:54 -08001078 def getMacAddress( self, host ):
1079 """
1080 Verifies the host's ip configured or not."""
1081 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001082 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001083 response = self.execute(
1084 cmd=host +
1085 " ifconfig",
1086 prompt="mininet>",
1087 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001088 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001089 main.log.error( self.name + ": EOF exception found" )
1090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001091 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001092 except Exception:
1093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001094 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001095
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001096 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001097 macAddressSearch = re.search( pattern, response, re.I )
1098 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001099 main.log.info(
1100 self.name +
1101 ": Mac-Address of Host " +
1102 host +
1103 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 macAddress )
1105 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001106 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001107 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001108
Jon Hall7eb38402015-01-08 17:19:54 -08001109 def getInterfaceMACAddress( self, host, interface ):
1110 """
1111 Return the IP address of the interface on the given host"""
1112 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001113 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001114 response = self.execute( cmd=host + " ifconfig " + interface,
1115 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001116 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 main.log.error( self.name + ": EOF exception found" )
1118 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001119 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001120 except Exception:
1121 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001122 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001123
1124 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 macAddressSearch = re.search( pattern, response, re.I )
1126 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001127 main.log.info( "No mac address found in %s" % response )
1128 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001130 main.log.info(
1131 "Mac-Address of " +
1132 host +
1133 ":" +
1134 interface +
1135 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 macAddress )
1137 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001138 else:
1139 main.log.error( "Connection failed to the host" )
1140
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001141 def getIPAddress( self, host , proto='IPV4'):
Jon Hall7eb38402015-01-08 17:19:54 -08001142 """
1143 Verifies the host's ip configured or not."""
1144 if self.handle:
1145 try:
1146 response = self.execute(
1147 cmd=host +
1148 " ifconfig",
1149 prompt="mininet>",
1150 timeout=10 )
1151 except pexpect.EOF:
1152 main.log.error( self.name + ": EOF exception found" )
1153 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001154 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001155 except Exception:
1156 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001157 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001158
sathishmad953462015-12-03 17:42:07 +05301159 pattern = ''
1160 if proto == 'IPV4':
1161 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1162 else:
Jon Hall439c8912016-04-15 02:22:03 -07001163 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001165 main.log.info(
1166 self.name +
1167 ": IP-Address of Host " +
1168 host +
1169 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 ipAddressSearch.group( 1 ) )
1171 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001172 else:
1173 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001174
Jon Hall7eb38402015-01-08 17:19:54 -08001175 def getSwitchDPID( self, switch ):
1176 """
1177 return the datapath ID of the switch"""
1178 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001179 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001180 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 response = self.execute(
1182 cmd=cmd,
1183 prompt="mininet>",
1184 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001185 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001188 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001189 except Exception:
1190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001191 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001192 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001193 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001194 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001195 main.log.info(
1196 "Couldn't find DPID for switch %s, found: %s" %
1197 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001198 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001199 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001200 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001201 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001202
Jon Hall7eb38402015-01-08 17:19:54 -08001203 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001204 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001205 self.handle.sendline( "" )
1206 self.expect( "mininet>" )
1207 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001208 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001209 response = self.execute(
1210 cmd=cmd,
1211 prompt="mininet>",
1212 timeout=10 )
1213 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001214 response = self.handle.before
1215 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001216 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001217 main.log.error(self.name + ": TIMEOUT exception found")
1218 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001219 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001220 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001221 main.log.error( self.name + ": EOF exception found" )
1222 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001223 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001224 except Exception:
1225 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001226 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001227
Jon Hall7eb38402015-01-08 17:19:54 -08001228 def getInterfaces( self, node ):
1229 """
1230 return information dict about interfaces connected to the node"""
1231 if self.handle:
1232 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001233 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001234 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001235 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 response = self.execute(
1237 cmd=cmd,
1238 prompt="mininet>",
1239 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001240 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 main.log.error( self.name + ": EOF exception found" )
1242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001243 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001244 except Exception:
1245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001246 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001247 return response
1248 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001250
Jon Hall7eb38402015-01-08 17:19:54 -08001251 def dump( self ):
1252 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001253 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001254 response = self.execute(
1255 cmd='dump',
1256 prompt='mininet>',
1257 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001258 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001261 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001262 except Exception:
1263 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001264 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001265 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001266
Jon Hall7eb38402015-01-08 17:19:54 -08001267 def intfs( self ):
1268 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001269 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001270 response = self.execute(
1271 cmd='intfs',
1272 prompt='mininet>',
1273 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001274 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001275 main.log.error( self.name + ": EOF exception found" )
1276 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001277 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001278 except Exception:
1279 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001280 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001281 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001282
Jon Hall7eb38402015-01-08 17:19:54 -08001283 def net( self ):
1284 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001285 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001286 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001287 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001288 main.log.error( self.name + ": EOF exception found" )
1289 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001290 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001291 except Exception:
1292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001293 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001294 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001295
Devin Lima7cfdbd2017-09-29 15:02:22 -07001296 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001297 main.log.info( self.name + ": List network links" )
1298 try:
1299 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001300 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001301 except pexpect.EOF:
1302 main.log.error( self.name + ": EOF exception found" )
1303 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001304 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001305 except Exception:
1306 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001307 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001308 return response
1309
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001310 def iperftcpAll(self, hosts, timeout=6):
1311 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001312 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001313
kelvin-onlab7cce9382015-07-17 10:21:03 -07001314 @parm:
1315 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1316 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001317 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001318 try:
1319 for host1 in hosts:
1320 for host2 in hosts:
1321 if host1 != host2:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001322 if self.iperftcp(host1, host2, timeout) == main.FALSE:
1323 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001324 except Exception:
1325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001326 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001327
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001328 def iperftcp(self, host1="h1", host2="h2", timeout=6):
1329 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001330 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1331 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001332
kelvin-onlab7cce9382015-07-17 10:21:03 -07001333 @parm:
1334 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1335 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001336 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001337 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1338 try:
1339 # Setup the mininet command
1340 cmd1 = 'iperf ' + host1 + " " + host2
1341 self.handle.sendline( cmd1 )
1342 outcome = self.handle.expect( "mininet>", timeout )
1343 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001344
kelvin-onlab7cce9382015-07-17 10:21:03 -07001345 # checks if there are results in the mininet response
1346 if "Results:" in response:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001347 main.log.report(self.name + ": iperf test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001348 # parse the mn results
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001349 response = response.split("\r\n")
1350 response = response[len(response)-2]
1351 response = response.split(": ")
1352 response = response[len(response)-1]
1353 response = response.replace("[", "")
1354 response = response.replace("]", "")
1355 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001356
kelvin-onlab7cce9382015-07-17 10:21:03 -07001357 # this is the bandwith two and from the two hosts
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001358 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001359
kelvin-onlab7cce9382015-07-17 10:21:03 -07001360 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001361 # ['host1 to host2', 'host2 to host1"]
1362 if len(bandwidth) == 2:
1363 main.log.report(self.name + ": iperf test successful")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001364 return main.TRUE
1365 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001366 main.log.error(self.name + ": invalid iperf results")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001367 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001368 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001369 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001370 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001371 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001372 main.log.error( self.name + ": TIMEOUT exception found" )
1373 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001374 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001375 # NOTE: Send ctrl-c to make sure iperf is done
1376 self.handle.sendline( "\x03" )
1377 self.handle.expect( "Interrupt" )
1378 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001379 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001380 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 main.log.error( self.name + ": EOF exception found" )
1382 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001383 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001384 except Exception:
1385 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001386 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001387
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001388 def iperftcpipv6(self, host1="h1", host2="h2", timeout=50):
Jon Hall439c8912016-04-15 02:22:03 -07001389 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1390 try:
1391 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001392 cmd1 = host1 +' iperf -V -sD -B '+ str(IP1)
Jon Hall439c8912016-04-15 02:22:03 -07001393 self.handle.sendline( cmd1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001394 outcome1 = self.handle.expect( "mininet>")
1395 cmd2 = host2 +' iperf -V -c '+ str(IP1) +' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001396 self.handle.sendline( cmd2 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001397 outcome2 = self.handle.expect( "mininet>")
Jon Hall439c8912016-04-15 02:22:03 -07001398 response1 = self.handle.before
1399 response2 = self.handle.after
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001400 print response1,response2
1401 pattern = "connected with "+ str(IP1)
Jon Hall439c8912016-04-15 02:22:03 -07001402 if pattern in response1:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001403 main.log.report(self.name + ": iperf test completed")
Jon Hall439c8912016-04-15 02:22:03 -07001404 return main.TRUE
1405 else:
1406 main.log.error( self.name + ": iperf test failed" )
1407 return main.FALSE
1408 except pexpect.TIMEOUT:
1409 main.log.error( self.name + ": TIMEOUT exception found" )
1410 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1411 self.handle.sendline( "\x03" )
1412 self.handle.expect( "Interrupt" )
1413 self.handle.expect( "mininet>" )
1414 return main.FALSE
1415 except pexpect.EOF:
1416 main.log.error( self.name + ": EOF exception found" )
1417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001418 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001419 except Exception:
1420 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001421 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001422
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001423 def iperfudpAll(self, hosts, bandwidth="10M"):
1424 '''
GlennRC61321f22015-07-16 13:36:54 -07001425 Runs the iperfudp function with a given set of hosts and specified
1426 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001427
GlennRC61321f22015-07-16 13:36:54 -07001428 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001429 bandwidth: the targeted bandwidth, in megabits ('M')
1430 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001431 try:
1432 for host1 in hosts:
1433 for host2 in hosts:
1434 if host1 != host2:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001435 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1436 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001437 except TypeError:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001438 main.log.exception(self.name + ": Object not as expected")
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001439 return main.FALSE
1440 except Exception:
1441 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001442 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001443
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001444 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1445
1446 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001447 Creates an iperf UDP test with a specific bandwidth.
1448 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001449
kelvin-onlab7cce9382015-07-17 10:21:03 -07001450 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001451 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1452 '''
1453 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001454 try:
1455 # setup the mininet command
1456 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001457 self.handle.sendline(cmd)
1458 self.handle.expect("mininet>")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001459 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001460
kelvin-onlab7cce9382015-07-17 10:21:03 -07001461 # check if there are in results in the mininet response
1462 if "Results:" in response:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001463 main.log.report(self.name + ": iperfudp test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001464 # parse the results
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001465 response = response.split("\r\n")
1466 response = response[len(response)-2]
1467 response = response.split(": ")
1468 response = response[len(response)-1]
1469 response = response.replace("[", "")
1470 response = response.replace("]", "")
1471 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001472
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001473 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001474
kelvin-onlab7cce9382015-07-17 10:21:03 -07001475 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001476 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1477 if len(mnBandwidth) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001478 # if one entry is blank then something is wrong
1479 for item in mnBandwidth:
1480 if item == "":
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001481 main.log.error(self.name + ": Could not parse iperf output")
1482 main.log.error(self.name + ": invalid iperfudp results")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001483 return main.FALSE
1484 # otherwise results are vaild
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001485 main.log.report(self.name + ": iperfudp test successful")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001486 return main.TRUE
1487 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001488 main.log.error(self.name + ": invalid iperfudp results")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001489 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001490
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001491 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001492 main.log.error(self.name + ": TIMEOUT exception found")
1493 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001494 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001495 except pexpect.EOF:
1496 main.log.error( self.name + ": EOF exception found" )
1497 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001498 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001499 except Exception:
1500 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001501 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001502
Jon Hall7eb38402015-01-08 17:19:54 -08001503 def nodes( self ):
1504 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001505 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001506 response = self.execute(
1507 cmd='nodes',
1508 prompt='mininet>',
1509 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001510 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001511 main.log.error( self.name + ": EOF exception found" )
1512 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001513 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001514 except Exception:
1515 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001516 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001517 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001518
Jon Hall7eb38402015-01-08 17:19:54 -08001519 def pingpair( self ):
1520 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001521 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001522 response = self.execute(
1523 cmd='pingpair',
1524 prompt='mininet>',
1525 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001526 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001527 main.log.error( self.name + ": EOF exception found" )
1528 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001529 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001530 except Exception:
1531 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001532 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001533
Jon Hall7eb38402015-01-08 17:19:54 -08001534 if re.search( ',\s0\%\spacket\sloss', response ):
1535 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001536 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001537 else:
alisone4121a92016-11-22 16:31:36 -08001538 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001539 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001540
Jon Hall7eb38402015-01-08 17:19:54 -08001541 def link( self, **linkargs ):
1542 """
GlennRCed771242016-01-13 17:02:47 -08001543 Bring link( s ) between two nodes up or down
1544 """
Jon Hall6094a362014-04-11 14:46:56 -07001545 try:
GlennRCed771242016-01-13 17:02:47 -08001546 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1547 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1548 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1549 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1550
1551 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1552 cmd = "link {} {} {}".format( end1, end2, option )
1553 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001554 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001555 response = self.handle.before
1556 main.log.info( response )
1557
1558 return main.TRUE
1559 except pexpect.TIMEOUT:
1560 main.log.exception( self.name + ": Command timed out" )
1561 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001562 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001563 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001564 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001565 except Exception:
1566 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001567 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001568
pingping-lin8244a3b2015-09-16 13:36:56 -07001569 def switch( self, **switchargs ):
1570 """
1571 start/stop a switch
1572 """
1573 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1574 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1575 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1576 command = "switch " + str( sw ) + " " + str( option )
1577 main.log.info( command )
1578 try:
1579 self.handle.sendline( command )
1580 self.handle.expect( "mininet>" )
1581 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001582 main.log.error(self.name + ": TIMEOUT exception found")
1583 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07001584 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001585 except pexpect.EOF:
1586 main.log.error( self.name + ": EOF exception found" )
1587 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001588 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001589 return main.TRUE
1590
pingping-lin5bb663b2015-09-24 11:47:50 -07001591 def node( self, nodeName, commandStr ):
1592 """
1593 Carry out a command line on a given node
1594 @parm:
1595 nodeName: the node name in Mininet testbed
1596 commandStr: the command line will be carried out on the node
1597 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1598 """
1599 command = str( nodeName ) + " " + str( commandStr )
1600 main.log.info( command )
1601
1602 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001603 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001604 if re.search( "Unknown command", response ):
1605 main.log.warn( response )
1606 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001607 if re.search( "Permission denied", response ):
1608 main.log.warn( response )
1609 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001610 except pexpect.EOF:
1611 main.log.error( self.name + ": EOF exception found" )
1612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001613 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001614 main.log.info( " response is :" )
1615 main.log.info( response )
1616 return response
1617
Jon Hall7eb38402015-01-08 17:19:54 -08001618 def yank( self, **yankargs ):
1619 """
1620 yank a mininet switch interface to a host"""
1621 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001622 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001623 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1624 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1625 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001626 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001627 response = self.execute(
1628 cmd=command,
1629 prompt="mininet>",
1630 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001631 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001632 main.log.error( self.name + ": EOF exception found" )
1633 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001634 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001635 except Exception:
1636 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001637 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001638 return main.TRUE
1639
Jon Hall7eb38402015-01-08 17:19:54 -08001640 def plug( self, **plugargs ):
1641 """
1642 plug the yanked mininet switch interface to a switch"""
1643 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001644 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001645 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1646 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1647 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001648 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001649 response = self.execute(
1650 cmd=command,
1651 prompt="mininet>",
1652 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001653 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001654 main.log.error( self.name + ": EOF exception found" )
1655 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001656 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001657 except Exception:
1658 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001659 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001660 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001661
Jon Hall7eb38402015-01-08 17:19:54 -08001662 def dpctl( self, **dpctlargs ):
1663 """
1664 Run dpctl command on all switches."""
1665 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001666 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001667 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1668 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1669 command = "dpctl " + cmd + " " + str( cmdargs )
1670 try:
1671 response = self.execute(
1672 cmd=command,
1673 prompt="mininet>",
1674 timeout=10 )
1675 except pexpect.EOF:
1676 main.log.error( self.name + ": EOF exception found" )
1677 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001678 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001679 except Exception:
1680 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001681 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001682 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001683
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001685 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001686 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001687 try:
1688 fileInput = path + '/lib/Mininet/INSTALL'
1689 version = super( Mininet, self ).getVersion()
1690 pattern = 'Mininet\s\w\.\w\.\w\w*'
1691 for line in open( fileInput, 'r' ).readlines():
1692 result = re.match( pattern, line )
1693 if result:
1694 version = result.group( 0 )
1695 return version
1696 except Exception:
1697 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001698 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001699
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001701 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001702 Parameters:
1703 sw: The name of an OVS switch. Example "s1"
1704 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001705 The output of the command from the mininet cli
1706 or main.FALSE on timeout"""
1707 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001708 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001709 response = self.execute(
1710 cmd=command,
1711 prompt="mininet>",
1712 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001713 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001714 return response
admin2a9548d2014-06-17 14:08:07 -07001715 else:
1716 return main.FALSE
1717 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001718 main.log.error( self.name + ": EOF exception found" )
1719 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001720 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001721 except Exception:
1722 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001723 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001724
Charles Chan029be652015-08-24 01:46:10 +08001725 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001726 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001727 Description:
1728 Assign switches to the controllers ( for ovs use only )
1729 Required:
1730 sw - Name of the switch. This can be a list or a string.
1731 ip - Ip addresses of controllers. This can be a list or a string.
1732 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001733 port - ONOS use port 6653, if no list of ports is passed, then
1734 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001735 ptcp - ptcp number, This can be a string or a list that has
1736 the same length as switch. This is optional and not required
1737 when using ovs switches.
1738 NOTE: If switches and ptcp are given in a list type they should have the
1739 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1740 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001741
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001742 Return:
1743 Returns main.TRUE if mininet correctly assigned switches to
1744 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001745 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001746 """
1747 assignResult = main.TRUE
1748 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001749 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001750 command = "sh ovs-vsctl set-controller "
1751 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001752 try:
1753 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001754 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001755 if isinstance( port, types.StringType ) or \
1756 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001757 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001758 elif isinstance( port, types.ListType ):
1759 main.log.error( self.name + ": Only one controller " +
1760 "assigned and a list of ports has" +
1761 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001762 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001763 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001764 main.log.error( self.name + ": Invalid controller port " +
1765 "number. Please specify correct " +
1766 "controller port" )
1767 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001768
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001769 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001770 if isinstance( port, types.StringType ) or \
1771 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001772 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001773 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1774 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001775 elif isinstance( port, types.ListType ):
1776 if ( len( ip ) != len( port ) ):
1777 main.log.error( self.name + ": Port list = " +
1778 str( len( port ) ) +
1779 "should be the same as controller" +
1780 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001781 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001782 else:
1783 onosIp = ""
1784 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001785 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1786 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001787 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001788 main.log.error( self.name + ": Invalid controller port " +
1789 "number. Please specify correct " +
1790 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001791 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001792 else:
1793 main.log.error( self.name + ": Invalid ip address" )
1794 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001795
1796 if isinstance( sw, types.StringType ):
1797 command += sw + " "
1798 if ptcp:
1799 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001800 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001801 elif isinstance( ptcp, types.ListType ):
1802 main.log.error( self.name + ": Only one switch is " +
1803 "being set and multiple PTCP is " +
1804 "being passed " )
1805 else:
1806 main.log.error( self.name + ": Invalid PTCP" )
1807 ptcp = ""
1808 command += onosIp
1809 commandList.append( command )
1810
1811 elif isinstance( sw, types.ListType ):
1812 if ptcp:
1813 if isinstance( ptcp, types.ListType ):
1814 if len( ptcp ) != len( sw ):
1815 main.log.error( self.name + ": PTCP length = " +
1816 str( len( ptcp ) ) +
1817 " is not the same as switch" +
1818 " length = " +
1819 str( len( sw ) ) )
1820 return main.FALSE
1821 else:
1822 for switch, ptcpNum in zip( sw, ptcp ):
1823 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001824 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001825 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001826 tempCmd += onosIp
1827 commandList.append( tempCmd )
1828 else:
1829 main.log.error( self.name + ": Invalid PTCP" )
1830 return main.FALSE
1831 else:
1832 for switch in sw:
1833 tempCmd = "sh ovs-vsctl set-controller "
1834 tempCmd += switch + " " + onosIp
1835 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001836 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001837 main.log.error( self.name + ": Invalid switch type " )
1838 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001839
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001840 for cmd in commandList:
1841 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001842 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001843 except pexpect.TIMEOUT:
1844 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1845 return main.FALSE
1846 except pexpect.EOF:
1847 main.log.error( self.name + ": EOF exception found" )
1848 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001849 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001850 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001851 except pexpect.EOF:
1852 main.log.error( self.name + ": EOF exception found" )
1853 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001854 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001855 except Exception:
1856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001857 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001858
kelvin-onlabd3b64892015-01-20 13:26:24 -08001859 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001860 """
1861 Removes the controller target from sw"""
1862 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001863 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001864 response = self.execute(
1865 cmd=command,
1866 prompt="mininet>",
1867 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001868 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001869 main.log.error( self.name + ": EOF exception found" )
1870 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001871 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001872 except Exception:
1873 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001874 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001875 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001876 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001877
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001879 """
Jon Hallb1290e82014-11-18 16:17:48 -05001880 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001881 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001882 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001883 NOTE: cannot currently specify what type of switch
1884 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001885 sw = name of the new switch as a string
1886 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001887 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001888 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001889 """
1890 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001891 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001892 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001893 response = self.execute(
1894 cmd=command,
1895 prompt="mininet>",
1896 timeout=10 )
1897 if re.search( "already exists!", response ):
1898 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001899 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001900 elif re.search( "Error", response ):
1901 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001902 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001903 elif re.search( "usage:", response ):
1904 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001905 return main.FALSE
1906 else:
1907 return main.TRUE
1908 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001909 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001910 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001911 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001912 except Exception:
1913 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001914 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001915
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001917 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001918 delete a switch from the mininet topology
1919 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001920 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001921 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001922 sw = name of the switch as a string
1923 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001924 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001925 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001926 response = self.execute(
1927 cmd=command,
1928 prompt="mininet>",
1929 timeout=10 )
1930 if re.search( "no switch named", response ):
1931 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001932 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001933 elif re.search( "Error", response ):
1934 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001935 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001936 elif re.search( "usage:", response ):
1937 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001938 return main.FALSE
1939 else:
1940 return main.TRUE
1941 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001942 main.log.error( self.name + ": EOF exception found" )
1943 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001944 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001945 except Exception:
1946 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001947 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05001948
You Wangdb8cd0a2016-05-26 15:19:45 -07001949 def getSwitchRandom( self, timeout=60, nonCut=True ):
1950 """
1951 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001952 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001953 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001954 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07001955 it just randomly returns one switch from all current switches in
1956 Mininet.
1957 Returns the name of the chosen switch.
1958 """
1959 import random
1960 candidateSwitches = []
1961 try:
1962 if not nonCut:
1963 switches = self.getSwitches( timeout=timeout )
1964 assert len( switches ) != 0
1965 for switchName in switches.keys():
1966 candidateSwitches.append( switchName )
1967 else:
1968 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001969 if graphDict == None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001970 return None
1971 self.graph.update( graphDict )
1972 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001973 if candidateSwitches == None:
You Wangdb8cd0a2016-05-26 15:19:45 -07001974 return None
1975 elif len( candidateSwitches ) == 0:
1976 main.log.info( self.name + ": No candidate switch for deletion" )
1977 return None
1978 else:
1979 switch = random.sample( candidateSwitches, 1 )
1980 return switch[ 0 ]
1981 except KeyError:
1982 main.log.exception( self.name + ": KeyError exception found" )
1983 return None
1984 except AssertionError:
1985 main.log.exception( self.name + ": AssertionError exception found" )
1986 return None
1987 except Exception:
1988 main.log.exception( self.name + ": Uncaught exception" )
1989 return None
1990
1991 def delSwitchRandom( self, timeout=60, nonCut=True ):
1992 """
1993 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001994 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07001995 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001996 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07001997 otherwise it just randomly delete one switch from all current
1998 switches in Mininet.
1999 Returns the name of the deleted switch
2000 """
2001 try:
2002 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002003 if switch == None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002004 return None
2005 else:
2006 deletionResult = self.delSwitch( switch )
2007 if deletionResult:
2008 return switch
2009 else:
2010 return None
2011 except Exception:
2012 main.log.exception( self.name + ": Uncaught exception" )
2013 return None
2014
kelvin-onlabd3b64892015-01-20 13:26:24 -08002015 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002016 """
2017 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002018 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002019 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002020 NOTE: cannot currently specify what type of link
2021 required params:
2022 node1 = the string node name of the first endpoint of the link
2023 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002024 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002025 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002026 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002027 response = self.execute(
2028 cmd=command,
2029 prompt="mininet>",
2030 timeout=10 )
2031 if re.search( "doesnt exist!", response ):
2032 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002033 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002034 elif re.search( "Error", response ):
2035 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002036 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002037 elif re.search( "usage:", response ):
2038 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002039 return main.FALSE
2040 else:
2041 return main.TRUE
2042 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002043 main.log.error( self.name + ": EOF exception found" )
2044 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002045 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002046 except Exception:
2047 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002048 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002049
kelvin-onlabd3b64892015-01-20 13:26:24 -08002050 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002051 """
2052 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002053 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002054 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002055 required params:
2056 node1 = the string node name of the first endpoint of the link
2057 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002058 returns: main.FALSE on an error, else main.TRUE
2059 """
Jon Hallffb386d2014-11-21 13:43:38 -08002060 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002061 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002062 response = self.execute(
2063 cmd=command,
2064 prompt="mininet>",
2065 timeout=10 )
2066 if re.search( "no node named", response ):
2067 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002068 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002069 elif re.search( "Error", response ):
2070 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002071 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002072 elif re.search( "usage:", response ):
2073 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002074 return main.FALSE
2075 else:
2076 return main.TRUE
2077 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002078 main.log.error( self.name + ": EOF exception found" )
2079 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002080 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002081 except Exception:
2082 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002083 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002084
You Wangdb8cd0a2016-05-26 15:19:45 -07002085 def getLinkRandom( self, timeout=60, nonCut=True ):
2086 """
2087 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002088 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002089 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002090 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002091 it just randomly returns one link from all current links in
2092 Mininet.
2093 Returns the link as a list, e.g. [ 's1', 's2' ]
2094 """
2095 import random
2096 candidateLinks = []
2097 try:
2098 if not nonCut:
2099 links = self.getLinks( timeout=timeout )
2100 assert len( links ) != 0
2101 for link in links:
2102 # Exclude host-switch link
2103 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2104 continue
2105 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2106 else:
2107 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002108 if graphDict == None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002109 return None
2110 self.graph.update( graphDict )
2111 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002112 if candidateLinks == None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002113 return None
2114 elif len( candidateLinks ) == 0:
2115 main.log.info( self.name + ": No candidate link for deletion" )
2116 return None
2117 else:
2118 link = random.sample( candidateLinks, 1 )
2119 return link[ 0 ]
2120 except KeyError:
2121 main.log.exception( self.name + ": KeyError exception found" )
2122 return None
2123 except AssertionError:
2124 main.log.exception( self.name + ": AssertionError exception found" )
2125 return None
2126 except Exception:
2127 main.log.exception( self.name + ": Uncaught exception" )
2128 return None
2129
2130 def delLinkRandom( self, timeout=60, nonCut=True ):
2131 """
2132 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002133 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002134 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002135 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002136 otherwise it just randomly delete one link from all current links
2137 in Mininet.
2138 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2139 """
2140 try:
2141 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002142 if link == None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002143 return None
2144 else:
2145 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2146 if deletionResult:
2147 return link
2148 else:
2149 return None
2150 except Exception:
2151 main.log.exception( self.name + ": Uncaught exception" )
2152 return None
2153
kelvin-onlabd3b64892015-01-20 13:26:24 -08002154 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002155 """
Jon Hallb1290e82014-11-18 16:17:48 -05002156 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002157 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002158 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002159 NOTE: cannot currently specify what type of host
2160 required params:
2161 hostname = the string hostname
2162 optional key-value params
2163 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002164 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002165 """
2166 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002167 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002168 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002169 response = self.execute(
2170 cmd=command,
2171 prompt="mininet>",
2172 timeout=10 )
2173 if re.search( "already exists!", response ):
2174 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002175 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002176 elif re.search( "doesnt exists!", response ):
2177 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002178 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002179 elif re.search( "Error", response ):
2180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002181 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002182 elif re.search( "usage:", response ):
2183 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002184 return main.FALSE
2185 else:
2186 return main.TRUE
2187 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002190 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002193 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002194
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002196 """
2197 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002198 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002199 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002200 NOTE: this uses a custom mn function
2201 required params:
2202 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002203 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002204 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002205 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002206 response = self.execute(
2207 cmd=command,
2208 prompt="mininet>",
2209 timeout=10 )
2210 if re.search( "no host named", response ):
2211 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002212 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002213 elif re.search( "Error", response ):
2214 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002215 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002216 elif re.search( "usage:", response ):
2217 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002218 return main.FALSE
2219 else:
2220 return main.TRUE
2221 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002222 main.log.error( self.name + ": EOF exception found" )
2223 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002224 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002225 except Exception:
2226 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002227 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002228
Jon Hall7eb38402015-01-08 17:19:54 -08002229 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002230 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002231 Called at the end of the test to stop the mininet and
2232 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002233 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002234 try:
2235 self.handle.sendline( '' )
2236 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2237 timeout=2 )
2238 response = main.TRUE
2239 if i == 0:
2240 response = self.stopNet()
2241 elif i == 1:
2242 return main.TRUE
2243 # print "Disconnecting Mininet"
2244 if self.handle:
2245 self.handle.sendline( "exit" )
2246 self.handle.expect( "exit" )
2247 self.handle.expect( "(.*)" )
2248 else:
2249 main.log.error( "Connection failed to the host" )
2250 return response
2251 except pexpect.EOF:
2252 main.log.error( self.name + ": EOF exception found" )
2253 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002254 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002255 except Exception:
2256 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002257 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002258
Devin Lima7cfdbd2017-09-29 15:02:22 -07002259 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002260 """
Jon Hall21270ac2015-02-16 17:59:55 -08002261 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002262 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002263 main.FALSE if the pexpect handle does not exist.
2264
Jon Halld61331b2015-02-17 16:35:47 -08002265 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002266 """
Jon Halld61331b2015-02-17 16:35:47 -08002267 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002268 response = ''
2269 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002270 try:
Jon Halld80cc142015-07-06 13:36:05 -07002271 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002272 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002273 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002274 pexpect.EOF,
2275 pexpect.TIMEOUT ],
2276 timeout )
2277 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002278 main.log.info( "Exiting mininet.." )
2279 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002280 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002281 prompt=self.prompt,
2282 timeout=exitTimeout )
2283 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002284 self.handle.sendline( "sudo mn -c" )
2285 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002286
Jeremyd9e4eb12016-04-13 12:09:06 -07002287 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002288 main.log.info( " Mininet trying to exit while not " +
2289 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002290 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002291 elif i == 2:
2292 main.log.error( "Something went wrong exiting mininet" )
2293 elif i == 3: # timeout
2294 main.log.error( "Something went wrong exiting mininet " +
2295 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002296
Hari Krishnab35c6d02015-03-18 11:13:51 -07002297 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002298 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002299 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002300 self.handle.sendline(
2301 "sudo kill -9 \`ps -ef | grep \"" +
2302 fileName +
2303 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002304 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002305 main.log.error(self.name + ": TIMEOUT exception found")
2306 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07002307 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002308 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002309 main.log.error( self.name + ": EOF exception found" )
2310 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002311 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002312 except Exception:
2313 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002314 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002315 else:
2316 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002317 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002318 return response
2319
YPZhang26a139e2016-04-25 14:01:55 -07002320 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002321 """
2322 Description:
2323 Sends arp message from mininet host for hosts discovery
2324 Required:
2325 host - hosts name
2326 Optional:
2327 ip - ip address that does not exist in the network so there would
2328 be no reply.
2329 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002330 if ethDevice:
2331 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002332 cmd = srcHost + " arping -c1 "
2333 if noResult:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002334 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 -07002335 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002336 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002337 if output:
2338 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002339 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002340 i = self.handle.expect( [ "mininet>", "arping: " ] )
2341 if i == 0:
2342 return main.TRUE
2343 elif i == 1:
2344 response = self.handle.before + self.handle.after
2345 self.handle.expect( "mininet>" )
2346 response += self.handle.before + self.handle.after
2347 main.log.warn( "Error sending arping, output was: " +
2348 response )
2349 return main.FALSE
2350 except pexpect.TIMEOUT:
2351 main.log.error( self.name + ": TIMEOUT exception found" )
2352 main.log.warn( self.handle.before )
2353 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002354 except pexpect.EOF:
2355 main.log.error( self.name + ": EOF exception found" )
2356 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002357 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002358 except Exception:
2359 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002360 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002361
Jon Hall7eb38402015-01-08 17:19:54 -08002362 def decToHex( self, num ):
2363 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002364
Jon Hall7eb38402015-01-08 17:19:54 -08002365 def getSwitchFlowCount( self, switch ):
2366 """
2367 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002368 if self.handle:
2369 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2370 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002371 response = self.execute(
2372 cmd=cmd,
2373 prompt="mininet>",
2374 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002375 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002376 main.log.error( self.name + ": EOF exception found" )
2377 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002378 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002379 except Exception:
2380 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002381 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002382 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002383 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002384 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002385 main.log.info(
2386 "Couldn't find flows on switch %s, found: %s" %
2387 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002388 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002389 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002390 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002391 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002392
Jon Hall9ed8f372016-02-24 17:34:07 -08002393 def checkFlows( self, sw, dumpFormat=None ):
2394 if dumpFormat:
2395 command = "sh ovs-ofctl -F " + \
2396 dumpFormat + " dump-flows " + str( sw )
2397 else:
2398 command = "sh ovs-ofctl dump-flows " + str( sw )
2399 try:
2400 response = self.execute(
2401 cmd=command,
2402 prompt="mininet>",
2403 timeout=10 )
2404 return response
2405 except pexpect.EOF:
2406 main.log.error( self.name + ": EOF exception found" )
2407 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002408 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002409 except Exception:
2410 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002411 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002412
GlennRC68467eb2015-11-16 18:01:01 -08002413 def flowTableComp( self, flowTable1, flowTable2 ):
2414 # This function compares the selctors and treatments of each flow
2415 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002416 assert flowTable1, "flowTable1 is empty or None"
2417 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002418 returnValue = main.TRUE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002419 if len(flowTable1) != len(flowTable2):
GlennRC68467eb2015-11-16 18:01:01 -08002420 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002421 returnValue = main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002422 dFields = ["n_bytes", "cookie", "n_packets", "duration"]
2423 for flow1, flow2 in zip(flowTable1, flowTable2):
Jon Hallacd1b182015-12-17 11:43:20 -08002424 for field in dFields:
2425 try:
2426 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002427 except KeyError:
2428 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002429 try:
2430 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002431 except KeyError:
2432 pass
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002433 for i in range( len(flowTable1) ):
2434 if flowTable1[i] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002435 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002436 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[i] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002437 returnValue = main.FALSE
2438 break
2439 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002440 except AssertionError:
2441 main.log.exception( "Nothing to compare" )
2442 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002443 except Exception:
2444 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002445 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002446
GlennRC528ad292015-11-12 10:38:18 -08002447 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002448 '''
GlennRC956ea742015-11-05 16:14:15 -08002449 Discription: Parses flows into json format.
2450 NOTE: this can parse any string thats separated with commas
2451 Arguments:
2452 Required:
2453 flows: a list of strings that represnt flows
2454 Optional:
2455 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2456 debug: prints out the final result
2457 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002458 '''
GlennRC528ad292015-11-12 10:38:18 -08002459 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002460 try:
2461 for flow in flowTable:
2462 jsonFlow = {}
2463 # split up the fields of the flow
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002464 parsedFlow = flow.split(", ")
You Wang91c37cf2016-05-23 09:39:42 -07002465 # get rid of any spaces in front of the field
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002466 for i in range( len(parsedFlow) ):
2467 item = parsedFlow[i]
2468 if item[0] == " ":
2469 parsedFlow[i] = item[1:]
You Wang91c37cf2016-05-23 09:39:42 -07002470 # grab the selector and treatment from the parsed flow
2471 # the last element is the selector and the treatment
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002472 temp = parsedFlow.pop(-1)
You Wang91c37cf2016-05-23 09:39:42 -07002473 # split up the selector and the treatment
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002474 temp = temp.split(" ")
You Wang91c37cf2016-05-23 09:39:42 -07002475 index = 0
2476 # parse the flags
2477 # NOTE: This only parses one flag
2478 flag = {}
2479 if version == "1.3":
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002480 flag = {"flag":[temp[index]]}
You Wang91c37cf2016-05-23 09:39:42 -07002481 index += 1
2482 # the first element is the selector and split it up
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002483 sel = temp[index]
GlennRC528ad292015-11-12 10:38:18 -08002484 index += 1
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002485 sel = sel.split(",")
You Wang91c37cf2016-05-23 09:39:42 -07002486 # the priority is stuck in the selecter so put it back
2487 # in the flow
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002488 parsedFlow.append(sel.pop(0))
You Wang91c37cf2016-05-23 09:39:42 -07002489 # parse selector
2490 criteria = []
2491 for item in sel:
2492 # this is the type of the packet e.g. "arp"
2493 if "=" not in item:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002494 criteria.append( {"type":item} )
You Wang91c37cf2016-05-23 09:39:42 -07002495 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002496 field = item.split("=")
2497 criteria.append( {field[0]:field[1]} )
2498 selector = {"selector": {"criteria":sorted(criteria)} }
2499 treat = temp[index]
You Wang91c37cf2016-05-23 09:39:42 -07002500 # get rid of the action part e.g. "action=output:2"
2501 # we will add it back later
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002502 treat = treat.split("=")
2503 treat.pop(0)
You Wang91c37cf2016-05-23 09:39:42 -07002504 # parse treatment
2505 action = []
2506 for item in treat:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002507 field = item.split(":")
2508 action.append( {field[0]:field[1]} )
You Wang91c37cf2016-05-23 09:39:42 -07002509 # create the treatment field and add the actions
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002510 treatment = {"treatment": {"action":sorted(action)} }
You Wang91c37cf2016-05-23 09:39:42 -07002511 # parse the rest of the flow
2512 for item in parsedFlow:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002513 field = item.split("=")
2514 jsonFlow.update( {field[0]:field[1]} )
You Wang91c37cf2016-05-23 09:39:42 -07002515 # add the treatment and the selector to the json flow
2516 jsonFlow.update( selector )
2517 jsonFlow.update( treatment )
2518 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002519
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002520 if debug: main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format(jsonFlow) )
GlennRC956ea742015-11-05 16:14:15 -08002521
You Wang91c37cf2016-05-23 09:39:42 -07002522 # add the json flow to the json flow table
2523 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002524
You Wang91c37cf2016-05-23 09:39:42 -07002525 return jsonFlowTable
2526
2527 except IndexError:
2528 main.log.exception( self.name + ": IndexError found" )
2529 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002530 except pexpect.EOF:
2531 main.log.error( self.name + ": EOF exception found" )
2532 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002533 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002534 except Exception:
2535 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002536 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002537
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002538 def getFlowTable( self, sw, version="", debug=False):
2539 '''
2540 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002541 Each element is a flow.
2542 Arguments:
2543 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002544 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002545 a list of switches.
2546 Optional:
2547 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2548 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002549 '''
GlennRC956ea742015-11-05 16:14:15 -08002550 try:
2551 switches = []
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002552 if type(sw) is list:
2553 switches.extend(sw)
2554 else: switches.append(sw)
GlennRC956ea742015-11-05 16:14:15 -08002555
2556 flows = []
2557 for s in switches:
2558 cmd = "sh ovs-ofctl dump-flows " + s
2559
GlennRC528ad292015-11-12 10:38:18 -08002560 if "1.0" == version:
2561 cmd += " -F OpenFlow10-table_id"
2562 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002563 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002564
2565 main.log.info( "Sending: " + cmd )
2566 self.handle.sendline( cmd )
2567 self.handle.expect( "mininet>" )
2568 response = self.handle.before
2569 response = response.split( "\r\n" )
2570 # dump the first two elements and the last
2571 # the first element is the command that was sent
2572 # the second is the table header
2573 # the last element is empty
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002574 response = response[2:-1]
GlennRC956ea742015-11-05 16:14:15 -08002575 flows.extend( response )
2576
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002577 if debug: print "Flows:\n{}\n\n".format(flows)
GlennRC956ea742015-11-05 16:14:15 -08002578
GlennRC528ad292015-11-12 10:38:18 -08002579 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002580
GlennRC956ea742015-11-05 16:14:15 -08002581 except pexpect.EOF:
2582 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002583 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002584 except Exception:
2585 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002586 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002587
2588 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002589 '''
GlennRC956ea742015-11-05 16:14:15 -08002590 Discription: Checks whether the ID provided matches a flow ID in Mininet
2591 Arguments:
2592 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002593 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002594 a list of switches.
2595 flowId: the flow ID in hex format. Can also be a list of IDs
2596 Optional:
2597 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2598 debug: prints out the final result
2599 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2600 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002601 '''
GlennRC956ea742015-11-05 16:14:15 -08002602 try:
2603 main.log.info( "Getting flows from Mininet" )
2604 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002605 if flows == None:
You Wang083ae982016-05-25 09:31:09 -07002606 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002607
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002608 if debug: print "flow ids:\n{}\n\n".format(flowId)
GlennRC956ea742015-11-05 16:14:15 -08002609
2610 # Check flowId is a list or a string
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002611 if type( flowId ) is str:
GlennRC956ea742015-11-05 16:14:15 -08002612 result = False
2613 for f in flows:
2614 if flowId in f.get( 'cookie' ):
2615 result = True
2616 break
2617 # flowId is a list
2618 else:
2619 result = True
2620 # Get flow IDs from Mininet
2621 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2622 # Save the IDs that are not in Mininet
2623 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2624
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002625 if debug: print "mn flow ids:\n{}\n\n".format(mnFlowIds)
GlennRC956ea742015-11-05 16:14:15 -08002626
2627 # Print out the IDs that are not in Mininet
2628 if absentIds:
2629 main.log.warn( "Absent ids: {}".format( absentIds ) )
2630 result = False
2631
2632 return main.TRUE if result else main.FALSE
2633
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002634 except pexpect.EOF:
2635 main.log.error( self.name + ": EOF exception found" )
2636 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002637 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002638 except Exception:
2639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002640 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002641
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002642
Charles Chan029be652015-08-24 01:46:10 +08002643 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002644 """
Jon Hallefbd9792015-03-05 16:11:36 -08002645 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002646 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002647 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002648 self.handle.sendline( "" )
2649 self.handle.expect( "mininet>" )
2650 self.handle.sendline(
2651 "sh sudo tcpdump -n -i " +
2652 intf +
2653 " " +
2654 port +
2655 " -w " +
2656 filename.strip() +
2657 " &" )
2658 self.handle.sendline( "" )
2659 i = self.handle.expect( [ 'No\ssuch\device',
2660 'listening\son',
2661 pexpect.TIMEOUT,
2662 "mininet>" ],
2663 timeout=10 )
2664 main.log.warn( self.handle.before + self.handle.after )
2665 self.handle.sendline( "" )
2666 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002667 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002668 main.log.error(
2669 self.name +
2670 ": tcpdump - No such device exists. " +
2671 "tcpdump attempted on: " +
2672 intf )
admin2a9548d2014-06-17 14:08:07 -07002673 return main.FALSE
2674 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002675 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002676 return main.TRUE
2677 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002678 main.log.error(
2679 self.name +
2680 ": tcpdump command timed out! Check interface name," +
2681 " given interface was: " +
2682 intf )
admin2a9548d2014-06-17 14:08:07 -07002683 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002684 elif i == 3:
2685 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002686 return main.TRUE
2687 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002688 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002689 return main.FALSE
2690 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002691 main.log.error( self.name + ": EOF exception found" )
2692 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002693 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002694 except Exception:
2695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002696 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002697
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002699 """
2700 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002701 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002702 self.handle.sendline( "sh sudo pkill tcpdump" )
2703 self.handle.expect( "mininet>" )
2704 self.handle.sendline( "" )
2705 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002706 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002707 main.log.error(self.name + ": TIMEOUT exception found")
2708 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07002709 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002710 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002711 main.log.error( self.name + ": EOF exception found" )
2712 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002713 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002714 except Exception:
2715 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002716 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002717
Jon Halld80cc142015-07-06 13:36:05 -07002718 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002719 """
2720 Read ports from a Mininet switch.
2721
2722 Returns a json structure containing information about the
2723 ports of the given switch.
2724 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002725 try:
2726 response = self.getInterfaces( nodeName )
2727 # TODO: Sanity check on response. log if no such switch exists
2728 ports = []
2729 for line in response.split( "\n" ):
2730 if not line.startswith( "name=" ):
2731 continue
2732 portVars = {}
2733 for var in line.split( "," ):
2734 key, value = var.split( "=" )
2735 portVars[ key ] = value
2736 isUp = portVars.pop( 'enabled', "True" )
2737 isUp = "True" in isUp
2738 if verbose:
2739 main.log.info( "Reading switch port %s(%s)" %
2740 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2741 mac = portVars[ 'mac' ]
2742 if mac == 'None':
2743 mac = None
2744 ips = []
2745 ip = portVars[ 'ip' ]
2746 if ip == 'None':
2747 ip = None
2748 ips.append( ip )
2749 name = portVars[ 'name' ]
2750 if name == 'None':
2751 name = None
2752 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2753 if name == 'lo':
2754 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2755 else:
2756 portNo = re.search( portRe, name ).group( 'port' )
2757 ports.append( { 'of_port': portNo,
2758 'mac': str( mac ).replace( '\'', '' ),
2759 'name': name,
2760 'ips': ips,
2761 'enabled': isUp } )
2762 return ports
2763 except pexpect.EOF:
2764 main.log.error( self.name + ": EOF exception found" )
2765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002766 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002767 except Exception:
2768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002770
You Wangdb8cd0a2016-05-26 15:19:45 -07002771 def getOVSPorts( self, nodeName ):
2772 """
2773 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2774
2775 Returns a list of dictionaries containing information about each
2776 port of the given switch.
2777 """
2778 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2779 try:
2780 response = self.execute(
2781 cmd=command,
2782 prompt="mininet>",
2783 timeout=10 )
2784 ports = []
2785 if response:
2786 for line in response.split( "\n" ):
2787 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2788 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002789 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002790 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2791 result = re.search( pattern, line )
2792 if result:
2793 index = result.group( 'index' )
2794 name = result.group( 'name' )
2795 # This port number is extracted from port name
2796 port = result.group( 'port' )
2797 mac = result.group( 'mac' )
2798 ports.append( { 'index': index,
2799 'name': name,
2800 'port': port,
2801 'mac': mac } )
2802 return ports
2803 except pexpect.EOF:
2804 main.log.error( self.name + ": EOF exception found" )
2805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002806 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002807 except Exception:
2808 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002809 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002810
Devin Lima7cfdbd2017-09-29 15:02:22 -07002811 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002812 """
2813 Read switches from Mininet.
2814
2815 Returns a dictionary whose keys are the switch names and the value is
2816 a dictionary containing information about the switch.
2817 """
Jon Halla22481b2015-07-28 17:46:01 -07002818 # NOTE: To support new Mininet switch classes, just append the new
2819 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002820
Jon Halla22481b2015-07-28 17:46:01 -07002821 # Regex patterns to parse 'dump' output
2822 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002823 # <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=5238>
Jon Halld80cc142015-07-06 13:36:05 -07002824 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002825 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2826 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2827 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002828 try:
2829 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2830 swRE = r"<(?P<class>" + switchClasses + r")" +\
2831 r"(?P<options>\{.*\})?\s" +\
2832 r"(?P<name>[^:]+)\:\s" +\
2833 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2834 r"\spid=(?P<pid>(\d)+)"
2835 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002836 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002837 output = {}
2838 dump = self.dump().split( "\n" )
2839 for line in dump:
2840 result = re.search( swRE, line, re.I )
2841 if result:
2842 name = result.group( 'name' )
2843 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2844 pid = result.group( 'pid' )
2845 swClass = result.group( 'class' )
2846 options = result.group( 'options' )
2847 if verbose:
2848 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2849 ports = self.getPorts( name )
2850 output[ name ] = { "dpid": dpid,
2851 "ports": ports,
2852 "swClass": swClass,
2853 "pid": pid,
2854 "options": options }
2855 return output
2856 except pexpect.EOF:
2857 main.log.error( self.name + ": EOF exception found" )
2858 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002859 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002860 except Exception:
2861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002862 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002863
Devin Lima7cfdbd2017-09-29 15:02:22 -07002864 def getHosts( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002865 """
2866 Read hosts from Mininet.
2867
2868 Returns a dictionary whose keys are the host names and the value is
2869 a dictionary containing information about the host.
2870 """
2871 # Regex patterns to parse dump output
2872 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002873 # <Host h1: pid=12725>
2874 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2875 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2876 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002877 # NOTE: Does not correctly match hosts with multi-links
2878 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2879 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002880 try:
2881 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
2882 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
2883 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002884 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002885 # Get mininet dump
2886 dump = self.dump().split( "\n" )
2887 hosts = {}
2888 for line in dump:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002889 if "Host" in line :
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002890 result = re.search( hostRE, line )
2891 name = result.group( 'name' )
2892 interfaces = []
2893 response = self.getInterfaces( name )
2894 # Populate interface info
2895 for line in response.split( "\n" ):
2896 if line.startswith( "name=" ):
2897 portVars = {}
2898 for var in line.split( "," ):
2899 key, value = var.split( "=" )
2900 portVars[ key ] = value
2901 isUp = portVars.pop( 'enabled', "True" )
2902 isUp = "True" in isUp
2903 if verbose:
2904 main.log.info( "Reading host port %s(%s)" %
2905 ( portVars[ 'name' ],
2906 portVars[ 'mac' ] ) )
2907 mac = portVars[ 'mac' ]
2908 if mac == 'None':
2909 mac = None
2910 ips = []
2911 ip = portVars[ 'ip' ]
2912 if ip == 'None':
2913 ip = None
2914 ips.append( ip )
2915 intfName = portVars[ 'name' ]
2916 if name == 'None':
2917 name = None
2918 interfaces.append( {
2919 "name": intfName,
2920 "ips": ips,
2921 "mac": str( mac ),
2922 "isUp": isUp } )
2923 hosts[ name ] = { "interfaces": interfaces }
2924 return hosts
2925 except pexpect.EOF:
2926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002929 except Exception:
2930 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002932
Devin Lima7cfdbd2017-09-29 15:02:22 -07002933 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002934 """
2935 Gathers information about current Mininet links. These links may not
2936 be up if one of the ports is down.
2937
2938 Returns a list of dictionaries with link endpoints.
2939
2940 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002941 { 'node1': str( node1 name )
2942 'node2': str( node2 name )
2943 'port1': str( port1 of_port )
2944 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002945 Note: The port number returned is the eth#, not necessarily the of_port
2946 number. In Mininet, for OVS switch, these should be the same. For
2947 hosts, this is just the eth#.
2948 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002949 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002950 self.update()
2951 response = self.links(timeout=timeout).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07002952
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002953 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002954 # s1-eth3<->s2-eth1 (OK OK)
2955 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002956 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2957 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2958 links = []
2959 for line in response:
2960 match = re.search( linkRE, line )
2961 if match:
2962 node1 = match.group( 'node1' )
2963 node2 = match.group( 'node2' )
2964 port1 = match.group( 'port1' )
2965 port2 = match.group( 'port2' )
2966 links.append( { 'node1': node1,
2967 'node2': node2,
2968 'port1': port1,
2969 'port2': port2 } )
2970 return links
2971
2972 except pexpect.EOF:
2973 main.log.error( self.name + ": EOF exception found" )
2974 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002975 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002976 except Exception:
2977 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002978 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002979
2980 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002981 """
2982 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002983 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002984
Jon Hallafa8a472015-06-12 14:02:42 -07002985 Dependencies:
2986 1. numpy - "sudo pip install numpy"
2987 """
2988 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002989 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002990 try:
2991 mnDPIDs = []
2992 for swName, switch in switches.iteritems():
2993 mnDPIDs.append( switch[ 'dpid' ].lower() )
2994 mnDPIDs.sort()
2995 if switchesJson == "": # if rest call fails
2996 main.log.error(
2997 self.name +
2998 ".compareSwitches(): Empty JSON object given from ONOS" )
2999 return main.FALSE
3000 onos = switchesJson
3001 onosDPIDs = []
3002 for switch in onos:
3003 if switch[ 'available' ]:
3004 onosDPIDs.append(
3005 switch[ 'id' ].replace(
3006 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003007 '' ).replace(
3008 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003009 '' ).lower() )
3010 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003011
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003012 if mnDPIDs != onosDPIDs:
3013 switchResults = main.FALSE
3014 main.log.error( "Switches in MN but not in ONOS:" )
3015 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3016 main.log.error( str( list1 ) )
3017 main.log.error( "Switches in ONOS but not in MN:" )
3018 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3019 main.log.error( str( list2 ) )
3020 else: # list of dpid's match in onos and mn
3021 switchResults = main.TRUE
3022 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003023
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003024 # FIXME: this does not look for extra ports in ONOS, only checks that
3025 # ONOS has what is in MN
3026 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003027
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003028 # PORTS
3029 for name, mnSwitch in switches.iteritems():
3030 mnPorts = []
3031 onosPorts = []
3032 switchResult = main.TRUE
3033 for port in mnSwitch[ 'ports' ]:
3034 if port[ 'enabled' ]:
3035 mnPorts.append( int( port[ 'of_port' ] ) )
3036 for onosSwitch in portsJson:
3037 if onosSwitch[ 'device' ][ 'available' ]:
3038 if onosSwitch[ 'device' ][ 'id' ].replace(
3039 ':',
3040 '' ).replace(
3041 "of",
3042 '' ) == mnSwitch[ 'dpid' ]:
3043 for port in onosSwitch[ 'ports' ]:
3044 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003045 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003046 # onosPorts.append( 'local' )
3047 onosPorts.append( long( uint64( -2 ) ) )
3048 else:
3049 onosPorts.append( int( port[ 'port' ] ) )
3050 break
3051 mnPorts.sort( key=float )
3052 onosPorts.sort( key=float )
3053
3054 mnPortsLog = mnPorts
3055 onosPortsLog = onosPorts
3056 mnPorts = [ x for x in mnPorts ]
3057 onosPorts = [ x for x in onosPorts ]
3058
3059 # TODO: handle other reserved port numbers besides LOCAL
3060 # NOTE: Reserved ports
3061 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3062 # long( uint64( -2 ) )
3063 for mnPort in mnPortsLog:
3064 if mnPort in onosPorts:
3065 # don't set results to true here as this is just one of
3066 # many checks and it might override a failure
3067 mnPorts.remove( mnPort )
3068 onosPorts.remove( mnPort )
3069
3070 # NOTE: OVS reports this as down since there is no link
3071 # So ignoring these for now
3072 # TODO: Come up with a better way of handling these
3073 if 65534 in mnPorts:
3074 mnPorts.remove( 65534 )
3075 if long( uint64( -2 ) ) in onosPorts:
3076 onosPorts.remove( long( uint64( -2 ) ) )
3077 if len( mnPorts ): # the ports of this switch don't match
3078 switchResult = main.FALSE
3079 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3080 if len( onosPorts ): # the ports of this switch don't match
3081 switchResult = main.FALSE
3082 main.log.warn(
3083 "Ports in ONOS but not MN: " +
3084 str( onosPorts ) )
3085 if switchResult == main.FALSE:
3086 main.log.error(
3087 "The list of ports for switch %s(%s) does not match:" %
3088 ( name, mnSwitch[ 'dpid' ] ) )
3089 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3090 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3091 portsResults = portsResults and switchResult
3092 finalResults = finalResults and portsResults
3093 return finalResults
3094 except pexpect.EOF:
3095 main.log.error( self.name + ": EOF exception found" )
3096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003097 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003098 except Exception:
3099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003100 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003101
Jon Hallafa8a472015-06-12 14:02:42 -07003102 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003103 """
3104 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003105 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003106
Jon Hallafa8a472015-06-12 14:02:42 -07003107 """
Jon Hall7eb38402015-01-08 17:19:54 -08003108 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003109 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003110 try:
3111 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003112
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003113 mnLinks = []
3114 for l in links:
3115 try:
3116 node1 = switches[ l[ 'node1' ] ]
3117 node2 = switches[ l[ 'node2' ] ]
3118 enabled = True
3119 for port in node1[ 'ports' ]:
3120 if port[ 'of_port' ] == l[ 'port1' ]:
3121 enabled = enabled and port[ 'enabled' ]
3122 for port in node2[ 'ports' ]:
3123 if port[ 'of_port' ] == l[ 'port2' ]:
3124 enabled = enabled and port[ 'enabled' ]
3125 if enabled:
3126 mnLinks.append( l )
3127 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003128 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003129 if 2 * len( mnLinks ) == len( onos ):
3130 linkResults = main.TRUE
3131 else:
3132 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003133 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003134 "Mininet has " + str( len( mnLinks ) ) +
3135 " bidirectional links and ONOS has " +
3136 str( len( onos ) ) + " unidirectional links" )
3137
3138 # iterate through MN links and check if an ONOS link exists in
3139 # both directions
3140 for link in mnLinks:
3141 # TODO: Find a more efficient search method
3142 node1 = None
3143 port1 = None
3144 node2 = None
3145 port2 = None
3146 firstDir = main.FALSE
3147 secondDir = main.FALSE
3148 for swName, switch in switches.iteritems():
3149 if swName == link[ 'node1' ]:
3150 node1 = switch[ 'dpid' ]
3151 for port in switch[ 'ports' ]:
3152 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3153 port1 = port[ 'of_port' ]
3154 if node1 is not None and node2 is not None:
3155 break
3156 if swName == link[ 'node2' ]:
3157 node2 = switch[ 'dpid' ]
3158 for port in switch[ 'ports' ]:
3159 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3160 port2 = port[ 'of_port' ]
3161 if node1 is not None and node2 is not None:
3162 break
3163
3164 for onosLink in onos:
3165 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3166 ":", '' ).replace( "of", '' )
3167 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3168 ":", '' ).replace( "of", '' )
3169 onosPort1 = onosLink[ 'src' ][ 'port' ]
3170 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3171
3172 # check onos link from node1 to node2
3173 if str( onosNode1 ) == str( node1 ) and str(
3174 onosNode2 ) == str( node2 ):
3175 if int( onosPort1 ) == int( port1 ) and int(
3176 onosPort2 ) == int( port2 ):
3177 firstDir = main.TRUE
3178 else:
3179 main.log.warn(
3180 'The port numbers do not match for ' +
3181 str( link ) +
3182 ' between ONOS and MN. When checking ONOS for ' +
3183 'link %s/%s -> %s/%s' %
3184 ( node1, port1, node2, port2 ) +
3185 ' ONOS has the values %s/%s -> %s/%s' %
3186 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3187
3188 # check onos link from node2 to node1
3189 elif ( str( onosNode1 ) == str( node2 ) and
3190 str( onosNode2 ) == str( node1 ) ):
3191 if ( int( onosPort1 ) == int( port2 )
3192 and int( onosPort2 ) == int( port1 ) ):
3193 secondDir = main.TRUE
3194 else:
3195 main.log.warn(
3196 'The port numbers do not match for ' +
3197 str( link ) +
3198 ' between ONOS and MN. When checking ONOS for ' +
3199 'link %s/%s -> %s/%s' %
3200 ( node1, port1, node2, port2 ) +
3201 ' ONOS has the values %s/%s -> %s/%s' %
3202 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3203 else: # this is not the link you're looking for
3204 pass
3205 if not firstDir:
3206 main.log.error(
3207 'ONOS does not have the link %s/%s -> %s/%s' %
3208 ( node1, port1, node2, port2 ) )
3209 if not secondDir:
3210 main.log.error(
3211 'ONOS does not have the link %s/%s -> %s/%s' %
3212 ( node2, port2, node1, port1 ) )
3213 linkResults = linkResults and firstDir and secondDir
3214 return linkResults
3215 except pexpect.EOF:
3216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003219 except Exception:
3220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003221 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003222
Jon Hallafa8a472015-06-12 14:02:42 -07003223 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003224 """
Jon Hallafa8a472015-06-12 14:02:42 -07003225 Compare mn and onos Hosts.
3226 Since Mininet hosts are quiet, ONOS will only know of them when they
3227 speak. For this reason, we will only check that the hosts in ONOS
3228 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003229
Jon Hallafa8a472015-06-12 14:02:42 -07003230 Arguments:
3231 hostsJson: parsed json object from the onos hosts api
3232 Returns:
3233 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003234 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003235 try:
3236 hostResults = main.TRUE
3237 for onosHost in hostsJson:
3238 onosMAC = onosHost[ 'mac' ].lower()
3239 match = False
3240 for mnHost, info in hosts.iteritems():
3241 for mnIntf in info[ 'interfaces' ]:
3242 if onosMAC == mnIntf[ 'mac' ].lower():
3243 match = True
3244 for ip in mnIntf[ 'ips' ]:
3245 if ip in onosHost[ 'ipAddresses' ]:
3246 pass # all is well
3247 else:
3248 # misssing ip
3249 main.log.error( "ONOS host " +
3250 onosHost[ 'id' ] +
3251 " has a different IP(" +
3252 str( onosHost[ 'ipAddresses' ] ) +
3253 ") than the Mininet host(" +
3254 str( ip ) +
3255 ")." )
3256 output = json.dumps(
3257 onosHost,
3258 sort_keys=True,
3259 indent=4,
3260 separators=( ',', ': ' ) )
3261 main.log.info( output )
3262 hostResults = main.FALSE
3263 if not match:
3264 hostResults = main.FALSE
3265 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3266 "corresponding Mininet host." )
3267 output = json.dumps( onosHost,
3268 sort_keys=True,
3269 indent=4,
3270 separators=( ',', ': ' ) )
3271 main.log.info( output )
3272 return hostResults
3273 except pexpect.EOF:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003274 main.log.error(self.name + ": EOF exception found")
3275 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003276 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003277 except Exception:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003278 main.log.exception(self.name + ": Uncaught exception!")
Devin Lim44075962017-08-11 10:56:37 -07003279 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003280
Jon Hallafa8a472015-06-12 14:02:42 -07003281 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003282 """
3283 Returns a list of all hosts
3284 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003285 try:
3286 self.handle.sendline( "" )
3287 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003288
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003289 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3290 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003291
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003292 handlePy = self.handle.before
3293 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3294 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003295
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003296 self.handle.sendline( "" )
3297 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003298
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003299 hostStr = handlePy.replace( "]", "" )
3300 hostStr = hostStr.replace( "'", "" )
3301 hostStr = hostStr.replace( "[", "" )
3302 hostStr = hostStr.replace( " ", "" )
3303 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003304
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003305 return hostList
3306 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003307 main.log.error(self.name + ": TIMEOUT exception found")
3308 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003309 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003310 except pexpect.EOF:
3311 main.log.error( self.name + ": EOF exception found" )
3312 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003313 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003314 except Exception:
3315 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003316 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003317
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003318 def getSwitch( self ):
3319 """
3320 Returns a list of all switches
3321 Again, don't ask question just use it...
3322 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003323 try:
3324 # get host list...
3325 hostList = self.getHosts()
3326 # Make host set
3327 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003328
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003329 # Getting all the nodes in mininet
3330 self.handle.sendline( "" )
3331 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003332
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003333 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3334 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003335
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003336 handlePy = self.handle.before
3337 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3338 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003339
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003340 self.handle.sendline( "" )
3341 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003342
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003343 nodesStr = handlePy.replace( "]", "" )
3344 nodesStr = nodesStr.replace( "'", "" )
3345 nodesStr = nodesStr.replace( "[", "" )
3346 nodesStr = nodesStr.replace( " ", "" )
3347 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003348
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003349 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003350 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003351 nodesSet.discard( 'c0' )
3352 nodesSet.discard( 'c1' )
3353 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003354
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003355 switchSet = nodesSet - hostSet
3356 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003357
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003358 return switchList
3359 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003360 main.log.error(self.name + ": TIMEOUT exception found")
3361 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003362 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003363 except pexpect.EOF:
3364 main.log.error( self.name + ": EOF exception found" )
3365 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003366 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003367 except Exception:
3368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003369 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003370
You Wangdb8cd0a2016-05-26 15:19:45 -07003371 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3372 """
3373 Return a dictionary which describes the latest Mininet topology data as a
3374 graph.
3375 An example of the dictionary:
3376 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3377 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3378 Each vertex should at least have an 'edges' attribute which describes the
3379 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003380 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003381 list of attributes.
3382 An example of the edges dictionary:
3383 'edges': { vertex2: { 'port': ..., 'weight': ... },
3384 vertex3: { 'port': ..., 'weight': ... } }
3385 If useId == True, dpid/mac will be used instead of names to identify
3386 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3387 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003388 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003389 in topology data.
3390 Note that link or switch that are brought down by 'link x x down' or 'switch
3391 x down' commands still show in the output of Mininet CLI commands such as
3392 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3393 recommended to use delLink() or delSwitch functions to simulate link/switch
3394 down, and addLink() or addSwitch to add them back.
3395 """
3396 graphDict = {}
3397 try:
3398 links = self.getLinks( timeout=timeout )
3399 portDict = {}
3400 if useId:
3401 switches = self.getSwitches()
3402 if includeHost:
3403 hosts = self.getHosts()
3404 for link in links:
3405 # FIXME: support 'includeHost' argument
3406 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3407 continue
3408 nodeName1 = link[ 'node1' ]
3409 nodeName2 = link[ 'node2' ]
3410 port1 = link[ 'port1' ]
3411 port2 = link[ 'port2' ]
3412 # Loop for two nodes
3413 for i in range( 2 ):
3414 # Get port index from OVS
3415 # The index extracted from port name may be inconsistent with ONOS
3416 portIndex = -1
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003417 if not nodeName1 in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003418 portList = self.getOVSPorts( nodeName1 )
3419 if len( portList ) == 0:
3420 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3421 return None
3422 portDict[ nodeName1 ] = portList
3423 for port in portDict[ nodeName1 ]:
3424 if port[ 'port' ] == port1:
3425 portIndex = port[ 'index' ]
3426 break
3427 if portIndex == -1:
3428 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3429 return None
3430 if useId:
3431 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3432 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3433 else:
3434 node1 = nodeName1
3435 node2 = nodeName2
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003436 if not node1 in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003437 if useId:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003438 graphDict[ node1 ] = { 'edges':{},
3439 'dpid':switches[ nodeName1 ][ 'dpid' ],
3440 'name':nodeName1,
3441 'ports':switches[ nodeName1 ][ 'ports' ],
3442 'swClass':switches[ nodeName1 ][ 'swClass' ],
3443 'pid':switches[ nodeName1 ][ 'pid' ],
3444 'options':switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003445 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003446 graphDict[ node1 ] = { 'edges':{} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003447 else:
3448 # Assert node2 is not connected to any current links of node1
3449 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003450 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port':portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003451 # Swap two nodes/ports
3452 nodeName1, nodeName2 = nodeName2, nodeName1
3453 port1, port2 = port2, port1
3454 return graphDict
3455 except KeyError:
3456 main.log.exception( self.name + ": KeyError exception found" )
3457 return None
3458 except AssertionError:
3459 main.log.exception( self.name + ": AssertionError exception found" )
3460 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003461 except pexpect.EOF:
3462 main.log.error( self.name + ": EOF exception found" )
3463 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003464 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003465 except Exception:
3466 main.log.exception( self.name + ": Uncaught exception" )
3467 return None
3468
Devin Lima7cfdbd2017-09-29 15:02:22 -07003469 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003470 """
3471 updates the port address and status information for
3472 each port in mn"""
3473 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003474 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003475 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003476 self.handle.sendline( "" )
3477 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003478
Jon Hall7eb38402015-01-08 17:19:54 -08003479 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003480 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003481
Jon Hall7eb38402015-01-08 17:19:54 -08003482 self.handle.sendline( "" )
3483 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003484
Jon Hallb1290e82014-11-18 16:17:48 -05003485 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003486 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003487 main.log.error(self.name + ": TIMEOUT exception found")
3488 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003489 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003490 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003491 main.log.error( self.name + ": EOF exception found" )
3492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003493 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003494 except Exception:
3495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003496 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003497
Jon Halld80cc142015-07-06 13:36:05 -07003498 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003499 """
3500 Add vlan tag to a host.
3501 Dependencies:
3502 This class depends on the "vlan" package
3503 $ sudo apt-get install vlan
3504 Configuration:
3505 Load the 8021q module into the kernel
3506 $sudo modprobe 8021q
3507
3508 To make this setup permanent:
3509 $ sudo su -c 'echo "8021q" >> /etc/modules'
3510 """
3511 if self.handle:
3512 try:
Jon Halld80cc142015-07-06 13:36:05 -07003513 # get the ip address of the host
3514 main.log.info( "Get the ip address of the host" )
3515 ipaddr = self.getIPAddress( host )
3516 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003517
Jon Halld80cc142015-07-06 13:36:05 -07003518 # remove IP from interface intf
3519 # Ex: h1 ifconfig h1-eth0 inet 0
3520 main.log.info( "Remove IP from interface " )
3521 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3522 self.handle.sendline( cmd2 )
3523 self.handle.expect( "mininet>" )
3524 response = self.handle.before
3525 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003526
Jon Halld80cc142015-07-06 13:36:05 -07003527 # create VLAN interface
3528 # Ex: h1 vconfig add h1-eth0 100
3529 main.log.info( "Create Vlan" )
3530 cmd3 = host + " vconfig add " + intf + " " + vlan
3531 self.handle.sendline( cmd3 )
3532 self.handle.expect( "mininet>" )
3533 response = self.handle.before
3534 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003535
Jon Halld80cc142015-07-06 13:36:05 -07003536 # assign the host's IP to the VLAN interface
3537 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3538 main.log.info( "Assign the host IP to the vlan interface" )
3539 vintf = intf + "." + vlan
3540 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3541 self.handle.sendline( cmd4 )
3542 self.handle.expect( "mininet>" )
3543 response = self.handle.before
3544 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003545
3546 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003547 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003548 main.log.error(self.name + ": TIMEOUT exception found")
3549 main.log.error(self.name + ": " + self.handle.before)
Devin Lim44075962017-08-11 10:56:37 -07003550 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003551 except pexpect.EOF:
3552 main.log.error( self.name + ": EOF exception found" )
3553 main.log.error( self.name + ": " + self.handle.before )
3554 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003555 except Exception:
3556 main.log.exception( self.name + ": Uncaught exception!" )
3557 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003558
Jon Hall892818c2015-10-20 17:58:34 -07003559 def createHostComponent( self, name ):
3560 """
3561 Creates a new mininet cli component with the same parameters as self.
3562 This new component is intended to be used to login to the hosts created
3563 by mininet.
3564
3565 Arguments:
3566 name - The string of the name of this component. The new component
3567 will be assigned to main.<name> .
3568 In addition, main.<name>.name = str( name )
3569 """
3570 try:
3571 # look to see if this component already exists
3572 getattr( main, name )
3573 except AttributeError:
3574 # namespace is clear, creating component
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003575 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
3576 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003577 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003578 except pexpect.EOF:
3579 main.log.error( self.name + ": EOF exception found" )
3580 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003581 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003582 except Exception:
3583 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003585 else:
3586 # namespace is not clear!
3587 main.log.error( name + " component already exists!" )
3588 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003589 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003590
3591 def removeHostComponent( self, name ):
3592 """
3593 Remove host component
3594 Arguments:
3595 name - The string of the name of the component to delete.
3596 """
3597 try:
3598 # Get host component
3599 component = getattr( main, name )
3600 except AttributeError:
3601 main.log.error( "Component " + name + " does not exist." )
3602 return
3603 try:
3604 # Disconnect from component
3605 component.disconnect()
3606 # Delete component
3607 delattr( main, name )
3608 # Delete component from ComponentDictionary
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003609 del( main.componentDictionary[name] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003610 except pexpect.EOF:
3611 main.log.error( self.name + ": EOF exception found" )
3612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003614 except Exception:
3615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003616 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003617
3618 def startHostCli( self, host=None ):
3619 """
3620 Use the mininet m utility to connect to the host's cli
3621 """
3622 # These are fields that can be used by scapy packets. Initialized to None
3623 self.hostIp = None
3624 self.hostMac = None
3625 try:
3626 if not host:
3627 host = self.name
3628 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003629 self.handle.sendline( "cd" )
3630 self.handle.expect( self.hostPrompt )
3631 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003632 self.handle.expect( self.hostPrompt )
3633 return main.TRUE
3634 except pexpect.TIMEOUT:
3635 main.log.exception( self.name + ": Command timed out" )
3636 return main.FALSE
3637 except pexpect.EOF:
3638 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003639 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003640 except Exception:
3641 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003642 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003643
YPZhang801d46d2016-08-08 13:26:28 -07003644 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003645 '''
3646
YPZhang801d46d2016-08-08 13:26:28 -07003647 Args:
3648 devicename: switch name
3649 intf: port name on switch
3650 status: up or down
3651
3652 Returns: boolean to show success change status
3653
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003654 '''
YPZhang801d46d2016-08-08 13:26:28 -07003655 if status == "down" or status == "up":
3656 try:
3657 cmd = devicename + " ifconfig " + intf + " " + status
3658 self.handle.sendline( cmd )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003659 self.handle.expect("mininet>")
YPZhang801d46d2016-08-08 13:26:28 -07003660 return main.TRUE
3661 except pexpect.TIMEOUT:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003662 main.log.exception(self.name + ": Command timed out")
YPZhang801d46d2016-08-08 13:26:28 -07003663 return main.FALSE
3664 except pexpect.EOF:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003665 main.log.exception(self.name + ": connection closed.")
Devin Lim44075962017-08-11 10:56:37 -07003666 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003667 except TypeError:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003668 main.log.exception(self.name + ": TypeError")
Devin Lim44075962017-08-11 10:56:37 -07003669 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003670 except Exception:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003671 main.log.exception(self.name + ": Uncaught exception!")
Devin Lim44075962017-08-11 10:56:37 -07003672 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003673 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003674 main.log.warn("Interface status should be up or down!")
YPZhang801d46d2016-08-08 13:26:28 -07003675 return main.FALSE
3676
3677
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003678
adminbae64d82013-08-01 10:50:15 -07003679if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003680 sys.modules[ __name__ ] = MininetCliDriver()