blob: 0d27b438fea0c5b679358674661c4069b4611134 [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:
106 main.log.info(
107 self.name +
108 ": Clearing any residual state or processes" )
109 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:
116 main.log.info( self.name + ": Sending sudo password" )
117 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800118 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800119 '\$',
120 pexpect.EOF,
121 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800122 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800123 if i == 1:
124 main.log.info( self.name + ": Clean" )
125 elif i == 2:
126 main.log.error( self.name + ": Connection terminated" )
127 elif i == 3: # timeout
128 main.log.error(
129 self.name +
130 ": Something while cleaning MN took too long... " )
Jon Hallefbd9792015-03-05 16:11:36 -0800131 if topoFile == '' and args == '':
kelvin-onlaba1484582015-02-02 15:46:20 -0800132 main.log.info( self.name + ": building fresh mininet" )
133 # for reactive/PARP enabled tests
134 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
135 " " + self.options[ 'arg2' ] +\
136 " --mac --controller " +\
137 self.options[ 'controller' ] + " " +\
138 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -0800139
kelvin-onlaba1484582015-02-02 15:46:20 -0800140 argList = self.options[ 'arg1' ].split( "," )
141 global topoArgList
142 topoArgList = argList[ 0 ].split( " " )
143 argList = map( int, argList[ 1: ] )
144 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800145
kelvin-onlaba1484582015-02-02 15:46:20 -0800146 self.handle.sendline( cmdString )
147 self.handle.expect( [ "sudo mn",
148 pexpect.EOF,
149 pexpect.TIMEOUT ] )
150 while True:
151 i = self.handle.expect( [ 'mininet>',
152 '\*\*\*',
153 'Exception',
154 pexpect.EOF,
155 pexpect.TIMEOUT ],
156 timeout )
157 if i == 0:
158 main.log.info( self.name + ": mininet built" )
159 return main.TRUE
160 if i == 1:
161 self.handle.expect(
162 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
163 main.log.info( self.handle.before )
164 elif i == 2:
165 main.log.error(
166 self.name +
167 ": Launching mininet failed..." )
168 return main.FALSE
169 elif i == 3:
170 main.log.error( self.name + ": Connection timeout" )
171 return main.FALSE
172 elif i == 4: # timeout
173 main.log.error(
174 self.name +
175 ": Something took too long... " )
176 return main.FALSE
177 return main.TRUE
178 else:
179 main.log.info( "Starting topo file " + topoFile )
Jon Hallefbd9792015-03-05 16:11:36 -0800180 if args is None:
kelvin-onlaba1484582015-02-02 15:46:20 -0800181 args = ''
182 else:
183 main.log.info( "args = " + args)
184 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
Jon Hall7eb38402015-01-08 17:19:54 -0800185 i = self.handle.expect( [ 'mininet>',
Jon Hallefbd9792015-03-05 16:11:36 -0800186 pexpect.EOF,
187 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800188 timeout)
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800189 if i == 0:
190 main.log.info(self.name + ": Network started")
191 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800192 elif i == 1:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800193 main.log.error( self.name + ": Connection timeout" )
194 return main.FALSE
kelvin-onlabec228b82015-02-09 15:45:55 -0800195 elif i == 2: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800196 main.log.error(
197 self.name +
198 ": Something took too long... " )
199 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800200 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800201 else: # if no handle
202 main.log.error(
203 self.name +
204 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800205 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800206 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800207 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800208 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700209 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800210
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800211 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400212 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800213 # In tree topology, if fanout arg is not given, by default it is 2
214 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400215 fanout = 2
216 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500217 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800218 while( k <= depth - 1 ):
219 count = count + pow( fanout, k )
220 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800222 while( k <= depth - 2 ):
223 # depth-2 gives you only core links and not considering
224 # edge links as seen by ONOS. If all the links including
225 # edge links are required, do depth-1
226 count = count + pow( fanout, k )
227 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800229 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800230 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800231
Jon Hall7eb38402015-01-08 17:19:54 -0800232 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800234 # by default it is 1
235 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400236 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 numSwitches = depth
238 numHostsPerSw = fanout
239 totalNumHosts = numSwitches * numHostsPerSw
240 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800241 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800243 topoDict = { "num_switches": int( numSwitches ),
244 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400245 return topoDict
246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 def calculateSwAndLinks( self ):
248 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400249 return topoDict
250
kelvin-onlabc44f0192015-04-02 22:08:41 -0700251 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0):
Jon Hall7eb38402015-01-08 17:19:54 -0800252 """
253 Verifies the reachability of the hosts using pingall command.
254 Optional parameter timeout allows you to specify how long to
255 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700256 Optional:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700257 timeout(seconds) - This is the pexpect timeout; The function will
258 timeout if the amount of time between failed
259 pings exceedes this time and pingall is still
260 running
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700261 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700262 ping
263 acceptableFailed - Set the number of acceptable failed pings for the
264 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800265 Returns:
266 main.TRUE if pingall completes with no pings dropped
267 otherwise main.FALSE"""
268 if self.handle:
269 main.log.info(
270 self.name +
271 ": Checking reachabilty to the hosts using pingall" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700272 response = ""
273 failedPings = 0
274 returnValue = main.TRUE
275 self.handle.sendline( "pingall" )
276 while True:
277 i = self.handle.expect( [ "mininet>","X",
278 pexpect.EOF,
279 pexpect.TIMEOUT ],
280 timeout )
281 if i == 0:
282 main.log.info( self.name + ": pingall finished")
283 response += self.handle.before
284 break
285 elif i == 1:
286 response += self.handle.before + self.handle.after
287 failedPings = failedPings + 1
288 if failedPings >= acceptableFailed:
289 returnValue = main.FALSE
290 if shortCircuit:
291 main.log.error( self.name +
292 ": Aborting pingall - "
293 + str( failedPings ) +
294 " pings failed" )
295 break
296 elif i == 2:
297 main.log.error( self.name +
298 ": EOF exception found" )
299 main.log.error( self.name + ": " +
300 self.handle.before )
301 main.cleanup()
302 main.exit()
303 elif i == 3:
304 response += self.handle.before
305 main.log.error( self.name +
306 ": TIMEOUT exception found" )
307 main.log.error( self.name +
308 ": " +
309 str( response ) )
310 # NOTE: Send ctrl-c to make sure pingall is done
311 self.handle.send( "\x03" )
312 self.handle.expect( "Interrupt" )
313 self.handle.send( "" )
314 self.handle.expect( "mininet>" )
315 break
316 pattern = "Results\:"
317 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800318 if re.search( pattern, response ):
kelvin-onlabc44f0192015-04-02 22:08:41 -0700319 main.log.info( self.name + ": Pingall finished with "
320 + str( failedPings ) + " failed pings" )
321 return returnValue
adminbae64d82013-08-01 10:50:15 -0700322 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800323 # NOTE: Send ctrl-c to make sure pingall is done
324 self.handle.send( "\x03" )
325 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700326 self.handle.send( "" )
Jon Hall7eb38402015-01-08 17:19:54 -0800327 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700328 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800329 else:
330 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500331 main.cleanup()
332 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700333
Jon Hall7eb38402015-01-08 17:19:54 -0800334 def fpingHost( self, **pingParams ):
335 """
336 Uses the fping package for faster pinging...
337 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800338 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800339 command = args[ "SRC" ] + \
340 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
341 self.handle.sendline( command )
342 self.handle.expect(
343 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
344 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
345 response = self.handle.before
346 if re.search( ":\s-", response ):
347 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700348 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800349 elif re.search( ":\s\d{1,2}\.\d\d", response ):
350 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700351 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800352 main.log.info( self.name + ": Install fping on mininet machine... " )
353 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700354 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800355
Jon Hall7eb38402015-01-08 17:19:54 -0800356 def pingHost( self, **pingParams ):
357 """
358 Ping from one mininet host to another
359 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800360 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800361 command = args[ "SRC" ] + " ping " + \
362 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700363 try:
Jon Hall61282e32015-03-19 11:34:11 -0700364 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800365 self.handle.sendline( command )
366 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700367 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800368 main.log.error(
369 self.name +
370 ": timeout when waiting for response from mininet" )
371 main.log.error( "response: " + str( self.handle.before ) )
372 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700373 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800374 main.log.error(
375 self.name +
376 ": timeout when waiting for response from mininet" )
377 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700378 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800379 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800380 main.log.error( self.name + ": EOF exception found" )
381 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700382 main.cleanup()
383 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800384 main.log.info( self.name + ": Ping Response: " + response )
385 if re.search( ',\s0\%\spacket\sloss', response ):
386 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800387 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700388 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800389 else:
390 main.log.error(
391 self.name +
392 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800393 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700394 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800395
Jon Hall7eb38402015-01-08 17:19:54 -0800396 def checkIP( self, host ):
397 """
398 Verifies the host's ip configured or not."""
399 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700400 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800401 response = self.execute(
402 cmd=host +
403 " ifconfig",
404 prompt="mininet>",
405 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800406 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800407 main.log.error( self.name + ": EOF exception found" )
408 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700409 main.cleanup()
410 main.exit()
adminbae64d82013-08-01 10:50:15 -0700411
Jon Hall7eb38402015-01-08 17:19:54 -0800412 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800413 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
414 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
415 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
416 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
417 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800418 # pattern = "inet addr:10.0.0.6"
419 if re.search( pattern, response ):
420 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700421 return main.TRUE
422 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800423 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700424 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800425 else:
426 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800427
Jon Hall7eb38402015-01-08 17:19:54 -0800428 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800429 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700430 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800431 response = self.execute(
432 cmd="h1 /usr/sbin/sshd -D&",
433 prompt="mininet>",
434 timeout=10 )
435 response = self.execute(
436 cmd="h4 /usr/sbin/sshd -D&",
437 prompt="mininet>",
438 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700439 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800440 vars( self )[ key ] = connectargs[ key ]
441 response = self.execute(
442 cmd="xterm h1 h4 ",
443 prompt="mininet>",
444 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800445 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800446 main.log.error( self.name + ": EOF exception found" )
447 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700448 main.cleanup()
449 main.exit()
adminbae64d82013-08-01 10:50:15 -0700450 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800451 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700452 if self.flag == 0:
453 self.flag = 1
454 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800455 else:
adminbae64d82013-08-01 10:50:15 -0700456 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800457
kelvin-onlaba1484582015-02-02 15:46:20 -0800458 def moveHost( self, host, oldSw, newSw, ):
459 """
460 Moves a host from one switch to another on the fly
461 Note: The intf between host and oldSw when detached
462 using detach(), will still show up in the 'net'
463 cmd, because switch.detach() doesn't affect switch.intfs[]
464 (which is correct behavior since the interfaces
465 haven't moved).
466 """
467 if self.handle:
468 try:
469 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800470 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
471 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800472 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800473 response = self.execute( cmd=cmd,
474 prompt="mininet>",
475 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800476
477 # Determine hostintf and Oldswitchintf
478 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800479 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800480 print "cmd2= ", cmd
481 self.handle.sendline( cmd )
482 self.handle.expect( "mininet>" )
483
shahshreya73537862015-02-11 15:15:24 -0800484 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800485 cmd = "px ipaddr = hintf.IP()"
486 print "cmd3= ", cmd
487 self.handle.sendline( cmd )
488 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800489
490 cmd = "px macaddr = hintf.MAC()"
491 print "cmd3= ", cmd
492 self.handle.sendline( cmd )
493 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800494
495 # Detach interface between oldSw-host
496 cmd = "px " + oldSw + ".detach( sintf )"
497 print "cmd4= ", cmd
498 self.handle.sendline( cmd )
499 self.handle.expect( "mininet>" )
500
501 # Add link between host-newSw
502 cmd = "py net.addLink(" + host + "," + newSw + ")"
503 print "cmd5= ", cmd
504 self.handle.sendline( cmd )
505 self.handle.expect( "mininet>" )
506
507 # Determine hostintf and Newswitchintf
508 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800509 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800510 print "cmd6= ", cmd
511 self.handle.sendline( cmd )
512 self.handle.expect( "mininet>" )
513
514 # Attach interface between newSw-host
515 cmd = "px " + newSw + ".attach( sintf )"
516 print "cmd3= ", cmd
517 self.handle.sendline( cmd )
518 self.handle.expect( "mininet>" )
519
520 # Set ipaddress of the host-newSw interface
521 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
522 print "cmd7 = ", cmd
523 self.handle.sendline( cmd )
524 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800525
526 # Set macaddress of the host-newSw interface
527 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
528 print "cmd8 = ", cmd
529 self.handle.sendline( cmd )
530 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800531
532 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800533 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800534 self.handle.sendline( cmd )
535 self.handle.expect( "mininet>" )
536 print "output = ", self.handle.before
537
538 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800539 cmd = host + " ifconfig"
540 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800541 self.handle.sendline( cmd )
542 self.handle.expect( "mininet>" )
543 print "ifconfig o/p = ", self.handle.before
544
545 return main.TRUE
546 except pexpect.EOF:
547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
549 return main.FALSE
550
Jon Hall7eb38402015-01-08 17:19:54 -0800551 def changeIP( self, host, intf, newIP, newNetmask ):
552 """
553 Changes the ip address of a host on the fly
554 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800555 if self.handle:
556 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800557 cmd = host + " ifconfig " + intf + " " + \
558 newIP + " " + 'netmask' + " " + newNetmask
559 self.handle.sendline( cmd )
560 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800561 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800562 main.log.info( "response = " + response )
563 main.log.info(
564 "Ip of host " +
565 host +
566 " changed to new IP " +
567 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800568 return main.TRUE
569 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800570 main.log.error( self.name + ": EOF exception found" )
571 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800572 return main.FALSE
573
Jon Hall7eb38402015-01-08 17:19:54 -0800574 def changeDefaultGateway( self, host, newGW ):
575 """
576 Changes the default gateway of a host
577 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800578 if self.handle:
579 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800580 cmd = host + " route add default gw " + newGW
581 self.handle.sendline( cmd )
582 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800583 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800584 main.log.info( "response = " + response )
585 main.log.info(
586 "Default gateway of host " +
587 host +
588 " changed to " +
589 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800590 return main.TRUE
591 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800594 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800595
Jon Hall7eb38402015-01-08 17:19:54 -0800596 def addStaticMACAddress( self, host, GW, macaddr ):
597 """
Jon Hallefbd9792015-03-05 16:11:36 -0800598 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800599 if self.handle:
600 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800601 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
602 cmd = host + " arp -s " + GW + " " + macaddr
603 self.handle.sendline( cmd )
604 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800605 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800606 main.log.info( "response = " + response )
607 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800608 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800609 GW +
610 " changed to " +
611 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800612 return main.TRUE
613 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800614 main.log.error( self.name + ": EOF exception found" )
615 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800616 return main.FALSE
617
Jon Hall7eb38402015-01-08 17:19:54 -0800618 def verifyStaticGWandMAC( self, host ):
619 """
620 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800621 if self.handle:
622 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800623 # h1 arp -an
624 cmd = host + " arp -an "
625 self.handle.sendline( cmd )
626 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800627 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800628 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800629 return main.TRUE
630 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800633 return main.FALSE
634
Jon Hall7eb38402015-01-08 17:19:54 -0800635 def getMacAddress( self, host ):
636 """
637 Verifies the host's ip configured or not."""
638 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700639 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800640 response = self.execute(
641 cmd=host +
642 " ifconfig",
643 prompt="mininet>",
644 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800645 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800646 main.log.error( self.name + ": EOF exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700648 main.cleanup()
649 main.exit()
adminbae64d82013-08-01 10:50:15 -0700650
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700651 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 macAddressSearch = re.search( pattern, response, re.I )
653 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800654 main.log.info(
655 self.name +
656 ": Mac-Address of Host " +
657 host +
658 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 macAddress )
660 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700661 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800662 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700663
Jon Hall7eb38402015-01-08 17:19:54 -0800664 def getInterfaceMACAddress( self, host, interface ):
665 """
666 Return the IP address of the interface on the given host"""
667 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700668 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800669 response = self.execute( cmd=host + " ifconfig " + interface,
670 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800671 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800672 main.log.error( self.name + ": EOF exception found" )
673 main.log.error( self.name + ": " + self.handle.before )
674 main.cleanup()
675 main.exit()
676
677 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 macAddressSearch = re.search( pattern, response, re.I )
679 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800680 main.log.info( "No mac address found in %s" % response )
681 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800683 main.log.info(
684 "Mac-Address of " +
685 host +
686 ":" +
687 interface +
688 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 macAddress )
690 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800691 else:
692 main.log.error( "Connection failed to the host" )
693
694 def getIPAddress( self, host ):
695 """
696 Verifies the host's ip configured or not."""
697 if self.handle:
698 try:
699 response = self.execute(
700 cmd=host +
701 " ifconfig",
702 prompt="mininet>",
703 timeout=10 )
704 except pexpect.EOF:
705 main.log.error( self.name + ": EOF exception found" )
706 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700707 main.cleanup()
708 main.exit()
adminbae64d82013-08-01 10:50:15 -0700709
710 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800712 main.log.info(
713 self.name +
714 ": IP-Address of Host " +
715 host +
716 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 ipAddressSearch.group( 1 ) )
718 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800719 else:
720 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800721
Jon Hall7eb38402015-01-08 17:19:54 -0800722 def getSwitchDPID( self, switch ):
723 """
724 return the datapath ID of the switch"""
725 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700726 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700727 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800728 response = self.execute(
729 cmd=cmd,
730 prompt="mininet>",
731 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800732 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700735 main.cleanup()
736 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800737 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800738 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700739 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.info(
741 "Couldn't find DPID for switch %s, found: %s" %
742 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700743 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800744 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700745 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700747
Jon Hall7eb38402015-01-08 17:19:54 -0800748 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700749 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800750 self.handle.sendline( "" )
751 self.expect( "mininet>" )
752 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700753 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800754 response = self.execute(
755 cmd=cmd,
756 prompt="mininet>",
757 timeout=10 )
758 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700759 response = self.handle.before
760 return response
761 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700764 main.cleanup()
765 main.exit()
766
Jon Hall7eb38402015-01-08 17:19:54 -0800767 def getInterfaces( self, node ):
768 """
769 return information dict about interfaces connected to the node"""
770 if self.handle:
771 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800772 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700773 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700774 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800775 response = self.execute(
776 cmd=cmd,
777 prompt="mininet>",
778 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800779 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800780 main.log.error( self.name + ": EOF exception found" )
781 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700782 main.cleanup()
783 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700784 return response
785 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800786 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700787
Jon Hall7eb38402015-01-08 17:19:54 -0800788 def dump( self ):
789 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700790 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800791 response = self.execute(
792 cmd='dump',
793 prompt='mininet>',
794 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800795 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800796 main.log.error( self.name + ": EOF exception found" )
797 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700798 main.cleanup()
799 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700800 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800801
Jon Hall7eb38402015-01-08 17:19:54 -0800802 def intfs( self ):
803 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700804 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 response = self.execute(
806 cmd='intfs',
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()
Jon Hall668ed802014-04-08 17:17:59 -0700814 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800815
Jon Hall7eb38402015-01-08 17:19:54 -0800816 def net( self ):
817 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700818 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800820 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800821 main.log.error( self.name + ": EOF exception found" )
822 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700823 main.cleanup()
824 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700825 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800826
827 def iperf( self, host1, host2 ):
828 main.log.info(
829 self.name +
830 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700831 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800832 cmd1 = 'iperf ' + host1 + " " + host2
833 self.handle.sendline( cmd1 )
834 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800835 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800836 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800837 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800838 return main.TRUE
839 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800840 main.log.error( self.name + ": iperf test failed" )
841 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800842 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800843 main.log.error( self.name + ": EOF exception found" )
844 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800845 main.cleanup()
846 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800847
Jon Hall7eb38402015-01-08 17:19:54 -0800848 def iperfudp( self ):
849 main.log.info(
850 self.name +
851 ": Simple iperf TCP test between two " +
852 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700853 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800854 response = self.execute(
855 cmd='iperfudp',
856 prompt='mininet>',
857 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800858 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800859 main.log.error( self.name + ": EOF exception found" )
860 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700861 main.cleanup()
862 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700863 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800864
Jon Hall7eb38402015-01-08 17:19:54 -0800865 def nodes( self ):
866 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700867 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800868 response = self.execute(
869 cmd='nodes',
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 pingpair( self ):
880 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700881 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800882 response = self.execute(
883 cmd='pingpair',
884 prompt='mininet>',
885 timeout=20 )
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 Hallfbc828e2015-01-06 17:30:19 -0800891
Jon Hall7eb38402015-01-08 17:19:54 -0800892 if re.search( ',\s0\%\spacket\sloss', response ):
893 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700895 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800896 else:
897 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700899 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800900
Jon Hall7eb38402015-01-08 17:19:54 -0800901 def link( self, **linkargs ):
902 """
903 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800904 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800905 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
906 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
907 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
908 main.log.info(
909 "Bring link between '" +
910 end1 +
911 "' and '" +
912 end2 +
913 "' '" +
914 option +
915 "'" )
916 command = "link " + \
917 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700918 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800919 self.handle.sendline( command )
920 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800921 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800922 main.log.error( self.name + ": EOF exception found" )
923 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700924 main.cleanup()
925 main.exit()
adminbae64d82013-08-01 10:50:15 -0700926 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800927
Jon Hall7eb38402015-01-08 17:19:54 -0800928 def yank( self, **yankargs ):
929 """
930 yank a mininet switch interface to a host"""
931 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800932 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800933 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
934 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
935 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700936 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800937 response = self.execute(
938 cmd=command,
939 prompt="mininet>",
940 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800941 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800942 main.log.error( self.name + ": EOF exception found" )
943 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700944 main.cleanup()
945 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700946 return main.TRUE
947
Jon Hall7eb38402015-01-08 17:19:54 -0800948 def plug( self, **plugargs ):
949 """
950 plug the yanked mininet switch interface to a switch"""
951 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800952 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800953 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
954 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
955 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700956 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800957 response = self.execute(
958 cmd=command,
959 prompt="mininet>",
960 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800961 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700964 main.cleanup()
965 main.exit()
adminbae64d82013-08-01 10:50:15 -0700966 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800967
Jon Hall7eb38402015-01-08 17:19:54 -0800968 def dpctl( self, **dpctlargs ):
969 """
970 Run dpctl command on all switches."""
971 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800972 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800973 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
974 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
975 command = "dpctl " + cmd + " " + str( cmdargs )
976 try:
977 response = self.execute(
978 cmd=command,
979 prompt="mininet>",
980 timeout=10 )
981 except pexpect.EOF:
982 main.log.error( self.name + ": EOF exception found" )
983 main.log.error( self.name + ": " + self.handle.before )
984 main.cleanup()
985 main.exit()
986 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -0800989 #FIXME: What uses this? This should be refactored to get
990 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 fileInput = path + '/lib/Mininet/INSTALL'
992 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700993 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800995 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700996 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800997 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500998 return version
adminbae64d82013-08-01 10:50:15 -0700999
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001001 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001002 Parameters:
1003 sw: The name of an OVS switch. Example "s1"
1004 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001005 The output of the command from the mininet cli
1006 or main.FALSE on timeout"""
1007 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001008 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001009 response = self.execute(
1010 cmd=command,
1011 prompt="mininet>",
1012 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001013 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001014 return response
admin2a9548d2014-06-17 14:08:07 -07001015 else:
1016 return main.FALSE
1017 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001018 main.log.error( self.name + ": EOF exception found" )
1019 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001020 main.cleanup()
1021 main.exit()
adminbae64d82013-08-01 10:50:15 -07001022
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001024 """
1025 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001026 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001027 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001028
1029 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001030 for j in range( count ):
1031 argstring = argstring + ",IP" + \
1032 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001033 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001034
Jon Hall7eb38402015-01-08 17:19:54 -08001035 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1036 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001037 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001038 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001039
Jon Hall7eb38402015-01-08 17:19:54 -08001040 command = "sh ovs-vsctl set-controller s" + \
1041 str( sw ) + " " + ptcpB + " "
1042 for j in range( count ):
1043 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001044 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001045 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1046 ip = args[
1047 "IP" +
1048 str( i ) ] if args[
1049 "IP" +
1050 str( i ) ] is not None else ""
1051 port = args[
1052 "PORT" +
1053 str( i ) ] if args[
1054 "PORT" +
1055 str( i ) ] is not None else ""
1056 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001057 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001058 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001059 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001060 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001061 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001062 main.log.error( self.name + ": EOF exception found" )
1063 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001064 main.cleanup()
1065 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001066 except Exception:
1067 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001068 main.cleanup()
1069 main.exit()
adminbae64d82013-08-01 10:50:15 -07001070
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001072 """
1073 Removes the controller target from sw"""
1074 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001075 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001076 response = self.execute(
1077 cmd=command,
1078 prompt="mininet>",
1079 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001080 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001081 main.log.error( self.name + ": EOF exception found" )
1082 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001083 main.cleanup()
1084 main.exit()
1085 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001086 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001087
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001089 """
Jon Hallb1290e82014-11-18 16:17:48 -05001090 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001091 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001092 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001093 NOTE: cannot currently specify what type of switch
1094 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001095 sw = name of the new switch as a string
1096 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001097 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001098 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001099 """
1100 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001101 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001102 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001103 response = self.execute(
1104 cmd=command,
1105 prompt="mininet>",
1106 timeout=10 )
1107 if re.search( "already exists!", response ):
1108 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001109 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001110 elif re.search( "Error", response ):
1111 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001112 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001113 elif re.search( "usage:", response ):
1114 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001115 return main.FALSE
1116 else:
1117 return main.TRUE
1118 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001119 main.log.error( self.name + ": EOF exception found" )
1120 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001121 main.cleanup()
1122 main.exit()
1123
kelvin-onlabd3b64892015-01-20 13:26:24 -08001124 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001125 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001126 delete a switch from the mininet topology
1127 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001128 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001129 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001130 sw = name of the switch as a string
1131 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001132 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001133 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001134 response = self.execute(
1135 cmd=command,
1136 prompt="mininet>",
1137 timeout=10 )
1138 if re.search( "no switch named", response ):
1139 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001140 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001141 elif re.search( "Error", response ):
1142 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001143 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001144 elif re.search( "usage:", response ):
1145 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001146 return main.FALSE
1147 else:
1148 return main.TRUE
1149 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001150 main.log.error( self.name + ": EOF exception found" )
1151 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001152 main.cleanup()
1153 main.exit()
1154
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001156 """
1157 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001158 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001159 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001160 NOTE: cannot currently specify what type of link
1161 required params:
1162 node1 = the string node name of the first endpoint of the link
1163 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001164 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001165 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001166 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001167 response = self.execute(
1168 cmd=command,
1169 prompt="mininet>",
1170 timeout=10 )
1171 if re.search( "doesnt exist!", response ):
1172 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001173 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001174 elif re.search( "Error", response ):
1175 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001176 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001177 elif re.search( "usage:", response ):
1178 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001179 return main.FALSE
1180 else:
1181 return main.TRUE
1182 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001183 main.log.error( self.name + ": EOF exception found" )
1184 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001185 main.cleanup()
1186 main.exit()
1187
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001189 """
1190 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001191 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001192 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001193 required params:
1194 node1 = the string node name of the first endpoint of the link
1195 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001196 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001197 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001198 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001199 response = self.execute(
1200 cmd=command,
1201 prompt="mininet>",
1202 timeout=10 )
1203 if re.search( "no node named", response ):
1204 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001205 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001206 elif re.search( "Error", response ):
1207 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001208 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001209 elif re.search( "usage:", response ):
1210 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001211 return main.FALSE
1212 else:
1213 return main.TRUE
1214 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001215 main.log.error( self.name + ": EOF exception found" )
1216 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001217 main.cleanup()
1218 main.exit()
1219
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001221 """
Jon Hallb1290e82014-11-18 16:17:48 -05001222 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001223 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001224 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001225 NOTE: cannot currently specify what type of host
1226 required params:
1227 hostname = the string hostname
1228 optional key-value params
1229 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001230 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001231 """
1232 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001233 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001234 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001235 response = self.execute(
1236 cmd=command,
1237 prompt="mininet>",
1238 timeout=10 )
1239 if re.search( "already exists!", response ):
1240 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001241 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001242 elif re.search( "doesnt exists!", response ):
1243 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001244 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001245 elif re.search( "Error", response ):
1246 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001247 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001248 elif re.search( "usage:", response ):
1249 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001250 return main.FALSE
1251 else:
1252 return main.TRUE
1253 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001256 main.cleanup()
1257 main.exit()
1258
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001260 """
1261 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001262 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001263 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001264 NOTE: this uses a custom mn function
1265 required params:
1266 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001267 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001268 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001269 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001270 response = self.execute(
1271 cmd=command,
1272 prompt="mininet>",
1273 timeout=10 )
1274 if re.search( "no host named", response ):
1275 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001276 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001277 elif re.search( "Error", response ):
1278 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001279 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001280 elif re.search( "usage:", response ):
1281 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001282 return main.FALSE
1283 else:
1284 return main.TRUE
1285 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001286 main.log.error( self.name + ": EOF exception found" )
1287 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001288 main.cleanup()
1289 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001290
Jon Hall7eb38402015-01-08 17:19:54 -08001291 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001292 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001293 Called at the end of the test to stop the mininet and
1294 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001295 """
1296 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001297 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001298 timeout=2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001299 if i == 0:
1300 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001301 elif i == 1:
1302 return main.TRUE
1303 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001304 # print "Disconnecting Mininet"
1305 if self.handle:
1306 self.handle.sendline( "exit" )
1307 self.handle.expect( "exit" )
1308 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001309 else:
1310 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001311 return response
1312
Hari Krishnab35c6d02015-03-18 11:13:51 -07001313 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001314 """
Jon Hall21270ac2015-02-16 17:59:55 -08001315 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001316 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001317 main.FALSE if the pexpect handle does not exist.
1318
Jon Halld61331b2015-02-17 16:35:47 -08001319 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001320 """
Jon Hall21270ac2015-02-16 17:59:55 -08001321
Jon Halld61331b2015-02-17 16:35:47 -08001322 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001323 response = ''
1324 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001325 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001326 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001327 i = self.handle.expect( [ 'mininet>',
1328 '\$',
1329 pexpect.EOF,
1330 pexpect.TIMEOUT ],
1331 timeout )
1332 if i == 0:
1333 main.log.info( "Exiting mininet..." )
1334
Jon Hall7eb38402015-01-08 17:19:54 -08001335 response = self.execute(
1336 cmd="exit",
1337 prompt="(.*)",
1338 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001339 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001340 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001341 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001342
kelvin-onlab56a3f462015-02-06 14:04:43 -08001343 if i == 1:
1344 main.log.info( " Mininet trying to exit while not " +
1345 "in the mininet prompt" )
1346 elif i == 2:
1347 main.log.error( "Something went wrong exiting mininet" )
1348 elif i == 3: # timeout
1349 main.log.error( "Something went wrong exiting mininet " +
1350 "TIMEOUT" )
1351
Hari Krishnab35c6d02015-03-18 11:13:51 -07001352 if fileName:
1353 self.handle.sendline("")
1354 self.handle.expect('\$')
1355 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001356 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001357 main.log.error( self.name + ": EOF exception found" )
1358 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001359 main.cleanup()
1360 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001361 else:
1362 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001363 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001364 return response
1365
Jon Hall7eb38402015-01-08 17:19:54 -08001366 def arping( self, src, dest, destmac ):
1367 self.handle.sendline( '' )
1368 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001369
Jon Hall7eb38402015-01-08 17:19:54 -08001370 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001371 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001372 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1373 main.log.info( self.name + ": ARP successful" )
1374 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001375 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001376 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001377 main.log.warn( self.name + ": ARP FAILURE" )
1378 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001379 return main.FALSE
1380
Jon Hall7eb38402015-01-08 17:19:54 -08001381 def decToHex( self, num ):
1382 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001383
Jon Hall7eb38402015-01-08 17:19:54 -08001384 def getSwitchFlowCount( self, switch ):
1385 """
1386 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001387 if self.handle:
1388 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1389 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001390 response = self.execute(
1391 cmd=cmd,
1392 prompt="mininet>",
1393 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001394 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001395 main.log.error( self.name + ": EOF exception found" )
1396 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001397 main.cleanup()
1398 main.exit()
1399 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001400 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001401 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001402 main.log.info(
1403 "Couldn't find flows on switch %s, found: %s" %
1404 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001405 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001406 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001407 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001408 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001409
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 def checkFlows( self, sw, dumpFormat=None ):
1411 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001412 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001414 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001415 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001416 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001417 response = self.execute(
1418 cmd=command,
1419 prompt="mininet>",
1420 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001421 return response
1422 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001423 main.log.error( self.name + ": EOF exception found" )
1424 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001425 main.cleanup()
1426 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001427
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001429 """
Jon Hallefbd9792015-03-05 16:11:36 -08001430 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001431 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001432 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001433 self.handle.sendline( "" )
1434 self.handle.expect( "mininet>" )
1435 self.handle.sendline(
1436 "sh sudo tcpdump -n -i " +
1437 intf +
1438 " " +
1439 port +
1440 " -w " +
1441 filename.strip() +
1442 " &" )
1443 self.handle.sendline( "" )
1444 i = self.handle.expect( [ 'No\ssuch\device',
1445 'listening\son',
1446 pexpect.TIMEOUT,
1447 "mininet>" ],
1448 timeout=10 )
1449 main.log.warn( self.handle.before + self.handle.after )
1450 self.handle.sendline( "" )
1451 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001452 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001453 main.log.error(
1454 self.name +
1455 ": tcpdump - No such device exists. " +
1456 "tcpdump attempted on: " +
1457 intf )
admin2a9548d2014-06-17 14:08:07 -07001458 return main.FALSE
1459 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001460 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001461 return main.TRUE
1462 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001463 main.log.error(
1464 self.name +
1465 ": tcpdump command timed out! Check interface name," +
1466 " given interface was: " +
1467 intf )
admin2a9548d2014-06-17 14:08:07 -07001468 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001469 elif i == 3:
1470 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001471 return main.TRUE
1472 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001473 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001474 return main.FALSE
1475 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001476 main.log.error( self.name + ": EOF exception found" )
1477 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001478 main.cleanup()
1479 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001480 except Exception:
1481 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001482 main.cleanup()
1483 main.exit()
1484
kelvin-onlabd3b64892015-01-20 13:26:24 -08001485 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001486 """
1487 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001488 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001489 self.handle.sendline( "sh sudo pkill tcpdump" )
1490 self.handle.expect( "mininet>" )
1491 self.handle.sendline( "" )
1492 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001493 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001494 main.log.error( self.name + ": EOF exception found" )
1495 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001496 main.cleanup()
1497 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001498 except Exception:
1499 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001500 main.cleanup()
1501 main.exit()
1502
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001504 """
1505 Compare mn and onos switches
1506 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001508
Jon Hall7eb38402015-01-08 17:19:54 -08001509 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001511 output = { "switches": [] }
1512 # iterate through the MN topology and pull out switches and and port
1513 # info
1514 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001515 ports = []
1516 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001517 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001518 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001519 'name': port.name } )
1520 output[ 'switches' ].append( {
1521 "name": switch.name,
1522 "dpid": str( switch.dpid ).zfill( 16 ),
1523 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001524
Jon Hall7eb38402015-01-08 17:19:54 -08001525 # print "mn"
1526 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001527 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001528 # indent=4,
1529 # separators=( ',', ': ' ) )
1530 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001532 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001533 # indent=4,
1534 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001535
1536 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001537 mnDPIDs = []
1538 for switch in output[ 'switches' ]:
1539 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001540 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001541 # print "List of Mininet switch DPID's"
1542 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001544 main.log.error(
1545 self.name +
1546 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001547 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001549 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001550 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001551 if switch[ 'available' ]:
1552 onosDPIDs.append(
1553 switch[ 'id' ].replace(
1554 ":",
1555 '' ).replace(
1556 "of",
1557 '' ).lower() )
1558 # else:
1559 # print "Switch is unavailable:"
1560 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001561 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001562 # print "List of ONOS switch DPID's"
1563 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001564
Jon Hall7eb38402015-01-08 17:19:54 -08001565 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001567 main.log.report( "Switches in MN but not in ONOS:" )
1568 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1569 main.log.report( str( list1 ) )
1570 main.log.report( "Switches in ONOS but not in MN:" )
1571 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001572 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001573 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 switchResults = main.TRUE
1575 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001576
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001578 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001579 Compare mn and onos ports
1580 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001581 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001582
Jon Hallfbc828e2015-01-06 17:30:19 -08001583 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001584 1. This uses the sts TestONTopology object
1585 2. numpy - "sudo pip install numpy"
1586
Jon Hall7eb38402015-01-08 17:19:54 -08001587 """
1588 # FIXME: this does not look for extra ports in ONOS, only checks that
1589 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001590 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001592 output = { "switches": [] }
1593 # iterate through the MN topology and pull out switches and and port
1594 # info
1595 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001596 ports = []
1597 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001598 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001599 tmpPort = { 'of_port': port.port_no,
1600 'mac': str( port.hw_addr ).replace( '\'', '' ),
1601 'name': port.name,
1602 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001603
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001605 tmpSwitch = { 'name': switch.name,
1606 'dpid': str( switch.dpid ).zfill( 16 ),
1607 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001608
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001610
Jon Hall7eb38402015-01-08 17:19:54 -08001611 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 for mnSwitch in output[ 'switches' ]:
1613 mnPorts = []
1614 onosPorts = []
1615 switchResult = main.TRUE
1616 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001617 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 mnPorts.append( port[ 'of_port' ] )
1619 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001620 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 # print onosSwitch
1622 if onosSwitch[ 'device' ][ 'available' ]:
1623 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001624 ':',
1625 '' ).replace(
1626 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 '' ) == mnSwitch[ 'dpid' ]:
1628 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001629 if port[ 'isEnabled' ]:
1630 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001631 # onosPorts.append( 'local' )
1632 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001633 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001635 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 mnPorts.sort( key=float )
1637 onosPorts.sort( key=float )
1638 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1639 # print "\tmn_ports[] = ", mnPorts
1640 # print "\tonos_ports[] = ", onosPorts
1641 mnPortsLog = mnPorts
1642 onosPortsLog = onosPorts
1643 mnPorts = [ x for x in mnPorts ]
1644 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001645
Jon Hall7eb38402015-01-08 17:19:54 -08001646 # TODO: handle other reserved port numbers besides LOCAL
1647 # NOTE: Reserved ports
1648 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1649 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001650 for mnPort in mnPortsLog:
1651 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001652 # don't set results to true here as this is just one of
1653 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001654 mnPorts.remove( mnPort )
1655 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001656 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001657 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001658 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 if 65534 in mnPorts:
1660 mnPorts.remove( 65534 )
1661 if long( uint64( -2 ) ) in onosPorts:
1662 onosPorts.remove( long( uint64( -2 ) ) )
1663 if len( mnPorts ): # the ports of this switch don't match
1664 switchResult = main.FALSE
1665 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1666 if len( onosPorts ): # the ports of this switch don't match
1667 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001668 main.log.warn(
1669 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 str( onosPorts ) )
1671 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001672 main.log.report(
1673 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1675 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1676 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1677 portsResults = portsResults and switchResult
1678 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001679
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001681 """
1682 Compare mn and onos links
1683 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001685
Jon Hall7eb38402015-01-08 17:19:54 -08001686 This uses the sts TestONTopology object"""
1687 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001688 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001689 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001690 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001691 # iterate through the MN topology and pull out switches and and port
1692 # info
1693 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001694 # print "Iterating though switches as seen by Mininet"
1695 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001696 ports = []
1697 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001698 # print port.hw_addr.toStr( separator='' )
1699 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001700 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001701 'name': port.name } )
1702 output[ 'switches' ].append( {
1703 "name": switch.name,
1704 "dpid": str( switch.dpid ).zfill( 16 ),
1705 "ports": ports } )
1706 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001707
kelvin-onlabd3b64892015-01-20 13:26:24 -08001708 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001709 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001710 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 if 2 * len( mnLinks ) == len( onos ):
1712 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001713 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001714 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001715 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001716 "Mininet has " + str( len( mnLinks ) ) +
1717 " bidirectional links and ONOS has " +
1718 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001719
Jon Hall7eb38402015-01-08 17:19:54 -08001720 # iterate through MN links and check if an ONOS link exists in
1721 # both directions
1722 # NOTE: Will currently only show mn links as down if they are
1723 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001724 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001725 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001727 # print "Link: %s" % link
1728 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001729 node1 = None
1730 port1 = None
1731 node2 = None
1732 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 firstDir = main.FALSE
1734 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001735 for switch in output[ 'switches' ]:
1736 # print "Switch: %s" % switch[ 'name' ]
1737 if switch[ 'name' ] == link.node1.name:
1738 node1 = switch[ 'dpid' ]
1739 for port in switch[ 'ports' ]:
1740 if str( port[ 'name' ] ) == str( link.port1 ):
1741 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001742 if node1 is not None and node2 is not None:
1743 break
Jon Hall7eb38402015-01-08 17:19:54 -08001744 if switch[ 'name' ] == link.node2.name:
1745 node2 = switch[ 'dpid' ]
1746 for port in switch[ 'ports' ]:
1747 if str( port[ 'name' ] ) == str( link.port2 ):
1748 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001749 if node1 is not None and node2 is not None:
1750 break
1751
kelvin-onlabd3b64892015-01-20 13:26:24 -08001752 for onosLink in onos:
1753 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001754 ":",
1755 '' ).replace(
1756 "of",
1757 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001759 ":",
1760 '' ).replace(
1761 "of",
1762 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001763 onosPort1 = onosLink[ 'src' ][ 'port' ]
1764 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001765
Jon Hall72cf1dc2014-10-20 21:04:50 -04001766 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 if str( onosNode1 ) == str( node1 ) and str(
1768 onosNode2 ) == str( node2 ):
1769 if int( onosPort1 ) == int( port1 ) and int(
1770 onosPort2 ) == int( port2 ):
1771 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001772 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001773 main.log.warn(
1774 'The port numbers do not match for ' +
1775 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001776 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001777 'link %s/%s -> %s/%s' %
1778 ( node1,
1779 port1,
1780 node2,
1781 port2 ) +
1782 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001783 ( onosNode1,
1784 onosPort1,
1785 onosNode2,
1786 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001787
1788 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001789 elif ( str( onosNode1 ) == str( node2 ) and
1790 str( onosNode2 ) == str( node1 ) ):
1791 if ( int( onosPort1 ) == int( port2 )
1792 and int( onosPort2 ) == int( port1 ) ):
1793 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001794 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001795 main.log.warn(
1796 'The port numbers do not match for ' +
1797 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001798 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001799 'link %s/%s -> %s/%s' %
1800 ( node2,
1801 port2,
1802 node1,
1803 port1 ) +
1804 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 ( onosNode2,
1806 onosPort2,
1807 onosNode1,
1808 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001809 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001810 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001812 main.log.report(
1813 'ONOS does not have the link %s/%s -> %s/%s' %
1814 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001816 main.log.report(
1817 'ONOS does not have the link %s/%s -> %s/%s' %
1818 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001819 linkResults = linkResults and firstDir and secondDir
1820 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001821
Jon Hallff6b4b22015-02-23 09:25:15 -08001822 def compareHosts( self, topo, hostsJson ):
1823 """
1824 Compare mn and onos Hosts.
1825 Since Mininet hosts are quiet, ONOS will only know of them when they
1826 speak. For this reason, we will only check that the hosts in ONOS
1827 stores are in Mininet, and not vice versa.
1828 topo: sts TestONTopology object
1829 hostsJson: parsed json object from the onos hosts api
1830
1831 This uses the sts TestONTopology object"""
1832 import json
1833 hostResults = main.TRUE
1834 hosts = []
1835 # iterate through the MN topology and pull out hosts
1836 for mnHost in topo.graph.hosts:
1837 interfaces = []
1838 for intf in mnHost.interfaces:
1839 interfaces.append( {
1840 "name": intf.name, # str
1841 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1842 # hw_addr is of type EthAddr, Not JSON serializable
1843 "hw_addr": str( intf.hw_addr ) } )
1844 hosts.append( {
1845 "name": mnHost.name, # str
1846 "interfaces": interfaces } ) # list
1847 for onosHost in hostsJson:
1848 onosMAC = onosHost[ 'mac' ].lower()
1849 match = False
1850 for mnHost in hosts:
1851 for mnIntf in mnHost[ 'interfaces' ]:
1852 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1853 match = True
1854 for ip in mnIntf[ 'ips' ]:
1855 if ip in onosHost[ 'ips' ]:
1856 pass # all is well
1857 else:
1858 # misssing ip
1859 main.log.error( "ONOS host " + onosHost[ 'id' ]
1860 + " has a different IP than " +
1861 "the Mininet host." )
1862 output = json.dumps(
1863 onosHost,
1864 sort_keys=True,
1865 indent=4,
1866 separators=( ',', ': ' ) )
1867 main.log.info( output )
1868 hostResults = main.FALSE
1869 if not match:
1870 hostResults = main.FALSE
1871 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1872 "corresponding Mininet host." )
1873 output = json.dumps( onosHost,
1874 sort_keys=True,
1875 indent=4,
1876 separators=( ',', ': ' ) )
1877 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001878 return hostResults
1879
kelvin-onlabd3b64892015-01-20 13:26:24 -08001880 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001881 """
1882 Returns a list of all hosts
1883 Don't ask questions just use it"""
1884 self.handle.sendline( "" )
1885 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001886
Jon Hall7eb38402015-01-08 17:19:54 -08001887 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1888 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001889
kelvin-onlabd3b64892015-01-20 13:26:24 -08001890 handlePy = self.handle.before
1891 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1892 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001893
Jon Hall7eb38402015-01-08 17:19:54 -08001894 self.handle.sendline( "" )
1895 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001896
kelvin-onlabd3b64892015-01-20 13:26:24 -08001897 hostStr = handlePy.replace( "]", "" )
1898 hostStr = hostStr.replace( "'", "" )
1899 hostStr = hostStr.replace( "[", "" )
1900 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001901
kelvin-onlabd3b64892015-01-20 13:26:24 -08001902 return hostList
adminbae64d82013-08-01 10:50:15 -07001903
Jon Hall7eb38402015-01-08 17:19:54 -08001904 def update( self ):
1905 """
1906 updates the port address and status information for
1907 each port in mn"""
1908 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001909 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001910 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001911 self.handle.sendline( "" )
1912 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001913
Jon Hall7eb38402015-01-08 17:19:54 -08001914 self.handle.sendline( "update" )
1915 self.handle.expect( "update" )
1916 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001917
Jon Hall7eb38402015-01-08 17:19:54 -08001918 self.handle.sendline( "" )
1919 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001920
Jon Hallb1290e82014-11-18 16:17:48 -05001921 return main.TRUE
1922 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001923 main.log.error( self.name + ": EOF exception found" )
1924 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001925 main.cleanup()
1926 main.exit()
1927
adminbae64d82013-08-01 10:50:15 -07001928if __name__ != "__main__":
1929 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07001930 sys.modules[ __name__ ] = MininetCliDriver()