blob: 628257d1d7c1dac2881a661bdfb60e62ed17d53a [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-onlabb9408212015-04-01 13:34:04 -0700251 def pingall( self, timeout=300, shortCircuit = False ):
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
256 Returns:
257 main.TRUE if pingall completes with no pings dropped
258 otherwise main.FALSE"""
259 if self.handle:
260 main.log.info(
261 self.name +
262 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700263 try:
kelvin-onlabb9408212015-04-01 13:34:04 -0700264 if not shortCircuit:
265 response = self.execute(
266 cmd="pingall",
267 prompt="mininet>",
268 timeout=int( timeout ) )
269 else:
270 self.handle.sendline( "pingall" )
271 i = self.handle.expect( [ "mininet>","X X X",
272 pexpect.EOF,
273 pexpect.TIMEOUT ],
274 timeout )
275 if i == 0:
276 main.log.info("mininet> prompt found!")
277 response = str(self.handle.before)
278 if i == 1:
279 main.log.info( self.name + ": Cannot ping some of the Host")
280 main.log.info(str(self.handle.before))
281 response = str(self.handle.before)
282 if i == 2:
283 main.log.error( self.name + ": EOF exception found" )
284 main.log.error( self.name + ": " + self.handle.before )
285 main.cleanup()
286 main.exit()
287 if i == 3:
288 main.log.error( self.name + ": TIMEOUT exception found" )
289 main.log.error( self.name +
290 ": " +
291 str( self.handle.before ) )
292
Jon Hallb1290e82014-11-18 16:17:48 -0500293 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800294 main.log.error( self.name + ": EOF exception found" )
295 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500296 main.cleanup()
297 main.exit()
298 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800299 # We may not want to kill the test if pexpect times out
300 main.log.error( self.name + ": TIMEOUT exception found" )
301 main.log.error( self.name +
302 ": " +
303 str( self.handle.before ) )
304 # NOTE: mininet's pingall rounds, so we will check the number of
305 # passed and number of failed
306 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800307 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800308 if re.search( pattern, response ):
309 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700310 return main.TRUE
311 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800312 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800313 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800314 # NOTE: Send ctrl-c to make sure pingall is done
315 self.handle.send( "\x03" )
316 self.handle.expect( "Interrupt" )
317 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700318 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800319 else:
320 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500321 main.cleanup()
322 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700323
Jon Hall7eb38402015-01-08 17:19:54 -0800324 def fpingHost( self, **pingParams ):
325 """
326 Uses the fping package for faster pinging...
327 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800328 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800329 command = args[ "SRC" ] + \
330 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
331 self.handle.sendline( command )
332 self.handle.expect(
333 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
334 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
335 response = self.handle.before
336 if re.search( ":\s-", response ):
337 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700338 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800339 elif re.search( ":\s\d{1,2}\.\d\d", response ):
340 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700341 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800342 main.log.info( self.name + ": Install fping on mininet machine... " )
343 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700344 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800345
Jon Hall7eb38402015-01-08 17:19:54 -0800346 def pingHost( self, **pingParams ):
347 """
348 Ping from one mininet host to another
349 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800350 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800351 command = args[ "SRC" ] + " ping " + \
352 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700353 try:
Jon Hall61282e32015-03-19 11:34:11 -0700354 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800355 self.handle.sendline( command )
356 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700357 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800358 main.log.error(
359 self.name +
360 ": timeout when waiting for response from mininet" )
361 main.log.error( "response: " + str( self.handle.before ) )
362 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700363 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800364 main.log.error(
365 self.name +
366 ": timeout when waiting for response from mininet" )
367 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700368 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800369 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800370 main.log.error( self.name + ": EOF exception found" )
371 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700372 main.cleanup()
373 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800374 main.log.info( self.name + ": Ping Response: " + response )
375 if re.search( ',\s0\%\spacket\sloss', response ):
376 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700378 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800379 else:
380 main.log.error(
381 self.name +
382 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800383 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700384 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800385
Jon Hall7eb38402015-01-08 17:19:54 -0800386 def checkIP( self, host ):
387 """
388 Verifies the host's ip configured or not."""
389 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700390 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800391 response = self.execute(
392 cmd=host +
393 " ifconfig",
394 prompt="mininet>",
395 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800396 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800397 main.log.error( self.name + ": EOF exception found" )
398 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700399 main.cleanup()
400 main.exit()
adminbae64d82013-08-01 10:50:15 -0700401
Jon Hall7eb38402015-01-08 17:19:54 -0800402 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800403 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
404 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
405 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
406 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
407 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800408 # pattern = "inet addr:10.0.0.6"
409 if re.search( pattern, response ):
410 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700411 return main.TRUE
412 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800413 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700414 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800415 else:
416 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800417
Jon Hall7eb38402015-01-08 17:19:54 -0800418 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800419 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700420 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800421 response = self.execute(
422 cmd="h1 /usr/sbin/sshd -D&",
423 prompt="mininet>",
424 timeout=10 )
425 response = self.execute(
426 cmd="h4 /usr/sbin/sshd -D&",
427 prompt="mininet>",
428 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700429 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800430 vars( self )[ key ] = connectargs[ key ]
431 response = self.execute(
432 cmd="xterm h1 h4 ",
433 prompt="mininet>",
434 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800435 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800436 main.log.error( self.name + ": EOF exception found" )
437 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700438 main.cleanup()
439 main.exit()
adminbae64d82013-08-01 10:50:15 -0700440 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800441 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700442 if self.flag == 0:
443 self.flag = 1
444 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800445 else:
adminbae64d82013-08-01 10:50:15 -0700446 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800447
kelvin-onlaba1484582015-02-02 15:46:20 -0800448 def moveHost( self, host, oldSw, newSw, ):
449 """
450 Moves a host from one switch to another on the fly
451 Note: The intf between host and oldSw when detached
452 using detach(), will still show up in the 'net'
453 cmd, because switch.detach() doesn't affect switch.intfs[]
454 (which is correct behavior since the interfaces
455 haven't moved).
456 """
457 if self.handle:
458 try:
459 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800460 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
461 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800462 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800463 response = self.execute( cmd=cmd,
464 prompt="mininet>",
465 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800466
467 # Determine hostintf and Oldswitchintf
468 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800469 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800470 print "cmd2= ", cmd
471 self.handle.sendline( cmd )
472 self.handle.expect( "mininet>" )
473
shahshreya73537862015-02-11 15:15:24 -0800474 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800475 cmd = "px ipaddr = hintf.IP()"
476 print "cmd3= ", cmd
477 self.handle.sendline( cmd )
478 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800479
480 cmd = "px macaddr = hintf.MAC()"
481 print "cmd3= ", cmd
482 self.handle.sendline( cmd )
483 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800484
485 # Detach interface between oldSw-host
486 cmd = "px " + oldSw + ".detach( sintf )"
487 print "cmd4= ", cmd
488 self.handle.sendline( cmd )
489 self.handle.expect( "mininet>" )
490
491 # Add link between host-newSw
492 cmd = "py net.addLink(" + host + "," + newSw + ")"
493 print "cmd5= ", cmd
494 self.handle.sendline( cmd )
495 self.handle.expect( "mininet>" )
496
497 # Determine hostintf and Newswitchintf
498 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800499 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800500 print "cmd6= ", cmd
501 self.handle.sendline( cmd )
502 self.handle.expect( "mininet>" )
503
504 # Attach interface between newSw-host
505 cmd = "px " + newSw + ".attach( sintf )"
506 print "cmd3= ", cmd
507 self.handle.sendline( cmd )
508 self.handle.expect( "mininet>" )
509
510 # Set ipaddress of the host-newSw interface
511 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
512 print "cmd7 = ", cmd
513 self.handle.sendline( cmd )
514 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800515
516 # Set macaddress of the host-newSw interface
517 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
518 print "cmd8 = ", cmd
519 self.handle.sendline( cmd )
520 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800521
522 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800523 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800524 self.handle.sendline( cmd )
525 self.handle.expect( "mininet>" )
526 print "output = ", self.handle.before
527
528 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800529 cmd = host + " ifconfig"
530 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800531 self.handle.sendline( cmd )
532 self.handle.expect( "mininet>" )
533 print "ifconfig o/p = ", self.handle.before
534
535 return main.TRUE
536 except pexpect.EOF:
537 main.log.error( self.name + ": EOF exception found" )
538 main.log.error( self.name + ": " + self.handle.before )
539 return main.FALSE
540
Jon Hall7eb38402015-01-08 17:19:54 -0800541 def changeIP( self, host, intf, newIP, newNetmask ):
542 """
543 Changes the ip address of a host on the fly
544 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800545 if self.handle:
546 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800547 cmd = host + " ifconfig " + intf + " " + \
548 newIP + " " + 'netmask' + " " + newNetmask
549 self.handle.sendline( cmd )
550 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800551 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800552 main.log.info( "response = " + response )
553 main.log.info(
554 "Ip of host " +
555 host +
556 " changed to new IP " +
557 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800558 return main.TRUE
559 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800562 return main.FALSE
563
Jon Hall7eb38402015-01-08 17:19:54 -0800564 def changeDefaultGateway( self, host, newGW ):
565 """
566 Changes the default gateway of a host
567 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800568 if self.handle:
569 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800570 cmd = host + " route add default gw " + newGW
571 self.handle.sendline( cmd )
572 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800573 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800574 main.log.info( "response = " + response )
575 main.log.info(
576 "Default gateway of host " +
577 host +
578 " changed to " +
579 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800580 return main.TRUE
581 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800582 main.log.error( self.name + ": EOF exception found" )
583 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800584 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800585
Jon Hall7eb38402015-01-08 17:19:54 -0800586 def addStaticMACAddress( self, host, GW, macaddr ):
587 """
Jon Hallefbd9792015-03-05 16:11:36 -0800588 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800589 if self.handle:
590 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800591 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
592 cmd = host + " arp -s " + GW + " " + macaddr
593 self.handle.sendline( cmd )
594 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800595 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800596 main.log.info( "response = " + response )
597 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800598 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800599 GW +
600 " changed to " +
601 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800602 return main.TRUE
603 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800604 main.log.error( self.name + ": EOF exception found" )
605 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800606 return main.FALSE
607
Jon Hall7eb38402015-01-08 17:19:54 -0800608 def verifyStaticGWandMAC( self, host ):
609 """
610 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800611 if self.handle:
612 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800613 # h1 arp -an
614 cmd = host + " arp -an "
615 self.handle.sendline( cmd )
616 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800617 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800618 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800619 return main.TRUE
620 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800621 main.log.error( self.name + ": EOF exception found" )
622 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800623 return main.FALSE
624
Jon Hall7eb38402015-01-08 17:19:54 -0800625 def getMacAddress( self, host ):
626 """
627 Verifies the host's ip configured or not."""
628 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700629 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800630 response = self.execute(
631 cmd=host +
632 " ifconfig",
633 prompt="mininet>",
634 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800635 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800636 main.log.error( self.name + ": EOF exception found" )
637 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700638 main.cleanup()
639 main.exit()
adminbae64d82013-08-01 10:50:15 -0700640
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700641 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800642 macAddressSearch = re.search( pattern, response, re.I )
643 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800644 main.log.info(
645 self.name +
646 ": Mac-Address of Host " +
647 host +
648 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 macAddress )
650 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700651 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800652 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700653
Jon Hall7eb38402015-01-08 17:19:54 -0800654 def getInterfaceMACAddress( self, host, interface ):
655 """
656 Return the IP address of the interface on the given host"""
657 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700658 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800659 response = self.execute( cmd=host + " ifconfig " + interface,
660 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800661 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800662 main.log.error( self.name + ": EOF exception found" )
663 main.log.error( self.name + ": " + self.handle.before )
664 main.cleanup()
665 main.exit()
666
667 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 macAddressSearch = re.search( pattern, response, re.I )
669 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800670 main.log.info( "No mac address found in %s" % response )
671 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800673 main.log.info(
674 "Mac-Address of " +
675 host +
676 ":" +
677 interface +
678 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 macAddress )
680 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800681 else:
682 main.log.error( "Connection failed to the host" )
683
684 def getIPAddress( self, host ):
685 """
686 Verifies the host's ip configured or not."""
687 if self.handle:
688 try:
689 response = self.execute(
690 cmd=host +
691 " ifconfig",
692 prompt="mininet>",
693 timeout=10 )
694 except pexpect.EOF:
695 main.log.error( self.name + ": EOF exception found" )
696 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700697 main.cleanup()
698 main.exit()
adminbae64d82013-08-01 10:50:15 -0700699
700 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800701 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800702 main.log.info(
703 self.name +
704 ": IP-Address of Host " +
705 host +
706 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 ipAddressSearch.group( 1 ) )
708 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800709 else:
710 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800711
Jon Hall7eb38402015-01-08 17:19:54 -0800712 def getSwitchDPID( self, switch ):
713 """
714 return the datapath ID of the switch"""
715 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700716 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700717 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800718 response = self.execute(
719 cmd=cmd,
720 prompt="mininet>",
721 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800722 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700725 main.cleanup()
726 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800727 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800728 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700729 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800730 main.log.info(
731 "Couldn't find DPID for switch %s, found: %s" %
732 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700733 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800734 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700735 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800736 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700737
Jon Hall7eb38402015-01-08 17:19:54 -0800738 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700739 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 self.handle.sendline( "" )
741 self.expect( "mininet>" )
742 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700743 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800744 response = self.execute(
745 cmd=cmd,
746 prompt="mininet>",
747 timeout=10 )
748 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700749 response = self.handle.before
750 return response
751 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800752 main.log.error( self.name + ": EOF exception found" )
753 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700754 main.cleanup()
755 main.exit()
756
Jon Hall7eb38402015-01-08 17:19:54 -0800757 def getInterfaces( self, node ):
758 """
759 return information dict about interfaces connected to the node"""
760 if self.handle:
761 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800762 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700763 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700764 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800765 response = self.execute(
766 cmd=cmd,
767 prompt="mininet>",
768 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800769 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800770 main.log.error( self.name + ": EOF exception found" )
771 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700772 main.cleanup()
773 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700774 return response
775 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800776 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700777
Jon Hall7eb38402015-01-08 17:19:54 -0800778 def dump( self ):
779 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700780 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800781 response = self.execute(
782 cmd='dump',
783 prompt='mininet>',
784 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800785 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800786 main.log.error( self.name + ": EOF exception found" )
787 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700788 main.cleanup()
789 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700790 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800791
Jon Hall7eb38402015-01-08 17:19:54 -0800792 def intfs( self ):
793 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700794 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800795 response = self.execute(
796 cmd='intfs',
797 prompt='mininet>',
798 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800799 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 main.log.error( self.name + ": EOF exception found" )
801 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700802 main.cleanup()
803 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700804 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800805
Jon Hall7eb38402015-01-08 17:19:54 -0800806 def net( self ):
807 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700808 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800809 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800810 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800811 main.log.error( self.name + ": EOF exception found" )
812 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700813 main.cleanup()
814 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700815 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800816
817 def iperf( self, host1, host2 ):
818 main.log.info(
819 self.name +
820 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700821 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800822 cmd1 = 'iperf ' + host1 + " " + host2
823 self.handle.sendline( cmd1 )
824 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800825 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800826 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800827 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800828 return main.TRUE
829 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800830 main.log.error( self.name + ": iperf test failed" )
831 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800832 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 main.log.error( self.name + ": EOF exception found" )
834 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800835 main.cleanup()
836 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800837
Jon Hall7eb38402015-01-08 17:19:54 -0800838 def iperfudp( self ):
839 main.log.info(
840 self.name +
841 ": Simple iperf TCP test between two " +
842 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700843 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800844 response = self.execute(
845 cmd='iperfudp',
846 prompt='mininet>',
847 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800848 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700851 main.cleanup()
852 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700853 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800854
Jon Hall7eb38402015-01-08 17:19:54 -0800855 def nodes( self ):
856 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700857 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800858 response = self.execute(
859 cmd='nodes',
860 prompt='mininet>',
861 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800862 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800863 main.log.error( self.name + ": EOF exception found" )
864 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700865 main.cleanup()
866 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700867 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800868
Jon Hall7eb38402015-01-08 17:19:54 -0800869 def pingpair( self ):
870 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700871 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800872 response = self.execute(
873 cmd='pingpair',
874 prompt='mininet>',
875 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800876 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800877 main.log.error( self.name + ": EOF exception found" )
878 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700879 main.cleanup()
880 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800881
Jon Hall7eb38402015-01-08 17:19:54 -0800882 if re.search( ',\s0\%\spacket\sloss', response ):
883 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800884 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700885 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800886 else:
887 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700889 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800890
Jon Hall7eb38402015-01-08 17:19:54 -0800891 def link( self, **linkargs ):
892 """
893 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800894 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800895 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
896 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
897 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
898 main.log.info(
899 "Bring link between '" +
900 end1 +
901 "' and '" +
902 end2 +
903 "' '" +
904 option +
905 "'" )
906 command = "link " + \
907 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700908 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800909 self.handle.sendline( command )
910 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800911 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800912 main.log.error( self.name + ": EOF exception found" )
913 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700914 main.cleanup()
915 main.exit()
adminbae64d82013-08-01 10:50:15 -0700916 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800917
Jon Hall7eb38402015-01-08 17:19:54 -0800918 def yank( self, **yankargs ):
919 """
920 yank a mininet switch interface to a host"""
921 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800922 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800923 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
924 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
925 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700926 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800927 response = self.execute(
928 cmd=command,
929 prompt="mininet>",
930 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800931 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800932 main.log.error( self.name + ": EOF exception found" )
933 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700934 main.cleanup()
935 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700936 return main.TRUE
937
Jon Hall7eb38402015-01-08 17:19:54 -0800938 def plug( self, **plugargs ):
939 """
940 plug the yanked mininet switch interface to a switch"""
941 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800942 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800943 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
944 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
945 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700946 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800947 response = self.execute(
948 cmd=command,
949 prompt="mininet>",
950 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800951 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800952 main.log.error( self.name + ": EOF exception found" )
953 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700954 main.cleanup()
955 main.exit()
adminbae64d82013-08-01 10:50:15 -0700956 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800957
Jon Hall7eb38402015-01-08 17:19:54 -0800958 def dpctl( self, **dpctlargs ):
959 """
960 Run dpctl command on all switches."""
961 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800962 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800963 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
964 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
965 command = "dpctl " + cmd + " " + str( cmdargs )
966 try:
967 response = self.execute(
968 cmd=command,
969 prompt="mininet>",
970 timeout=10 )
971 except pexpect.EOF:
972 main.log.error( self.name + ": EOF exception found" )
973 main.log.error( self.name + ": " + self.handle.before )
974 main.cleanup()
975 main.exit()
976 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800977
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -0800979 #FIXME: What uses this? This should be refactored to get
980 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800981 fileInput = path + '/lib/Mininet/INSTALL'
982 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700983 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800985 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700986 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800987 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500988 return version
adminbae64d82013-08-01 10:50:15 -0700989
kelvin-onlabd3b64892015-01-20 13:26:24 -0800990 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800991 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500992 Parameters:
993 sw: The name of an OVS switch. Example "s1"
994 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800995 The output of the command from the mininet cli
996 or main.FALSE on timeout"""
997 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700998 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800999 response = self.execute(
1000 cmd=command,
1001 prompt="mininet>",
1002 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001003 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001004 return response
admin2a9548d2014-06-17 14:08:07 -07001005 else:
1006 return main.FALSE
1007 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001010 main.cleanup()
1011 main.exit()
adminbae64d82013-08-01 10:50:15 -07001012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001014 """
1015 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001016 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001017 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001018
1019 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001020 for j in range( count ):
1021 argstring = argstring + ",IP" + \
1022 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001023 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001024
Jon Hall7eb38402015-01-08 17:19:54 -08001025 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1026 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001027 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001028 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001029
Jon Hall7eb38402015-01-08 17:19:54 -08001030 command = "sh ovs-vsctl set-controller s" + \
1031 str( sw ) + " " + ptcpB + " "
1032 for j in range( count ):
1033 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001034 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001035 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1036 ip = args[
1037 "IP" +
1038 str( i ) ] if args[
1039 "IP" +
1040 str( i ) ] is not None else ""
1041 port = args[
1042 "PORT" +
1043 str( i ) ] if args[
1044 "PORT" +
1045 str( i ) ] is not None else ""
1046 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001047 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001048 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001049 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001050 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001051 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001052 main.log.error( self.name + ": EOF exception found" )
1053 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001054 main.cleanup()
1055 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001056 except Exception:
1057 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001058 main.cleanup()
1059 main.exit()
adminbae64d82013-08-01 10:50:15 -07001060
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001062 """
1063 Removes the controller target from sw"""
1064 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001065 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001066 response = self.execute(
1067 cmd=command,
1068 prompt="mininet>",
1069 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001070 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 Hall0819fd92014-05-23 12:08:13 -07001073 main.cleanup()
1074 main.exit()
1075 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001076 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001079 """
Jon Hallb1290e82014-11-18 16:17:48 -05001080 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001081 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001082 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001083 NOTE: cannot currently specify what type of switch
1084 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001085 sw = name of the new switch as a string
1086 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001087 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001088 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001089 """
1090 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001091 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001092 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001093 response = self.execute(
1094 cmd=command,
1095 prompt="mininet>",
1096 timeout=10 )
1097 if re.search( "already exists!", response ):
1098 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001099 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001100 elif re.search( "Error", response ):
1101 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001102 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001103 elif re.search( "usage:", response ):
1104 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001105 return main.FALSE
1106 else:
1107 return main.TRUE
1108 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001109 main.log.error( self.name + ": EOF exception found" )
1110 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001111 main.cleanup()
1112 main.exit()
1113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001115 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001116 delete a switch from the mininet topology
1117 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001118 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001119 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001120 sw = name of the switch as a string
1121 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001122 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001123 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001124 response = self.execute(
1125 cmd=command,
1126 prompt="mininet>",
1127 timeout=10 )
1128 if re.search( "no switch named", response ):
1129 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001130 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001131 elif re.search( "Error", response ):
1132 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001133 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001134 elif re.search( "usage:", response ):
1135 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001136 return main.FALSE
1137 else:
1138 return main.TRUE
1139 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001140 main.log.error( self.name + ": EOF exception found" )
1141 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001142 main.cleanup()
1143 main.exit()
1144
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001146 """
1147 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001148 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001149 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001150 NOTE: cannot currently specify what type of link
1151 required params:
1152 node1 = the string node name of the first endpoint of the link
1153 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001154 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001155 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001156 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001157 response = self.execute(
1158 cmd=command,
1159 prompt="mininet>",
1160 timeout=10 )
1161 if re.search( "doesnt exist!", response ):
1162 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001163 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001164 elif re.search( "Error", response ):
1165 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001166 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001167 elif re.search( "usage:", response ):
1168 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001169 return main.FALSE
1170 else:
1171 return main.TRUE
1172 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001173 main.log.error( self.name + ": EOF exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001175 main.cleanup()
1176 main.exit()
1177
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001179 """
1180 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001181 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001182 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001183 required params:
1184 node1 = the string node name of the first endpoint of the link
1185 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001186 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001187 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001188 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001189 response = self.execute(
1190 cmd=command,
1191 prompt="mininet>",
1192 timeout=10 )
1193 if re.search( "no node named", response ):
1194 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001195 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001196 elif re.search( "Error", response ):
1197 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001198 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001199 elif re.search( "usage:", response ):
1200 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001201 return main.FALSE
1202 else:
1203 return main.TRUE
1204 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001205 main.log.error( self.name + ": EOF exception found" )
1206 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001207 main.cleanup()
1208 main.exit()
1209
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001211 """
Jon Hallb1290e82014-11-18 16:17:48 -05001212 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001213 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001214 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001215 NOTE: cannot currently specify what type of host
1216 required params:
1217 hostname = the string hostname
1218 optional key-value params
1219 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001220 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001221 """
1222 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001223 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001224 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001225 response = self.execute(
1226 cmd=command,
1227 prompt="mininet>",
1228 timeout=10 )
1229 if re.search( "already exists!", response ):
1230 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001231 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001232 elif re.search( "doesnt exists!", response ):
1233 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001234 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001235 elif re.search( "Error", response ):
1236 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001237 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001238 elif re.search( "usage:", response ):
1239 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001240 return main.FALSE
1241 else:
1242 return main.TRUE
1243 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001244 main.log.error( self.name + ": EOF exception found" )
1245 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001246 main.cleanup()
1247 main.exit()
1248
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001250 """
1251 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001252 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001253 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001254 NOTE: this uses a custom mn function
1255 required params:
1256 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001257 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001258 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001259 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001260 response = self.execute(
1261 cmd=command,
1262 prompt="mininet>",
1263 timeout=10 )
1264 if re.search( "no host named", response ):
1265 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001266 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001267 elif re.search( "Error", response ):
1268 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001269 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001270 elif re.search( "usage:", response ):
1271 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001272 return main.FALSE
1273 else:
1274 return main.TRUE
1275 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001276 main.log.error( self.name + ": EOF exception found" )
1277 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001278 main.cleanup()
1279 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001280
Jon Hall7eb38402015-01-08 17:19:54 -08001281 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001282 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001283 Called at the end of the test to stop the mininet and
1284 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001285 """
1286 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001287 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001288 timeout=2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001289 if i == 0:
1290 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001291 elif i == 1:
1292 return main.TRUE
1293 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001294 # print "Disconnecting Mininet"
1295 if self.handle:
1296 self.handle.sendline( "exit" )
1297 self.handle.expect( "exit" )
1298 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001299 else:
1300 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001301 return response
1302
Hari Krishnab35c6d02015-03-18 11:13:51 -07001303 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001304 """
Jon Hall21270ac2015-02-16 17:59:55 -08001305 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001306 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001307 main.FALSE if the pexpect handle does not exist.
1308
Jon Halld61331b2015-02-17 16:35:47 -08001309 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001310 """
Jon Hall21270ac2015-02-16 17:59:55 -08001311
Jon Halld61331b2015-02-17 16:35:47 -08001312 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001313 response = ''
1314 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001315 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001316 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001317 i = self.handle.expect( [ 'mininet>',
1318 '\$',
1319 pexpect.EOF,
1320 pexpect.TIMEOUT ],
1321 timeout )
1322 if i == 0:
1323 main.log.info( "Exiting mininet..." )
1324
Jon Hall7eb38402015-01-08 17:19:54 -08001325 response = self.execute(
1326 cmd="exit",
1327 prompt="(.*)",
1328 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001329 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001330 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001331 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001332
kelvin-onlab56a3f462015-02-06 14:04:43 -08001333 if i == 1:
1334 main.log.info( " Mininet trying to exit while not " +
1335 "in the mininet prompt" )
1336 elif i == 2:
1337 main.log.error( "Something went wrong exiting mininet" )
1338 elif i == 3: # timeout
1339 main.log.error( "Something went wrong exiting mininet " +
1340 "TIMEOUT" )
1341
Hari Krishnab35c6d02015-03-18 11:13:51 -07001342 if fileName:
1343 self.handle.sendline("")
1344 self.handle.expect('\$')
1345 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001346 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001347 main.log.error( self.name + ": EOF exception found" )
1348 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001349 main.cleanup()
1350 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001351 else:
1352 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001353 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001354 return response
1355
Jon Hall7eb38402015-01-08 17:19:54 -08001356 def arping( self, src, dest, destmac ):
1357 self.handle.sendline( '' )
1358 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001359
Jon Hall7eb38402015-01-08 17:19:54 -08001360 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001361 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001362 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1363 main.log.info( self.name + ": ARP successful" )
1364 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001365 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001366 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001367 main.log.warn( self.name + ": ARP FAILURE" )
1368 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001369 return main.FALSE
1370
Jon Hall7eb38402015-01-08 17:19:54 -08001371 def decToHex( self, num ):
1372 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001373
Jon Hall7eb38402015-01-08 17:19:54 -08001374 def getSwitchFlowCount( self, switch ):
1375 """
1376 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001377 if self.handle:
1378 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1379 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001380 response = self.execute(
1381 cmd=cmd,
1382 prompt="mininet>",
1383 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001384 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001385 main.log.error( self.name + ": EOF exception found" )
1386 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001387 main.cleanup()
1388 main.exit()
1389 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001390 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001391 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001392 main.log.info(
1393 "Couldn't find flows on switch %s, found: %s" %
1394 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001395 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001396 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001397 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001398 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001399
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 def checkFlows( self, sw, dumpFormat=None ):
1401 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001402 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001404 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001405 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001406 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001407 response = self.execute(
1408 cmd=command,
1409 prompt="mininet>",
1410 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001411 return response
1412 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001413 main.log.error( self.name + ": EOF exception found" )
1414 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001415 main.cleanup()
1416 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001417
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001419 """
Jon Hallefbd9792015-03-05 16:11:36 -08001420 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001421 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001422 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001423 self.handle.sendline( "" )
1424 self.handle.expect( "mininet>" )
1425 self.handle.sendline(
1426 "sh sudo tcpdump -n -i " +
1427 intf +
1428 " " +
1429 port +
1430 " -w " +
1431 filename.strip() +
1432 " &" )
1433 self.handle.sendline( "" )
1434 i = self.handle.expect( [ 'No\ssuch\device',
1435 'listening\son',
1436 pexpect.TIMEOUT,
1437 "mininet>" ],
1438 timeout=10 )
1439 main.log.warn( self.handle.before + self.handle.after )
1440 self.handle.sendline( "" )
1441 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001442 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001443 main.log.error(
1444 self.name +
1445 ": tcpdump - No such device exists. " +
1446 "tcpdump attempted on: " +
1447 intf )
admin2a9548d2014-06-17 14:08:07 -07001448 return main.FALSE
1449 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001450 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001451 return main.TRUE
1452 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001453 main.log.error(
1454 self.name +
1455 ": tcpdump command timed out! Check interface name," +
1456 " given interface was: " +
1457 intf )
admin2a9548d2014-06-17 14:08:07 -07001458 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001459 elif i == 3:
1460 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001461 return main.TRUE
1462 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001463 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001464 return main.FALSE
1465 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001466 main.log.error( self.name + ": EOF exception found" )
1467 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001468 main.cleanup()
1469 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001470 except Exception:
1471 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001472 main.cleanup()
1473 main.exit()
1474
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001476 """
1477 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001478 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001479 self.handle.sendline( "sh sudo pkill tcpdump" )
1480 self.handle.expect( "mininet>" )
1481 self.handle.sendline( "" )
1482 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001483 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001484 main.log.error( self.name + ": EOF exception found" )
1485 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001486 main.cleanup()
1487 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001488 except Exception:
1489 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001490 main.cleanup()
1491 main.exit()
1492
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001494 """
1495 Compare mn and onos switches
1496 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001498
Jon Hall7eb38402015-01-08 17:19:54 -08001499 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001501 output = { "switches": [] }
1502 # iterate through the MN topology and pull out switches and and port
1503 # info
1504 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001505 ports = []
1506 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001507 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001508 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001509 'name': port.name } )
1510 output[ 'switches' ].append( {
1511 "name": switch.name,
1512 "dpid": str( switch.dpid ).zfill( 16 ),
1513 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001514
Jon Hall7eb38402015-01-08 17:19:54 -08001515 # print "mn"
1516 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001517 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001518 # indent=4,
1519 # separators=( ',', ': ' ) )
1520 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001522 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001523 # indent=4,
1524 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001525
1526 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001527 mnDPIDs = []
1528 for switch in output[ 'switches' ]:
1529 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001530 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001531 # print "List of Mininet switch DPID's"
1532 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001534 main.log.error(
1535 self.name +
1536 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001537 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001539 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001540 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001541 if switch[ 'available' ]:
1542 onosDPIDs.append(
1543 switch[ 'id' ].replace(
1544 ":",
1545 '' ).replace(
1546 "of",
1547 '' ).lower() )
1548 # else:
1549 # print "Switch is unavailable:"
1550 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001551 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001552 # print "List of ONOS switch DPID's"
1553 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001554
Jon Hall7eb38402015-01-08 17:19:54 -08001555 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001557 main.log.report( "Switches in MN but not in ONOS:" )
1558 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1559 main.log.report( str( list1 ) )
1560 main.log.report( "Switches in ONOS but not in MN:" )
1561 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001562 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001563 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 switchResults = main.TRUE
1565 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001566
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001568 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001569 Compare mn and onos ports
1570 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001572
Jon Hallfbc828e2015-01-06 17:30:19 -08001573 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001574 1. This uses the sts TestONTopology object
1575 2. numpy - "sudo pip install numpy"
1576
Jon Hall7eb38402015-01-08 17:19:54 -08001577 """
1578 # FIXME: this does not look for extra ports in ONOS, only checks that
1579 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001580 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001581 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001582 output = { "switches": [] }
1583 # iterate through the MN topology and pull out switches and and port
1584 # info
1585 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001586 ports = []
1587 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001588 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001589 tmpPort = { 'of_port': port.port_no,
1590 'mac': str( port.hw_addr ).replace( '\'', '' ),
1591 'name': port.name,
1592 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001593
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001595 tmpSwitch = { 'name': switch.name,
1596 'dpid': str( switch.dpid ).zfill( 16 ),
1597 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001598
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001600
Jon Hall7eb38402015-01-08 17:19:54 -08001601 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 for mnSwitch in output[ 'switches' ]:
1603 mnPorts = []
1604 onosPorts = []
1605 switchResult = main.TRUE
1606 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001607 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 mnPorts.append( port[ 'of_port' ] )
1609 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001610 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 # print onosSwitch
1612 if onosSwitch[ 'device' ][ 'available' ]:
1613 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001614 ':',
1615 '' ).replace(
1616 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 '' ) == mnSwitch[ 'dpid' ]:
1618 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001619 if port[ 'isEnabled' ]:
1620 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 # onosPorts.append( 'local' )
1622 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001623 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001624 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001625 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 mnPorts.sort( key=float )
1627 onosPorts.sort( key=float )
1628 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1629 # print "\tmn_ports[] = ", mnPorts
1630 # print "\tonos_ports[] = ", onosPorts
1631 mnPortsLog = mnPorts
1632 onosPortsLog = onosPorts
1633 mnPorts = [ x for x in mnPorts ]
1634 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001635
Jon Hall7eb38402015-01-08 17:19:54 -08001636 # TODO: handle other reserved port numbers besides LOCAL
1637 # NOTE: Reserved ports
1638 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1639 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 for mnPort in mnPortsLog:
1641 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001642 # don't set results to true here as this is just one of
1643 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 mnPorts.remove( mnPort )
1645 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001646 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001647 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001648 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 if 65534 in mnPorts:
1650 mnPorts.remove( 65534 )
1651 if long( uint64( -2 ) ) in onosPorts:
1652 onosPorts.remove( long( uint64( -2 ) ) )
1653 if len( mnPorts ): # the ports of this switch don't match
1654 switchResult = main.FALSE
1655 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1656 if len( onosPorts ): # the ports of this switch don't match
1657 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001658 main.log.warn(
1659 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 str( onosPorts ) )
1661 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001662 main.log.report(
1663 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1665 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1666 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1667 portsResults = portsResults and switchResult
1668 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001669
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001671 """
1672 Compare mn and onos links
1673 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001675
Jon Hall7eb38402015-01-08 17:19:54 -08001676 This uses the sts TestONTopology object"""
1677 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001678 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001679 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001681 # iterate through the MN topology and pull out switches and and port
1682 # info
1683 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001684 # print "Iterating though switches as seen by Mininet"
1685 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001686 ports = []
1687 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001688 # print port.hw_addr.toStr( separator='' )
1689 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001690 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001691 'name': port.name } )
1692 output[ 'switches' ].append( {
1693 "name": switch.name,
1694 "dpid": str( switch.dpid ).zfill( 16 ),
1695 "ports": ports } )
1696 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001697
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001699 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001700 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001701 if 2 * len( mnLinks ) == len( onos ):
1702 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001703 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001704 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001705 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001706 "Mininet has " + str( len( mnLinks ) ) +
1707 " bidirectional links and ONOS has " +
1708 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001709
Jon Hall7eb38402015-01-08 17:19:54 -08001710 # iterate through MN links and check if an ONOS link exists in
1711 # both directions
1712 # NOTE: Will currently only show mn links as down if they are
1713 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001714 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001715 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001717 # print "Link: %s" % link
1718 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001719 node1 = None
1720 port1 = None
1721 node2 = None
1722 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 firstDir = main.FALSE
1724 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001725 for switch in output[ 'switches' ]:
1726 # print "Switch: %s" % switch[ 'name' ]
1727 if switch[ 'name' ] == link.node1.name:
1728 node1 = switch[ 'dpid' ]
1729 for port in switch[ 'ports' ]:
1730 if str( port[ 'name' ] ) == str( link.port1 ):
1731 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001732 if node1 is not None and node2 is not None:
1733 break
Jon Hall7eb38402015-01-08 17:19:54 -08001734 if switch[ 'name' ] == link.node2.name:
1735 node2 = switch[ 'dpid' ]
1736 for port in switch[ 'ports' ]:
1737 if str( port[ 'name' ] ) == str( link.port2 ):
1738 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001739 if node1 is not None and node2 is not None:
1740 break
1741
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 for onosLink in onos:
1743 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001744 ":",
1745 '' ).replace(
1746 "of",
1747 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001749 ":",
1750 '' ).replace(
1751 "of",
1752 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001753 onosPort1 = onosLink[ 'src' ][ 'port' ]
1754 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001755
Jon Hall72cf1dc2014-10-20 21:04:50 -04001756 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001757 if str( onosNode1 ) == str( node1 ) and str(
1758 onosNode2 ) == str( node2 ):
1759 if int( onosPort1 ) == int( port1 ) and int(
1760 onosPort2 ) == int( port2 ):
1761 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001762 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001763 main.log.warn(
1764 'The port numbers do not match for ' +
1765 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001766 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001767 'link %s/%s -> %s/%s' %
1768 ( node1,
1769 port1,
1770 node2,
1771 port2 ) +
1772 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001773 ( onosNode1,
1774 onosPort1,
1775 onosNode2,
1776 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001777
1778 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 elif ( str( onosNode1 ) == str( node2 ) and
1780 str( onosNode2 ) == str( node1 ) ):
1781 if ( int( onosPort1 ) == int( port2 )
1782 and int( onosPort2 ) == int( port1 ) ):
1783 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001784 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001785 main.log.warn(
1786 'The port numbers do not match for ' +
1787 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001788 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001789 'link %s/%s -> %s/%s' %
1790 ( node2,
1791 port2,
1792 node1,
1793 port1 ) +
1794 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 ( onosNode2,
1796 onosPort2,
1797 onosNode1,
1798 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001799 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001800 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001802 main.log.report(
1803 'ONOS does not have the link %s/%s -> %s/%s' %
1804 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001806 main.log.report(
1807 'ONOS does not have the link %s/%s -> %s/%s' %
1808 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001809 linkResults = linkResults and firstDir and secondDir
1810 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001811
Jon Hallff6b4b22015-02-23 09:25:15 -08001812 def compareHosts( self, topo, hostsJson ):
1813 """
1814 Compare mn and onos Hosts.
1815 Since Mininet hosts are quiet, ONOS will only know of them when they
1816 speak. For this reason, we will only check that the hosts in ONOS
1817 stores are in Mininet, and not vice versa.
1818 topo: sts TestONTopology object
1819 hostsJson: parsed json object from the onos hosts api
1820
1821 This uses the sts TestONTopology object"""
1822 import json
1823 hostResults = main.TRUE
1824 hosts = []
1825 # iterate through the MN topology and pull out hosts
1826 for mnHost in topo.graph.hosts:
1827 interfaces = []
1828 for intf in mnHost.interfaces:
1829 interfaces.append( {
1830 "name": intf.name, # str
1831 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1832 # hw_addr is of type EthAddr, Not JSON serializable
1833 "hw_addr": str( intf.hw_addr ) } )
1834 hosts.append( {
1835 "name": mnHost.name, # str
1836 "interfaces": interfaces } ) # list
1837 for onosHost in hostsJson:
1838 onosMAC = onosHost[ 'mac' ].lower()
1839 match = False
1840 for mnHost in hosts:
1841 for mnIntf in mnHost[ 'interfaces' ]:
1842 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1843 match = True
1844 for ip in mnIntf[ 'ips' ]:
1845 if ip in onosHost[ 'ips' ]:
1846 pass # all is well
1847 else:
1848 # misssing ip
1849 main.log.error( "ONOS host " + onosHost[ 'id' ]
1850 + " has a different IP than " +
1851 "the Mininet host." )
1852 output = json.dumps(
1853 onosHost,
1854 sort_keys=True,
1855 indent=4,
1856 separators=( ',', ': ' ) )
1857 main.log.info( output )
1858 hostResults = main.FALSE
1859 if not match:
1860 hostResults = main.FALSE
1861 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1862 "corresponding Mininet host." )
1863 output = json.dumps( onosHost,
1864 sort_keys=True,
1865 indent=4,
1866 separators=( ',', ': ' ) )
1867 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001868 return hostResults
1869
kelvin-onlabd3b64892015-01-20 13:26:24 -08001870 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001871 """
1872 Returns a list of all hosts
1873 Don't ask questions just use it"""
1874 self.handle.sendline( "" )
1875 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001876
Jon Hall7eb38402015-01-08 17:19:54 -08001877 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1878 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001879
kelvin-onlabd3b64892015-01-20 13:26:24 -08001880 handlePy = self.handle.before
1881 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1882 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001883
Jon Hall7eb38402015-01-08 17:19:54 -08001884 self.handle.sendline( "" )
1885 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001886
kelvin-onlabd3b64892015-01-20 13:26:24 -08001887 hostStr = handlePy.replace( "]", "" )
1888 hostStr = hostStr.replace( "'", "" )
1889 hostStr = hostStr.replace( "[", "" )
1890 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001891
kelvin-onlabd3b64892015-01-20 13:26:24 -08001892 return hostList
adminbae64d82013-08-01 10:50:15 -07001893
Jon Hall7eb38402015-01-08 17:19:54 -08001894 def update( self ):
1895 """
1896 updates the port address and status information for
1897 each port in mn"""
1898 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001899 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001900 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001901 self.handle.sendline( "" )
1902 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001903
Jon Hall7eb38402015-01-08 17:19:54 -08001904 self.handle.sendline( "update" )
1905 self.handle.expect( "update" )
1906 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001907
Jon Hall7eb38402015-01-08 17:19:54 -08001908 self.handle.sendline( "" )
1909 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001910
Jon Hallb1290e82014-11-18 16:17:48 -05001911 return main.TRUE
1912 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001913 main.log.error( self.name + ": EOF exception found" )
1914 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001915 main.cleanup()
1916 main.exit()
1917
adminbae64d82013-08-01 10:50:15 -07001918if __name__ != "__main__":
1919 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07001920 sys.modules[ __name__ ] = MininetCliDriver()