blob: 29265bf1135a82b5c6da89c86e70d14224d400ca [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
46class MininetCliDriver( Emulator ):
47
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(
68 MininetCliDriver,
69 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
Jon Hall7eb38402015-01-08 17:19:54 -0800251 def pingall( self, timeout=300 ):
252 """
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:
Jon Hall7eb38402015-01-08 17:19:54 -0800264 response = self.execute(
265 cmd="pingall",
266 prompt="mininet>",
267 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500268 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800269 main.log.error( self.name + ": EOF exception found" )
270 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500271 main.cleanup()
272 main.exit()
273 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800274 # We may not want to kill the test if pexpect times out
275 main.log.error( self.name + ": TIMEOUT exception found" )
276 main.log.error( self.name +
277 ": " +
278 str( self.handle.before ) )
279 # NOTE: mininet's pingall rounds, so we will check the number of
280 # passed and number of failed
281 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800283 if re.search( pattern, response ):
284 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700285 return main.TRUE
286 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800287 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800289 # NOTE: Send ctrl-c to make sure pingall is done
290 self.handle.send( "\x03" )
291 self.handle.expect( "Interrupt" )
292 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700293 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800294 else:
295 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500296 main.cleanup()
297 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700298
Jon Hall7eb38402015-01-08 17:19:54 -0800299 def fpingHost( self, **pingParams ):
300 """
301 Uses the fping package for faster pinging...
302 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800303 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800304 command = args[ "SRC" ] + \
305 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
306 self.handle.sendline( command )
307 self.handle.expect(
308 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
309 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
310 response = self.handle.before
311 if re.search( ":\s-", response ):
312 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700313 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800314 elif re.search( ":\s\d{1,2}\.\d\d", response ):
315 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700316 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800317 main.log.info( self.name + ": Install fping on mininet machine... " )
318 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700319 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800320
Jon Hall7eb38402015-01-08 17:19:54 -0800321 def pingHost( self, **pingParams ):
322 """
323 Ping from one mininet host to another
324 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800325 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800326 command = args[ "SRC" ] + " ping " + \
327 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700328 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800329 main.log.warn( "Sending: " + command )
330 self.handle.sendline( command )
331 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700332 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800333 main.log.error(
334 self.name +
335 ": timeout when waiting for response from mininet" )
336 main.log.error( "response: " + str( self.handle.before ) )
337 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700338 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800339 main.log.error(
340 self.name +
341 ": timeout when waiting for response from mininet" )
342 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700343 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800344 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800345 main.log.error( self.name + ": EOF exception found" )
346 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700347 main.cleanup()
348 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800349 main.log.info( self.name + ": Ping Response: " + response )
350 if re.search( ',\s0\%\spacket\sloss', response ):
351 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800352 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700353 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800354 else:
355 main.log.error(
356 self.name +
357 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700359 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800360
Jon Hall7eb38402015-01-08 17:19:54 -0800361 def checkIP( self, host ):
362 """
363 Verifies the host's ip configured or not."""
364 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700365 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800366 response = self.execute(
367 cmd=host +
368 " ifconfig",
369 prompt="mininet>",
370 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800371 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800372 main.log.error( self.name + ": EOF exception found" )
373 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700374 main.cleanup()
375 main.exit()
adminbae64d82013-08-01 10:50:15 -0700376
Jon Hall7eb38402015-01-08 17:19:54 -0800377 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800378 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
379 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
380 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
381 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
382 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800383 # pattern = "inet addr:10.0.0.6"
384 if re.search( pattern, response ):
385 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700386 return main.TRUE
387 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800388 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700389 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800390 else:
391 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800392
Jon Hall7eb38402015-01-08 17:19:54 -0800393 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800394 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700395 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800396 response = self.execute(
397 cmd="h1 /usr/sbin/sshd -D&",
398 prompt="mininet>",
399 timeout=10 )
400 response = self.execute(
401 cmd="h4 /usr/sbin/sshd -D&",
402 prompt="mininet>",
403 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700404 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800405 vars( self )[ key ] = connectargs[ key ]
406 response = self.execute(
407 cmd="xterm h1 h4 ",
408 prompt="mininet>",
409 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800410 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800411 main.log.error( self.name + ": EOF exception found" )
412 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700413 main.cleanup()
414 main.exit()
adminbae64d82013-08-01 10:50:15 -0700415 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800416 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700417 if self.flag == 0:
418 self.flag = 1
419 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800420 else:
adminbae64d82013-08-01 10:50:15 -0700421 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800422
kelvin-onlaba1484582015-02-02 15:46:20 -0800423 def moveHost( self, host, oldSw, newSw, ):
424 """
425 Moves a host from one switch to another on the fly
426 Note: The intf between host and oldSw when detached
427 using detach(), will still show up in the 'net'
428 cmd, because switch.detach() doesn't affect switch.intfs[]
429 (which is correct behavior since the interfaces
430 haven't moved).
431 """
432 if self.handle:
433 try:
434 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800435 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
436 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800437 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800438 response = self.execute( cmd=cmd,
439 prompt="mininet>",
440 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800441
442 # Determine hostintf and Oldswitchintf
443 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800444 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800445 print "cmd2= ", cmd
446 self.handle.sendline( cmd )
447 self.handle.expect( "mininet>" )
448
shahshreya73537862015-02-11 15:15:24 -0800449 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800450 cmd = "px ipaddr = hintf.IP()"
451 print "cmd3= ", cmd
452 self.handle.sendline( cmd )
453 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800454
455 cmd = "px macaddr = hintf.MAC()"
456 print "cmd3= ", cmd
457 self.handle.sendline( cmd )
458 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800459
460 # Detach interface between oldSw-host
461 cmd = "px " + oldSw + ".detach( sintf )"
462 print "cmd4= ", cmd
463 self.handle.sendline( cmd )
464 self.handle.expect( "mininet>" )
465
466 # Add link between host-newSw
467 cmd = "py net.addLink(" + host + "," + newSw + ")"
468 print "cmd5= ", cmd
469 self.handle.sendline( cmd )
470 self.handle.expect( "mininet>" )
471
472 # Determine hostintf and Newswitchintf
473 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800474 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800475 print "cmd6= ", cmd
476 self.handle.sendline( cmd )
477 self.handle.expect( "mininet>" )
478
479 # Attach interface between newSw-host
480 cmd = "px " + newSw + ".attach( sintf )"
481 print "cmd3= ", cmd
482 self.handle.sendline( cmd )
483 self.handle.expect( "mininet>" )
484
485 # Set ipaddress of the host-newSw interface
486 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
487 print "cmd7 = ", cmd
488 self.handle.sendline( cmd )
489 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800490
491 # Set macaddress of the host-newSw interface
492 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
493 print "cmd8 = ", cmd
494 self.handle.sendline( cmd )
495 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800496
497 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800498 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800499 self.handle.sendline( cmd )
500 self.handle.expect( "mininet>" )
501 print "output = ", self.handle.before
502
503 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800504 cmd = host + " ifconfig"
505 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800506 self.handle.sendline( cmd )
507 self.handle.expect( "mininet>" )
508 print "ifconfig o/p = ", self.handle.before
509
510 return main.TRUE
511 except pexpect.EOF:
512 main.log.error( self.name + ": EOF exception found" )
513 main.log.error( self.name + ": " + self.handle.before )
514 return main.FALSE
515
Jon Hall7eb38402015-01-08 17:19:54 -0800516 def changeIP( self, host, intf, newIP, newNetmask ):
517 """
518 Changes the ip address of a host on the fly
519 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800520 if self.handle:
521 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800522 cmd = host + " ifconfig " + intf + " " + \
523 newIP + " " + 'netmask' + " " + newNetmask
524 self.handle.sendline( cmd )
525 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800526 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800527 main.log.info( "response = " + response )
528 main.log.info(
529 "Ip of host " +
530 host +
531 " changed to new IP " +
532 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800533 return main.TRUE
534 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800535 main.log.error( self.name + ": EOF exception found" )
536 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800537 return main.FALSE
538
Jon Hall7eb38402015-01-08 17:19:54 -0800539 def changeDefaultGateway( self, host, newGW ):
540 """
541 Changes the default gateway of a host
542 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800543 if self.handle:
544 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800545 cmd = host + " route add default gw " + newGW
546 self.handle.sendline( cmd )
547 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800548 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800549 main.log.info( "response = " + response )
550 main.log.info(
551 "Default gateway of host " +
552 host +
553 " changed to " +
554 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800555 return main.TRUE
556 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800557 main.log.error( self.name + ": EOF exception found" )
558 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800559 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800560
Jon Hall7eb38402015-01-08 17:19:54 -0800561 def addStaticMACAddress( self, host, GW, macaddr ):
562 """
Jon Hallefbd9792015-03-05 16:11:36 -0800563 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800564 if self.handle:
565 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800566 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
567 cmd = host + " arp -s " + GW + " " + macaddr
568 self.handle.sendline( cmd )
569 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800570 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800571 main.log.info( "response = " + response )
572 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800573 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800574 GW +
575 " changed to " +
576 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800577 return main.TRUE
578 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800579 main.log.error( self.name + ": EOF exception found" )
580 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800581 return main.FALSE
582
Jon Hall7eb38402015-01-08 17:19:54 -0800583 def verifyStaticGWandMAC( self, host ):
584 """
585 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800586 if self.handle:
587 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800588 # h1 arp -an
589 cmd = host + " arp -an "
590 self.handle.sendline( cmd )
591 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800592 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800593 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800594 return main.TRUE
595 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800596 main.log.error( self.name + ": EOF exception found" )
597 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800598 return main.FALSE
599
Jon Hall7eb38402015-01-08 17:19:54 -0800600 def getMacAddress( self, host ):
601 """
602 Verifies the host's ip configured or not."""
603 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700604 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800605 response = self.execute(
606 cmd=host +
607 " ifconfig",
608 prompt="mininet>",
609 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800610 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700613 main.cleanup()
614 main.exit()
adminbae64d82013-08-01 10:50:15 -0700615
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700616 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 macAddressSearch = re.search( pattern, response, re.I )
618 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800619 main.log.info(
620 self.name +
621 ": Mac-Address of Host " +
622 host +
623 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 macAddress )
625 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700626 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800627 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700628
Jon Hall7eb38402015-01-08 17:19:54 -0800629 def getInterfaceMACAddress( self, host, interface ):
630 """
631 Return the IP address of the interface on the given host"""
632 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700633 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800634 response = self.execute( cmd=host + " ifconfig " + interface,
635 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800636 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800637 main.log.error( self.name + ": EOF exception found" )
638 main.log.error( self.name + ": " + self.handle.before )
639 main.cleanup()
640 main.exit()
641
642 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 macAddressSearch = re.search( pattern, response, re.I )
644 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800645 main.log.info( "No mac address found in %s" % response )
646 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800647 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800648 main.log.info(
649 "Mac-Address of " +
650 host +
651 ":" +
652 interface +
653 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 macAddress )
655 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800656 else:
657 main.log.error( "Connection failed to the host" )
658
659 def getIPAddress( self, host ):
660 """
661 Verifies the host's ip configured or not."""
662 if self.handle:
663 try:
664 response = self.execute(
665 cmd=host +
666 " ifconfig",
667 prompt="mininet>",
668 timeout=10 )
669 except pexpect.EOF:
670 main.log.error( self.name + ": EOF exception found" )
671 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700672 main.cleanup()
673 main.exit()
adminbae64d82013-08-01 10:50:15 -0700674
675 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800677 main.log.info(
678 self.name +
679 ": IP-Address of Host " +
680 host +
681 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 ipAddressSearch.group( 1 ) )
683 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800684 else:
685 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800686
Jon Hall7eb38402015-01-08 17:19:54 -0800687 def getSwitchDPID( self, switch ):
688 """
689 return the datapath ID of the switch"""
690 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700691 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700692 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800693 response = self.execute(
694 cmd=cmd,
695 prompt="mininet>",
696 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800697 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700700 main.cleanup()
701 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800702 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800703 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700704 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800705 main.log.info(
706 "Couldn't find DPID for switch %s, found: %s" %
707 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700708 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800709 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700710 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700712
Jon Hall7eb38402015-01-08 17:19:54 -0800713 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700714 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800715 self.handle.sendline( "" )
716 self.expect( "mininet>" )
717 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700718 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800719 response = self.execute(
720 cmd=cmd,
721 prompt="mininet>",
722 timeout=10 )
723 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700724 response = self.handle.before
725 return response
726 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700729 main.cleanup()
730 main.exit()
731
Jon Hall7eb38402015-01-08 17:19:54 -0800732 def getInterfaces( self, node ):
733 """
734 return information dict about interfaces connected to the node"""
735 if self.handle:
736 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800737 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700738 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700739 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 response = self.execute(
741 cmd=cmd,
742 prompt="mininet>",
743 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800744 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800745 main.log.error( self.name + ": EOF exception found" )
746 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700747 main.cleanup()
748 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700749 return response
750 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800751 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700752
Jon Hall7eb38402015-01-08 17:19:54 -0800753 def dump( self ):
754 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700755 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800756 response = self.execute(
757 cmd='dump',
758 prompt='mininet>',
759 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800760 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700763 main.cleanup()
764 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700765 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800766
Jon Hall7eb38402015-01-08 17:19:54 -0800767 def intfs( self ):
768 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700769 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800770 response = self.execute(
771 cmd='intfs',
772 prompt='mininet>',
773 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800774 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800775 main.log.error( self.name + ": EOF exception found" )
776 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700777 main.cleanup()
778 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700779 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800780
Jon Hall7eb38402015-01-08 17:19:54 -0800781 def net( self ):
782 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700783 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800784 response = self.execute( cmd='net', prompt='mininet>', 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()
Jon Hall668ed802014-04-08 17:17:59 -0700790 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800791
792 def iperf( self, host1, host2 ):
793 main.log.info(
794 self.name +
795 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700796 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800797 cmd1 = 'iperf ' + host1 + " " + host2
798 self.handle.sendline( cmd1 )
799 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800800 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800801 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800802 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800803 return main.TRUE
804 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 main.log.error( self.name + ": iperf test failed" )
806 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800807 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800808 main.log.error( self.name + ": EOF exception found" )
809 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800810 main.cleanup()
811 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800812
Jon Hall7eb38402015-01-08 17:19:54 -0800813 def iperfudp( self ):
814 main.log.info(
815 self.name +
816 ": Simple iperf TCP test between two " +
817 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700818 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 response = self.execute(
820 cmd='iperfudp',
821 prompt='mininet>',
822 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800823 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800824 main.log.error( self.name + ": EOF exception found" )
825 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700826 main.cleanup()
827 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700828 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800829
Jon Hall7eb38402015-01-08 17:19:54 -0800830 def nodes( self ):
831 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700832 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 response = self.execute(
834 cmd='nodes',
835 prompt='mininet>',
836 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800837 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800838 main.log.error( self.name + ": EOF exception found" )
839 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700840 main.cleanup()
841 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700842 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800843
Jon Hall7eb38402015-01-08 17:19:54 -0800844 def pingpair( self ):
845 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700846 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800847 response = self.execute(
848 cmd='pingpair',
849 prompt='mininet>',
850 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800851 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800852 main.log.error( self.name + ": EOF exception found" )
853 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700854 main.cleanup()
855 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800856
Jon Hall7eb38402015-01-08 17:19:54 -0800857 if re.search( ',\s0\%\spacket\sloss', response ):
858 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700860 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800861 else:
862 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700864 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800865
Jon Hall7eb38402015-01-08 17:19:54 -0800866 def link( self, **linkargs ):
867 """
868 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800869 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800870 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
871 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
872 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
873 main.log.info(
874 "Bring link between '" +
875 end1 +
876 "' and '" +
877 end2 +
878 "' '" +
879 option +
880 "'" )
881 command = "link " + \
882 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700883 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800884 self.handle.sendline( command )
885 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800886 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( self.name + ": EOF exception found" )
888 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700889 main.cleanup()
890 main.exit()
adminbae64d82013-08-01 10:50:15 -0700891 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800892
Jon Hall7eb38402015-01-08 17:19:54 -0800893 def yank( self, **yankargs ):
894 """
895 yank a mininet switch interface to a host"""
896 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800897 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800898 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
899 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
900 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700901 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800902 response = self.execute(
903 cmd=command,
904 prompt="mininet>",
905 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800906 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700909 main.cleanup()
910 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700911 return main.TRUE
912
Jon Hall7eb38402015-01-08 17:19:54 -0800913 def plug( self, **plugargs ):
914 """
915 plug the yanked mininet switch interface to a switch"""
916 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800917 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800918 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
919 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
920 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700921 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800922 response = self.execute(
923 cmd=command,
924 prompt="mininet>",
925 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800926 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800927 main.log.error( self.name + ": EOF exception found" )
928 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700929 main.cleanup()
930 main.exit()
adminbae64d82013-08-01 10:50:15 -0700931 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800932
Jon Hall7eb38402015-01-08 17:19:54 -0800933 def dpctl( self, **dpctlargs ):
934 """
935 Run dpctl command on all switches."""
936 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800937 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800938 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
939 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
940 command = "dpctl " + cmd + " " + str( cmdargs )
941 try:
942 response = self.execute(
943 cmd=command,
944 prompt="mininet>",
945 timeout=10 )
946 except pexpect.EOF:
947 main.log.error( self.name + ": EOF exception found" )
948 main.log.error( self.name + ": " + self.handle.before )
949 main.cleanup()
950 main.exit()
951 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getVersion( self ):
954 fileInput = path + '/lib/Mininet/INSTALL'
955 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700956 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800958 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700959 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800960 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500961 return version
adminbae64d82013-08-01 10:50:15 -0700962
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800964 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500965 Parameters:
966 sw: The name of an OVS switch. Example "s1"
967 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800968 The output of the command from the mininet cli
969 or main.FALSE on timeout"""
970 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700971 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800972 response = self.execute(
973 cmd=command,
974 prompt="mininet>",
975 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700976 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500977 return response
admin2a9548d2014-06-17 14:08:07 -0700978 else:
979 return main.FALSE
980 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800981 main.log.error( self.name + ": EOF exception found" )
982 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700983 main.cleanup()
984 main.exit()
adminbae64d82013-08-01 10:50:15 -0700985
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800987 """
988 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800989 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800990 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700991
992 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800993 for j in range( count ):
994 argstring = argstring + ",IP" + \
995 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800996 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700997
Jon Hall7eb38402015-01-08 17:19:54 -0800998 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
999 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001000 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001001 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001002
Jon Hall7eb38402015-01-08 17:19:54 -08001003 command = "sh ovs-vsctl set-controller s" + \
1004 str( sw ) + " " + ptcpB + " "
1005 for j in range( count ):
1006 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001007 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001008 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1009 ip = args[
1010 "IP" +
1011 str( i ) ] if args[
1012 "IP" +
1013 str( i ) ] is not None else ""
1014 port = args[
1015 "PORT" +
1016 str( i ) ] if args[
1017 "PORT" +
1018 str( i ) ] is not None else ""
1019 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001020 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001021 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001022 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001023 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001024 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001025 main.log.error( self.name + ": EOF exception found" )
1026 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001027 main.cleanup()
1028 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001029 except Exception:
1030 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001031 main.cleanup()
1032 main.exit()
adminbae64d82013-08-01 10:50:15 -07001033
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001035 """
1036 Removes the controller target from sw"""
1037 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001038 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001039 response = self.execute(
1040 cmd=command,
1041 prompt="mininet>",
1042 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001043 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001044 main.log.error( self.name + ": EOF exception found" )
1045 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001046 main.cleanup()
1047 main.exit()
1048 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001049 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001050
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001052 """
Jon Hallb1290e82014-11-18 16:17:48 -05001053 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001054 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001055 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001056 NOTE: cannot currently specify what type of switch
1057 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001058 sw = name of the new switch as a string
1059 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001060 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001061 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001062 """
1063 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001064 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001065 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001066 response = self.execute(
1067 cmd=command,
1068 prompt="mininet>",
1069 timeout=10 )
1070 if re.search( "already exists!", response ):
1071 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001072 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001073 elif re.search( "Error", response ):
1074 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001075 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001076 elif re.search( "usage:", response ):
1077 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001078 return main.FALSE
1079 else:
1080 return main.TRUE
1081 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001082 main.log.error( self.name + ": EOF exception found" )
1083 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001084 main.cleanup()
1085 main.exit()
1086
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001088 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001089 delete a switch from the mininet topology
1090 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001091 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001092 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001093 sw = name of the switch as a string
1094 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001095 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001096 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001097 response = self.execute(
1098 cmd=command,
1099 prompt="mininet>",
1100 timeout=10 )
1101 if re.search( "no switch named", response ):
1102 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001103 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001104 elif re.search( "Error", response ):
1105 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001106 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001107 elif re.search( "usage:", response ):
1108 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001109 return main.FALSE
1110 else:
1111 return main.TRUE
1112 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001115 main.cleanup()
1116 main.exit()
1117
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001119 """
1120 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001121 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001122 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001123 NOTE: cannot currently specify what type of link
1124 required params:
1125 node1 = the string node name of the first endpoint of the link
1126 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001127 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001128 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001129 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001130 response = self.execute(
1131 cmd=command,
1132 prompt="mininet>",
1133 timeout=10 )
1134 if re.search( "doesnt exist!", response ):
1135 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001136 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001137 elif re.search( "Error", response ):
1138 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001139 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001140 elif re.search( "usage:", response ):
1141 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001142 return main.FALSE
1143 else:
1144 return main.TRUE
1145 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001148 main.cleanup()
1149 main.exit()
1150
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001152 """
1153 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001154 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001155 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001156 required params:
1157 node1 = the string node name of the first endpoint of the link
1158 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001159 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001160 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001161 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001162 response = self.execute(
1163 cmd=command,
1164 prompt="mininet>",
1165 timeout=10 )
1166 if re.search( "no node named", response ):
1167 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001168 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001169 elif re.search( "Error", response ):
1170 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001171 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001172 elif re.search( "usage:", response ):
1173 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001174 return main.FALSE
1175 else:
1176 return main.TRUE
1177 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001178 main.log.error( self.name + ": EOF exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001180 main.cleanup()
1181 main.exit()
1182
kelvin-onlabd3b64892015-01-20 13:26:24 -08001183 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001184 """
Jon Hallb1290e82014-11-18 16:17:48 -05001185 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001186 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001187 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001188 NOTE: cannot currently specify what type of host
1189 required params:
1190 hostname = the string hostname
1191 optional key-value params
1192 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001193 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001194 """
1195 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001196 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001197 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001198 response = self.execute(
1199 cmd=command,
1200 prompt="mininet>",
1201 timeout=10 )
1202 if re.search( "already exists!", response ):
1203 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001204 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001205 elif re.search( "doesnt exists!", response ):
1206 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001207 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001208 elif re.search( "Error", response ):
1209 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001210 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001211 elif re.search( "usage:", response ):
1212 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001213 return main.FALSE
1214 else:
1215 return main.TRUE
1216 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001217 main.log.error( self.name + ": EOF exception found" )
1218 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001219 main.cleanup()
1220 main.exit()
1221
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001223 """
1224 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001225 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001226 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001227 NOTE: this uses a custom mn function
1228 required params:
1229 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001230 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001231 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001232 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001233 response = self.execute(
1234 cmd=command,
1235 prompt="mininet>",
1236 timeout=10 )
1237 if re.search( "no host named", response ):
1238 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001239 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001240 elif re.search( "Error", response ):
1241 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001242 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001243 elif re.search( "usage:", response ):
1244 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001245 return main.FALSE
1246 else:
1247 return main.TRUE
1248 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 main.log.error( self.name + ": EOF exception found" )
1250 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001251 main.cleanup()
1252 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001253
Jon Hall7eb38402015-01-08 17:19:54 -08001254 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001255 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001256 Called at the end of the test to stop the mininet and
1257 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001258 """
1259 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001260 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001261 timeout=2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001262 if i == 0:
1263 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001264 elif i == 1:
1265 return main.TRUE
1266 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001267 # print "Disconnecting Mininet"
1268 if self.handle:
1269 self.handle.sendline( "exit" )
1270 self.handle.expect( "exit" )
1271 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001272 else:
1273 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001274 return response
1275
Jon Hallefbd9792015-03-05 16:11:36 -08001276 def stopNet( self, timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001277 """
Jon Hall21270ac2015-02-16 17:59:55 -08001278 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001279 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001280 main.FALSE if the pexpect handle does not exist.
1281
Jon Halld61331b2015-02-17 16:35:47 -08001282 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001283 """
Jon Hall21270ac2015-02-16 17:59:55 -08001284
Jon Halld61331b2015-02-17 16:35:47 -08001285 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001286 response = ''
1287 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001288 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001289 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001290 i = self.handle.expect( [ 'mininet>',
1291 '\$',
1292 pexpect.EOF,
1293 pexpect.TIMEOUT ],
1294 timeout )
1295 if i == 0:
1296 main.log.info( "Exiting mininet..." )
1297
Jon Hall7eb38402015-01-08 17:19:54 -08001298 response = self.execute(
1299 cmd="exit",
1300 prompt="(.*)",
1301 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001302 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001303 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001304 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08001305
1306 if i == 1:
1307 main.log.info( " Mininet trying to exit while not " +
1308 "in the mininet prompt" )
1309 elif i == 2:
1310 main.log.error( "Something went wrong exiting mininet" )
1311 elif i == 3: # timeout
1312 main.log.error( "Something went wrong exiting mininet " +
1313 "TIMEOUT" )
1314
Jon Hallfbc828e2015-01-06 17:30:19 -08001315 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001316 main.log.error( self.name + ": EOF exception found" )
1317 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001318 main.cleanup()
1319 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001320 else:
1321 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001322 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001323 return response
1324
Jon Hall7eb38402015-01-08 17:19:54 -08001325 def arping( self, src, dest, destmac ):
1326 self.handle.sendline( '' )
1327 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001328
Jon Hall7eb38402015-01-08 17:19:54 -08001329 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001330 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001331 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1332 main.log.info( self.name + ": ARP successful" )
1333 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001334 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001335 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001336 main.log.warn( self.name + ": ARP FAILURE" )
1337 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001338 return main.FALSE
1339
Jon Hall7eb38402015-01-08 17:19:54 -08001340 def decToHex( self, num ):
1341 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001342
Jon Hall7eb38402015-01-08 17:19:54 -08001343 def getSwitchFlowCount( self, switch ):
1344 """
1345 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001346 if self.handle:
1347 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1348 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001349 response = self.execute(
1350 cmd=cmd,
1351 prompt="mininet>",
1352 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001353 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001354 main.log.error( self.name + ": EOF exception found" )
1355 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001356 main.cleanup()
1357 main.exit()
1358 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001359 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001360 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001361 main.log.info(
1362 "Couldn't find flows on switch %s, found: %s" %
1363 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001364 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001365 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001366 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001367 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001368
kelvin-onlabd3b64892015-01-20 13:26:24 -08001369 def checkFlows( self, sw, dumpFormat=None ):
1370 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001373 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001374 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001375 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 response = self.execute(
1377 cmd=command,
1378 prompt="mininet>",
1379 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001380 return response
1381 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001382 main.log.error( self.name + ": EOF exception found" )
1383 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001384 main.cleanup()
1385 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001386
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001388 """
Jon Hallefbd9792015-03-05 16:11:36 -08001389 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001390 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001391 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001392 self.handle.sendline( "" )
1393 self.handle.expect( "mininet>" )
1394 self.handle.sendline(
1395 "sh sudo tcpdump -n -i " +
1396 intf +
1397 " " +
1398 port +
1399 " -w " +
1400 filename.strip() +
1401 " &" )
1402 self.handle.sendline( "" )
1403 i = self.handle.expect( [ 'No\ssuch\device',
1404 'listening\son',
1405 pexpect.TIMEOUT,
1406 "mininet>" ],
1407 timeout=10 )
1408 main.log.warn( self.handle.before + self.handle.after )
1409 self.handle.sendline( "" )
1410 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001411 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001412 main.log.error(
1413 self.name +
1414 ": tcpdump - No such device exists. " +
1415 "tcpdump attempted on: " +
1416 intf )
admin2a9548d2014-06-17 14:08:07 -07001417 return main.FALSE
1418 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001419 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001420 return main.TRUE
1421 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001422 main.log.error(
1423 self.name +
1424 ": tcpdump command timed out! Check interface name," +
1425 " given interface was: " +
1426 intf )
admin2a9548d2014-06-17 14:08:07 -07001427 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001428 elif i == 3:
1429 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001430 return main.TRUE
1431 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001432 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001433 return main.FALSE
1434 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001437 main.cleanup()
1438 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001439 except Exception:
1440 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001441 main.cleanup()
1442 main.exit()
1443
kelvin-onlabd3b64892015-01-20 13:26:24 -08001444 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001445 """
1446 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001447 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001448 self.handle.sendline( "sh sudo pkill tcpdump" )
1449 self.handle.expect( "mininet>" )
1450 self.handle.sendline( "" )
1451 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001452 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001453 main.log.error( self.name + ": EOF exception found" )
1454 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001455 main.cleanup()
1456 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001457 except Exception:
1458 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001459 main.cleanup()
1460 main.exit()
1461
kelvin-onlabd3b64892015-01-20 13:26:24 -08001462 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001463 """
1464 Compare mn and onos switches
1465 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001467
Jon Hall7eb38402015-01-08 17:19:54 -08001468 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001469 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001470 output = { "switches": [] }
1471 # iterate through the MN topology and pull out switches and and port
1472 # info
1473 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001474 ports = []
1475 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001476 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001477 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001478 'name': port.name } )
1479 output[ 'switches' ].append( {
1480 "name": switch.name,
1481 "dpid": str( switch.dpid ).zfill( 16 ),
1482 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001483
Jon Hall7eb38402015-01-08 17:19:54 -08001484 # print "mn"
1485 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001486 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001487 # indent=4,
1488 # separators=( ',', ': ' ) )
1489 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 # print json.dumps( switchesJson,
1491 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001492 # indent=4,
1493 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001494
1495 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001496 mnDPIDs = []
1497 for switch in output[ 'switches' ]:
1498 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001499 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001500 # print "List of Mininet switch DPID's"
1501 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001503 main.log.error(
1504 self.name +
1505 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001506 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001508 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001509 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001510 if switch[ 'available' ]:
1511 onosDPIDs.append(
1512 switch[ 'id' ].replace(
1513 ":",
1514 '' ).replace(
1515 "of",
1516 '' ).lower() )
1517 # else:
1518 # print "Switch is unavailable:"
1519 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001520 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001521 # print "List of ONOS switch DPID's"
1522 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001523
Jon Hall7eb38402015-01-08 17:19:54 -08001524 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001526 main.log.report( "Switches in MN but not in ONOS:" )
1527 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1528 main.log.report( str( list1 ) )
1529 main.log.report( "Switches in ONOS but not in MN:" )
1530 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001531 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001532 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 switchResults = main.TRUE
1534 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001535
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001537 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001538 Compare mn and onos ports
1539 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001541
Jon Hallfbc828e2015-01-06 17:30:19 -08001542 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001543 1. This uses the sts TestONTopology object
1544 2. numpy - "sudo pip install numpy"
1545
Jon Hall7eb38402015-01-08 17:19:54 -08001546 """
1547 # FIXME: this does not look for extra ports in ONOS, only checks that
1548 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001549 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001551 output = { "switches": [] }
1552 # iterate through the MN topology and pull out switches and and port
1553 # info
1554 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001555 ports = []
1556 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001557 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001558 tmpPort = { 'of_port': port.port_no,
1559 'mac': str( port.hw_addr ).replace( '\'', '' ),
1560 'name': port.name,
1561 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001562
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001564 tmpSwitch = { 'name': switch.name,
1565 'dpid': str( switch.dpid ).zfill( 16 ),
1566 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001567
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001569
Jon Hall7eb38402015-01-08 17:19:54 -08001570 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 for mnSwitch in output[ 'switches' ]:
1572 mnPorts = []
1573 onosPorts = []
1574 switchResult = main.TRUE
1575 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001576 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 mnPorts.append( port[ 'of_port' ] )
1578 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001579 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 # print onosSwitch
1581 if onosSwitch[ 'device' ][ 'available' ]:
1582 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001583 ':',
1584 '' ).replace(
1585 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 '' ) == mnSwitch[ 'dpid' ]:
1587 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001588 if port[ 'isEnabled' ]:
1589 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 # onosPorts.append( 'local' )
1591 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001592 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001594 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 mnPorts.sort( key=float )
1596 onosPorts.sort( key=float )
1597 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1598 # print "\tmn_ports[] = ", mnPorts
1599 # print "\tonos_ports[] = ", onosPorts
1600 mnPortsLog = mnPorts
1601 onosPortsLog = onosPorts
1602 mnPorts = [ x for x in mnPorts ]
1603 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001604
Jon Hall7eb38402015-01-08 17:19:54 -08001605 # TODO: handle other reserved port numbers besides LOCAL
1606 # NOTE: Reserved ports
1607 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1608 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 for mnPort in mnPortsLog:
1610 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001611 # don't set results to true here as this is just one of
1612 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 mnPorts.remove( mnPort )
1614 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001615 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001616 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001617 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 if 65534 in mnPorts:
1619 mnPorts.remove( 65534 )
1620 if long( uint64( -2 ) ) in onosPorts:
1621 onosPorts.remove( long( uint64( -2 ) ) )
1622 if len( mnPorts ): # the ports of this switch don't match
1623 switchResult = main.FALSE
1624 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1625 if len( onosPorts ): # the ports of this switch don't match
1626 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001627 main.log.warn(
1628 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 str( onosPorts ) )
1630 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001631 main.log.report(
1632 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001633 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1634 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1635 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1636 portsResults = portsResults and switchResult
1637 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001638
kelvin-onlabd3b64892015-01-20 13:26:24 -08001639 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001640 """
1641 Compare mn and onos links
1642 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001644
Jon Hall7eb38402015-01-08 17:19:54 -08001645 This uses the sts TestONTopology object"""
1646 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001647 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001648 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001650 # iterate through the MN topology and pull out switches and and port
1651 # info
1652 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001653 # print "Iterating though switches as seen by Mininet"
1654 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001655 ports = []
1656 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001657 # print port.hw_addr.toStr( separator='' )
1658 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001659 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001660 'name': port.name } )
1661 output[ 'switches' ].append( {
1662 "name": switch.name,
1663 "dpid": str( switch.dpid ).zfill( 16 ),
1664 "ports": ports } )
1665 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001666
kelvin-onlabd3b64892015-01-20 13:26:24 -08001667 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001668 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001669 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 if 2 * len( mnLinks ) == len( onos ):
1671 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001672 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001673 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001674 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001675 "Mininet has " + str( len( mnLinks ) ) +
1676 " bidirectional links and ONOS has " +
1677 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001678
Jon Hall7eb38402015-01-08 17:19:54 -08001679 # iterate through MN links and check if an ONOS link exists in
1680 # both directions
1681 # NOTE: Will currently only show mn links as down if they are
1682 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001684 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001686 # print "Link: %s" % link
1687 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001688 node1 = None
1689 port1 = None
1690 node2 = None
1691 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 firstDir = main.FALSE
1693 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001694 for switch in output[ 'switches' ]:
1695 # print "Switch: %s" % switch[ 'name' ]
1696 if switch[ 'name' ] == link.node1.name:
1697 node1 = switch[ 'dpid' ]
1698 for port in switch[ 'ports' ]:
1699 if str( port[ 'name' ] ) == str( link.port1 ):
1700 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001701 if node1 is not None and node2 is not None:
1702 break
Jon Hall7eb38402015-01-08 17:19:54 -08001703 if switch[ 'name' ] == link.node2.name:
1704 node2 = switch[ 'dpid' ]
1705 for port in switch[ 'ports' ]:
1706 if str( port[ 'name' ] ) == str( link.port2 ):
1707 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001708 if node1 is not None and node2 is not None:
1709 break
1710
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 for onosLink in onos:
1712 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001713 ":",
1714 '' ).replace(
1715 "of",
1716 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001717 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001718 ":",
1719 '' ).replace(
1720 "of",
1721 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001722 onosPort1 = onosLink[ 'src' ][ 'port' ]
1723 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001724
Jon Hall72cf1dc2014-10-20 21:04:50 -04001725 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 if str( onosNode1 ) == str( node1 ) and str(
1727 onosNode2 ) == str( node2 ):
1728 if int( onosPort1 ) == int( port1 ) and int(
1729 onosPort2 ) == int( port2 ):
1730 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001731 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001732 main.log.warn(
1733 'The port numbers do not match for ' +
1734 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001735 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001736 'link %s/%s -> %s/%s' %
1737 ( node1,
1738 port1,
1739 node2,
1740 port2 ) +
1741 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 ( onosNode1,
1743 onosPort1,
1744 onosNode2,
1745 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001746
1747 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 elif ( str( onosNode1 ) == str( node2 ) and
1749 str( onosNode2 ) == str( node1 ) ):
1750 if ( int( onosPort1 ) == int( port2 )
1751 and int( onosPort2 ) == int( port1 ) ):
1752 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001753 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001754 main.log.warn(
1755 'The port numbers do not match for ' +
1756 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001757 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001758 'link %s/%s -> %s/%s' %
1759 ( node2,
1760 port2,
1761 node1,
1762 port1 ) +
1763 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 ( onosNode2,
1765 onosPort2,
1766 onosNode1,
1767 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001768 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001769 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001771 main.log.report(
1772 'ONOS does not have the link %s/%s -> %s/%s' %
1773 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001775 main.log.report(
1776 'ONOS does not have the link %s/%s -> %s/%s' %
1777 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001778 linkResults = linkResults and firstDir and secondDir
1779 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001780
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001782 """
1783 Returns a list of all hosts
1784 Don't ask questions just use it"""
1785 self.handle.sendline( "" )
1786 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001787
Jon Hall7eb38402015-01-08 17:19:54 -08001788 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1789 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001790
kelvin-onlabd3b64892015-01-20 13:26:24 -08001791 handlePy = self.handle.before
1792 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1793 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001794
Jon Hall7eb38402015-01-08 17:19:54 -08001795 self.handle.sendline( "" )
1796 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001797
kelvin-onlabd3b64892015-01-20 13:26:24 -08001798 hostStr = handlePy.replace( "]", "" )
1799 hostStr = hostStr.replace( "'", "" )
1800 hostStr = hostStr.replace( "[", "" )
1801 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001802
kelvin-onlabd3b64892015-01-20 13:26:24 -08001803 return hostList
adminbae64d82013-08-01 10:50:15 -07001804
Jon Hall7eb38402015-01-08 17:19:54 -08001805 def update( self ):
1806 """
1807 updates the port address and status information for
1808 each port in mn"""
1809 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001810 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001811 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001812 self.handle.sendline( "" )
1813 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001814
Jon Hall7eb38402015-01-08 17:19:54 -08001815 self.handle.sendline( "update" )
1816 self.handle.expect( "update" )
1817 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001818
Jon Hall7eb38402015-01-08 17:19:54 -08001819 self.handle.sendline( "" )
1820 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001821
Jon Hallb1290e82014-11-18 16:17:48 -05001822 return main.TRUE
1823 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001824 main.log.error( self.name + ": EOF exception found" )
1825 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001826 main.cleanup()
1827 main.exit()
1828
adminbae64d82013-08-01 10:50:15 -07001829if __name__ != "__main__":
1830 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001831 sys.modules[ __name__ ] = MininetCliDriver()