blob: dcc11b00b8c41ae737436f8c8e22fb0e5938e82e [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
kelvin-onlabf0594d72015-05-19 17:25:12 -07001380 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001381 """
1382 Description:
1383 Sends arp message from mininet host for hosts discovery
1384 Required:
1385 host - hosts name
1386 Optional:
1387 ip - ip address that does not exist in the network so there would
1388 be no reply.
1389 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001390 if ethDevice:
1391 ethDevice = '-I ' + ethDevice + ' '
1392 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001393 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001394 main.log.warn( "Sending: " + cmd )
1395 self.handle.sendline( cmd )
1396 response = self.handle.before
1397 self.handle.sendline( "" )
1398 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001399 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001400
1401 except pexpect.EOF:
1402 main.log.error( self.name + ": EOF exception found" )
1403 main.log.error( self.name + ": " + self.handle.before )
1404 main.cleanup()
1405 main.exit()
admin07529932013-11-22 14:58:28 -08001406
Jon Hall7eb38402015-01-08 17:19:54 -08001407 def decToHex( self, num ):
1408 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001409
Jon Hall7eb38402015-01-08 17:19:54 -08001410 def getSwitchFlowCount( self, switch ):
1411 """
1412 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001413 if self.handle:
1414 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1415 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001416 response = self.execute(
1417 cmd=cmd,
1418 prompt="mininet>",
1419 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001420 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 main.log.error( self.name + ": EOF exception found" )
1422 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001423 main.cleanup()
1424 main.exit()
1425 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001426 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001427 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001428 main.log.info(
1429 "Couldn't find flows on switch %s, found: %s" %
1430 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001431 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001432 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001433 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001434 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001435
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 def checkFlows( self, sw, dumpFormat=None ):
1437 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001438 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001439 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001440 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001441 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001442 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001443 response = self.execute(
1444 cmd=command,
1445 prompt="mininet>",
1446 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001447 return response
1448 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001449 main.log.error( self.name + ": EOF exception found" )
1450 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001451 main.cleanup()
1452 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001453
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001455 """
Jon Hallefbd9792015-03-05 16:11:36 -08001456 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001457 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001458 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001459 self.handle.sendline( "" )
1460 self.handle.expect( "mininet>" )
1461 self.handle.sendline(
1462 "sh sudo tcpdump -n -i " +
1463 intf +
1464 " " +
1465 port +
1466 " -w " +
1467 filename.strip() +
1468 " &" )
1469 self.handle.sendline( "" )
1470 i = self.handle.expect( [ 'No\ssuch\device',
1471 'listening\son',
1472 pexpect.TIMEOUT,
1473 "mininet>" ],
1474 timeout=10 )
1475 main.log.warn( self.handle.before + self.handle.after )
1476 self.handle.sendline( "" )
1477 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001478 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001479 main.log.error(
1480 self.name +
1481 ": tcpdump - No such device exists. " +
1482 "tcpdump attempted on: " +
1483 intf )
admin2a9548d2014-06-17 14:08:07 -07001484 return main.FALSE
1485 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001486 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001487 return main.TRUE
1488 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001489 main.log.error(
1490 self.name +
1491 ": tcpdump command timed out! Check interface name," +
1492 " given interface was: " +
1493 intf )
admin2a9548d2014-06-17 14:08:07 -07001494 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001495 elif i == 3:
1496 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001497 return main.TRUE
1498 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001499 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001500 return main.FALSE
1501 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001504 main.cleanup()
1505 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001506 except Exception:
1507 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001508 main.cleanup()
1509 main.exit()
1510
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001512 """
1513 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001514 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001515 self.handle.sendline( "sh sudo pkill tcpdump" )
1516 self.handle.expect( "mininet>" )
1517 self.handle.sendline( "" )
1518 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001519 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001520 main.log.error( self.name + ": EOF exception found" )
1521 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001522 main.cleanup()
1523 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001524 except Exception:
1525 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001526 main.cleanup()
1527 main.exit()
1528
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001530 """
1531 Compare mn and onos switches
1532 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001534
Jon Hall7eb38402015-01-08 17:19:54 -08001535 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001537 output = { "switches": [] }
1538 # iterate through the MN topology and pull out switches and and port
1539 # info
1540 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001541 ports = []
1542 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001543 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001544 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001545 'name': port.name } )
1546 output[ 'switches' ].append( {
1547 "name": switch.name,
1548 "dpid": str( switch.dpid ).zfill( 16 ),
1549 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001550
Jon Hall7eb38402015-01-08 17:19:54 -08001551 # print "mn"
1552 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001553 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001554 # indent=4,
1555 # separators=( ',', ': ' ) )
1556 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001558 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001559 # indent=4,
1560 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001561
1562 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001563 mnDPIDs = []
1564 for switch in output[ 'switches' ]:
1565 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001566 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001567 # print "List of Mininet switch DPID's"
1568 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001570 main.log.error(
1571 self.name +
1572 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001573 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001575 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001576 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001577 if switch[ 'available' ]:
1578 onosDPIDs.append(
1579 switch[ 'id' ].replace(
1580 ":",
1581 '' ).replace(
1582 "of",
1583 '' ).lower() )
1584 # else:
1585 # print "Switch is unavailable:"
1586 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001587 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001588 # print "List of ONOS switch DPID's"
1589 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001590
Jon Hall7eb38402015-01-08 17:19:54 -08001591 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001593 main.log.report( "Switches in MN but not in ONOS:" )
1594 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1595 main.log.report( str( list1 ) )
1596 main.log.report( "Switches in ONOS but not in MN:" )
1597 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001598 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001599 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 switchResults = main.TRUE
1601 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001602
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001604 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001605 Compare mn and onos ports
1606 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001608
Jon Hallfbc828e2015-01-06 17:30:19 -08001609 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001610 1. This uses the sts TestONTopology object
1611 2. numpy - "sudo pip install numpy"
1612
Jon Hall7eb38402015-01-08 17:19:54 -08001613 """
1614 # FIXME: this does not look for extra ports in ONOS, only checks that
1615 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001616 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001618 output = { "switches": [] }
1619 # iterate through the MN topology and pull out switches and and port
1620 # info
1621 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001622 ports = []
1623 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001624 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001625 tmpPort = { 'of_port': port.port_no,
1626 'mac': str( port.hw_addr ).replace( '\'', '' ),
1627 'name': port.name,
1628 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001629
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001631 tmpSwitch = { 'name': switch.name,
1632 'dpid': str( switch.dpid ).zfill( 16 ),
1633 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001634
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001636
Jon Hall7eb38402015-01-08 17:19:54 -08001637 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 for mnSwitch in output[ 'switches' ]:
1639 mnPorts = []
1640 onosPorts = []
1641 switchResult = main.TRUE
1642 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001643 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 mnPorts.append( port[ 'of_port' ] )
1645 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001646 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001647 # print onosSwitch
1648 if onosSwitch[ 'device' ][ 'available' ]:
1649 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001650 ':',
1651 '' ).replace(
1652 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 '' ) == mnSwitch[ 'dpid' ]:
1654 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001655 if port[ 'isEnabled' ]:
1656 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 # onosPorts.append( 'local' )
1658 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001659 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001661 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 mnPorts.sort( key=float )
1663 onosPorts.sort( key=float )
1664 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1665 # print "\tmn_ports[] = ", mnPorts
1666 # print "\tonos_ports[] = ", onosPorts
1667 mnPortsLog = mnPorts
1668 onosPortsLog = onosPorts
1669 mnPorts = [ x for x in mnPorts ]
1670 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001671
Jon Hall7eb38402015-01-08 17:19:54 -08001672 # TODO: handle other reserved port numbers besides LOCAL
1673 # NOTE: Reserved ports
1674 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1675 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001676 for mnPort in mnPortsLog:
1677 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001678 # don't set results to true here as this is just one of
1679 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 mnPorts.remove( mnPort )
1681 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001682 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001683 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001684 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 if 65534 in mnPorts:
1686 mnPorts.remove( 65534 )
1687 if long( uint64( -2 ) ) in onosPorts:
1688 onosPorts.remove( long( uint64( -2 ) ) )
1689 if len( mnPorts ): # the ports of this switch don't match
1690 switchResult = main.FALSE
1691 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1692 if len( onosPorts ): # the ports of this switch don't match
1693 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001694 main.log.warn(
1695 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001696 str( onosPorts ) )
1697 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001698 main.log.report(
1699 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1701 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1702 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1703 portsResults = portsResults and switchResult
1704 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001705
kelvin-onlabd3b64892015-01-20 13:26:24 -08001706 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001707 """
1708 Compare mn and onos links
1709 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001710 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001711
Jon Hall7eb38402015-01-08 17:19:54 -08001712 This uses the sts TestONTopology object"""
1713 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001714 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001715 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001717 # iterate through the MN topology and pull out switches and and port
1718 # info
1719 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001720 # print "Iterating though switches as seen by Mininet"
1721 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001722 ports = []
1723 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001724 # print port.hw_addr.toStr( separator='' )
1725 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001726 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001727 'name': port.name } )
1728 output[ 'switches' ].append( {
1729 "name": switch.name,
1730 "dpid": str( switch.dpid ).zfill( 16 ),
1731 "ports": ports } )
1732 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001733
kelvin-onlabd3b64892015-01-20 13:26:24 -08001734 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001735 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001736 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001737 if 2 * len( mnLinks ) == len( onos ):
1738 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001739 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001741 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001742 "Mininet has " + str( len( mnLinks ) ) +
1743 " bidirectional links and ONOS has " +
1744 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001745
Jon Hall7eb38402015-01-08 17:19:54 -08001746 # iterate through MN links and check if an ONOS link exists in
1747 # both directions
1748 # NOTE: Will currently only show mn links as down if they are
1749 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001751 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001752 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001753 # print "Link: %s" % link
1754 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001755 node1 = None
1756 port1 = None
1757 node2 = None
1758 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 firstDir = main.FALSE
1760 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001761 for switch in output[ 'switches' ]:
1762 # print "Switch: %s" % switch[ 'name' ]
1763 if switch[ 'name' ] == link.node1.name:
1764 node1 = switch[ 'dpid' ]
1765 for port in switch[ 'ports' ]:
1766 if str( port[ 'name' ] ) == str( link.port1 ):
1767 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001768 if node1 is not None and node2 is not None:
1769 break
Jon Hall7eb38402015-01-08 17:19:54 -08001770 if switch[ 'name' ] == link.node2.name:
1771 node2 = switch[ 'dpid' ]
1772 for port in switch[ 'ports' ]:
1773 if str( port[ 'name' ] ) == str( link.port2 ):
1774 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001775 if node1 is not None and node2 is not None:
1776 break
1777
kelvin-onlabd3b64892015-01-20 13:26:24 -08001778 for onosLink in onos:
1779 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001780 ":",
1781 '' ).replace(
1782 "of",
1783 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001785 ":",
1786 '' ).replace(
1787 "of",
1788 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001789 onosPort1 = onosLink[ 'src' ][ 'port' ]
1790 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001791
Jon Hall72cf1dc2014-10-20 21:04:50 -04001792 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 if str( onosNode1 ) == str( node1 ) and str(
1794 onosNode2 ) == str( node2 ):
1795 if int( onosPort1 ) == int( port1 ) and int(
1796 onosPort2 ) == int( port2 ):
1797 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001798 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001799 main.log.warn(
1800 'The port numbers do not match for ' +
1801 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001802 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001803 'link %s/%s -> %s/%s' %
1804 ( node1,
1805 port1,
1806 node2,
1807 port2 ) +
1808 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001809 ( onosNode1,
1810 onosPort1,
1811 onosNode2,
1812 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001813
1814 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 elif ( str( onosNode1 ) == str( node2 ) and
1816 str( onosNode2 ) == str( node1 ) ):
1817 if ( int( onosPort1 ) == int( port2 )
1818 and int( onosPort2 ) == int( port1 ) ):
1819 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001820 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001821 main.log.warn(
1822 'The port numbers do not match for ' +
1823 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001824 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001825 'link %s/%s -> %s/%s' %
1826 ( node2,
1827 port2,
1828 node1,
1829 port1 ) +
1830 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 ( onosNode2,
1832 onosPort2,
1833 onosNode1,
1834 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001835 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001836 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001837 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001838 main.log.report(
1839 'ONOS does not have the link %s/%s -> %s/%s' %
1840 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001842 main.log.report(
1843 'ONOS does not have the link %s/%s -> %s/%s' %
1844 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 linkResults = linkResults and firstDir and secondDir
1846 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001847
Jon Hallff6b4b22015-02-23 09:25:15 -08001848 def compareHosts( self, topo, hostsJson ):
1849 """
1850 Compare mn and onos Hosts.
1851 Since Mininet hosts are quiet, ONOS will only know of them when they
1852 speak. For this reason, we will only check that the hosts in ONOS
1853 stores are in Mininet, and not vice versa.
1854 topo: sts TestONTopology object
1855 hostsJson: parsed json object from the onos hosts api
1856
1857 This uses the sts TestONTopology object"""
1858 import json
1859 hostResults = main.TRUE
1860 hosts = []
1861 # iterate through the MN topology and pull out hosts
1862 for mnHost in topo.graph.hosts:
1863 interfaces = []
1864 for intf in mnHost.interfaces:
1865 interfaces.append( {
1866 "name": intf.name, # str
1867 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1868 # hw_addr is of type EthAddr, Not JSON serializable
1869 "hw_addr": str( intf.hw_addr ) } )
1870 hosts.append( {
1871 "name": mnHost.name, # str
1872 "interfaces": interfaces } ) # list
1873 for onosHost in hostsJson:
1874 onosMAC = onosHost[ 'mac' ].lower()
1875 match = False
1876 for mnHost in hosts:
1877 for mnIntf in mnHost[ 'interfaces' ]:
1878 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1879 match = True
1880 for ip in mnIntf[ 'ips' ]:
1881 if ip in onosHost[ 'ips' ]:
1882 pass # all is well
1883 else:
1884 # misssing ip
1885 main.log.error( "ONOS host " + onosHost[ 'id' ]
1886 + " has a different IP than " +
1887 "the Mininet host." )
1888 output = json.dumps(
1889 onosHost,
1890 sort_keys=True,
1891 indent=4,
1892 separators=( ',', ': ' ) )
1893 main.log.info( output )
1894 hostResults = main.FALSE
1895 if not match:
1896 hostResults = main.FALSE
1897 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1898 "corresponding Mininet host." )
1899 output = json.dumps( onosHost,
1900 sort_keys=True,
1901 indent=4,
1902 separators=( ',', ': ' ) )
1903 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001904 return hostResults
1905
kelvin-onlabd3b64892015-01-20 13:26:24 -08001906 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001907 """
1908 Returns a list of all hosts
1909 Don't ask questions just use it"""
1910 self.handle.sendline( "" )
1911 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001912
Jon Hall7eb38402015-01-08 17:19:54 -08001913 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1914 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001915
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 handlePy = self.handle.before
1917 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1918 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001919
Jon Hall7eb38402015-01-08 17:19:54 -08001920 self.handle.sendline( "" )
1921 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001922
kelvin-onlabd3b64892015-01-20 13:26:24 -08001923 hostStr = handlePy.replace( "]", "" )
1924 hostStr = hostStr.replace( "'", "" )
1925 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07001926 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001927 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001928
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 return hostList
adminbae64d82013-08-01 10:50:15 -07001930
Jon Hall7eb38402015-01-08 17:19:54 -08001931 def update( self ):
1932 """
1933 updates the port address and status information for
1934 each port in mn"""
1935 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001936 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001937 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001938 self.handle.sendline( "" )
1939 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001940
Jon Hall7eb38402015-01-08 17:19:54 -08001941 self.handle.sendline( "update" )
1942 self.handle.expect( "update" )
1943 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001944
Jon Hall7eb38402015-01-08 17:19:54 -08001945 self.handle.sendline( "" )
1946 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001947
Jon Hallb1290e82014-11-18 16:17:48 -05001948 return main.TRUE
1949 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001950 main.log.error( self.name + ": EOF exception found" )
1951 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001952 main.cleanup()
1953 main.exit()
1954
adminbae64d82013-08-01 10:50:15 -07001955if __name__ != "__main__":
1956 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07001957 sys.modules[ __name__ ] = MininetCliDriver()