blob: 28688563917e8b3916698a5fadc6e54f94a0c6b1 [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"""
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700268 try:
269 if self.handle:
270 main.log.info(
271 self.name +
272 ": Checking reachabilty to the hosts using pingall" )
273 response = ""
274 failedPings = 0
275 returnValue = main.TRUE
276 self.handle.sendline( "pingall" )
277 while True:
278 i = self.handle.expect( [ "mininet>","X",
279 pexpect.EOF,
280 pexpect.TIMEOUT ],
281 timeout )
282 if i == 0:
283 main.log.info( self.name + ": pingall finished")
284 response += self.handle.before
285 break
286 elif i == 1:
287 response += self.handle.before + self.handle.after
288 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700289 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700290 returnValue = main.FALSE
291 if shortCircuit:
292 main.log.error( self.name +
293 ": Aborting pingall - "
294 + str( failedPings ) +
295 " pings failed" )
296 break
297 elif i == 2:
298 main.log.error( self.name +
299 ": EOF exception found" )
300 main.log.error( self.name + ": " +
301 self.handle.before )
302 main.cleanup()
303 main.exit()
304 elif i == 3:
305 response += self.handle.before
306 main.log.error( self.name +
307 ": TIMEOUT exception found" )
308 main.log.error( self.name +
309 ": " +
310 str( response ) )
311 # NOTE: Send ctrl-c to make sure pingall is done
312 self.handle.sendline( "\x03" )
313 self.handle.expect( "Interrupt" )
314 self.handle.expect( "mininet>" )
315 break
316 pattern = "Results\:"
317 main.log.info( "Pingall output: " + str( response ) )
318 if re.search( pattern, response ):
319 main.log.info( self.name + ": Pingall finished with "
320 + str( failedPings ) + " failed pings" )
321 return returnValue
322 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700323 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700324 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700325 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700326 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700327 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700328 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700329 main.log.error( self.name + ": Connection failed to the host" )
330 main.cleanup()
331 main.exit()
332 except pexpect.TIMEOUT:
333 if response:
334 main.log.info( "Pingall output: " + str( response ) )
335 main.log.error( self.name + ": pexpect.TIMEOUT found" )
336 return main.FALSE
337 except pexpect.EOF:
338 main.log.error( self.name + ": EOF exception found" )
339 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500340 main.cleanup()
341 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700342
Jon Hall7eb38402015-01-08 17:19:54 -0800343 def fpingHost( self, **pingParams ):
344 """
345 Uses the fping package for faster pinging...
346 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800347 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800348 command = args[ "SRC" ] + \
349 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
350 self.handle.sendline( command )
351 self.handle.expect(
352 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
353 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
354 response = self.handle.before
355 if re.search( ":\s-", response ):
356 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700357 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800358 elif re.search( ":\s\d{1,2}\.\d\d", response ):
359 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700360 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800361 main.log.info( self.name + ": Install fping on mininet machine... " )
362 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700363 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800364
Jon Hall7eb38402015-01-08 17:19:54 -0800365 def pingHost( self, **pingParams ):
366 """
367 Ping from one mininet host to another
368 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800369 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800370 command = args[ "SRC" ] + " ping " + \
371 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700372 try:
Jon Hall61282e32015-03-19 11:34:11 -0700373 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800374 self.handle.sendline( command )
375 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700376 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800377 main.log.error(
378 self.name +
379 ": timeout when waiting for response from mininet" )
380 main.log.error( "response: " + str( self.handle.before ) )
381 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700382 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800383 main.log.error(
384 self.name +
385 ": timeout when waiting for response from mininet" )
386 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700387 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800388 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800389 main.log.error( self.name + ": EOF exception found" )
390 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700391 main.cleanup()
392 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800393 main.log.info( self.name + ": Ping Response: " + response )
394 if re.search( ',\s0\%\spacket\sloss', response ):
395 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800396 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700397 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800398 else:
399 main.log.error(
400 self.name +
401 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700403 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800404
Jon Hall7eb38402015-01-08 17:19:54 -0800405 def checkIP( self, host ):
406 """
407 Verifies the host's ip configured or not."""
408 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700409 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800410 response = self.execute(
411 cmd=host +
412 " ifconfig",
413 prompt="mininet>",
414 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800415 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800416 main.log.error( self.name + ": EOF exception found" )
417 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700418 main.cleanup()
419 main.exit()
adminbae64d82013-08-01 10:50:15 -0700420
Jon Hall7eb38402015-01-08 17:19:54 -0800421 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800422 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
423 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
424 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
425 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
426 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800427 # pattern = "inet addr:10.0.0.6"
428 if re.search( pattern, response ):
429 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700430 return main.TRUE
431 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800432 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700433 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800434 else:
435 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800436
Jon Hall7eb38402015-01-08 17:19:54 -0800437 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800438 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700439 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800440 response = self.execute(
441 cmd="h1 /usr/sbin/sshd -D&",
442 prompt="mininet>",
443 timeout=10 )
444 response = self.execute(
445 cmd="h4 /usr/sbin/sshd -D&",
446 prompt="mininet>",
447 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700448 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800449 vars( self )[ key ] = connectargs[ key ]
450 response = self.execute(
451 cmd="xterm h1 h4 ",
452 prompt="mininet>",
453 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800454 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800455 main.log.error( self.name + ": EOF exception found" )
456 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700457 main.cleanup()
458 main.exit()
adminbae64d82013-08-01 10:50:15 -0700459 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800460 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700461 if self.flag == 0:
462 self.flag = 1
463 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800464 else:
adminbae64d82013-08-01 10:50:15 -0700465 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800466
kelvin-onlaba1484582015-02-02 15:46:20 -0800467 def moveHost( self, host, oldSw, newSw, ):
468 """
469 Moves a host from one switch to another on the fly
470 Note: The intf between host and oldSw when detached
471 using detach(), will still show up in the 'net'
472 cmd, because switch.detach() doesn't affect switch.intfs[]
473 (which is correct behavior since the interfaces
474 haven't moved).
475 """
476 if self.handle:
477 try:
478 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800479 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
480 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800481 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800482 response = self.execute( cmd=cmd,
483 prompt="mininet>",
484 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800485
486 # Determine hostintf and Oldswitchintf
487 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800488 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800489 print "cmd2= ", cmd
490 self.handle.sendline( cmd )
491 self.handle.expect( "mininet>" )
492
shahshreya73537862015-02-11 15:15:24 -0800493 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800494 cmd = "px ipaddr = hintf.IP()"
495 print "cmd3= ", cmd
496 self.handle.sendline( cmd )
497 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800498
499 cmd = "px macaddr = hintf.MAC()"
500 print "cmd3= ", cmd
501 self.handle.sendline( cmd )
502 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800503
504 # Detach interface between oldSw-host
505 cmd = "px " + oldSw + ".detach( sintf )"
506 print "cmd4= ", cmd
507 self.handle.sendline( cmd )
508 self.handle.expect( "mininet>" )
509
510 # Add link between host-newSw
511 cmd = "py net.addLink(" + host + "," + newSw + ")"
512 print "cmd5= ", cmd
513 self.handle.sendline( cmd )
514 self.handle.expect( "mininet>" )
515
516 # Determine hostintf and Newswitchintf
517 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800518 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800519 print "cmd6= ", cmd
520 self.handle.sendline( cmd )
521 self.handle.expect( "mininet>" )
522
523 # Attach interface between newSw-host
524 cmd = "px " + newSw + ".attach( sintf )"
525 print "cmd3= ", cmd
526 self.handle.sendline( cmd )
527 self.handle.expect( "mininet>" )
528
529 # Set ipaddress of the host-newSw interface
530 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
531 print "cmd7 = ", cmd
532 self.handle.sendline( cmd )
533 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800534
535 # Set macaddress of the host-newSw interface
536 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
537 print "cmd8 = ", cmd
538 self.handle.sendline( cmd )
539 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800540
541 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800542 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800543 self.handle.sendline( cmd )
544 self.handle.expect( "mininet>" )
545 print "output = ", self.handle.before
546
547 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800548 cmd = host + " ifconfig"
549 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800550 self.handle.sendline( cmd )
551 self.handle.expect( "mininet>" )
552 print "ifconfig o/p = ", self.handle.before
553
554 return main.TRUE
555 except pexpect.EOF:
556 main.log.error( self.name + ": EOF exception found" )
557 main.log.error( self.name + ": " + self.handle.before )
558 return main.FALSE
559
Jon Hall7eb38402015-01-08 17:19:54 -0800560 def changeIP( self, host, intf, newIP, newNetmask ):
561 """
562 Changes the ip address of a host on the fly
563 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800564 if self.handle:
565 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800566 cmd = host + " ifconfig " + intf + " " + \
567 newIP + " " + 'netmask' + " " + newNetmask
568 self.handle.sendline( cmd )
569 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800570 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800571 main.log.info( "response = " + response )
572 main.log.info(
573 "Ip of host " +
574 host +
575 " changed to new IP " +
576 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800577 return main.TRUE
578 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800579 main.log.error( self.name + ": EOF exception found" )
580 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800581 return main.FALSE
582
Jon Hall7eb38402015-01-08 17:19:54 -0800583 def changeDefaultGateway( self, host, newGW ):
584 """
585 Changes the default gateway of a host
586 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800587 if self.handle:
588 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800589 cmd = host + " route add default gw " + newGW
590 self.handle.sendline( cmd )
591 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800592 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800593 main.log.info( "response = " + response )
594 main.log.info(
595 "Default gateway of host " +
596 host +
597 " changed to " +
598 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800599 return main.TRUE
600 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800601 main.log.error( self.name + ": EOF exception found" )
602 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800603 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800604
Jon Hall7eb38402015-01-08 17:19:54 -0800605 def addStaticMACAddress( self, host, GW, macaddr ):
606 """
Jon Hallefbd9792015-03-05 16:11:36 -0800607 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800608 if self.handle:
609 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800610 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
611 cmd = host + " arp -s " + GW + " " + macaddr
612 self.handle.sendline( cmd )
613 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800614 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800615 main.log.info( "response = " + response )
616 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800617 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800618 GW +
619 " changed to " +
620 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800621 return main.TRUE
622 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800623 main.log.error( self.name + ": EOF exception found" )
624 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800625 return main.FALSE
626
Jon Hall7eb38402015-01-08 17:19:54 -0800627 def verifyStaticGWandMAC( self, host ):
628 """
629 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800630 if self.handle:
631 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800632 # h1 arp -an
633 cmd = host + " arp -an "
634 self.handle.sendline( cmd )
635 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800636 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800637 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800638 return main.TRUE
639 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800642 return main.FALSE
643
Jon Hall7eb38402015-01-08 17:19:54 -0800644 def getMacAddress( self, host ):
645 """
646 Verifies the host's ip configured or not."""
647 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700648 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800649 response = self.execute(
650 cmd=host +
651 " ifconfig",
652 prompt="mininet>",
653 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800654 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800655 main.log.error( self.name + ": EOF exception found" )
656 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700657 main.cleanup()
658 main.exit()
adminbae64d82013-08-01 10:50:15 -0700659
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700660 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 macAddressSearch = re.search( pattern, response, re.I )
662 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800663 main.log.info(
664 self.name +
665 ": Mac-Address of Host " +
666 host +
667 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 macAddress )
669 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700670 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800671 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700672
Jon Hall7eb38402015-01-08 17:19:54 -0800673 def getInterfaceMACAddress( self, host, interface ):
674 """
675 Return the IP address of the interface on the given host"""
676 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700677 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800678 response = self.execute( cmd=host + " ifconfig " + interface,
679 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800680 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800681 main.log.error( self.name + ": EOF exception found" )
682 main.log.error( self.name + ": " + self.handle.before )
683 main.cleanup()
684 main.exit()
685
686 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 macAddressSearch = re.search( pattern, response, re.I )
688 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800689 main.log.info( "No mac address found in %s" % response )
690 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800691 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800692 main.log.info(
693 "Mac-Address of " +
694 host +
695 ":" +
696 interface +
697 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 macAddress )
699 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800700 else:
701 main.log.error( "Connection failed to the host" )
702
703 def getIPAddress( self, host ):
704 """
705 Verifies the host's ip configured or not."""
706 if self.handle:
707 try:
708 response = self.execute(
709 cmd=host +
710 " ifconfig",
711 prompt="mininet>",
712 timeout=10 )
713 except pexpect.EOF:
714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700716 main.cleanup()
717 main.exit()
adminbae64d82013-08-01 10:50:15 -0700718
719 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800721 main.log.info(
722 self.name +
723 ": IP-Address of Host " +
724 host +
725 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800726 ipAddressSearch.group( 1 ) )
727 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800728 else:
729 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800730
Jon Hall7eb38402015-01-08 17:19:54 -0800731 def getSwitchDPID( self, switch ):
732 """
733 return the datapath ID of the switch"""
734 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700735 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700736 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800737 response = self.execute(
738 cmd=cmd,
739 prompt="mininet>",
740 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800741 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800742 main.log.error( self.name + ": EOF exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700744 main.cleanup()
745 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800746 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800747 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700748 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800749 main.log.info(
750 "Couldn't find DPID for switch %s, found: %s" %
751 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700752 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800753 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700754 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800755 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700756
Jon Hall7eb38402015-01-08 17:19:54 -0800757 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700758 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800759 self.handle.sendline( "" )
760 self.expect( "mininet>" )
761 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700762 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800763 response = self.execute(
764 cmd=cmd,
765 prompt="mininet>",
766 timeout=10 )
767 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700768 response = self.handle.before
769 return response
770 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800771 main.log.error( self.name + ": EOF exception found" )
772 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700773 main.cleanup()
774 main.exit()
775
Jon Hall7eb38402015-01-08 17:19:54 -0800776 def getInterfaces( self, node ):
777 """
778 return information dict about interfaces connected to the node"""
779 if self.handle:
780 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800781 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700782 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700783 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800784 response = self.execute(
785 cmd=cmd,
786 prompt="mininet>",
787 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800788 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700791 main.cleanup()
792 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700793 return response
794 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800795 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700796
Jon Hall7eb38402015-01-08 17:19:54 -0800797 def dump( self ):
798 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700799 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 response = self.execute(
801 cmd='dump',
802 prompt='mininet>',
803 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800804 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700807 main.cleanup()
808 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700809 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800810
Jon Hall7eb38402015-01-08 17:19:54 -0800811 def intfs( self ):
812 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700813 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 response = self.execute(
815 cmd='intfs',
816 prompt='mininet>',
817 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800818 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700821 main.cleanup()
822 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700823 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800824
Jon Hall7eb38402015-01-08 17:19:54 -0800825 def net( self ):
826 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700827 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800828 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800829 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800830 main.log.error( self.name + ": EOF exception found" )
831 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700832 main.cleanup()
833 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700834 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800835
836 def iperf( self, host1, host2 ):
837 main.log.info(
838 self.name +
839 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700840 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800841 cmd1 = 'iperf ' + host1 + " " + host2
842 self.handle.sendline( cmd1 )
843 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800844 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800845 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800846 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800847 return main.TRUE
848 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800849 main.log.error( self.name + ": iperf test failed" )
850 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800851 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800852 main.log.error( self.name + ": EOF exception found" )
853 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800854 main.cleanup()
855 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800856
Jon Hall7eb38402015-01-08 17:19:54 -0800857 def iperfudp( self ):
858 main.log.info(
859 self.name +
860 ": Simple iperf TCP test between two " +
861 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700862 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800863 response = self.execute(
864 cmd='iperfudp',
865 prompt='mininet>',
866 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800867 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700870 main.cleanup()
871 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700872 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800873
Jon Hall7eb38402015-01-08 17:19:54 -0800874 def nodes( self ):
875 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700876 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800877 response = self.execute(
878 cmd='nodes',
879 prompt='mininet>',
880 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800881 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800882 main.log.error( self.name + ": EOF exception found" )
883 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700884 main.cleanup()
885 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700886 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800887
Jon Hall7eb38402015-01-08 17:19:54 -0800888 def pingpair( self ):
889 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700890 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800891 response = self.execute(
892 cmd='pingpair',
893 prompt='mininet>',
894 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800895 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800896 main.log.error( self.name + ": EOF exception found" )
897 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700898 main.cleanup()
899 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800900
Jon Hall7eb38402015-01-08 17:19:54 -0800901 if re.search( ',\s0\%\spacket\sloss', response ):
902 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700904 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800905 else:
906 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700908 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800909
Jon Hall7eb38402015-01-08 17:19:54 -0800910 def link( self, **linkargs ):
911 """
912 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800913 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800914 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
915 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
916 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
917 main.log.info(
918 "Bring link between '" +
919 end1 +
920 "' and '" +
921 end2 +
922 "' '" +
923 option +
924 "'" )
925 command = "link " + \
926 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700927 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800928 self.handle.sendline( command )
929 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800930 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800931 main.log.error( self.name + ": EOF exception found" )
932 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700933 main.cleanup()
934 main.exit()
adminbae64d82013-08-01 10:50:15 -0700935 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800936
Jon Hall7eb38402015-01-08 17:19:54 -0800937 def yank( self, **yankargs ):
938 """
939 yank a mininet switch interface to a host"""
940 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800941 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800942 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
943 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
944 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700945 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800946 response = self.execute(
947 cmd=command,
948 prompt="mininet>",
949 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800950 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800951 main.log.error( self.name + ": EOF exception found" )
952 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700953 main.cleanup()
954 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700955 return main.TRUE
956
Jon Hall7eb38402015-01-08 17:19:54 -0800957 def plug( self, **plugargs ):
958 """
959 plug the yanked mininet switch interface to a switch"""
960 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800961 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800962 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
963 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
964 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700965 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800966 response = self.execute(
967 cmd=command,
968 prompt="mininet>",
969 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800970 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800971 main.log.error( self.name + ": EOF exception found" )
972 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700973 main.cleanup()
974 main.exit()
adminbae64d82013-08-01 10:50:15 -0700975 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800976
Jon Hall7eb38402015-01-08 17:19:54 -0800977 def dpctl( self, **dpctlargs ):
978 """
979 Run dpctl command on all switches."""
980 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800981 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800982 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
983 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
984 command = "dpctl " + cmd + " " + str( cmdargs )
985 try:
986 response = self.execute(
987 cmd=command,
988 prompt="mininet>",
989 timeout=10 )
990 except pexpect.EOF:
991 main.log.error( self.name + ": EOF exception found" )
992 main.log.error( self.name + ": " + self.handle.before )
993 main.cleanup()
994 main.exit()
995 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800996
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -0800998 #FIXME: What uses this? This should be refactored to get
999 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 fileInput = path + '/lib/Mininet/INSTALL'
1001 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001002 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001004 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001005 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001006 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001007 return version
adminbae64d82013-08-01 10:50:15 -07001008
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001010 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001011 Parameters:
1012 sw: The name of an OVS switch. Example "s1"
1013 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001014 The output of the command from the mininet cli
1015 or main.FALSE on timeout"""
1016 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001017 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001018 response = self.execute(
1019 cmd=command,
1020 prompt="mininet>",
1021 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001022 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001023 return response
admin2a9548d2014-06-17 14:08:07 -07001024 else:
1025 return main.FALSE
1026 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001029 main.cleanup()
1030 main.exit()
adminbae64d82013-08-01 10:50:15 -07001031
kelvin-onlabd3b64892015-01-20 13:26:24 -08001032 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001033 """
1034 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001035 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001036 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001037
1038 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001039 for j in range( count ):
1040 argstring = argstring + ",IP" + \
1041 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001042 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001043
Jon Hall7eb38402015-01-08 17:19:54 -08001044 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1045 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001046 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001047 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001048
Jon Hall7eb38402015-01-08 17:19:54 -08001049 command = "sh ovs-vsctl set-controller s" + \
1050 str( sw ) + " " + ptcpB + " "
1051 for j in range( count ):
1052 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001053 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001054 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1055 ip = args[
1056 "IP" +
1057 str( i ) ] if args[
1058 "IP" +
1059 str( i ) ] is not None else ""
1060 port = args[
1061 "PORT" +
1062 str( i ) ] if args[
1063 "PORT" +
1064 str( i ) ] is not None else ""
1065 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001066 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001067 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001068 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001069 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001070 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001073 main.cleanup()
1074 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
1076 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001077 main.cleanup()
1078 main.exit()
adminbae64d82013-08-01 10:50:15 -07001079
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001081 """
1082 Removes the controller target from sw"""
1083 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001084 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001085 response = self.execute(
1086 cmd=command,
1087 prompt="mininet>",
1088 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001089 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001090 main.log.error( self.name + ": EOF exception found" )
1091 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001092 main.cleanup()
1093 main.exit()
1094 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001095 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001096
kelvin-onlabd3b64892015-01-20 13:26:24 -08001097 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001098 """
Jon Hallb1290e82014-11-18 16:17:48 -05001099 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001100 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001101 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001102 NOTE: cannot currently specify what type of switch
1103 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001104 sw = name of the new switch as a string
1105 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001106 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001107 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001108 """
1109 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001110 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001111 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001112 response = self.execute(
1113 cmd=command,
1114 prompt="mininet>",
1115 timeout=10 )
1116 if re.search( "already exists!", response ):
1117 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001118 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001119 elif re.search( "Error", response ):
1120 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001121 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001122 elif re.search( "usage:", response ):
1123 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001124 return main.FALSE
1125 else:
1126 return main.TRUE
1127 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001128 main.log.error( self.name + ": EOF exception found" )
1129 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001130 main.cleanup()
1131 main.exit()
1132
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001134 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001135 delete a switch from the mininet topology
1136 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001137 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001138 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001139 sw = name of the switch as a string
1140 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001141 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001142 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001143 response = self.execute(
1144 cmd=command,
1145 prompt="mininet>",
1146 timeout=10 )
1147 if re.search( "no switch named", response ):
1148 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001149 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001150 elif re.search( "Error", response ):
1151 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001152 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001153 elif re.search( "usage:", response ):
1154 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001155 return main.FALSE
1156 else:
1157 return main.TRUE
1158 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001159 main.log.error( self.name + ": EOF exception found" )
1160 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001161 main.cleanup()
1162 main.exit()
1163
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001165 """
1166 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001167 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001168 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001169 NOTE: cannot currently specify what type of link
1170 required params:
1171 node1 = the string node name of the first endpoint of the link
1172 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001173 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001174 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001175 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001176 response = self.execute(
1177 cmd=command,
1178 prompt="mininet>",
1179 timeout=10 )
1180 if re.search( "doesnt exist!", response ):
1181 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001182 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001183 elif re.search( "Error", response ):
1184 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001185 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001186 elif re.search( "usage:", response ):
1187 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001188 return main.FALSE
1189 else:
1190 return main.TRUE
1191 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001192 main.log.error( self.name + ": EOF exception found" )
1193 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001194 main.cleanup()
1195 main.exit()
1196
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001198 """
1199 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001200 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001201 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001202 required params:
1203 node1 = the string node name of the first endpoint of the link
1204 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001205 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001206 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001207 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001208 response = self.execute(
1209 cmd=command,
1210 prompt="mininet>",
1211 timeout=10 )
1212 if re.search( "no node named", response ):
1213 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001214 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001215 elif re.search( "Error", response ):
1216 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001217 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001218 elif re.search( "usage:", response ):
1219 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001220 return main.FALSE
1221 else:
1222 return main.TRUE
1223 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001226 main.cleanup()
1227 main.exit()
1228
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001230 """
Jon Hallb1290e82014-11-18 16:17:48 -05001231 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001232 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001233 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001234 NOTE: cannot currently specify what type of host
1235 required params:
1236 hostname = the string hostname
1237 optional key-value params
1238 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001239 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001240 """
1241 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001242 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001243 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001244 response = self.execute(
1245 cmd=command,
1246 prompt="mininet>",
1247 timeout=10 )
1248 if re.search( "already exists!", response ):
1249 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001250 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001251 elif re.search( "doesnt exists!", response ):
1252 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001253 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001254 elif re.search( "Error", response ):
1255 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001256 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001257 elif re.search( "usage:", response ):
1258 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001259 return main.FALSE
1260 else:
1261 return main.TRUE
1262 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001263 main.log.error( self.name + ": EOF exception found" )
1264 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001265 main.cleanup()
1266 main.exit()
1267
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001269 """
1270 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001271 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001272 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001273 NOTE: this uses a custom mn function
1274 required params:
1275 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001276 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001277 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001278 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001279 response = self.execute(
1280 cmd=command,
1281 prompt="mininet>",
1282 timeout=10 )
1283 if re.search( "no host named", response ):
1284 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001285 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001286 elif re.search( "Error", response ):
1287 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001288 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001289 elif re.search( "usage:", response ):
1290 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001291 return main.FALSE
1292 else:
1293 return main.TRUE
1294 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001295 main.log.error( self.name + ": EOF exception found" )
1296 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001297 main.cleanup()
1298 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001299
Jon Hall7eb38402015-01-08 17:19:54 -08001300 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001301 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001302 Called at the end of the test to stop the mininet and
1303 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001304 """
1305 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001306 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001307 timeout=2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001308 if i == 0:
1309 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001310 elif i == 1:
1311 return main.TRUE
1312 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001313 # print "Disconnecting Mininet"
1314 if self.handle:
1315 self.handle.sendline( "exit" )
1316 self.handle.expect( "exit" )
1317 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001318 else:
1319 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001320 return response
1321
Hari Krishnab35c6d02015-03-18 11:13:51 -07001322 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001323 """
Jon Hall21270ac2015-02-16 17:59:55 -08001324 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001325 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001326 main.FALSE if the pexpect handle does not exist.
1327
Jon Halld61331b2015-02-17 16:35:47 -08001328 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001329 """
Jon Hall21270ac2015-02-16 17:59:55 -08001330
Jon Halld61331b2015-02-17 16:35:47 -08001331 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001332 response = ''
1333 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001334 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001335 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001336 i = self.handle.expect( [ 'mininet>',
1337 '\$',
1338 pexpect.EOF,
1339 pexpect.TIMEOUT ],
1340 timeout )
1341 if i == 0:
1342 main.log.info( "Exiting mininet..." )
1343
Jon Hall7eb38402015-01-08 17:19:54 -08001344 response = self.execute(
1345 cmd="exit",
1346 prompt="(.*)",
1347 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001348 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001349 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001350 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001351
kelvin-onlab56a3f462015-02-06 14:04:43 -08001352 if i == 1:
1353 main.log.info( " Mininet trying to exit while not " +
1354 "in the mininet prompt" )
1355 elif i == 2:
1356 main.log.error( "Something went wrong exiting mininet" )
1357 elif i == 3: # timeout
1358 main.log.error( "Something went wrong exiting mininet " +
1359 "TIMEOUT" )
1360
Hari Krishnab35c6d02015-03-18 11:13:51 -07001361 if fileName:
1362 self.handle.sendline("")
1363 self.handle.expect('\$')
1364 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001365 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.error( self.name + ": EOF exception found" )
1367 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001368 main.cleanup()
1369 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001370 else:
1371 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001372 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001373 return response
1374
Jon Hall7eb38402015-01-08 17:19:54 -08001375 def arping( self, src, dest, destmac ):
1376 self.handle.sendline( '' )
1377 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001378
Jon Hall7eb38402015-01-08 17:19:54 -08001379 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001380 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1382 main.log.info( self.name + ": ARP successful" )
1383 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001384 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001385 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 main.log.warn( self.name + ": ARP FAILURE" )
1387 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001388 return main.FALSE
1389
Jon Hall7eb38402015-01-08 17:19:54 -08001390 def decToHex( self, num ):
1391 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001392
Jon Hall7eb38402015-01-08 17:19:54 -08001393 def getSwitchFlowCount( self, switch ):
1394 """
1395 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001396 if self.handle:
1397 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1398 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001399 response = self.execute(
1400 cmd=cmd,
1401 prompt="mininet>",
1402 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001403 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001404 main.log.error( self.name + ": EOF exception found" )
1405 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001406 main.cleanup()
1407 main.exit()
1408 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001409 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001410 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001411 main.log.info(
1412 "Couldn't find flows on switch %s, found: %s" %
1413 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001414 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001415 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001416 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001417 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001418
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 def checkFlows( self, sw, dumpFormat=None ):
1420 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001422 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001423 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001425 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 response = self.execute(
1427 cmd=command,
1428 prompt="mininet>",
1429 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001430 return response
1431 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001432 main.log.error( self.name + ": EOF exception found" )
1433 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001434 main.cleanup()
1435 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001436
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001438 """
Jon Hallefbd9792015-03-05 16:11:36 -08001439 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001440 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001441 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001442 self.handle.sendline( "" )
1443 self.handle.expect( "mininet>" )
1444 self.handle.sendline(
1445 "sh sudo tcpdump -n -i " +
1446 intf +
1447 " " +
1448 port +
1449 " -w " +
1450 filename.strip() +
1451 " &" )
1452 self.handle.sendline( "" )
1453 i = self.handle.expect( [ 'No\ssuch\device',
1454 'listening\son',
1455 pexpect.TIMEOUT,
1456 "mininet>" ],
1457 timeout=10 )
1458 main.log.warn( self.handle.before + self.handle.after )
1459 self.handle.sendline( "" )
1460 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001461 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001462 main.log.error(
1463 self.name +
1464 ": tcpdump - No such device exists. " +
1465 "tcpdump attempted on: " +
1466 intf )
admin2a9548d2014-06-17 14:08:07 -07001467 return main.FALSE
1468 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001469 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001470 return main.TRUE
1471 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001472 main.log.error(
1473 self.name +
1474 ": tcpdump command timed out! Check interface name," +
1475 " given interface was: " +
1476 intf )
admin2a9548d2014-06-17 14:08:07 -07001477 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001478 elif i == 3:
1479 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001480 return main.TRUE
1481 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001482 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001483 return main.FALSE
1484 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001485 main.log.error( self.name + ": EOF exception found" )
1486 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001487 main.cleanup()
1488 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001489 except Exception:
1490 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001491 main.cleanup()
1492 main.exit()
1493
kelvin-onlabd3b64892015-01-20 13:26:24 -08001494 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001495 """
1496 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001497 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001498 self.handle.sendline( "sh sudo pkill tcpdump" )
1499 self.handle.expect( "mininet>" )
1500 self.handle.sendline( "" )
1501 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001502 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001503 main.log.error( self.name + ": EOF exception found" )
1504 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001505 main.cleanup()
1506 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001507 except Exception:
1508 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001509 main.cleanup()
1510 main.exit()
1511
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001513 """
1514 Compare mn and onos switches
1515 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001517
Jon Hall7eb38402015-01-08 17:19:54 -08001518 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001520 output = { "switches": [] }
1521 # iterate through the MN topology and pull out switches and and port
1522 # info
1523 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001524 ports = []
1525 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001526 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001527 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001528 'name': port.name } )
1529 output[ 'switches' ].append( {
1530 "name": switch.name,
1531 "dpid": str( switch.dpid ).zfill( 16 ),
1532 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001533
Jon Hall7eb38402015-01-08 17:19:54 -08001534 # print "mn"
1535 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001536 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001537 # indent=4,
1538 # separators=( ',', ': ' ) )
1539 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001541 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001542 # indent=4,
1543 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001544
1545 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001546 mnDPIDs = []
1547 for switch in output[ 'switches' ]:
1548 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001549 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001550 # print "List of Mininet switch DPID's"
1551 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001553 main.log.error(
1554 self.name +
1555 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001556 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001558 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001559 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001560 if switch[ 'available' ]:
1561 onosDPIDs.append(
1562 switch[ 'id' ].replace(
1563 ":",
1564 '' ).replace(
1565 "of",
1566 '' ).lower() )
1567 # else:
1568 # print "Switch is unavailable:"
1569 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001570 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001571 # print "List of ONOS switch DPID's"
1572 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001573
Jon Hall7eb38402015-01-08 17:19:54 -08001574 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001575 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001576 main.log.report( "Switches in MN but not in ONOS:" )
1577 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1578 main.log.report( str( list1 ) )
1579 main.log.report( "Switches in ONOS but not in MN:" )
1580 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001581 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001582 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 switchResults = main.TRUE
1584 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001585
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001587 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001588 Compare mn and onos ports
1589 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001591
Jon Hallfbc828e2015-01-06 17:30:19 -08001592 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001593 1. This uses the sts TestONTopology object
1594 2. numpy - "sudo pip install numpy"
1595
Jon Hall7eb38402015-01-08 17:19:54 -08001596 """
1597 # FIXME: this does not look for extra ports in ONOS, only checks that
1598 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001599 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001601 output = { "switches": [] }
1602 # iterate through the MN topology and pull out switches and and port
1603 # info
1604 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001605 ports = []
1606 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001607 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001608 tmpPort = { 'of_port': port.port_no,
1609 'mac': str( port.hw_addr ).replace( '\'', '' ),
1610 'name': port.name,
1611 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001612
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001614 tmpSwitch = { 'name': switch.name,
1615 'dpid': str( switch.dpid ).zfill( 16 ),
1616 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001617
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001619
Jon Hall7eb38402015-01-08 17:19:54 -08001620 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 for mnSwitch in output[ 'switches' ]:
1622 mnPorts = []
1623 onosPorts = []
1624 switchResult = main.TRUE
1625 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001626 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 mnPorts.append( port[ 'of_port' ] )
1628 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001629 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 # print onosSwitch
1631 if onosSwitch[ 'device' ][ 'available' ]:
1632 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001633 ':',
1634 '' ).replace(
1635 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 '' ) == mnSwitch[ 'dpid' ]:
1637 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001638 if port[ 'isEnabled' ]:
1639 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 # onosPorts.append( 'local' )
1641 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001642 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001644 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 mnPorts.sort( key=float )
1646 onosPorts.sort( key=float )
1647 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1648 # print "\tmn_ports[] = ", mnPorts
1649 # print "\tonos_ports[] = ", onosPorts
1650 mnPortsLog = mnPorts
1651 onosPortsLog = onosPorts
1652 mnPorts = [ x for x in mnPorts ]
1653 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001654
Jon Hall7eb38402015-01-08 17:19:54 -08001655 # TODO: handle other reserved port numbers besides LOCAL
1656 # NOTE: Reserved ports
1657 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1658 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 for mnPort in mnPortsLog:
1660 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001661 # don't set results to true here as this is just one of
1662 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 mnPorts.remove( mnPort )
1664 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001665 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001666 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001667 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 if 65534 in mnPorts:
1669 mnPorts.remove( 65534 )
1670 if long( uint64( -2 ) ) in onosPorts:
1671 onosPorts.remove( long( uint64( -2 ) ) )
1672 if len( mnPorts ): # the ports of this switch don't match
1673 switchResult = main.FALSE
1674 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1675 if len( onosPorts ): # the ports of this switch don't match
1676 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001677 main.log.warn(
1678 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 str( onosPorts ) )
1680 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001681 main.log.report(
1682 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1684 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1685 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1686 portsResults = portsResults and switchResult
1687 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001688
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001690 """
1691 Compare mn and onos links
1692 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001693 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001694
Jon Hall7eb38402015-01-08 17:19:54 -08001695 This uses the sts TestONTopology object"""
1696 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001697 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001698 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001699 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001700 # iterate through the MN topology and pull out switches and and port
1701 # info
1702 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001703 # print "Iterating though switches as seen by Mininet"
1704 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001705 ports = []
1706 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001707 # print port.hw_addr.toStr( separator='' )
1708 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001709 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001710 'name': port.name } )
1711 output[ 'switches' ].append( {
1712 "name": switch.name,
1713 "dpid": str( switch.dpid ).zfill( 16 ),
1714 "ports": ports } )
1715 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001716
kelvin-onlabd3b64892015-01-20 13:26:24 -08001717 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001718 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001719 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001720 if 2 * len( mnLinks ) == len( onos ):
1721 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001722 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001724 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001725 "Mininet has " + str( len( mnLinks ) ) +
1726 " bidirectional links and ONOS has " +
1727 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001728
Jon Hall7eb38402015-01-08 17:19:54 -08001729 # iterate through MN links and check if an ONOS link exists in
1730 # both directions
1731 # NOTE: Will currently only show mn links as down if they are
1732 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001734 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001735 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001736 # print "Link: %s" % link
1737 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001738 node1 = None
1739 port1 = None
1740 node2 = None
1741 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 firstDir = main.FALSE
1743 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001744 for switch in output[ 'switches' ]:
1745 # print "Switch: %s" % switch[ 'name' ]
1746 if switch[ 'name' ] == link.node1.name:
1747 node1 = switch[ 'dpid' ]
1748 for port in switch[ 'ports' ]:
1749 if str( port[ 'name' ] ) == str( link.port1 ):
1750 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001751 if node1 is not None and node2 is not None:
1752 break
Jon Hall7eb38402015-01-08 17:19:54 -08001753 if switch[ 'name' ] == link.node2.name:
1754 node2 = switch[ 'dpid' ]
1755 for port in switch[ 'ports' ]:
1756 if str( port[ 'name' ] ) == str( link.port2 ):
1757 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001758 if node1 is not None and node2 is not None:
1759 break
1760
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 for onosLink in onos:
1762 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001763 ":",
1764 '' ).replace(
1765 "of",
1766 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001768 ":",
1769 '' ).replace(
1770 "of",
1771 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 onosPort1 = onosLink[ 'src' ][ 'port' ]
1773 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001774
Jon Hall72cf1dc2014-10-20 21:04:50 -04001775 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 if str( onosNode1 ) == str( node1 ) and str(
1777 onosNode2 ) == str( node2 ):
1778 if int( onosPort1 ) == int( port1 ) and int(
1779 onosPort2 ) == int( port2 ):
1780 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001781 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001782 main.log.warn(
1783 'The port numbers do not match for ' +
1784 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001785 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001786 'link %s/%s -> %s/%s' %
1787 ( node1,
1788 port1,
1789 node2,
1790 port2 ) +
1791 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 ( onosNode1,
1793 onosPort1,
1794 onosNode2,
1795 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001796
1797 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001798 elif ( str( onosNode1 ) == str( node2 ) and
1799 str( onosNode2 ) == str( node1 ) ):
1800 if ( int( onosPort1 ) == int( port2 )
1801 and int( onosPort2 ) == int( port1 ) ):
1802 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001803 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001804 main.log.warn(
1805 'The port numbers do not match for ' +
1806 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001807 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001808 'link %s/%s -> %s/%s' %
1809 ( node2,
1810 port2,
1811 node1,
1812 port1 ) +
1813 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 ( onosNode2,
1815 onosPort2,
1816 onosNode1,
1817 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001818 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001819 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001820 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001821 main.log.report(
1822 'ONOS does not have the link %s/%s -> %s/%s' %
1823 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001825 main.log.report(
1826 'ONOS does not have the link %s/%s -> %s/%s' %
1827 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001828 linkResults = linkResults and firstDir and secondDir
1829 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001830
Jon Hallff6b4b22015-02-23 09:25:15 -08001831 def compareHosts( self, topo, hostsJson ):
1832 """
1833 Compare mn and onos Hosts.
1834 Since Mininet hosts are quiet, ONOS will only know of them when they
1835 speak. For this reason, we will only check that the hosts in ONOS
1836 stores are in Mininet, and not vice versa.
1837 topo: sts TestONTopology object
1838 hostsJson: parsed json object from the onos hosts api
1839
1840 This uses the sts TestONTopology object"""
1841 import json
1842 hostResults = main.TRUE
1843 hosts = []
1844 # iterate through the MN topology and pull out hosts
1845 for mnHost in topo.graph.hosts:
1846 interfaces = []
1847 for intf in mnHost.interfaces:
1848 interfaces.append( {
1849 "name": intf.name, # str
1850 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1851 # hw_addr is of type EthAddr, Not JSON serializable
1852 "hw_addr": str( intf.hw_addr ) } )
1853 hosts.append( {
1854 "name": mnHost.name, # str
1855 "interfaces": interfaces } ) # list
1856 for onosHost in hostsJson:
1857 onosMAC = onosHost[ 'mac' ].lower()
1858 match = False
1859 for mnHost in hosts:
1860 for mnIntf in mnHost[ 'interfaces' ]:
1861 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1862 match = True
1863 for ip in mnIntf[ 'ips' ]:
1864 if ip in onosHost[ 'ips' ]:
1865 pass # all is well
1866 else:
1867 # misssing ip
1868 main.log.error( "ONOS host " + onosHost[ 'id' ]
1869 + " has a different IP than " +
1870 "the Mininet host." )
1871 output = json.dumps(
1872 onosHost,
1873 sort_keys=True,
1874 indent=4,
1875 separators=( ',', ': ' ) )
1876 main.log.info( output )
1877 hostResults = main.FALSE
1878 if not match:
1879 hostResults = main.FALSE
1880 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1881 "corresponding Mininet host." )
1882 output = json.dumps( onosHost,
1883 sort_keys=True,
1884 indent=4,
1885 separators=( ',', ': ' ) )
1886 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001887 return hostResults
1888
kelvin-onlabd3b64892015-01-20 13:26:24 -08001889 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001890 """
1891 Returns a list of all hosts
1892 Don't ask questions just use it"""
1893 self.handle.sendline( "" )
1894 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001895
Jon Hall7eb38402015-01-08 17:19:54 -08001896 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1897 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001898
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 handlePy = self.handle.before
1900 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1901 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001902
Jon Hall7eb38402015-01-08 17:19:54 -08001903 self.handle.sendline( "" )
1904 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001905
kelvin-onlabd3b64892015-01-20 13:26:24 -08001906 hostStr = handlePy.replace( "]", "" )
1907 hostStr = hostStr.replace( "'", "" )
1908 hostStr = hostStr.replace( "[", "" )
1909 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001910
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 return hostList
adminbae64d82013-08-01 10:50:15 -07001912
Jon Hall7eb38402015-01-08 17:19:54 -08001913 def update( self ):
1914 """
1915 updates the port address and status information for
1916 each port in mn"""
1917 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001918 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001919 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001920 self.handle.sendline( "" )
1921 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001922
Jon Hall7eb38402015-01-08 17:19:54 -08001923 self.handle.sendline( "update" )
1924 self.handle.expect( "update" )
1925 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001926
Jon Hall7eb38402015-01-08 17:19:54 -08001927 self.handle.sendline( "" )
1928 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001929
Jon Hallb1290e82014-11-18 16:17:48 -05001930 return main.TRUE
1931 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001932 main.log.error( self.name + ": EOF exception found" )
1933 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001934 main.cleanup()
1935 main.exit()
1936
adminbae64d82013-08-01 10:50:15 -07001937if __name__ != "__main__":
1938 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07001939 sys.modules[ __name__ ] = MininetCliDriver()