blob: ad50b9c21c2147f250c5db7680535bc309cc6ae8 [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:
Jon Hall390696c2015-05-05 17:13:41 -0700255 timeout(seconds) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700256 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700257 ping
258 acceptableFailed - Set the number of acceptable failed pings for the
259 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800260 Returns:
261 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700262 otherwise main.FALSE
263 """
264 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700265 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700266 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700267 if self.handle:
268 main.log.info(
269 self.name +
270 ": Checking reachabilty to the hosts using pingall" )
271 response = ""
272 failedPings = 0
273 returnValue = main.TRUE
274 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700275 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700276 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
Jon Hall390696c2015-05-05 17:13:41 -0700296 if ( time.time() - startTime ) > timeout:
297 returnValue = main.FALSE
298 main.log.error( self.name +
299 ": Aborting pingall - " +
300 "Function took too long " )
301 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700302 elif i == 2:
303 main.log.error( self.name +
304 ": EOF exception found" )
305 main.log.error( self.name + ": " +
306 self.handle.before )
307 main.cleanup()
308 main.exit()
309 elif i == 3:
310 response += self.handle.before
311 main.log.error( self.name +
312 ": TIMEOUT exception found" )
313 main.log.error( self.name +
314 ": " +
315 str( response ) )
316 # NOTE: Send ctrl-c to make sure pingall is done
317 self.handle.sendline( "\x03" )
318 self.handle.expect( "Interrupt" )
319 self.handle.expect( "mininet>" )
320 break
321 pattern = "Results\:"
322 main.log.info( "Pingall output: " + str( response ) )
323 if re.search( pattern, response ):
324 main.log.info( self.name + ": Pingall finished with "
325 + str( failedPings ) + " failed pings" )
326 return returnValue
327 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700328 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700329 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700330 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700331 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700332 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700333 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700334 main.log.error( self.name + ": Connection failed to the host" )
335 main.cleanup()
336 main.exit()
337 except pexpect.TIMEOUT:
338 if response:
339 main.log.info( "Pingall output: " + str( response ) )
340 main.log.error( self.name + ": pexpect.TIMEOUT found" )
341 return main.FALSE
342 except pexpect.EOF:
343 main.log.error( self.name + ": EOF exception found" )
344 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500345 main.cleanup()
346 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700347
Jon Hall7eb38402015-01-08 17:19:54 -0800348 def fpingHost( self, **pingParams ):
349 """
350 Uses the fping package for faster pinging...
351 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800352 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800353 command = args[ "SRC" ] + \
354 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
355 self.handle.sendline( command )
356 self.handle.expect(
357 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
358 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
359 response = self.handle.before
360 if re.search( ":\s-", response ):
361 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700362 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800363 elif re.search( ":\s\d{1,2}\.\d\d", response ):
364 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700365 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800366 main.log.info( self.name + ": Install fping on mininet machine... " )
367 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700368 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800369
Jon Hall7eb38402015-01-08 17:19:54 -0800370 def pingHost( self, **pingParams ):
371 """
372 Ping from one mininet host to another
373 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800374 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800375 command = args[ "SRC" ] + " ping " + \
376 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700377 try:
Jon Hall61282e32015-03-19 11:34:11 -0700378 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800379 self.handle.sendline( command )
380 i = self.handle.expect( [ command, 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 ) )
386 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700387 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800388 main.log.error(
389 self.name +
390 ": timeout when waiting for response from mininet" )
391 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700392 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800393 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800394 main.log.error( self.name + ": EOF exception found" )
395 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700396 main.cleanup()
397 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800398 main.log.info( self.name + ": Ping Response: " + response )
399 if re.search( ',\s0\%\spacket\sloss', response ):
400 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800401 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700402 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800403 else:
404 main.log.error(
405 self.name +
406 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800407 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700408 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800409
Jon Hall7eb38402015-01-08 17:19:54 -0800410 def checkIP( self, host ):
411 """
412 Verifies the host's ip configured or not."""
413 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700414 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800415 response = self.execute(
416 cmd=host +
417 " ifconfig",
418 prompt="mininet>",
419 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800420 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800421 main.log.error( self.name + ": EOF exception found" )
422 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700423 main.cleanup()
424 main.exit()
adminbae64d82013-08-01 10:50:15 -0700425
Jon Hall7eb38402015-01-08 17:19:54 -0800426 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800427 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
428 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
429 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
430 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
431 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800432 # pattern = "inet addr:10.0.0.6"
433 if re.search( pattern, response ):
434 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700435 return main.TRUE
436 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800437 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700438 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800439 else:
440 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800441
Jon Hall7eb38402015-01-08 17:19:54 -0800442 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800443 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700444 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800445 response = self.execute(
446 cmd="h1 /usr/sbin/sshd -D&",
447 prompt="mininet>",
448 timeout=10 )
449 response = self.execute(
450 cmd="h4 /usr/sbin/sshd -D&",
451 prompt="mininet>",
452 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700453 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800454 vars( self )[ key ] = connectargs[ key ]
455 response = self.execute(
456 cmd="xterm h1 h4 ",
457 prompt="mininet>",
458 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800459 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800460 main.log.error( self.name + ": EOF exception found" )
461 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700462 main.cleanup()
463 main.exit()
adminbae64d82013-08-01 10:50:15 -0700464 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800465 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700466 if self.flag == 0:
467 self.flag = 1
468 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800469 else:
adminbae64d82013-08-01 10:50:15 -0700470 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800471
kelvin-onlaba1484582015-02-02 15:46:20 -0800472 def moveHost( self, host, oldSw, newSw, ):
473 """
474 Moves a host from one switch to another on the fly
475 Note: The intf between host and oldSw when detached
476 using detach(), will still show up in the 'net'
477 cmd, because switch.detach() doesn't affect switch.intfs[]
478 (which is correct behavior since the interfaces
479 haven't moved).
480 """
481 if self.handle:
482 try:
483 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800484 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
485 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800486 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800487 response = self.execute( cmd=cmd,
488 prompt="mininet>",
489 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800490
491 # Determine hostintf and Oldswitchintf
492 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800493 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800494 print "cmd2= ", cmd
495 self.handle.sendline( cmd )
496 self.handle.expect( "mininet>" )
497
shahshreya73537862015-02-11 15:15:24 -0800498 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800499 cmd = "px ipaddr = hintf.IP()"
500 print "cmd3= ", cmd
501 self.handle.sendline( cmd )
502 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800503
504 cmd = "px macaddr = hintf.MAC()"
505 print "cmd3= ", cmd
506 self.handle.sendline( cmd )
507 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800508
509 # Detach interface between oldSw-host
510 cmd = "px " + oldSw + ".detach( sintf )"
511 print "cmd4= ", cmd
512 self.handle.sendline( cmd )
513 self.handle.expect( "mininet>" )
514
515 # Add link between host-newSw
516 cmd = "py net.addLink(" + host + "," + newSw + ")"
517 print "cmd5= ", cmd
518 self.handle.sendline( cmd )
519 self.handle.expect( "mininet>" )
520
521 # Determine hostintf and Newswitchintf
522 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800523 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800524 print "cmd6= ", cmd
525 self.handle.sendline( cmd )
526 self.handle.expect( "mininet>" )
527
528 # Attach interface between newSw-host
529 cmd = "px " + newSw + ".attach( sintf )"
530 print "cmd3= ", cmd
531 self.handle.sendline( cmd )
532 self.handle.expect( "mininet>" )
533
534 # Set ipaddress of the host-newSw interface
535 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
536 print "cmd7 = ", cmd
537 self.handle.sendline( cmd )
538 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800539
540 # Set macaddress of the host-newSw interface
541 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
542 print "cmd8 = ", cmd
543 self.handle.sendline( cmd )
544 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800545
546 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800547 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800548 self.handle.sendline( cmd )
549 self.handle.expect( "mininet>" )
550 print "output = ", self.handle.before
551
552 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800553 cmd = host + " ifconfig"
554 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800555 self.handle.sendline( cmd )
556 self.handle.expect( "mininet>" )
557 print "ifconfig o/p = ", self.handle.before
558
559 return main.TRUE
560 except pexpect.EOF:
561 main.log.error( self.name + ": EOF exception found" )
562 main.log.error( self.name + ": " + self.handle.before )
563 return main.FALSE
564
Jon Hall7eb38402015-01-08 17:19:54 -0800565 def changeIP( self, host, intf, newIP, newNetmask ):
566 """
567 Changes the ip address of a host on the fly
568 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800569 if self.handle:
570 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800571 cmd = host + " ifconfig " + intf + " " + \
572 newIP + " " + 'netmask' + " " + newNetmask
573 self.handle.sendline( cmd )
574 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800575 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800576 main.log.info( "response = " + response )
577 main.log.info(
578 "Ip of host " +
579 host +
580 " changed to new IP " +
581 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800582 return main.TRUE
583 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800584 main.log.error( self.name + ": EOF exception found" )
585 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800586 return main.FALSE
587
Jon Hall7eb38402015-01-08 17:19:54 -0800588 def changeDefaultGateway( self, host, newGW ):
589 """
590 Changes the default gateway of a host
591 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800592 if self.handle:
593 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800594 cmd = host + " route add default gw " + newGW
595 self.handle.sendline( cmd )
596 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800597 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800598 main.log.info( "response = " + response )
599 main.log.info(
600 "Default gateway of host " +
601 host +
602 " changed to " +
603 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800604 return main.TRUE
605 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800606 main.log.error( self.name + ": EOF exception found" )
607 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800608 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800609
Jon Hall7eb38402015-01-08 17:19:54 -0800610 def addStaticMACAddress( self, host, GW, macaddr ):
611 """
Jon Hallefbd9792015-03-05 16:11:36 -0800612 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800613 if self.handle:
614 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800615 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
616 cmd = host + " arp -s " + GW + " " + macaddr
617 self.handle.sendline( cmd )
618 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800619 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800620 main.log.info( "response = " + response )
621 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800622 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800623 GW +
624 " changed to " +
625 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800626 return main.TRUE
627 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800628 main.log.error( self.name + ": EOF exception found" )
629 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800630 return main.FALSE
631
Jon Hall7eb38402015-01-08 17:19:54 -0800632 def verifyStaticGWandMAC( self, host ):
633 """
634 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800635 if self.handle:
636 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800637 # h1 arp -an
638 cmd = host + " arp -an "
639 self.handle.sendline( cmd )
640 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800641 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800642 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800643 return main.TRUE
644 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800645 main.log.error( self.name + ": EOF exception found" )
646 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800647 return main.FALSE
648
Jon Hall7eb38402015-01-08 17:19:54 -0800649 def getMacAddress( self, host ):
650 """
651 Verifies the host's ip configured or not."""
652 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700653 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800654 response = self.execute(
655 cmd=host +
656 " ifconfig",
657 prompt="mininet>",
658 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800659 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800660 main.log.error( self.name + ": EOF exception found" )
661 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700662 main.cleanup()
663 main.exit()
adminbae64d82013-08-01 10:50:15 -0700664
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700665 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 macAddressSearch = re.search( pattern, response, re.I )
667 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800668 main.log.info(
669 self.name +
670 ": Mac-Address of Host " +
671 host +
672 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800673 macAddress )
674 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700675 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800676 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700677
Jon Hall7eb38402015-01-08 17:19:54 -0800678 def getInterfaceMACAddress( self, host, interface ):
679 """
680 Return the IP address of the interface on the given host"""
681 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700682 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800683 response = self.execute( cmd=host + " ifconfig " + interface,
684 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800685 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800686 main.log.error( self.name + ": EOF exception found" )
687 main.log.error( self.name + ": " + self.handle.before )
688 main.cleanup()
689 main.exit()
690
691 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 macAddressSearch = re.search( pattern, response, re.I )
693 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800694 main.log.info( "No mac address found in %s" % response )
695 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800696 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800697 main.log.info(
698 "Mac-Address of " +
699 host +
700 ":" +
701 interface +
702 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800703 macAddress )
704 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800705 else:
706 main.log.error( "Connection failed to the host" )
707
708 def getIPAddress( self, host ):
709 """
710 Verifies the host's ip configured or not."""
711 if self.handle:
712 try:
713 response = self.execute(
714 cmd=host +
715 " ifconfig",
716 prompt="mininet>",
717 timeout=10 )
718 except pexpect.EOF:
719 main.log.error( self.name + ": EOF exception found" )
720 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700721 main.cleanup()
722 main.exit()
adminbae64d82013-08-01 10:50:15 -0700723
724 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800725 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800726 main.log.info(
727 self.name +
728 ": IP-Address of Host " +
729 host +
730 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 ipAddressSearch.group( 1 ) )
732 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800733 else:
734 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800735
Jon Hall7eb38402015-01-08 17:19:54 -0800736 def getSwitchDPID( self, switch ):
737 """
738 return the datapath ID of the switch"""
739 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700740 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700741 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800742 response = self.execute(
743 cmd=cmd,
744 prompt="mininet>",
745 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800746 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 main.log.error( self.name + ": EOF exception found" )
748 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700749 main.cleanup()
750 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800751 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800752 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700753 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800754 main.log.info(
755 "Couldn't find DPID for switch %s, found: %s" %
756 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700757 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800758 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700759 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800760 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700761
Jon Hall7eb38402015-01-08 17:19:54 -0800762 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700763 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800764 self.handle.sendline( "" )
765 self.expect( "mininet>" )
766 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700767 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800768 response = self.execute(
769 cmd=cmd,
770 prompt="mininet>",
771 timeout=10 )
772 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700773 response = self.handle.before
774 return response
775 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800776 main.log.error( self.name + ": EOF exception found" )
777 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700778 main.cleanup()
779 main.exit()
780
Jon Hall7eb38402015-01-08 17:19:54 -0800781 def getInterfaces( self, node ):
782 """
783 return information dict about interfaces connected to the node"""
784 if self.handle:
785 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800786 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700787 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700788 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800789 response = self.execute(
790 cmd=cmd,
791 prompt="mininet>",
792 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800793 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800794 main.log.error( self.name + ": EOF exception found" )
795 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700796 main.cleanup()
797 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700798 return response
799 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700801
Jon Hall7eb38402015-01-08 17:19:54 -0800802 def dump( self ):
803 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700804 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 response = self.execute(
806 cmd='dump',
807 prompt='mininet>',
808 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800809 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700812 main.cleanup()
813 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700814 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800815
Jon Hall7eb38402015-01-08 17:19:54 -0800816 def intfs( self ):
817 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700818 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 response = self.execute(
820 cmd='intfs',
821 prompt='mininet>',
822 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800823 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800824 main.log.error( self.name + ": EOF exception found" )
825 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700826 main.cleanup()
827 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700828 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800829
Jon Hall7eb38402015-01-08 17:19:54 -0800830 def net( self ):
831 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700832 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800834 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800835 main.log.error( self.name + ": EOF exception found" )
836 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700837 main.cleanup()
838 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700839 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800840
841 def iperf( self, host1, host2 ):
842 main.log.info(
843 self.name +
844 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700845 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800846 cmd1 = 'iperf ' + host1 + " " + host2
847 self.handle.sendline( cmd1 )
848 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800849 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800850 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800851 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800852 return main.TRUE
853 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800854 main.log.error( self.name + ": iperf test failed" )
855 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800856 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800857 main.log.error( self.name + ": EOF exception found" )
858 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800859 main.cleanup()
860 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800861
Jon Hall7eb38402015-01-08 17:19:54 -0800862 def iperfudp( self ):
863 main.log.info(
864 self.name +
865 ": Simple iperf TCP test between two " +
866 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700867 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800868 response = self.execute(
869 cmd='iperfudp',
870 prompt='mininet>',
871 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800872 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800873 main.log.error( self.name + ": EOF exception found" )
874 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700875 main.cleanup()
876 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700877 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800878
Jon Hall7eb38402015-01-08 17:19:54 -0800879 def nodes( self ):
880 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700881 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800882 response = self.execute(
883 cmd='nodes',
884 prompt='mininet>',
885 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800886 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( self.name + ": EOF exception found" )
888 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700889 main.cleanup()
890 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700891 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800892
Jon Hall7eb38402015-01-08 17:19:54 -0800893 def pingpair( self ):
894 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700895 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800896 response = self.execute(
897 cmd='pingpair',
898 prompt='mininet>',
899 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800900 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700903 main.cleanup()
904 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800905
Jon Hall7eb38402015-01-08 17:19:54 -0800906 if re.search( ',\s0\%\spacket\sloss', response ):
907 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700909 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800910 else:
911 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700913 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800914
Jon Hall7eb38402015-01-08 17:19:54 -0800915 def link( self, **linkargs ):
916 """
917 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800918 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800919 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
920 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
921 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
922 main.log.info(
923 "Bring link between '" +
924 end1 +
925 "' and '" +
926 end2 +
927 "' '" +
928 option +
929 "'" )
930 command = "link " + \
931 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700932 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800933 self.handle.sendline( command )
934 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800935 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800936 main.log.error( self.name + ": EOF exception found" )
937 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700938 main.cleanup()
939 main.exit()
adminbae64d82013-08-01 10:50:15 -0700940 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800941
Jon Hall7eb38402015-01-08 17:19:54 -0800942 def yank( self, **yankargs ):
943 """
944 yank a mininet switch interface to a host"""
945 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800946 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800947 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
948 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
949 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700950 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800951 response = self.execute(
952 cmd=command,
953 prompt="mininet>",
954 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800955 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700958 main.cleanup()
959 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700960 return main.TRUE
961
Jon Hall7eb38402015-01-08 17:19:54 -0800962 def plug( self, **plugargs ):
963 """
964 plug the yanked mininet switch interface to a switch"""
965 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800966 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800967 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
968 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
969 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700970 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800971 response = self.execute(
972 cmd=command,
973 prompt="mininet>",
974 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800975 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800976 main.log.error( self.name + ": EOF exception found" )
977 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700978 main.cleanup()
979 main.exit()
adminbae64d82013-08-01 10:50:15 -0700980 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800981
Jon Hall7eb38402015-01-08 17:19:54 -0800982 def dpctl( self, **dpctlargs ):
983 """
984 Run dpctl command on all switches."""
985 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800986 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800987 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
988 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
989 command = "dpctl " + cmd + " " + str( cmdargs )
990 try:
991 response = self.execute(
992 cmd=command,
993 prompt="mininet>",
994 timeout=10 )
995 except pexpect.EOF:
996 main.log.error( self.name + ": EOF exception found" )
997 main.log.error( self.name + ": " + self.handle.before )
998 main.cleanup()
999 main.exit()
1000 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001001
kelvin-onlabd3b64892015-01-20 13:26:24 -08001002 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -08001003 #FIXME: What uses this? This should be refactored to get
1004 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 fileInput = path + '/lib/Mininet/INSTALL'
1006 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001007 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001009 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001010 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001011 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001012 return version
adminbae64d82013-08-01 10:50:15 -07001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001015 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001016 Parameters:
1017 sw: The name of an OVS switch. Example "s1"
1018 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001019 The output of the command from the mininet cli
1020 or main.FALSE on timeout"""
1021 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001022 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001023 response = self.execute(
1024 cmd=command,
1025 prompt="mininet>",
1026 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001027 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001028 return response
admin2a9548d2014-06-17 14:08:07 -07001029 else:
1030 return main.FALSE
1031 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001032 main.log.error( self.name + ": EOF exception found" )
1033 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001034 main.cleanup()
1035 main.exit()
adminbae64d82013-08-01 10:50:15 -07001036
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001038 """
1039 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001040 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001041 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001042
1043 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001044 for j in range( count ):
1045 argstring = argstring + ",IP" + \
1046 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001047 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001048
Jon Hall7eb38402015-01-08 17:19:54 -08001049 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1050 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001051 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001052 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001053
Jon Hall7eb38402015-01-08 17:19:54 -08001054 command = "sh ovs-vsctl set-controller s" + \
1055 str( sw ) + " " + ptcpB + " "
1056 for j in range( count ):
1057 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001058 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001059 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1060 ip = args[
1061 "IP" +
1062 str( i ) ] if args[
1063 "IP" +
1064 str( i ) ] is not None else ""
1065 port = args[
1066 "PORT" +
1067 str( i ) ] if args[
1068 "PORT" +
1069 str( i ) ] is not None else ""
1070 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001071 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001072 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001073 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001074 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001075 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001076 main.log.error( self.name + ": EOF exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001078 main.cleanup()
1079 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001080 except Exception:
1081 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001082 main.cleanup()
1083 main.exit()
adminbae64d82013-08-01 10:50:15 -07001084
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001086 """
1087 Removes the controller target from sw"""
1088 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001089 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001090 response = self.execute(
1091 cmd=command,
1092 prompt="mininet>",
1093 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001094 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001095 main.log.error( self.name + ": EOF exception found" )
1096 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001097 main.cleanup()
1098 main.exit()
1099 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001100 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001103 """
Jon Hallb1290e82014-11-18 16:17:48 -05001104 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001105 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001106 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001107 NOTE: cannot currently specify what type of switch
1108 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001109 sw = name of the new switch as a string
1110 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001111 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001112 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001113 """
1114 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001115 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001116 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 response = self.execute(
1118 cmd=command,
1119 prompt="mininet>",
1120 timeout=10 )
1121 if re.search( "already exists!", response ):
1122 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001123 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001124 elif re.search( "Error", response ):
1125 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001126 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001127 elif re.search( "usage:", response ):
1128 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001129 return main.FALSE
1130 else:
1131 return main.TRUE
1132 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 main.log.error( self.name + ": EOF exception found" )
1134 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001135 main.cleanup()
1136 main.exit()
1137
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001139 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001140 delete a switch from the mininet topology
1141 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001142 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001143 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001144 sw = name of the switch as a string
1145 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001146 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001147 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001148 response = self.execute(
1149 cmd=command,
1150 prompt="mininet>",
1151 timeout=10 )
1152 if re.search( "no switch named", response ):
1153 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001154 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001155 elif re.search( "Error", response ):
1156 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001157 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001158 elif re.search( "usage:", response ):
1159 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001160 return main.FALSE
1161 else:
1162 return main.TRUE
1163 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001164 main.log.error( self.name + ": EOF exception found" )
1165 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001166 main.cleanup()
1167 main.exit()
1168
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001170 """
1171 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001172 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001173 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001174 NOTE: cannot currently specify what type of link
1175 required params:
1176 node1 = the string node name of the first endpoint of the link
1177 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001178 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001179 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001180 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 response = self.execute(
1182 cmd=command,
1183 prompt="mininet>",
1184 timeout=10 )
1185 if re.search( "doesnt exist!", response ):
1186 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001187 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001188 elif re.search( "Error", response ):
1189 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001190 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001191 elif re.search( "usage:", response ):
1192 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001193 return main.FALSE
1194 else:
1195 return main.TRUE
1196 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001197 main.log.error( self.name + ": EOF exception found" )
1198 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001199 main.cleanup()
1200 main.exit()
1201
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001203 """
1204 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001205 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001206 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001207 required params:
1208 node1 = the string node name of the first endpoint of the link
1209 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001210 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001211 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001212 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001213 response = self.execute(
1214 cmd=command,
1215 prompt="mininet>",
1216 timeout=10 )
1217 if re.search( "no node named", response ):
1218 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001219 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001220 elif re.search( "Error", response ):
1221 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001222 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001223 elif re.search( "usage:", response ):
1224 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001225 return main.FALSE
1226 else:
1227 return main.TRUE
1228 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001229 main.log.error( self.name + ": EOF exception found" )
1230 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001231 main.cleanup()
1232 main.exit()
1233
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001235 """
Jon Hallb1290e82014-11-18 16:17:48 -05001236 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001237 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001238 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001239 NOTE: cannot currently specify what type of host
1240 required params:
1241 hostname = the string hostname
1242 optional key-value params
1243 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001244 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001245 """
1246 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001247 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001248 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 response = self.execute(
1250 cmd=command,
1251 prompt="mininet>",
1252 timeout=10 )
1253 if re.search( "already exists!", 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( "doesnt exists!", response ):
1257 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001258 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001259 elif re.search( "Error", response ):
1260 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001261 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001262 elif re.search( "usage:", response ):
1263 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001264 return main.FALSE
1265 else:
1266 return main.TRUE
1267 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001268 main.log.error( self.name + ": EOF exception found" )
1269 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001270 main.cleanup()
1271 main.exit()
1272
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001274 """
1275 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001276 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001277 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001278 NOTE: this uses a custom mn function
1279 required params:
1280 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001281 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001282 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001283 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001284 response = self.execute(
1285 cmd=command,
1286 prompt="mininet>",
1287 timeout=10 )
1288 if re.search( "no host named", response ):
1289 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001290 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001291 elif re.search( "Error", response ):
1292 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001293 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001294 elif re.search( "usage:", response ):
1295 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001296 return main.FALSE
1297 else:
1298 return main.TRUE
1299 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001300 main.log.error( self.name + ": EOF exception found" )
1301 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001302 main.cleanup()
1303 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001304
Jon Hall7eb38402015-01-08 17:19:54 -08001305 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001306 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001307 Called at the end of the test to stop the mininet and
1308 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001309 """
1310 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001311 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001312 timeout=2)
Jon Hall390696c2015-05-05 17:13:41 -07001313 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001314 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001315 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001316 elif i == 1:
1317 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001318 # print "Disconnecting Mininet"
1319 if self.handle:
1320 self.handle.sendline( "exit" )
1321 self.handle.expect( "exit" )
1322 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001323 else:
1324 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001325 return response
1326
Hari Krishnab35c6d02015-03-18 11:13:51 -07001327 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001328 """
Jon Hall21270ac2015-02-16 17:59:55 -08001329 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001330 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001331 main.FALSE if the pexpect handle does not exist.
1332
Jon Halld61331b2015-02-17 16:35:47 -08001333 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001334 """
Jon Hall21270ac2015-02-16 17:59:55 -08001335
Jon Halld61331b2015-02-17 16:35:47 -08001336 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001337 response = ''
1338 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001339 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001340 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001341 i = self.handle.expect( [ 'mininet>',
1342 '\$',
1343 pexpect.EOF,
1344 pexpect.TIMEOUT ],
1345 timeout )
1346 if i == 0:
1347 main.log.info( "Exiting mininet..." )
1348
Jon Hall7eb38402015-01-08 17:19:54 -08001349 response = self.execute(
1350 cmd="exit",
1351 prompt="(.*)",
1352 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001353 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001354 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001355 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001356
kelvin-onlab56a3f462015-02-06 14:04:43 -08001357 if i == 1:
1358 main.log.info( " Mininet trying to exit while not " +
1359 "in the mininet prompt" )
1360 elif i == 2:
1361 main.log.error( "Something went wrong exiting mininet" )
1362 elif i == 3: # timeout
1363 main.log.error( "Something went wrong exiting mininet " +
1364 "TIMEOUT" )
1365
Hari Krishnab35c6d02015-03-18 11:13:51 -07001366 if fileName:
1367 self.handle.sendline("")
1368 self.handle.expect('\$')
1369 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001370 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 main.log.error( self.name + ": EOF exception found" )
1372 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001373 main.cleanup()
1374 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001375 else:
1376 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001377 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001378 return response
1379
Jon Hall7eb38402015-01-08 17:19:54 -08001380 def arping( self, src, dest, destmac ):
1381 self.handle.sendline( '' )
1382 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001383
Jon Hall7eb38402015-01-08 17:19:54 -08001384 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001385 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1387 main.log.info( self.name + ": ARP successful" )
1388 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001389 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001390 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001391 main.log.warn( self.name + ": ARP FAILURE" )
1392 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001393 return main.FALSE
1394
Jon Hall7eb38402015-01-08 17:19:54 -08001395 def decToHex( self, num ):
1396 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001397
Jon Hall7eb38402015-01-08 17:19:54 -08001398 def getSwitchFlowCount( self, switch ):
1399 """
1400 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001401 if self.handle:
1402 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1403 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001404 response = self.execute(
1405 cmd=cmd,
1406 prompt="mininet>",
1407 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001408 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001409 main.log.error( self.name + ": EOF exception found" )
1410 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001411 main.cleanup()
1412 main.exit()
1413 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001414 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001415 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001416 main.log.info(
1417 "Couldn't find flows on switch %s, found: %s" %
1418 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001419 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001420 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001421 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001422 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001423
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 def checkFlows( self, sw, dumpFormat=None ):
1425 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001428 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001430 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001431 response = self.execute(
1432 cmd=command,
1433 prompt="mininet>",
1434 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001435 return response
1436 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001437 main.log.error( self.name + ": EOF exception found" )
1438 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001439 main.cleanup()
1440 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001441
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001443 """
Jon Hallefbd9792015-03-05 16:11:36 -08001444 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001445 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001446 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001447 self.handle.sendline( "" )
1448 self.handle.expect( "mininet>" )
1449 self.handle.sendline(
1450 "sh sudo tcpdump -n -i " +
1451 intf +
1452 " " +
1453 port +
1454 " -w " +
1455 filename.strip() +
1456 " &" )
1457 self.handle.sendline( "" )
1458 i = self.handle.expect( [ 'No\ssuch\device',
1459 'listening\son',
1460 pexpect.TIMEOUT,
1461 "mininet>" ],
1462 timeout=10 )
1463 main.log.warn( self.handle.before + self.handle.after )
1464 self.handle.sendline( "" )
1465 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001466 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001467 main.log.error(
1468 self.name +
1469 ": tcpdump - No such device exists. " +
1470 "tcpdump attempted on: " +
1471 intf )
admin2a9548d2014-06-17 14:08:07 -07001472 return main.FALSE
1473 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001474 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001475 return main.TRUE
1476 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001477 main.log.error(
1478 self.name +
1479 ": tcpdump command timed out! Check interface name," +
1480 " given interface was: " +
1481 intf )
admin2a9548d2014-06-17 14:08:07 -07001482 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001483 elif i == 3:
1484 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001485 return main.TRUE
1486 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001487 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001488 return main.FALSE
1489 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001490 main.log.error( self.name + ": EOF exception found" )
1491 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001492 main.cleanup()
1493 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001494 except Exception:
1495 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001496 main.cleanup()
1497 main.exit()
1498
kelvin-onlabd3b64892015-01-20 13:26:24 -08001499 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001500 """
1501 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001502 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001503 self.handle.sendline( "sh sudo pkill tcpdump" )
1504 self.handle.expect( "mininet>" )
1505 self.handle.sendline( "" )
1506 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001507 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001508 main.log.error( self.name + ": EOF exception found" )
1509 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001510 main.cleanup()
1511 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001512 except Exception:
1513 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001514 main.cleanup()
1515 main.exit()
1516
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001518 """
1519 Compare mn and onos switches
1520 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001522
Jon Hall7eb38402015-01-08 17:19:54 -08001523 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001525 output = { "switches": [] }
1526 # iterate through the MN topology and pull out switches and and port
1527 # info
1528 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001529 ports = []
1530 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001531 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001532 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001533 'name': port.name } )
1534 output[ 'switches' ].append( {
1535 "name": switch.name,
1536 "dpid": str( switch.dpid ).zfill( 16 ),
1537 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001538
Jon Hall7eb38402015-01-08 17:19:54 -08001539 # print "mn"
1540 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001541 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001542 # indent=4,
1543 # separators=( ',', ': ' ) )
1544 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001546 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001547 # indent=4,
1548 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001549
1550 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001551 mnDPIDs = []
1552 for switch in output[ 'switches' ]:
1553 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001554 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001555 # print "List of Mininet switch DPID's"
1556 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001558 main.log.error(
1559 self.name +
1560 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001561 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001562 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001563 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001564 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001565 if switch[ 'available' ]:
1566 onosDPIDs.append(
1567 switch[ 'id' ].replace(
1568 ":",
1569 '' ).replace(
1570 "of",
1571 '' ).lower() )
1572 # else:
1573 # print "Switch is unavailable:"
1574 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001575 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001576 # print "List of ONOS switch DPID's"
1577 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001578
Jon Hall7eb38402015-01-08 17:19:54 -08001579 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001581 main.log.report( "Switches in MN but not in ONOS:" )
1582 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1583 main.log.report( str( list1 ) )
1584 main.log.report( "Switches in ONOS but not in MN:" )
1585 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001586 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001587 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001588 switchResults = main.TRUE
1589 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001590
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001592 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001593 Compare mn and onos ports
1594 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001596
Jon Hallfbc828e2015-01-06 17:30:19 -08001597 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001598 1. This uses the sts TestONTopology object
1599 2. numpy - "sudo pip install numpy"
1600
Jon Hall7eb38402015-01-08 17:19:54 -08001601 """
1602 # FIXME: this does not look for extra ports in ONOS, only checks that
1603 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001604 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001606 output = { "switches": [] }
1607 # iterate through the MN topology and pull out switches and and port
1608 # info
1609 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001610 ports = []
1611 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001612 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001613 tmpPort = { 'of_port': port.port_no,
1614 'mac': str( port.hw_addr ).replace( '\'', '' ),
1615 'name': port.name,
1616 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001617
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001619 tmpSwitch = { 'name': switch.name,
1620 'dpid': str( switch.dpid ).zfill( 16 ),
1621 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001622
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001624
Jon Hall7eb38402015-01-08 17:19:54 -08001625 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 for mnSwitch in output[ 'switches' ]:
1627 mnPorts = []
1628 onosPorts = []
1629 switchResult = main.TRUE
1630 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001631 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 mnPorts.append( port[ 'of_port' ] )
1633 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001634 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 # print onosSwitch
1636 if onosSwitch[ 'device' ][ 'available' ]:
1637 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001638 ':',
1639 '' ).replace(
1640 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001641 '' ) == mnSwitch[ 'dpid' ]:
1642 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001643 if port[ 'isEnabled' ]:
1644 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 # onosPorts.append( 'local' )
1646 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001647 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001649 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001650 mnPorts.sort( key=float )
1651 onosPorts.sort( key=float )
1652 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1653 # print "\tmn_ports[] = ", mnPorts
1654 # print "\tonos_ports[] = ", onosPorts
1655 mnPortsLog = mnPorts
1656 onosPortsLog = onosPorts
1657 mnPorts = [ x for x in mnPorts ]
1658 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001659
Jon Hall7eb38402015-01-08 17:19:54 -08001660 # TODO: handle other reserved port numbers besides LOCAL
1661 # NOTE: Reserved ports
1662 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1663 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 for mnPort in mnPortsLog:
1665 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001666 # don't set results to true here as this is just one of
1667 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 mnPorts.remove( mnPort )
1669 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001670 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001671 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001672 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001673 if 65534 in mnPorts:
1674 mnPorts.remove( 65534 )
1675 if long( uint64( -2 ) ) in onosPorts:
1676 onosPorts.remove( long( uint64( -2 ) ) )
1677 if len( mnPorts ): # the ports of this switch don't match
1678 switchResult = main.FALSE
1679 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1680 if len( onosPorts ): # the ports of this switch don't match
1681 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001682 main.log.warn(
1683 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 str( onosPorts ) )
1685 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001686 main.log.report(
1687 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001688 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1689 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1690 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1691 portsResults = portsResults and switchResult
1692 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001693
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001695 """
1696 Compare mn and onos links
1697 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001699
Jon Hall7eb38402015-01-08 17:19:54 -08001700 This uses the sts TestONTopology object"""
1701 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001702 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001703 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001704 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001705 # iterate through the MN topology and pull out switches and and port
1706 # info
1707 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001708 # print "Iterating though switches as seen by Mininet"
1709 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001710 ports = []
1711 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001712 # print port.hw_addr.toStr( separator='' )
1713 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001714 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001715 'name': port.name } )
1716 output[ 'switches' ].append( {
1717 "name": switch.name,
1718 "dpid": str( switch.dpid ).zfill( 16 ),
1719 "ports": ports } )
1720 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001721
kelvin-onlabd3b64892015-01-20 13:26:24 -08001722 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001723 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001724 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001725 if 2 * len( mnLinks ) == len( onos ):
1726 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001727 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001728 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001729 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001730 "Mininet has " + str( len( mnLinks ) ) +
1731 " bidirectional links and ONOS has " +
1732 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001733
Jon Hall7eb38402015-01-08 17:19:54 -08001734 # iterate through MN links and check if an ONOS link exists in
1735 # both directions
1736 # NOTE: Will currently only show mn links as down if they are
1737 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001739 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001741 # print "Link: %s" % link
1742 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001743 node1 = None
1744 port1 = None
1745 node2 = None
1746 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 firstDir = main.FALSE
1748 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001749 for switch in output[ 'switches' ]:
1750 # print "Switch: %s" % switch[ 'name' ]
1751 if switch[ 'name' ] == link.node1.name:
1752 node1 = switch[ 'dpid' ]
1753 for port in switch[ 'ports' ]:
1754 if str( port[ 'name' ] ) == str( link.port1 ):
1755 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001756 if node1 is not None and node2 is not None:
1757 break
Jon Hall7eb38402015-01-08 17:19:54 -08001758 if switch[ 'name' ] == link.node2.name:
1759 node2 = switch[ 'dpid' ]
1760 for port in switch[ 'ports' ]:
1761 if str( port[ 'name' ] ) == str( link.port2 ):
1762 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001763 if node1 is not None and node2 is not None:
1764 break
1765
kelvin-onlabd3b64892015-01-20 13:26:24 -08001766 for onosLink in onos:
1767 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001768 ":",
1769 '' ).replace(
1770 "of",
1771 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001773 ":",
1774 '' ).replace(
1775 "of",
1776 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001777 onosPort1 = onosLink[ 'src' ][ 'port' ]
1778 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001779
Jon Hall72cf1dc2014-10-20 21:04:50 -04001780 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 if str( onosNode1 ) == str( node1 ) and str(
1782 onosNode2 ) == str( node2 ):
1783 if int( onosPort1 ) == int( port1 ) and int(
1784 onosPort2 ) == int( port2 ):
1785 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001786 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001787 main.log.warn(
1788 'The port numbers do not match for ' +
1789 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001790 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001791 'link %s/%s -> %s/%s' %
1792 ( node1,
1793 port1,
1794 node2,
1795 port2 ) +
1796 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001797 ( onosNode1,
1798 onosPort1,
1799 onosNode2,
1800 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001801
1802 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001803 elif ( str( onosNode1 ) == str( node2 ) and
1804 str( onosNode2 ) == str( node1 ) ):
1805 if ( int( onosPort1 ) == int( port2 )
1806 and int( onosPort2 ) == int( port1 ) ):
1807 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001808 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001809 main.log.warn(
1810 'The port numbers do not match for ' +
1811 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001812 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001813 'link %s/%s -> %s/%s' %
1814 ( node2,
1815 port2,
1816 node1,
1817 port1 ) +
1818 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001819 ( onosNode2,
1820 onosPort2,
1821 onosNode1,
1822 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001823 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001824 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001825 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001826 main.log.report(
1827 'ONOS does not have the link %s/%s -> %s/%s' %
1828 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001829 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001830 main.log.report(
1831 'ONOS does not have the link %s/%s -> %s/%s' %
1832 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 linkResults = linkResults and firstDir and secondDir
1834 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001835
Jon Hallff6b4b22015-02-23 09:25:15 -08001836 def compareHosts( self, topo, hostsJson ):
1837 """
1838 Compare mn and onos Hosts.
1839 Since Mininet hosts are quiet, ONOS will only know of them when they
1840 speak. For this reason, we will only check that the hosts in ONOS
1841 stores are in Mininet, and not vice versa.
1842 topo: sts TestONTopology object
1843 hostsJson: parsed json object from the onos hosts api
1844
1845 This uses the sts TestONTopology object"""
1846 import json
1847 hostResults = main.TRUE
1848 hosts = []
1849 # iterate through the MN topology and pull out hosts
1850 for mnHost in topo.graph.hosts:
1851 interfaces = []
1852 for intf in mnHost.interfaces:
1853 interfaces.append( {
1854 "name": intf.name, # str
1855 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1856 # hw_addr is of type EthAddr, Not JSON serializable
1857 "hw_addr": str( intf.hw_addr ) } )
1858 hosts.append( {
1859 "name": mnHost.name, # str
1860 "interfaces": interfaces } ) # list
1861 for onosHost in hostsJson:
1862 onosMAC = onosHost[ 'mac' ].lower()
1863 match = False
1864 for mnHost in hosts:
1865 for mnIntf in mnHost[ 'interfaces' ]:
1866 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1867 match = True
1868 for ip in mnIntf[ 'ips' ]:
1869 if ip in onosHost[ 'ips' ]:
1870 pass # all is well
1871 else:
1872 # misssing ip
1873 main.log.error( "ONOS host " + onosHost[ 'id' ]
1874 + " has a different IP than " +
1875 "the Mininet host." )
1876 output = json.dumps(
1877 onosHost,
1878 sort_keys=True,
1879 indent=4,
1880 separators=( ',', ': ' ) )
1881 main.log.info( output )
1882 hostResults = main.FALSE
1883 if not match:
1884 hostResults = main.FALSE
1885 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1886 "corresponding Mininet host." )
1887 output = json.dumps( onosHost,
1888 sort_keys=True,
1889 indent=4,
1890 separators=( ',', ': ' ) )
1891 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001892 return hostResults
1893
kelvin-onlabd3b64892015-01-20 13:26:24 -08001894 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001895 """
1896 Returns a list of all hosts
1897 Don't ask questions just use it"""
1898 self.handle.sendline( "" )
1899 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001900
Jon Hall7eb38402015-01-08 17:19:54 -08001901 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1902 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001903
kelvin-onlabd3b64892015-01-20 13:26:24 -08001904 handlePy = self.handle.before
1905 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1906 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001907
Jon Hall7eb38402015-01-08 17:19:54 -08001908 self.handle.sendline( "" )
1909 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001910
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 hostStr = handlePy.replace( "]", "" )
1912 hostStr = hostStr.replace( "'", "" )
1913 hostStr = hostStr.replace( "[", "" )
1914 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001915
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 return hostList
adminbae64d82013-08-01 10:50:15 -07001917
Jon Hall7eb38402015-01-08 17:19:54 -08001918 def update( self ):
1919 """
1920 updates the port address and status information for
1921 each port in mn"""
1922 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001923 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001924 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001925 self.handle.sendline( "" )
1926 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001927
Jon Hall7eb38402015-01-08 17:19:54 -08001928 self.handle.sendline( "update" )
1929 self.handle.expect( "update" )
1930 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001931
Jon Hall7eb38402015-01-08 17:19:54 -08001932 self.handle.sendline( "" )
1933 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001934
Jon Hallb1290e82014-11-18 16:17:48 -05001935 return main.TRUE
1936 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001937 main.log.error( self.name + ": EOF exception found" )
1938 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001939 main.cleanup()
1940 main.exit()
1941
adminbae64d82013-08-01 10:50:15 -07001942if __name__ != "__main__":
1943 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07001944 sys.modules[ __name__ ] = MininetCliDriver()