blob: 32339a4c556ec66c9397b776e1f328cd1e36eb35 [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
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
Jon Hallbe6dfc42015-01-12 17:37:25 -080022MininetCliDriver is the basic driver which will handle the Mininet functions
23
Jon Hall272a4db2015-01-12 17:43:48 -080024Some functions rely on STS module. To install this,
25 git clone https://github.com/jhall11/sts.git
26
Jon Hallbe6dfc42015-01-12 17:37:25 -080027Some functions rely on a modified version of Mininet. These functions
28should all be noted in the comments. To get this MN version run these commands
29from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080030 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080032 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080033 git pull
34
Jon Hall272a4db2015-01-12 17:43:48 -080035
36 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080037changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070038import pexpect
adminbae64d82013-08-01 10:50:15 -070039import re
40import sys
Jon Hall7eb38402015-01-08 17:19:54 -080041sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040042from math import pow
adminbae64d82013-08-01 10:50:15 -070043from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070044
Jon Hall7eb38402015-01-08 17:19:54 -080045
kelvin-onlab50907142015-04-01 13:37:45 -070046class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080047
48 """
49 MininetCliDriver is the basic driver which will handle
50 the Mininet functions"""
51 def __init__( self ):
52 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070053 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080054 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080055 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070056 self.flag = 0
57
Jon Hall7eb38402015-01-08 17:19:54 -080058 def connect( self, **connectargs ):
59 """
60 Here the main is the TestON instance after creating
61 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080062 try:
63 for key in connectargs:
64 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080065
kelvin-onlaba1484582015-02-02 15:46:20 -080066 self.name = self.options[ 'name' ]
67 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070068 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080069 self ).connect(
70 user_name=self.user_name,
71 ip_address=self.ip_address,
72 port=None,
73 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080074
kelvin-onlaba1484582015-02-02 15:46:20 -080075 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080076 main.log.info( "Connection successful to the host " +
77 self.user_name +
78 "@" +
79 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080080 return main.TRUE
81 else:
82 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080083 self.user_name +
84 "@" +
85 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080086 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -080087 return main.FALSE
88 except pexpect.EOF:
89 main.log.error( self.name + ": EOF exception found" )
90 main.log.error( self.name + ": " + self.handle.before )
91 main.cleanup()
92 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080093 except Exception:
94 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -080095 main.cleanup()
96 main.exit()
97
Jon Hallefbd9792015-03-05 16:11:36 -080098 def startNet( self, topoFile='', args='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -080099 """
100 Starts Mininet accepts a topology(.py) file and/or an optional
Jon Hallefbd9792015-03-05 16:11:36 -0800101 argument ,to start the mininet, as a parameter.
Jon Hall21270ac2015-02-16 17:59:55 -0800102 Returns main.TRUE if the mininet starts successfully and
103 main.FALSE otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800104 """
Jon Hall7eb38402015-01-08 17:19:54 -0800105 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700106 # make sure old networks are cleaned up
107 main.log.info( self.name +
108 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800109 self.handle.sendline( "sudo mn -c" )
110 i = self.handle.expect( [ 'password\sfor\s',
111 'Cleanup\scomplete',
112 pexpect.EOF,
113 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800114 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800115 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700116 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800117 main.log.info( self.name + ": Sending sudo password" )
118 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800119 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800120 '\$',
121 pexpect.EOF,
122 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800123 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800124 if i == 1:
125 main.log.info( self.name + ": Clean" )
126 elif i == 2:
127 main.log.error( self.name + ": Connection terminated" )
128 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700129 main.log.error( self.name + ": Something while cleaning " +
130 "Mininet took too long... " )
131 # Craft the string to start mininet
132 cmdString = "sudo "
133 if topoFile is None or topoFile == '': # If no file is given
134 main.log.info( self.name + ": building fresh Mininet" )
135 cmdString += "mn "
136 if args is None or args == '':
137 # If no args given, use args from .topo file
138 args = self.options[ 'arg1' ] +\
139 " " + self.options[ 'arg2' ] +\
140 " --mac --controller " +\
141 self.options[ 'controller' ] + " " +\
142 self.options[ 'arg3' ]
143 else: # else only use given args
144 pass
145 # TODO: allow use of topo args and method args?
146 else: # Use given topology file
147 main.log.info( "Starting Mininet from topo file " + topoFile )
148 cmdString += topoFile + " "
Jon Hallefbd9792015-03-05 16:11:36 -0800149 if args is None:
kelvin-onlaba1484582015-02-02 15:46:20 -0800150 args = ''
Jon Hall689d8e42015-04-03 13:59:24 -0700151 # TODO: allow use of args from .topo file?
152 cmdString += args
153 # Send the command and check if network started
154 self.handle.sendline( "" )
155 self.handle.expect( '\$' )
156 main.log.info( "Sending '" + cmdString + "' to " + self.name )
157 self.handle.sendline( cmdString )
158 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800159 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700160 'Exception',
161 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800162 pexpect.EOF,
163 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700164 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800165 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700166 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800167 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800168 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700169 response = str( self.handle.before +
170 self.handle.after )
171 self.handle.expect( '\$' )
172 response += str( self.handle.before +
173 self.handle.after )
174 main.log.error(
175 self.name +
176 ": Launching Mininet failed: " + response )
177 return main.FALSE
178 elif i == 2:
179 self.handle.expect( [ "\n",
180 pexpect.EOF,
181 pexpect.TIMEOUT ],
182 timeout )
183 main.log.info( self.handle.before )
184 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800185 main.log.error( self.name + ": Connection timeout" )
186 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700187 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800188 main.log.error(
189 self.name +
190 ": Something took too long... " )
191 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700192 # Why did we hit this part?
193 main.log.error( "startNet did not return correctly" )
194 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800195 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700196 main.log.error( self.name + ": Connection failed to the host " +
197 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800198 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700199 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800200
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800201 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400202 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800203 # In tree topology, if fanout arg is not given, by default it is 2
204 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400205 fanout = 2
206 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500207 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800208 while( k <= depth - 1 ):
209 count = count + pow( fanout, k )
210 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800211 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800212 while( k <= depth - 2 ):
213 # depth-2 gives you only core links and not considering
214 # edge links as seen by ONOS. If all the links including
215 # edge links are required, do depth-1
216 count = count + pow( fanout, k )
217 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800219 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800221
Jon Hall7eb38402015-01-08 17:19:54 -0800222 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800224 # by default it is 1
225 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400226 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 numSwitches = depth
228 numHostsPerSw = fanout
229 totalNumHosts = numSwitches * numHostsPerSw
230 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800231 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800233 topoDict = { "num_switches": int( numSwitches ),
234 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400235 return topoDict
236
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700238 """
239 Calculate the number of switches and links in a topo."""
240 # TODO: combine this function and numSwitchesNlinks
241 argList = self.options[ 'arg1' ].split( "," )
242 topoArgList = argList[ 0 ].split( " " )
243 argList = map( int, argList[ 1: ] )
244 topoArgList = topoArgList[ 1: ] + argList
245
246 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400247 return topoDict
248
kelvin-onlabc44f0192015-04-02 22:08:41 -0700249 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0):
Jon Hall7eb38402015-01-08 17:19:54 -0800250 """
251 Verifies the reachability of the hosts using pingall command.
252 Optional parameter timeout allows you to specify how long to
253 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700254 Optional:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700255 timeout(seconds) - This is the pexpect timeout; The function will
256 timeout if the amount of time between failed
257 pings exceedes this time and pingall is still
258 running
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700259 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700260 ping
261 acceptableFailed - Set the number of acceptable failed pings for the
262 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800263 Returns:
264 main.TRUE if pingall completes with no pings dropped
265 otherwise main.FALSE"""
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700266 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700267 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700268 if self.handle:
269 main.log.info(
270 self.name +
271 ": Checking reachabilty to the hosts using pingall" )
272 response = ""
273 failedPings = 0
274 returnValue = main.TRUE
275 self.handle.sendline( "pingall" )
276 while True:
277 i = self.handle.expect( [ "mininet>","X",
278 pexpect.EOF,
279 pexpect.TIMEOUT ],
280 timeout )
281 if i == 0:
282 main.log.info( self.name + ": pingall finished")
283 response += self.handle.before
284 break
285 elif i == 1:
286 response += self.handle.before + self.handle.after
287 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700288 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700289 returnValue = main.FALSE
290 if shortCircuit:
291 main.log.error( self.name +
292 ": Aborting pingall - "
293 + str( failedPings ) +
294 " pings failed" )
295 break
296 elif i == 2:
297 main.log.error( self.name +
298 ": EOF exception found" )
299 main.log.error( self.name + ": " +
300 self.handle.before )
301 main.cleanup()
302 main.exit()
303 elif i == 3:
304 response += self.handle.before
305 main.log.error( self.name +
306 ": TIMEOUT exception found" )
307 main.log.error( self.name +
308 ": " +
309 str( response ) )
310 # NOTE: Send ctrl-c to make sure pingall is done
311 self.handle.sendline( "\x03" )
312 self.handle.expect( "Interrupt" )
313 self.handle.expect( "mininet>" )
314 break
315 pattern = "Results\:"
316 main.log.info( "Pingall output: " + str( response ) )
317 if re.search( pattern, response ):
318 main.log.info( self.name + ": Pingall finished with "
319 + str( failedPings ) + " failed pings" )
320 return returnValue
321 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700322 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700323 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700324 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700325 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700326 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700327 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700328 main.log.error( self.name + ": Connection failed to the host" )
329 main.cleanup()
330 main.exit()
331 except pexpect.TIMEOUT:
332 if response:
333 main.log.info( "Pingall output: " + str( response ) )
334 main.log.error( self.name + ": pexpect.TIMEOUT found" )
335 return main.FALSE
336 except pexpect.EOF:
337 main.log.error( self.name + ": EOF exception found" )
338 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500339 main.cleanup()
340 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700341
Jon Hall7eb38402015-01-08 17:19:54 -0800342 def fpingHost( self, **pingParams ):
343 """
344 Uses the fping package for faster pinging...
345 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800346 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800347 command = args[ "SRC" ] + \
348 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
349 self.handle.sendline( command )
350 self.handle.expect(
351 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
352 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
353 response = self.handle.before
354 if re.search( ":\s-", response ):
355 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700356 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800357 elif re.search( ":\s\d{1,2}\.\d\d", response ):
358 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700359 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800360 main.log.info( self.name + ": Install fping on mininet machine... " )
361 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700362 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800363
Jon Hall7eb38402015-01-08 17:19:54 -0800364 def pingHost( self, **pingParams ):
365 """
366 Ping from one mininet host to another
367 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800368 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800369 command = args[ "SRC" ] + " ping " + \
370 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700371 try:
Jon Hall61282e32015-03-19 11:34:11 -0700372 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800373 self.handle.sendline( command )
374 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700375 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800376 main.log.error(
377 self.name +
378 ": timeout when waiting for response from mininet" )
379 main.log.error( "response: " + str( self.handle.before ) )
380 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700381 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800382 main.log.error(
383 self.name +
384 ": timeout when waiting for response from mininet" )
385 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700386 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800387 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800388 main.log.error( self.name + ": EOF exception found" )
389 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700390 main.cleanup()
391 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800392 main.log.info( self.name + ": Ping Response: " + response )
393 if re.search( ',\s0\%\spacket\sloss', response ):
394 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800395 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700396 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800397 else:
398 main.log.error(
399 self.name +
400 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800401 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700402 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800403
Jon Hall7eb38402015-01-08 17:19:54 -0800404 def checkIP( self, host ):
405 """
406 Verifies the host's ip configured or not."""
407 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700408 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800409 response = self.execute(
410 cmd=host +
411 " ifconfig",
412 prompt="mininet>",
413 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800414 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800415 main.log.error( self.name + ": EOF exception found" )
416 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700417 main.cleanup()
418 main.exit()
adminbae64d82013-08-01 10:50:15 -0700419
Jon Hall7eb38402015-01-08 17:19:54 -0800420 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800421 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
422 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
423 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
424 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
425 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800426 # pattern = "inet addr:10.0.0.6"
427 if re.search( pattern, response ):
428 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700429 return main.TRUE
430 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800431 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700432 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800433 else:
434 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800435
Jon Hall7eb38402015-01-08 17:19:54 -0800436 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800437 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700438 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800439 response = self.execute(
440 cmd="h1 /usr/sbin/sshd -D&",
441 prompt="mininet>",
442 timeout=10 )
443 response = self.execute(
444 cmd="h4 /usr/sbin/sshd -D&",
445 prompt="mininet>",
446 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700447 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800448 vars( self )[ key ] = connectargs[ key ]
449 response = self.execute(
450 cmd="xterm h1 h4 ",
451 prompt="mininet>",
452 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800453 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800454 main.log.error( self.name + ": EOF exception found" )
455 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700456 main.cleanup()
457 main.exit()
adminbae64d82013-08-01 10:50:15 -0700458 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800459 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700460 if self.flag == 0:
461 self.flag = 1
462 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800463 else:
adminbae64d82013-08-01 10:50:15 -0700464 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800465
kelvin-onlaba1484582015-02-02 15:46:20 -0800466 def moveHost( self, host, oldSw, newSw, ):
467 """
468 Moves a host from one switch to another on the fly
469 Note: The intf between host and oldSw when detached
470 using detach(), will still show up in the 'net'
471 cmd, because switch.detach() doesn't affect switch.intfs[]
472 (which is correct behavior since the interfaces
473 haven't moved).
474 """
475 if self.handle:
476 try:
477 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800478 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
479 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800480 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800481 response = self.execute( cmd=cmd,
482 prompt="mininet>",
483 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800484
485 # Determine hostintf and Oldswitchintf
486 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800487 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800488 print "cmd2= ", cmd
489 self.handle.sendline( cmd )
490 self.handle.expect( "mininet>" )
491
shahshreya73537862015-02-11 15:15:24 -0800492 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800493 cmd = "px ipaddr = hintf.IP()"
494 print "cmd3= ", cmd
495 self.handle.sendline( cmd )
496 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800497
498 cmd = "px macaddr = hintf.MAC()"
499 print "cmd3= ", cmd
500 self.handle.sendline( cmd )
501 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800502
503 # Detach interface between oldSw-host
504 cmd = "px " + oldSw + ".detach( sintf )"
505 print "cmd4= ", cmd
506 self.handle.sendline( cmd )
507 self.handle.expect( "mininet>" )
508
509 # Add link between host-newSw
510 cmd = "py net.addLink(" + host + "," + newSw + ")"
511 print "cmd5= ", cmd
512 self.handle.sendline( cmd )
513 self.handle.expect( "mininet>" )
514
515 # Determine hostintf and Newswitchintf
516 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800517 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800518 print "cmd6= ", cmd
519 self.handle.sendline( cmd )
520 self.handle.expect( "mininet>" )
521
522 # Attach interface between newSw-host
523 cmd = "px " + newSw + ".attach( sintf )"
524 print "cmd3= ", cmd
525 self.handle.sendline( cmd )
526 self.handle.expect( "mininet>" )
527
528 # Set ipaddress of the host-newSw interface
529 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
530 print "cmd7 = ", cmd
531 self.handle.sendline( cmd )
532 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800533
534 # Set macaddress of the host-newSw interface
535 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
536 print "cmd8 = ", cmd
537 self.handle.sendline( cmd )
538 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800539
540 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800541 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800542 self.handle.sendline( cmd )
543 self.handle.expect( "mininet>" )
544 print "output = ", self.handle.before
545
546 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800547 cmd = host + " ifconfig"
548 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800549 self.handle.sendline( cmd )
550 self.handle.expect( "mininet>" )
551 print "ifconfig o/p = ", self.handle.before
552
553 return main.TRUE
554 except pexpect.EOF:
555 main.log.error( self.name + ": EOF exception found" )
556 main.log.error( self.name + ": " + self.handle.before )
557 return main.FALSE
558
Jon Hall7eb38402015-01-08 17:19:54 -0800559 def changeIP( self, host, intf, newIP, newNetmask ):
560 """
561 Changes the ip address of a host on the fly
562 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800563 if self.handle:
564 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800565 cmd = host + " ifconfig " + intf + " " + \
566 newIP + " " + 'netmask' + " " + newNetmask
567 self.handle.sendline( cmd )
568 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800569 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800570 main.log.info( "response = " + response )
571 main.log.info(
572 "Ip of host " +
573 host +
574 " changed to new IP " +
575 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800576 return main.TRUE
577 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800578 main.log.error( self.name + ": EOF exception found" )
579 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800580 return main.FALSE
581
Jon Hall7eb38402015-01-08 17:19:54 -0800582 def changeDefaultGateway( self, host, newGW ):
583 """
584 Changes the default gateway of a host
585 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800586 if self.handle:
587 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800588 cmd = host + " route add default gw " + newGW
589 self.handle.sendline( cmd )
590 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800591 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800592 main.log.info( "response = " + response )
593 main.log.info(
594 "Default gateway of host " +
595 host +
596 " changed to " +
597 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800598 return main.TRUE
599 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800600 main.log.error( self.name + ": EOF exception found" )
601 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800602 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800603
Jon Hall7eb38402015-01-08 17:19:54 -0800604 def addStaticMACAddress( self, host, GW, macaddr ):
605 """
Jon Hallefbd9792015-03-05 16:11:36 -0800606 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800607 if self.handle:
608 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800609 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
610 cmd = host + " arp -s " + GW + " " + macaddr
611 self.handle.sendline( cmd )
612 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800613 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800614 main.log.info( "response = " + response )
615 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800616 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800617 GW +
618 " changed to " +
619 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800620 return main.TRUE
621 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800622 main.log.error( self.name + ": EOF exception found" )
623 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800624 return main.FALSE
625
Jon Hall7eb38402015-01-08 17:19:54 -0800626 def verifyStaticGWandMAC( self, host ):
627 """
628 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800629 if self.handle:
630 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800631 # h1 arp -an
632 cmd = host + " arp -an "
633 self.handle.sendline( cmd )
634 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800635 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800636 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800637 return main.TRUE
638 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800639 main.log.error( self.name + ": EOF exception found" )
640 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800641 return main.FALSE
642
Jon Hall7eb38402015-01-08 17:19:54 -0800643 def getMacAddress( self, host ):
644 """
645 Verifies the host's ip configured or not."""
646 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700647 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800648 response = self.execute(
649 cmd=host +
650 " ifconfig",
651 prompt="mininet>",
652 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800653 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800654 main.log.error( self.name + ": EOF exception found" )
655 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700656 main.cleanup()
657 main.exit()
adminbae64d82013-08-01 10:50:15 -0700658
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700659 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 macAddressSearch = re.search( pattern, response, re.I )
661 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800662 main.log.info(
663 self.name +
664 ": Mac-Address of Host " +
665 host +
666 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800667 macAddress )
668 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700669 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800670 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700671
Jon Hall7eb38402015-01-08 17:19:54 -0800672 def getInterfaceMACAddress( self, host, interface ):
673 """
674 Return the IP address of the interface on the given host"""
675 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700676 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800677 response = self.execute( cmd=host + " ifconfig " + interface,
678 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800679 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800680 main.log.error( self.name + ": EOF exception found" )
681 main.log.error( self.name + ": " + self.handle.before )
682 main.cleanup()
683 main.exit()
684
685 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 macAddressSearch = re.search( pattern, response, re.I )
687 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800688 main.log.info( "No mac address found in %s" % response )
689 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800691 main.log.info(
692 "Mac-Address of " +
693 host +
694 ":" +
695 interface +
696 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 macAddress )
698 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800699 else:
700 main.log.error( "Connection failed to the host" )
701
702 def getIPAddress( self, host ):
703 """
704 Verifies the host's ip configured or not."""
705 if self.handle:
706 try:
707 response = self.execute(
708 cmd=host +
709 " ifconfig",
710 prompt="mininet>",
711 timeout=10 )
712 except pexpect.EOF:
713 main.log.error( self.name + ": EOF exception found" )
714 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700715 main.cleanup()
716 main.exit()
adminbae64d82013-08-01 10:50:15 -0700717
718 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800720 main.log.info(
721 self.name +
722 ": IP-Address of Host " +
723 host +
724 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800725 ipAddressSearch.group( 1 ) )
726 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800727 else:
728 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800729
Jon Hall7eb38402015-01-08 17:19:54 -0800730 def getSwitchDPID( self, switch ):
731 """
732 return the datapath ID of the switch"""
733 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700734 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700735 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800736 response = self.execute(
737 cmd=cmd,
738 prompt="mininet>",
739 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800740 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 main.log.error( self.name + ": EOF exception found" )
742 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700743 main.cleanup()
744 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800745 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800746 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700747 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.info(
749 "Couldn't find DPID for switch %s, found: %s" %
750 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700751 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800752 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700753 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800754 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700755
Jon Hall7eb38402015-01-08 17:19:54 -0800756 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700757 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800758 self.handle.sendline( "" )
759 self.expect( "mininet>" )
760 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700761 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800762 response = self.execute(
763 cmd=cmd,
764 prompt="mininet>",
765 timeout=10 )
766 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700767 response = self.handle.before
768 return response
769 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800770 main.log.error( self.name + ": EOF exception found" )
771 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700772 main.cleanup()
773 main.exit()
774
Jon Hall7eb38402015-01-08 17:19:54 -0800775 def getInterfaces( self, node ):
776 """
777 return information dict about interfaces connected to the node"""
778 if self.handle:
779 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800780 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700781 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700782 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800783 response = self.execute(
784 cmd=cmd,
785 prompt="mininet>",
786 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800787 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700790 main.cleanup()
791 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700792 return response
793 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800794 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700795
Jon Hall7eb38402015-01-08 17:19:54 -0800796 def dump( self ):
797 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700798 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800799 response = self.execute(
800 cmd='dump',
801 prompt='mininet>',
802 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800803 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800804 main.log.error( self.name + ": EOF exception found" )
805 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700806 main.cleanup()
807 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700808 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800809
Jon Hall7eb38402015-01-08 17:19:54 -0800810 def intfs( self ):
811 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700812 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800813 response = self.execute(
814 cmd='intfs',
815 prompt='mininet>',
816 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800817 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800818 main.log.error( self.name + ": EOF exception found" )
819 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700820 main.cleanup()
821 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700822 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800823
Jon Hall7eb38402015-01-08 17:19:54 -0800824 def net( self ):
825 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700826 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800827 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800828 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800829 main.log.error( self.name + ": EOF exception found" )
830 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700831 main.cleanup()
832 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700833 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800834
835 def iperf( self, host1, host2 ):
836 main.log.info(
837 self.name +
838 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700839 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800840 cmd1 = 'iperf ' + host1 + " " + host2
841 self.handle.sendline( cmd1 )
842 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800843 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800844 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800845 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800846 return main.TRUE
847 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800848 main.log.error( self.name + ": iperf test failed" )
849 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800850 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800851 main.log.error( self.name + ": EOF exception found" )
852 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800853 main.cleanup()
854 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800855
Jon Hall7eb38402015-01-08 17:19:54 -0800856 def iperfudp( self ):
857 main.log.info(
858 self.name +
859 ": Simple iperf TCP test between two " +
860 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700861 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800862 response = self.execute(
863 cmd='iperfudp',
864 prompt='mininet>',
865 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800866 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800867 main.log.error( self.name + ": EOF exception found" )
868 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700869 main.cleanup()
870 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700871 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800872
Jon Hall7eb38402015-01-08 17:19:54 -0800873 def nodes( self ):
874 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700875 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800876 response = self.execute(
877 cmd='nodes',
878 prompt='mininet>',
879 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800880 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800881 main.log.error( self.name + ": EOF exception found" )
882 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700883 main.cleanup()
884 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700885 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800886
Jon Hall7eb38402015-01-08 17:19:54 -0800887 def pingpair( self ):
888 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700889 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800890 response = self.execute(
891 cmd='pingpair',
892 prompt='mininet>',
893 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800894 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800895 main.log.error( self.name + ": EOF exception found" )
896 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700897 main.cleanup()
898 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800899
Jon Hall7eb38402015-01-08 17:19:54 -0800900 if re.search( ',\s0\%\spacket\sloss', response ):
901 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700903 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800904 else:
905 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700907 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800908
Jon Hall7eb38402015-01-08 17:19:54 -0800909 def link( self, **linkargs ):
910 """
911 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800912 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800913 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
914 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
915 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
916 main.log.info(
917 "Bring link between '" +
918 end1 +
919 "' and '" +
920 end2 +
921 "' '" +
922 option +
923 "'" )
924 command = "link " + \
925 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700926 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800927 self.handle.sendline( command )
928 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800929 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700932 main.cleanup()
933 main.exit()
adminbae64d82013-08-01 10:50:15 -0700934 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800935
Jon Hall7eb38402015-01-08 17:19:54 -0800936 def yank( self, **yankargs ):
937 """
938 yank a mininet switch interface to a host"""
939 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800940 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800941 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
942 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
943 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700944 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800945 response = self.execute(
946 cmd=command,
947 prompt="mininet>",
948 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800949 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700952 main.cleanup()
953 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700954 return main.TRUE
955
Jon Hall7eb38402015-01-08 17:19:54 -0800956 def plug( self, **plugargs ):
957 """
958 plug the yanked mininet switch interface to a switch"""
959 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800960 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800961 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
962 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
963 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700964 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800965 response = self.execute(
966 cmd=command,
967 prompt="mininet>",
968 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800969 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800970 main.log.error( self.name + ": EOF exception found" )
971 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700972 main.cleanup()
973 main.exit()
adminbae64d82013-08-01 10:50:15 -0700974 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800975
Jon Hall7eb38402015-01-08 17:19:54 -0800976 def dpctl( self, **dpctlargs ):
977 """
978 Run dpctl command on all switches."""
979 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800980 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800981 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
982 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
983 command = "dpctl " + cmd + " " + str( cmdargs )
984 try:
985 response = self.execute(
986 cmd=command,
987 prompt="mininet>",
988 timeout=10 )
989 except pexpect.EOF:
990 main.log.error( self.name + ": EOF exception found" )
991 main.log.error( self.name + ": " + self.handle.before )
992 main.cleanup()
993 main.exit()
994 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800995
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -0800997 #FIXME: What uses this? This should be refactored to get
998 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 fileInput = path + '/lib/Mininet/INSTALL'
1000 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001001 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001002 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001003 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001004 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001005 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001006 return version
adminbae64d82013-08-01 10:50:15 -07001007
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001009 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001010 Parameters:
1011 sw: The name of an OVS switch. Example "s1"
1012 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001013 The output of the command from the mininet cli
1014 or main.FALSE on timeout"""
1015 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001016 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001017 response = self.execute(
1018 cmd=command,
1019 prompt="mininet>",
1020 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001021 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001022 return response
admin2a9548d2014-06-17 14:08:07 -07001023 else:
1024 return main.FALSE
1025 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001026 main.log.error( self.name + ": EOF exception found" )
1027 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001028 main.cleanup()
1029 main.exit()
adminbae64d82013-08-01 10:50:15 -07001030
kelvin-onlabd3b64892015-01-20 13:26:24 -08001031 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001032 """
1033 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001034 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001035 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001036
1037 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001038 for j in range( count ):
1039 argstring = argstring + ",IP" + \
1040 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001041 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001042
Jon Hall7eb38402015-01-08 17:19:54 -08001043 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1044 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001045 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001046 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001047
Jon Hall7eb38402015-01-08 17:19:54 -08001048 command = "sh ovs-vsctl set-controller s" + \
1049 str( sw ) + " " + ptcpB + " "
1050 for j in range( count ):
1051 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001052 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001053 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1054 ip = args[
1055 "IP" +
1056 str( i ) ] if args[
1057 "IP" +
1058 str( i ) ] is not None else ""
1059 port = args[
1060 "PORT" +
1061 str( i ) ] if args[
1062 "PORT" +
1063 str( i ) ] is not None else ""
1064 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001065 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001066 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001067 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001068 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001069 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001072 main.cleanup()
1073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
1075 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001076 main.cleanup()
1077 main.exit()
adminbae64d82013-08-01 10:50:15 -07001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001080 """
1081 Removes the controller target from sw"""
1082 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001083 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001084 response = self.execute(
1085 cmd=command,
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 )
Jon Hall0819fd92014-05-23 12:08:13 -07001091 main.cleanup()
1092 main.exit()
1093 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001094 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001097 """
Jon Hallb1290e82014-11-18 16:17:48 -05001098 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001099 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001100 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001101 NOTE: cannot currently specify what type of switch
1102 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001103 sw = name of the new switch as a string
1104 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001105 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001106 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001107 """
1108 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001109 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001110 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001111 response = self.execute(
1112 cmd=command,
1113 prompt="mininet>",
1114 timeout=10 )
1115 if re.search( "already exists!", response ):
1116 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001117 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001118 elif re.search( "Error", response ):
1119 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001120 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001121 elif re.search( "usage:", response ):
1122 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001123 return main.FALSE
1124 else:
1125 return main.TRUE
1126 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001127 main.log.error( self.name + ": EOF exception found" )
1128 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001129 main.cleanup()
1130 main.exit()
1131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001133 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001134 delete a switch from the mininet topology
1135 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001136 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001137 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001138 sw = name of the switch as a string
1139 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001140 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001141 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001142 response = self.execute(
1143 cmd=command,
1144 prompt="mininet>",
1145 timeout=10 )
1146 if re.search( "no switch named", response ):
1147 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001148 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001149 elif re.search( "Error", response ):
1150 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001151 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001152 elif re.search( "usage:", response ):
1153 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001154 return main.FALSE
1155 else:
1156 return main.TRUE
1157 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001158 main.log.error( self.name + ": EOF exception found" )
1159 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001160 main.cleanup()
1161 main.exit()
1162
kelvin-onlabd3b64892015-01-20 13:26:24 -08001163 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001164 """
1165 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001166 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001167 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001168 NOTE: cannot currently specify what type of link
1169 required params:
1170 node1 = the string node name of the first endpoint of the link
1171 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001172 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001173 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001174 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001175 response = self.execute(
1176 cmd=command,
1177 prompt="mininet>",
1178 timeout=10 )
1179 if re.search( "doesnt exist!", response ):
1180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001181 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001182 elif re.search( "Error", response ):
1183 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001184 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001185 elif re.search( "usage:", response ):
1186 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001187 return main.FALSE
1188 else:
1189 return main.TRUE
1190 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001191 main.log.error( self.name + ": EOF exception found" )
1192 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001193 main.cleanup()
1194 main.exit()
1195
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001197 """
1198 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001199 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001200 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001201 required params:
1202 node1 = the string node name of the first endpoint of the link
1203 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001204 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001205 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001206 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001207 response = self.execute(
1208 cmd=command,
1209 prompt="mininet>",
1210 timeout=10 )
1211 if re.search( "no node named", response ):
1212 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001213 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001214 elif re.search( "Error", response ):
1215 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001216 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001217 elif re.search( "usage:", response ):
1218 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001219 return main.FALSE
1220 else:
1221 return main.TRUE
1222 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001223 main.log.error( self.name + ": EOF exception found" )
1224 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001225 main.cleanup()
1226 main.exit()
1227
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001229 """
Jon Hallb1290e82014-11-18 16:17:48 -05001230 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001231 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001232 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001233 NOTE: cannot currently specify what type of host
1234 required params:
1235 hostname = the string hostname
1236 optional key-value params
1237 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001238 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001239 """
1240 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001241 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001242 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001243 response = self.execute(
1244 cmd=command,
1245 prompt="mininet>",
1246 timeout=10 )
1247 if re.search( "already exists!", response ):
1248 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001249 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001250 elif re.search( "doesnt exists!", response ):
1251 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001252 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001253 elif re.search( "Error", response ):
1254 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001255 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001256 elif re.search( "usage:", response ):
1257 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001258 return main.FALSE
1259 else:
1260 return main.TRUE
1261 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001262 main.log.error( self.name + ": EOF exception found" )
1263 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001264 main.cleanup()
1265 main.exit()
1266
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001268 """
1269 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001270 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001271 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001272 NOTE: this uses a custom mn function
1273 required params:
1274 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001275 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001276 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001277 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001278 response = self.execute(
1279 cmd=command,
1280 prompt="mininet>",
1281 timeout=10 )
1282 if re.search( "no host named", response ):
1283 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001284 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001285 elif re.search( "Error", response ):
1286 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001287 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001288 elif re.search( "usage:", response ):
1289 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001290 return main.FALSE
1291 else:
1292 return main.TRUE
1293 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001294 main.log.error( self.name + ": EOF exception found" )
1295 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001296 main.cleanup()
1297 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001298
Jon Hall7eb38402015-01-08 17:19:54 -08001299 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001300 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001301 Called at the end of the test to stop the mininet and
1302 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001303 """
1304 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001305 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001306 timeout=2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001307 if i == 0:
1308 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001309 elif i == 1:
1310 return main.TRUE
1311 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001312 # print "Disconnecting Mininet"
1313 if self.handle:
1314 self.handle.sendline( "exit" )
1315 self.handle.expect( "exit" )
1316 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001317 else:
1318 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001319 return response
1320
Hari Krishnab35c6d02015-03-18 11:13:51 -07001321 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001322 """
Jon Hall21270ac2015-02-16 17:59:55 -08001323 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001324 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001325 main.FALSE if the pexpect handle does not exist.
1326
Jon Halld61331b2015-02-17 16:35:47 -08001327 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001328 """
Jon Hall21270ac2015-02-16 17:59:55 -08001329
Jon Halld61331b2015-02-17 16:35:47 -08001330 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001331 response = ''
1332 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001333 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001334 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001335 i = self.handle.expect( [ 'mininet>',
1336 '\$',
1337 pexpect.EOF,
1338 pexpect.TIMEOUT ],
1339 timeout )
1340 if i == 0:
1341 main.log.info( "Exiting mininet..." )
1342
Jon Hall7eb38402015-01-08 17:19:54 -08001343 response = self.execute(
1344 cmd="exit",
1345 prompt="(.*)",
1346 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001347 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001348 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001349 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001350
kelvin-onlab56a3f462015-02-06 14:04:43 -08001351 if i == 1:
1352 main.log.info( " Mininet trying to exit while not " +
1353 "in the mininet prompt" )
1354 elif i == 2:
1355 main.log.error( "Something went wrong exiting mininet" )
1356 elif i == 3: # timeout
1357 main.log.error( "Something went wrong exiting mininet " +
1358 "TIMEOUT" )
1359
Hari Krishnab35c6d02015-03-18 11:13:51 -07001360 if fileName:
1361 self.handle.sendline("")
1362 self.handle.expect('\$')
1363 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001364 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001365 main.log.error( self.name + ": EOF exception found" )
1366 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001367 main.cleanup()
1368 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001369 else:
1370 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001371 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001372 return response
1373
kelvin-onlab65782a82015-05-07 14:12:13 -07001374 def arping( self, host="", ip="10.128.20.211" ):
1375 """
1376 Description:
1377 Sends arp message from mininet host for hosts discovery
1378 Required:
1379 host - hosts name
1380 Optional:
1381 ip - ip address that does not exist in the network so there would
1382 be no reply.
1383 """
1384 cmd = " py " + host + ".cmd(\"arping -c 1 " + ip + "\")"
admin07529932013-11-22 14:58:28 -08001385 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001386 main.log.warn( "Sending: " + cmd )
1387 self.handle.sendline( cmd )
1388 response = self.handle.before
1389 self.handle.sendline( "" )
1390 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001391 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001392
1393 except pexpect.EOF:
1394 main.log.error( self.name + ": EOF exception found" )
1395 main.log.error( self.name + ": " + self.handle.before )
1396 main.cleanup()
1397 main.exit()
admin07529932013-11-22 14:58:28 -08001398
Jon Hall7eb38402015-01-08 17:19:54 -08001399 def decToHex( self, num ):
1400 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001401
Jon Hall7eb38402015-01-08 17:19:54 -08001402 def getSwitchFlowCount( self, switch ):
1403 """
1404 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001405 if self.handle:
1406 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1407 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001408 response = self.execute(
1409 cmd=cmd,
1410 prompt="mininet>",
1411 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001412 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001413 main.log.error( self.name + ": EOF exception found" )
1414 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001415 main.cleanup()
1416 main.exit()
1417 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001418 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001419 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001420 main.log.info(
1421 "Couldn't find flows on switch %s, found: %s" %
1422 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001423 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001424 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001425 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001427
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 def checkFlows( self, sw, dumpFormat=None ):
1429 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001430 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001432 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001433 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001434 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001435 response = self.execute(
1436 cmd=command,
1437 prompt="mininet>",
1438 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001439 return response
1440 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001441 main.log.error( self.name + ": EOF exception found" )
1442 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001443 main.cleanup()
1444 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001445
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001447 """
Jon Hallefbd9792015-03-05 16:11:36 -08001448 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001449 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001450 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001451 self.handle.sendline( "" )
1452 self.handle.expect( "mininet>" )
1453 self.handle.sendline(
1454 "sh sudo tcpdump -n -i " +
1455 intf +
1456 " " +
1457 port +
1458 " -w " +
1459 filename.strip() +
1460 " &" )
1461 self.handle.sendline( "" )
1462 i = self.handle.expect( [ 'No\ssuch\device',
1463 'listening\son',
1464 pexpect.TIMEOUT,
1465 "mininet>" ],
1466 timeout=10 )
1467 main.log.warn( self.handle.before + self.handle.after )
1468 self.handle.sendline( "" )
1469 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001470 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001471 main.log.error(
1472 self.name +
1473 ": tcpdump - No such device exists. " +
1474 "tcpdump attempted on: " +
1475 intf )
admin2a9548d2014-06-17 14:08:07 -07001476 return main.FALSE
1477 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001478 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001479 return main.TRUE
1480 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001481 main.log.error(
1482 self.name +
1483 ": tcpdump command timed out! Check interface name," +
1484 " given interface was: " +
1485 intf )
admin2a9548d2014-06-17 14:08:07 -07001486 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001487 elif i == 3:
1488 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001489 return main.TRUE
1490 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001491 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001492 return main.FALSE
1493 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001494 main.log.error( self.name + ": EOF exception found" )
1495 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001496 main.cleanup()
1497 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001498 except Exception:
1499 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001500 main.cleanup()
1501 main.exit()
1502
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001504 """
1505 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001506 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001507 self.handle.sendline( "sh sudo pkill tcpdump" )
1508 self.handle.expect( "mininet>" )
1509 self.handle.sendline( "" )
1510 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001511 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001512 main.log.error( self.name + ": EOF exception found" )
1513 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001514 main.cleanup()
1515 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001516 except Exception:
1517 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001518 main.cleanup()
1519 main.exit()
1520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001522 """
1523 Compare mn and onos switches
1524 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001526
Jon Hall7eb38402015-01-08 17:19:54 -08001527 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001529 output = { "switches": [] }
1530 # iterate through the MN topology and pull out switches and and port
1531 # info
1532 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001533 ports = []
1534 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001535 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001536 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001537 'name': port.name } )
1538 output[ 'switches' ].append( {
1539 "name": switch.name,
1540 "dpid": str( switch.dpid ).zfill( 16 ),
1541 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001542
Jon Hall7eb38402015-01-08 17:19:54 -08001543 # print "mn"
1544 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001545 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001546 # indent=4,
1547 # separators=( ',', ': ' ) )
1548 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001550 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001551 # indent=4,
1552 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001553
1554 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001555 mnDPIDs = []
1556 for switch in output[ 'switches' ]:
1557 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001558 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001559 # print "List of Mininet switch DPID's"
1560 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001562 main.log.error(
1563 self.name +
1564 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001565 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001567 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001568 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001569 if switch[ 'available' ]:
1570 onosDPIDs.append(
1571 switch[ 'id' ].replace(
1572 ":",
1573 '' ).replace(
1574 "of",
1575 '' ).lower() )
1576 # else:
1577 # print "Switch is unavailable:"
1578 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001579 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001580 # print "List of ONOS switch DPID's"
1581 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001582
Jon Hall7eb38402015-01-08 17:19:54 -08001583 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001585 main.log.report( "Switches in MN but not in ONOS:" )
1586 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1587 main.log.report( str( list1 ) )
1588 main.log.report( "Switches in ONOS but not in MN:" )
1589 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001590 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001591 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 switchResults = main.TRUE
1593 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001594
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001596 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001597 Compare mn and onos ports
1598 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001600
Jon Hallfbc828e2015-01-06 17:30:19 -08001601 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001602 1. This uses the sts TestONTopology object
1603 2. numpy - "sudo pip install numpy"
1604
Jon Hall7eb38402015-01-08 17:19:54 -08001605 """
1606 # FIXME: this does not look for extra ports in ONOS, only checks that
1607 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001608 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001610 output = { "switches": [] }
1611 # iterate through the MN topology and pull out switches and and port
1612 # info
1613 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001614 ports = []
1615 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001616 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001617 tmpPort = { 'of_port': port.port_no,
1618 'mac': str( port.hw_addr ).replace( '\'', '' ),
1619 'name': port.name,
1620 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001621
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001623 tmpSwitch = { 'name': switch.name,
1624 'dpid': str( switch.dpid ).zfill( 16 ),
1625 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001626
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001628
Jon Hall7eb38402015-01-08 17:19:54 -08001629 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 for mnSwitch in output[ 'switches' ]:
1631 mnPorts = []
1632 onosPorts = []
1633 switchResult = main.TRUE
1634 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001635 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 mnPorts.append( port[ 'of_port' ] )
1637 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001638 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001639 # print onosSwitch
1640 if onosSwitch[ 'device' ][ 'available' ]:
1641 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001642 ':',
1643 '' ).replace(
1644 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 '' ) == mnSwitch[ 'dpid' ]:
1646 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001647 if port[ 'isEnabled' ]:
1648 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 # onosPorts.append( 'local' )
1650 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001651 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001653 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001654 mnPorts.sort( key=float )
1655 onosPorts.sort( key=float )
1656 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1657 # print "\tmn_ports[] = ", mnPorts
1658 # print "\tonos_ports[] = ", onosPorts
1659 mnPortsLog = mnPorts
1660 onosPortsLog = onosPorts
1661 mnPorts = [ x for x in mnPorts ]
1662 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001663
Jon Hall7eb38402015-01-08 17:19:54 -08001664 # TODO: handle other reserved port numbers besides LOCAL
1665 # NOTE: Reserved ports
1666 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1667 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 for mnPort in mnPortsLog:
1669 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001670 # don't set results to true here as this is just one of
1671 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 mnPorts.remove( mnPort )
1673 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001674 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001675 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001676 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 if 65534 in mnPorts:
1678 mnPorts.remove( 65534 )
1679 if long( uint64( -2 ) ) in onosPorts:
1680 onosPorts.remove( long( uint64( -2 ) ) )
1681 if len( mnPorts ): # the ports of this switch don't match
1682 switchResult = main.FALSE
1683 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1684 if len( onosPorts ): # the ports of this switch don't match
1685 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001686 main.log.warn(
1687 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001688 str( onosPorts ) )
1689 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001690 main.log.report(
1691 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1693 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1694 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1695 portsResults = portsResults and switchResult
1696 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001697
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001699 """
1700 Compare mn and onos links
1701 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001702 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001703
Jon Hall7eb38402015-01-08 17:19:54 -08001704 This uses the sts TestONTopology object"""
1705 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001706 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001707 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001708 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001709 # iterate through the MN topology and pull out switches and and port
1710 # info
1711 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001712 # print "Iterating though switches as seen by Mininet"
1713 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001714 ports = []
1715 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001716 # print port.hw_addr.toStr( separator='' )
1717 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001718 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001719 'name': port.name } )
1720 output[ 'switches' ].append( {
1721 "name": switch.name,
1722 "dpid": str( switch.dpid ).zfill( 16 ),
1723 "ports": ports } )
1724 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001725
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001727 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001728 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001729 if 2 * len( mnLinks ) == len( onos ):
1730 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001731 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001732 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001733 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001734 "Mininet has " + str( len( mnLinks ) ) +
1735 " bidirectional links and ONOS has " +
1736 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001737
Jon Hall7eb38402015-01-08 17:19:54 -08001738 # iterate through MN links and check if an ONOS link exists in
1739 # both directions
1740 # NOTE: Will currently only show mn links as down if they are
1741 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001743 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001745 # print "Link: %s" % link
1746 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001747 node1 = None
1748 port1 = None
1749 node2 = None
1750 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001751 firstDir = main.FALSE
1752 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001753 for switch in output[ 'switches' ]:
1754 # print "Switch: %s" % switch[ 'name' ]
1755 if switch[ 'name' ] == link.node1.name:
1756 node1 = switch[ 'dpid' ]
1757 for port in switch[ 'ports' ]:
1758 if str( port[ 'name' ] ) == str( link.port1 ):
1759 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001760 if node1 is not None and node2 is not None:
1761 break
Jon Hall7eb38402015-01-08 17:19:54 -08001762 if switch[ 'name' ] == link.node2.name:
1763 node2 = switch[ 'dpid' ]
1764 for port in switch[ 'ports' ]:
1765 if str( port[ 'name' ] ) == str( link.port2 ):
1766 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001767 if node1 is not None and node2 is not None:
1768 break
1769
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 for onosLink in onos:
1771 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001772 ":",
1773 '' ).replace(
1774 "of",
1775 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001777 ":",
1778 '' ).replace(
1779 "of",
1780 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 onosPort1 = onosLink[ 'src' ][ 'port' ]
1782 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001783
Jon Hall72cf1dc2014-10-20 21:04:50 -04001784 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 if str( onosNode1 ) == str( node1 ) and str(
1786 onosNode2 ) == str( node2 ):
1787 if int( onosPort1 ) == int( port1 ) and int(
1788 onosPort2 ) == int( port2 ):
1789 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001790 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001791 main.log.warn(
1792 'The port numbers do not match for ' +
1793 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001794 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001795 'link %s/%s -> %s/%s' %
1796 ( node1,
1797 port1,
1798 node2,
1799 port2 ) +
1800 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 ( onosNode1,
1802 onosPort1,
1803 onosNode2,
1804 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001805
1806 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001807 elif ( str( onosNode1 ) == str( node2 ) and
1808 str( onosNode2 ) == str( node1 ) ):
1809 if ( int( onosPort1 ) == int( port2 )
1810 and int( onosPort2 ) == int( port1 ) ):
1811 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001812 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001813 main.log.warn(
1814 'The port numbers do not match for ' +
1815 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001816 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001817 'link %s/%s -> %s/%s' %
1818 ( node2,
1819 port2,
1820 node1,
1821 port1 ) +
1822 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001823 ( onosNode2,
1824 onosPort2,
1825 onosNode1,
1826 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001827 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001828 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001829 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001830 main.log.report(
1831 'ONOS does not have the link %s/%s -> %s/%s' %
1832 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001834 main.log.report(
1835 'ONOS does not have the link %s/%s -> %s/%s' %
1836 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001837 linkResults = linkResults and firstDir and secondDir
1838 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001839
Jon Hallff6b4b22015-02-23 09:25:15 -08001840 def compareHosts( self, topo, hostsJson ):
1841 """
1842 Compare mn and onos Hosts.
1843 Since Mininet hosts are quiet, ONOS will only know of them when they
1844 speak. For this reason, we will only check that the hosts in ONOS
1845 stores are in Mininet, and not vice versa.
1846 topo: sts TestONTopology object
1847 hostsJson: parsed json object from the onos hosts api
1848
1849 This uses the sts TestONTopology object"""
1850 import json
1851 hostResults = main.TRUE
1852 hosts = []
1853 # iterate through the MN topology and pull out hosts
1854 for mnHost in topo.graph.hosts:
1855 interfaces = []
1856 for intf in mnHost.interfaces:
1857 interfaces.append( {
1858 "name": intf.name, # str
1859 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1860 # hw_addr is of type EthAddr, Not JSON serializable
1861 "hw_addr": str( intf.hw_addr ) } )
1862 hosts.append( {
1863 "name": mnHost.name, # str
1864 "interfaces": interfaces } ) # list
1865 for onosHost in hostsJson:
1866 onosMAC = onosHost[ 'mac' ].lower()
1867 match = False
1868 for mnHost in hosts:
1869 for mnIntf in mnHost[ 'interfaces' ]:
1870 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1871 match = True
1872 for ip in mnIntf[ 'ips' ]:
1873 if ip in onosHost[ 'ips' ]:
1874 pass # all is well
1875 else:
1876 # misssing ip
1877 main.log.error( "ONOS host " + onosHost[ 'id' ]
1878 + " has a different IP than " +
1879 "the Mininet host." )
1880 output = json.dumps(
1881 onosHost,
1882 sort_keys=True,
1883 indent=4,
1884 separators=( ',', ': ' ) )
1885 main.log.info( output )
1886 hostResults = main.FALSE
1887 if not match:
1888 hostResults = main.FALSE
1889 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1890 "corresponding Mininet host." )
1891 output = json.dumps( onosHost,
1892 sort_keys=True,
1893 indent=4,
1894 separators=( ',', ': ' ) )
1895 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001896 return hostResults
1897
kelvin-onlabd3b64892015-01-20 13:26:24 -08001898 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001899 """
1900 Returns a list of all hosts
1901 Don't ask questions just use it"""
1902 self.handle.sendline( "" )
1903 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001904
Jon Hall7eb38402015-01-08 17:19:54 -08001905 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1906 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001907
kelvin-onlabd3b64892015-01-20 13:26:24 -08001908 handlePy = self.handle.before
1909 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1910 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001911
Jon Hall7eb38402015-01-08 17:19:54 -08001912 self.handle.sendline( "" )
1913 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001914
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 hostStr = handlePy.replace( "]", "" )
1916 hostStr = hostStr.replace( "'", "" )
1917 hostStr = hostStr.replace( "[", "" )
1918 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001919
kelvin-onlabd3b64892015-01-20 13:26:24 -08001920 return hostList
adminbae64d82013-08-01 10:50:15 -07001921
Jon Hall7eb38402015-01-08 17:19:54 -08001922 def update( self ):
1923 """
1924 updates the port address and status information for
1925 each port in mn"""
1926 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001927 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001928 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001929 self.handle.sendline( "" )
1930 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001931
Jon Hall7eb38402015-01-08 17:19:54 -08001932 self.handle.sendline( "update" )
1933 self.handle.expect( "update" )
1934 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001935
Jon Hall7eb38402015-01-08 17:19:54 -08001936 self.handle.sendline( "" )
1937 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001938
Jon Hallb1290e82014-11-18 16:17:48 -05001939 return main.TRUE
1940 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001941 main.log.error( self.name + ": EOF exception found" )
1942 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001943 main.cleanup()
1944 main.exit()
1945
adminbae64d82013-08-01 10:50:15 -07001946if __name__ != "__main__":
1947 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07001948 sys.modules[ __name__ ] = MininetCliDriver()