blob: eaed3a28e8ebfa39c87edc1829aa73dcf50c1b04 [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 Hall7eb38402015-01-08 17:19:54 -080054 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070055 self.flag = 0
56
Jon Hall7eb38402015-01-08 17:19:54 -080057 def connect( self, **connectargs ):
58 """
59 Here the main is the TestON instance after creating
60 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080061 try:
62 for key in connectargs:
63 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080064
kelvin-onlaba1484582015-02-02 15:46:20 -080065 self.name = self.options[ 'name' ]
66 self.handle = super(
67 MininetCliDriver,
68 self ).connect(
69 user_name=self.user_name,
70 ip_address=self.ip_address,
71 port=None,
72 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080073
kelvin-onlaba1484582015-02-02 15:46:20 -080074 if self.handle:
75 main.log.info("Connection successful to the host " +
76 self.user_name +
77 "@" +
78 self.ip_address )
79 return main.TRUE
80 else:
81 main.log.error( "Connection failed to the host " +
82 self.user_name +
83 "@" +
84 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080085 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -080086 return main.FALSE
87 except pexpect.EOF:
88 main.log.error( self.name + ": EOF exception found" )
89 main.log.error( self.name + ": " + self.handle.before )
90 main.cleanup()
91 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080092 except Exception:
93 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -080094 main.cleanup()
95 main.exit()
96
97
98 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
101 arguement ,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 )
118 i = self.handle.expect( [ '%s:' % ( self.user ),
119 '\$',
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... " )
kelvin-onlaba1484582015-02-02 15:46:20 -0800131 if topoFile == '' and args == '':
132 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 )
180 if args == None:
181 args = ''
182 else:
183 main.log.info( "args = " + args)
184 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
185 i = 1
Jon Hall7eb38402015-01-08 17:19:54 -0800186 i = self.handle.expect( [ 'mininet>',
kelvin-onlaba1484582015-02-02 15:46:20 -0800187 pexpect.EOF ,
188 pexpect.TIMEOUT ],
189 timeout)
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800190 if i == 0:
191 main.log.info(self.name + ": Network started")
192 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800193 elif i == 1:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800194 main.log.error( self.name + ": Connection timeout" )
195 return main.FALSE
kelvin-onlabec228b82015-02-09 15:45:55 -0800196 elif i == 2: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800197 main.log.error(
198 self.name +
199 ": Something took too long... " )
200 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800201 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800202 else: # if no handle
203 main.log.error(
204 self.name +
205 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800206 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800207 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800208 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800209 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700210 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800211
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800212 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400213 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800214 # In tree topology, if fanout arg is not given, by default it is 2
215 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400216 fanout = 2
217 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500218 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800219 while( k <= depth - 1 ):
220 count = count + pow( fanout, k )
221 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800223 while( k <= depth - 2 ):
224 # depth-2 gives you only core links and not considering
225 # edge links as seen by ONOS. If all the links including
226 # edge links are required, do depth-1
227 count = count + pow( fanout, k )
228 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800230 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800232
Jon Hall7eb38402015-01-08 17:19:54 -0800233 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800235 # by default it is 1
236 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400237 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 numSwitches = depth
239 numHostsPerSw = fanout
240 totalNumHosts = numSwitches * numHostsPerSw
241 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800242 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400244 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800245 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 "num_switches": int( numSwitches ),
247 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400248 return topoDict
249
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 def calculateSwAndLinks( self ):
251 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400252 return topoDict
253
Jon Hall7eb38402015-01-08 17:19:54 -0800254 def pingall( self, timeout=300 ):
255 """
256 Verifies the reachability of the hosts using pingall command.
257 Optional parameter timeout allows you to specify how long to
258 wait for pingall to complete
259 Returns:
260 main.TRUE if pingall completes with no pings dropped
261 otherwise main.FALSE"""
262 if self.handle:
263 main.log.info(
264 self.name +
265 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700266 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800267 response = self.execute(
268 cmd="pingall",
269 prompt="mininet>",
270 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500271 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800272 main.log.error( self.name + ": EOF exception found" )
273 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500274 main.cleanup()
275 main.exit()
276 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800277 # We may not want to kill the test if pexpect times out
278 main.log.error( self.name + ": TIMEOUT exception found" )
279 main.log.error( self.name +
280 ": " +
281 str( self.handle.before ) )
282 # NOTE: mininet's pingall rounds, so we will check the number of
283 # passed and number of failed
284 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800286 if re.search( pattern, response ):
287 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700288 return main.TRUE
289 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800290 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800292 # NOTE: Send ctrl-c to make sure pingall is done
293 self.handle.send( "\x03" )
294 self.handle.expect( "Interrupt" )
295 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700296 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800297 else:
298 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500299 main.cleanup()
300 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700301
Jon Hall7eb38402015-01-08 17:19:54 -0800302 def fpingHost( self, **pingParams ):
303 """
304 Uses the fping package for faster pinging...
305 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800306 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800307 command = args[ "SRC" ] + \
308 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
309 self.handle.sendline( command )
310 self.handle.expect(
311 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
312 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
313 response = self.handle.before
314 if re.search( ":\s-", response ):
315 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700316 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800317 elif re.search( ":\s\d{1,2}\.\d\d", response ):
318 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700319 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800320 main.log.info( self.name + ": Install fping on mininet machine... " )
321 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700322 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800323
Jon Hall7eb38402015-01-08 17:19:54 -0800324 def pingHost( self, **pingParams ):
325 """
326 Ping from one mininet host to another
327 Currently the only supported Params: SRC and TARGET"""
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" ] + " ping " + \
330 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700331 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800332 main.log.warn( "Sending: " + command )
333 self.handle.sendline( command )
334 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700335 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800336 main.log.error(
337 self.name +
338 ": timeout when waiting for response from mininet" )
339 main.log.error( "response: " + str( self.handle.before ) )
340 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700341 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800342 main.log.error(
343 self.name +
344 ": timeout when waiting for response from mininet" )
345 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700346 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800347 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800348 main.log.error( self.name + ": EOF exception found" )
349 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700350 main.cleanup()
351 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800352 main.log.info( self.name + ": Ping Response: " + response )
353 if re.search( ',\s0\%\spacket\sloss', response ):
354 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800355 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700356 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800357 else:
358 main.log.error(
359 self.name +
360 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800361 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700362 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800363
Jon Hall7eb38402015-01-08 17:19:54 -0800364 def checkIP( self, host ):
365 """
366 Verifies the host's ip configured or not."""
367 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700368 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800369 response = self.execute(
370 cmd=host +
371 " ifconfig",
372 prompt="mininet>",
373 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800374 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800375 main.log.error( self.name + ": EOF exception found" )
376 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700377 main.cleanup()
378 main.exit()
adminbae64d82013-08-01 10:50:15 -0700379
Jon Hall7eb38402015-01-08 17:19:54 -0800380 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800381 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
382 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
383 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
384 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
385 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800386 # pattern = "inet addr:10.0.0.6"
387 if re.search( pattern, response ):
388 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700389 return main.TRUE
390 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800391 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700392 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800393 else:
394 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800395
Jon Hall7eb38402015-01-08 17:19:54 -0800396 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700397 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800398 response = self.execute(
399 cmd="h1 /usr/sbin/sshd -D&",
400 prompt="mininet>",
401 timeout=10 )
402 response = self.execute(
403 cmd="h4 /usr/sbin/sshd -D&",
404 prompt="mininet>",
405 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700406 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800407 vars( self )[ key ] = connectargs[ key ]
408 response = self.execute(
409 cmd="xterm h1 h4 ",
410 prompt="mininet>",
411 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800412 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800413 main.log.error( self.name + ": EOF exception found" )
414 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700415 main.cleanup()
416 main.exit()
adminbae64d82013-08-01 10:50:15 -0700417 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800418 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700419 if self.flag == 0:
420 self.flag = 1
421 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800422 else:
adminbae64d82013-08-01 10:50:15 -0700423 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800424
kelvin-onlaba1484582015-02-02 15:46:20 -0800425 def moveHost( self, host, oldSw, newSw, ):
426 """
427 Moves a host from one switch to another on the fly
428 Note: The intf between host and oldSw when detached
429 using detach(), will still show up in the 'net'
430 cmd, because switch.detach() doesn't affect switch.intfs[]
431 (which is correct behavior since the interfaces
432 haven't moved).
433 """
434 if self.handle:
435 try:
436 # Bring link between oldSw-host down
437 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
438 "'down')"
439 print "cmd1= ", cmd
440 response = self.execute(
441 cmd=cmd,
442 prompt="mininet>",
443 timeout=10 )
444
445 # Determine hostintf and Oldswitchintf
446 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
447 ")[0]"
448 print "cmd2= ", cmd
449 self.handle.sendline( cmd )
450 self.handle.expect( "mininet>" )
451
shahshreya73537862015-02-11 15:15:24 -0800452 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800453 cmd = "px ipaddr = hintf.IP()"
454 print "cmd3= ", cmd
455 self.handle.sendline( cmd )
456 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800457
458 cmd = "px macaddr = hintf.MAC()"
459 print "cmd3= ", cmd
460 self.handle.sendline( cmd )
461 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800462
463 # Detach interface between oldSw-host
464 cmd = "px " + oldSw + ".detach( sintf )"
465 print "cmd4= ", cmd
466 self.handle.sendline( cmd )
467 self.handle.expect( "mininet>" )
468
469 # Add link between host-newSw
470 cmd = "py net.addLink(" + host + "," + newSw + ")"
471 print "cmd5= ", cmd
472 self.handle.sendline( cmd )
473 self.handle.expect( "mininet>" )
474
475 # Determine hostintf and Newswitchintf
476 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
477 ")[0]"
478 print "cmd6= ", cmd
479 self.handle.sendline( cmd )
480 self.handle.expect( "mininet>" )
481
482 # Attach interface between newSw-host
483 cmd = "px " + newSw + ".attach( sintf )"
484 print "cmd3= ", cmd
485 self.handle.sendline( cmd )
486 self.handle.expect( "mininet>" )
487
488 # Set ipaddress of the host-newSw interface
489 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
490 print "cmd7 = ", cmd
491 self.handle.sendline( cmd )
492 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800493
494 # Set macaddress of the host-newSw interface
495 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
496 print "cmd8 = ", cmd
497 self.handle.sendline( cmd )
498 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800499
500 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800501 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800502 self.handle.sendline( cmd )
503 self.handle.expect( "mininet>" )
504 print "output = ", self.handle.before
505
506 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800507 cmd = host + " ifconfig"
508 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800509 self.handle.sendline( cmd )
510 self.handle.expect( "mininet>" )
511 print "ifconfig o/p = ", self.handle.before
512
513 return main.TRUE
514 except pexpect.EOF:
515 main.log.error( self.name + ": EOF exception found" )
516 main.log.error( self.name + ": " + self.handle.before )
517 return main.FALSE
518
Jon Hall7eb38402015-01-08 17:19:54 -0800519 def changeIP( self, host, intf, newIP, newNetmask ):
520 """
521 Changes the ip address of a host on the fly
522 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800523 if self.handle:
524 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800525 cmd = host + " ifconfig " + intf + " " + \
526 newIP + " " + 'netmask' + " " + newNetmask
527 self.handle.sendline( cmd )
528 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800529 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800530 main.log.info( "response = " + response )
531 main.log.info(
532 "Ip of host " +
533 host +
534 " changed to new IP " +
535 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800536 return main.TRUE
537 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800538 main.log.error( self.name + ": EOF exception found" )
539 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800540 return main.FALSE
541
Jon Hall7eb38402015-01-08 17:19:54 -0800542 def changeDefaultGateway( self, host, newGW ):
543 """
544 Changes the default gateway of a host
545 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800546 if self.handle:
547 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800548 cmd = host + " route add default gw " + newGW
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 "Default gateway of host " +
555 host +
556 " changed to " +
557 newGW )
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
Jon Hallfbc828e2015-01-06 17:30:19 -0800563
Jon Hall7eb38402015-01-08 17:19:54 -0800564 def addStaticMACAddress( self, host, GW, macaddr ):
565 """
566 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800567 if self.handle:
568 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800569 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
570 cmd = host + " arp -s " + GW + " " + macaddr
571 self.handle.sendline( cmd )
572 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800573 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800574 main.log.info( "response = " + response )
575 main.log.info(
576 "Mac adrress of gateway " +
577 GW +
578 " changed to " +
579 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -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 )
shahshreyad0c80432014-12-04 16:56:05 -0800584 return main.FALSE
585
Jon Hall7eb38402015-01-08 17:19:54 -0800586 def verifyStaticGWandMAC( self, host ):
587 """
588 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800589 if self.handle:
590 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800591 # h1 arp -an
592 cmd = host + " arp -an "
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( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800597 return main.TRUE
598 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800599 main.log.error( self.name + ": EOF exception found" )
600 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800601 return main.FALSE
602
Jon Hall7eb38402015-01-08 17:19:54 -0800603 def getMacAddress( self, host ):
604 """
605 Verifies the host's ip configured or not."""
606 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700607 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800608 response = self.execute(
609 cmd=host +
610 " ifconfig",
611 prompt="mininet>",
612 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800613 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800614 main.log.error( self.name + ": EOF exception found" )
615 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700616 main.cleanup()
617 main.exit()
adminbae64d82013-08-01 10:50:15 -0700618
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700619 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 macAddressSearch = re.search( pattern, response, re.I )
621 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800622 main.log.info(
623 self.name +
624 ": Mac-Address of Host " +
625 host +
626 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 macAddress )
628 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700629 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800630 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700631
Jon Hall7eb38402015-01-08 17:19:54 -0800632 def getInterfaceMACAddress( self, host, interface ):
633 """
634 Return the IP address of the interface on the given host"""
635 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700636 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800637 response = self.execute( cmd=host + " ifconfig " + interface,
638 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800639 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
642 main.cleanup()
643 main.exit()
644
645 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800646 macAddressSearch = re.search( pattern, response, re.I )
647 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800648 main.log.info( "No mac address found in %s" % response )
649 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800651 main.log.info(
652 "Mac-Address of " +
653 host +
654 ":" +
655 interface +
656 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800657 macAddress )
658 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800659 else:
660 main.log.error( "Connection failed to the host" )
661
662 def getIPAddress( self, host ):
663 """
664 Verifies the host's ip configured or not."""
665 if self.handle:
666 try:
667 response = self.execute(
668 cmd=host +
669 " ifconfig",
670 prompt="mininet>",
671 timeout=10 )
672 except pexpect.EOF:
673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700675 main.cleanup()
676 main.exit()
adminbae64d82013-08-01 10:50:15 -0700677
678 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800680 main.log.info(
681 self.name +
682 ": IP-Address of Host " +
683 host +
684 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 ipAddressSearch.group( 1 ) )
686 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800687 else:
688 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800689
Jon Hall7eb38402015-01-08 17:19:54 -0800690 def getSwitchDPID( self, switch ):
691 """
692 return the datapath ID of the switch"""
693 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700694 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700695 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800696 response = self.execute(
697 cmd=cmd,
698 prompt="mininet>",
699 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800700 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700703 main.cleanup()
704 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800705 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800706 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700707 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800708 main.log.info(
709 "Couldn't find DPID for switch %s, found: %s" %
710 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700711 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800712 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700713 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800714 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700715
Jon Hall7eb38402015-01-08 17:19:54 -0800716 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700717 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800718 self.handle.sendline( "" )
719 self.expect( "mininet>" )
720 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700721 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800722 response = self.execute(
723 cmd=cmd,
724 prompt="mininet>",
725 timeout=10 )
726 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700727 response = self.handle.before
728 return response
729 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700732 main.cleanup()
733 main.exit()
734
Jon Hall7eb38402015-01-08 17:19:54 -0800735 def getInterfaces( self, node ):
736 """
737 return information dict about interfaces connected to the node"""
738 if self.handle:
739 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800740 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700741 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700742 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800743 response = self.execute(
744 cmd=cmd,
745 prompt="mininet>",
746 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800747 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.error( self.name + ": EOF exception found" )
749 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700750 main.cleanup()
751 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700752 return response
753 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800754 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700755
Jon Hall7eb38402015-01-08 17:19:54 -0800756 def dump( self ):
757 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700758 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800759 response = self.execute(
760 cmd='dump',
761 prompt='mininet>',
762 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800763 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700766 main.cleanup()
767 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700768 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800769
Jon Hall7eb38402015-01-08 17:19:54 -0800770 def intfs( self ):
771 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700772 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800773 response = self.execute(
774 cmd='intfs',
775 prompt='mininet>',
776 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800777 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700780 main.cleanup()
781 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700782 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800783
Jon Hall7eb38402015-01-08 17:19:54 -0800784 def net( self ):
785 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700786 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800787 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800788 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700791 main.cleanup()
792 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700793 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800794
795 def iperf( self, host1, host2 ):
796 main.log.info(
797 self.name +
798 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700799 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 cmd1 = 'iperf ' + host1 + " " + host2
801 self.handle.sendline( cmd1 )
802 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800803 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800804 if re.search( 'Results:', response ):
805 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800806 return main.TRUE
807 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800808 main.log.error( self.name + ": iperf test failed" )
809 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -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 )
shahshreyae6c7cf42014-11-26 16:39:01 -0800813 main.cleanup()
814 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800815
Jon Hall7eb38402015-01-08 17:19:54 -0800816 def iperfudp( self ):
817 main.log.info(
818 self.name +
819 ": Simple iperf TCP test between two " +
820 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700821 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800822 response = self.execute(
823 cmd='iperfudp',
824 prompt='mininet>',
825 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800826 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800827 main.log.error( self.name + ": EOF exception found" )
828 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700829 main.cleanup()
830 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700831 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800832
Jon Hall7eb38402015-01-08 17:19:54 -0800833 def nodes( self ):
834 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700835 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800836 response = self.execute(
837 cmd='nodes',
838 prompt='mininet>',
839 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800840 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800841 main.log.error( self.name + ": EOF exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700843 main.cleanup()
844 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700845 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800846
Jon Hall7eb38402015-01-08 17:19:54 -0800847 def pingpair( self ):
848 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700849 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800850 response = self.execute(
851 cmd='pingpair',
852 prompt='mininet>',
853 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800854 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800855 main.log.error( self.name + ": EOF exception found" )
856 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700857 main.cleanup()
858 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800859
Jon Hall7eb38402015-01-08 17:19:54 -0800860 if re.search( ',\s0\%\spacket\sloss', response ):
861 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700863 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800864 else:
865 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800866 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700867 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800868
Jon Hall7eb38402015-01-08 17:19:54 -0800869 def link( self, **linkargs ):
870 """
871 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800872 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800873 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
874 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
875 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
876 main.log.info(
877 "Bring link between '" +
878 end1 +
879 "' and '" +
880 end2 +
881 "' '" +
882 option +
883 "'" )
884 command = "link " + \
885 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700886 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 self.handle.sendline( command )
888 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800889 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700892 main.cleanup()
893 main.exit()
adminbae64d82013-08-01 10:50:15 -0700894 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800895
Jon Hall7eb38402015-01-08 17:19:54 -0800896 def yank( self, **yankargs ):
897 """
898 yank a mininet switch interface to a host"""
899 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800900 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800901 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
902 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
903 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700904 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800905 response = self.execute(
906 cmd=command,
907 prompt="mininet>",
908 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800909 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800910 main.log.error( self.name + ": EOF exception found" )
911 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700912 main.cleanup()
913 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700914 return main.TRUE
915
Jon Hall7eb38402015-01-08 17:19:54 -0800916 def plug( self, **plugargs ):
917 """
918 plug the yanked mininet switch interface to a switch"""
919 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800920 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800921 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
922 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
923 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700924 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800925 response = self.execute(
926 cmd=command,
927 prompt="mininet>",
928 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800929 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700932 main.cleanup()
933 main.exit()
adminbae64d82013-08-01 10:50:15 -0700934 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800935
Jon Hall7eb38402015-01-08 17:19:54 -0800936 def dpctl( self, **dpctlargs ):
937 """
938 Run dpctl command on all switches."""
939 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800940 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800941 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
942 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
943 command = "dpctl " + cmd + " " + str( cmdargs )
944 try:
945 response = self.execute(
946 cmd=command,
947 prompt="mininet>",
948 timeout=10 )
949 except pexpect.EOF:
950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
952 main.cleanup()
953 main.exit()
954 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800955
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 def getVersion( self ):
957 fileInput = path + '/lib/Mininet/INSTALL'
958 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700959 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800961 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700962 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800963 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500964 return version
adminbae64d82013-08-01 10:50:15 -0700965
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800967 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500968 Parameters:
969 sw: The name of an OVS switch. Example "s1"
970 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800971 The output of the command from the mininet cli
972 or main.FALSE on timeout"""
973 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700974 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800975 response = self.execute(
976 cmd=command,
977 prompt="mininet>",
978 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700979 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500980 return response
admin2a9548d2014-06-17 14:08:07 -0700981 else:
982 return main.FALSE
983 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700986 main.cleanup()
987 main.exit()
adminbae64d82013-08-01 10:50:15 -0700988
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800990 """
991 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800992 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800993 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700994
995 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800996 for j in range( count ):
997 argstring = argstring + ",IP" + \
998 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800999 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001000
Jon Hall7eb38402015-01-08 17:19:54 -08001001 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1002 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001003 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001004 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001005
Jon Hall7eb38402015-01-08 17:19:54 -08001006 command = "sh ovs-vsctl set-controller s" + \
1007 str( sw ) + " " + ptcpB + " "
1008 for j in range( count ):
1009 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001010 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001011 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1012 ip = args[
1013 "IP" +
1014 str( i ) ] if args[
1015 "IP" +
1016 str( i ) ] is not None else ""
1017 port = args[
1018 "PORT" +
1019 str( i ) ] if args[
1020 "PORT" +
1021 str( i ) ] is not None else ""
1022 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001023 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001024 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001025 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001026 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001027 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001028 main.log.error( self.name + ": EOF exception found" )
1029 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001030 main.cleanup()
1031 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001032 except Exception:
1033 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001034 main.cleanup()
1035 main.exit()
adminbae64d82013-08-01 10:50:15 -07001036
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001038 """
1039 Removes the controller target from sw"""
1040 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001041 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001042 response = self.execute(
1043 cmd=command,
1044 prompt="mininet>",
1045 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001046 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001047 main.log.error( self.name + ": EOF exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001049 main.cleanup()
1050 main.exit()
1051 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001052 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001053
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001055 """
Jon Hallb1290e82014-11-18 16:17:48 -05001056 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001057 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001058 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001059 NOTE: cannot currently specify what type of switch
1060 required params:
1061 switchname = name of the new switch as a string
1062 optional keyvalues:
1063 dpid = "dpid"
1064 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001065 """
1066 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001067 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001068 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001069 response = self.execute(
1070 cmd=command,
1071 prompt="mininet>",
1072 timeout=10 )
1073 if re.search( "already exists!", 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( "Error", response ):
1077 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001078 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001079 elif re.search( "usage:", response ):
1080 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001081 return main.FALSE
1082 else:
1083 return main.TRUE
1084 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001085 main.log.error( self.name + ": EOF exception found" )
1086 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001087 main.cleanup()
1088 main.exit()
1089
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001091 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001092 delete a switch from the mininet topology
1093 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001094 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001095 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001096 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001097 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001098 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001099 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001100 response = self.execute(
1101 cmd=command,
1102 prompt="mininet>",
1103 timeout=10 )
1104 if re.search( "no switch named", 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( "Error", response ):
1108 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001109 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001110 elif re.search( "usage:", response ):
1111 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001112 return main.FALSE
1113 else:
1114 return main.TRUE
1115 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001116 main.log.error( self.name + ": EOF exception found" )
1117 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001118 main.cleanup()
1119 main.exit()
1120
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001122 """
1123 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001124 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001125 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001126 NOTE: cannot currently specify what type of link
1127 required params:
1128 node1 = the string node name of the first endpoint of the link
1129 node2 = the string node name of the second endpoint of the link
1130 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001131 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001132 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 response = self.execute(
1134 cmd=command,
1135 prompt="mininet>",
1136 timeout=10 )
1137 if re.search( "doesnt exist!", 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( "Error", response ):
1141 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001142 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001143 elif re.search( "usage:", response ):
1144 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001145 return main.FALSE
1146 else:
1147 return main.TRUE
1148 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001149 main.log.error( self.name + ": EOF exception found" )
1150 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001151 main.cleanup()
1152 main.exit()
1153
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001155 """
1156 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001157 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001158 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001159 required params:
1160 node1 = the string node name of the first endpoint of the link
1161 node2 = the string node name of the second endpoint of the link
1162 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001163 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001164 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001165 response = self.execute(
1166 cmd=command,
1167 prompt="mininet>",
1168 timeout=10 )
1169 if re.search( "no node named", 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( "Error", response ):
1173 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001174 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001175 elif re.search( "usage:", response ):
1176 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001177 return main.FALSE
1178 else:
1179 return main.TRUE
1180 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 main.log.error( self.name + ": EOF exception found" )
1182 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001183 main.cleanup()
1184 main.exit()
1185
kelvin-onlabd3b64892015-01-20 13:26:24 -08001186 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001187 """
Jon Hallb1290e82014-11-18 16:17:48 -05001188 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001189 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001190 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001191 NOTE: cannot currently specify what type of host
1192 required params:
1193 hostname = the string hostname
1194 optional key-value params
1195 switch = "switch name"
1196 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001197 """
1198 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001199 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001200 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001201 response = self.execute(
1202 cmd=command,
1203 prompt="mininet>",
1204 timeout=10 )
1205 if re.search( "already 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( "doesnt exists!", 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( "Error", response ):
1212 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001213 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001214 elif re.search( "usage:", response ):
1215 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001216 return main.FALSE
1217 else:
1218 return main.TRUE
1219 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001220 main.log.error( self.name + ": EOF exception found" )
1221 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001222 main.cleanup()
1223 main.exit()
1224
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001226 """
1227 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001228 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001229 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001230 NOTE: this uses a custom mn function
1231 required params:
1232 hostname = the string hostname
1233 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001234 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001235 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 response = self.execute(
1237 cmd=command,
1238 prompt="mininet>",
1239 timeout=10 )
1240 if re.search( "no host named", 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( "Error", response ):
1244 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001245 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001246 elif re.search( "usage:", response ):
1247 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001248 return main.FALSE
1249 else:
1250 return main.TRUE
1251 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001252 main.log.error( self.name + ": EOF exception found" )
1253 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001254 main.cleanup()
1255 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001256
Jon Hall7eb38402015-01-08 17:19:54 -08001257 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001258 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001259 Called at the end of the test to stop the mininet and
1260 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001261 """
1262 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001263 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
1264 timeout = 2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001265 if i == 0:
1266 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001267 elif i == 1:
1268 return main.TRUE
1269 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001270 # print "Disconnecting Mininet"
1271 if self.handle:
1272 self.handle.sendline( "exit" )
1273 self.handle.expect( "exit" )
1274 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001275 else:
1276 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001277 return response
1278
kelvin-onlab56a3f462015-02-06 14:04:43 -08001279 def stopNet( self , timeout = 5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001280 """
Jon Hall21270ac2015-02-16 17:59:55 -08001281 Stops mininet.
1282 Returns main.TRUE if the mininet succesfully stops and
1283 main.FALSE if the pexpect handle does not exist.
1284
Jon Halld61331b2015-02-17 16:35:47 -08001285 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001286 """
Jon Hall21270ac2015-02-16 17:59:55 -08001287
Jon Halld61331b2015-02-17 16:35:47 -08001288 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001289 response = ''
1290 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001291 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001292 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001293 i = self.handle.expect( [ 'mininet>',
1294 '\$',
1295 pexpect.EOF,
1296 pexpect.TIMEOUT ],
1297 timeout )
1298 if i == 0:
1299 main.log.info( "Exiting mininet..." )
1300
Jon Hall7eb38402015-01-08 17:19:54 -08001301 response = self.execute(
1302 cmd="exit",
1303 prompt="(.*)",
1304 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001305 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001306 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001307 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08001308
1309 if i == 1:
1310 main.log.info( " Mininet trying to exit while not " +
1311 "in the mininet prompt" )
1312 elif i == 2:
1313 main.log.error( "Something went wrong exiting mininet" )
1314 elif i == 3: # timeout
1315 main.log.error( "Something went wrong exiting mininet " +
1316 "TIMEOUT" )
1317
Jon Hallfbc828e2015-01-06 17:30:19 -08001318 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001319 main.log.error( self.name + ": EOF exception found" )
1320 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001321 main.cleanup()
1322 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001323 else:
1324 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001325 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001326 return response
1327
kelvin-onlaba1484582015-02-02 15:46:20 -08001328
1329
Jon Hall7eb38402015-01-08 17:19:54 -08001330 def arping( self, src, dest, destmac ):
1331 self.handle.sendline( '' )
1332 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001333
Jon Hall7eb38402015-01-08 17:19:54 -08001334 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001335 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001336 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1337 main.log.info( self.name + ": ARP successful" )
1338 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001339 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001340 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001341 main.log.warn( self.name + ": ARP FAILURE" )
1342 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001343 return main.FALSE
1344
Jon Hall7eb38402015-01-08 17:19:54 -08001345 def decToHex( self, num ):
1346 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001347
Jon Hall7eb38402015-01-08 17:19:54 -08001348 def getSwitchFlowCount( self, switch ):
1349 """
1350 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001351 if self.handle:
1352 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1353 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001354 response = self.execute(
1355 cmd=cmd,
1356 prompt="mininet>",
1357 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001358 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001359 main.log.error( self.name + ": EOF exception found" )
1360 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001361 main.cleanup()
1362 main.exit()
1363 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001364 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001365 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.info(
1367 "Couldn't find flows on switch %s, found: %s" %
1368 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001369 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001370 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001371 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001372 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001373
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 def checkFlows( self, sw, dumpFormat=None ):
1375 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001377 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001378 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001379 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001380 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 response = self.execute(
1382 cmd=command,
1383 prompt="mininet>",
1384 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001385 return response
1386 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001387 main.log.error( self.name + ": EOF exception found" )
1388 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001389 main.cleanup()
1390 main.exit()
1391 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001392 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001393
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001395 """
1396 Runs tpdump on an intferface and saves the file
1397 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001398 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001399 self.handle.sendline( "" )
1400 self.handle.expect( "mininet>" )
1401 self.handle.sendline(
1402 "sh sudo tcpdump -n -i " +
1403 intf +
1404 " " +
1405 port +
1406 " -w " +
1407 filename.strip() +
1408 " &" )
1409 self.handle.sendline( "" )
1410 i = self.handle.expect( [ 'No\ssuch\device',
1411 'listening\son',
1412 pexpect.TIMEOUT,
1413 "mininet>" ],
1414 timeout=10 )
1415 main.log.warn( self.handle.before + self.handle.after )
1416 self.handle.sendline( "" )
1417 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001418 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001419 main.log.error(
1420 self.name +
1421 ": tcpdump - No such device exists. " +
1422 "tcpdump attempted on: " +
1423 intf )
admin2a9548d2014-06-17 14:08:07 -07001424 return main.FALSE
1425 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001427 return main.TRUE
1428 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 main.log.error(
1430 self.name +
1431 ": tcpdump command timed out! Check interface name," +
1432 " given interface was: " +
1433 intf )
admin2a9548d2014-06-17 14:08:07 -07001434 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001435 elif i == 3:
1436 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001437 return main.TRUE
1438 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001439 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001440 return main.FALSE
1441 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001442 main.log.error( self.name + ": EOF exception found" )
1443 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001444 main.cleanup()
1445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001446 except Exception:
1447 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001448 main.cleanup()
1449 main.exit()
1450
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001452 "pkills tcpdump"
1453 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001454 self.handle.sendline( "sh sudo pkill tcpdump" )
1455 self.handle.expect( "mininet>" )
1456 self.handle.sendline( "" )
1457 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001458 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001459 main.log.error( self.name + ": EOF exception found" )
1460 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001461 main.cleanup()
1462 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001463 except Exception:
1464 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001465 main.cleanup()
1466 main.exit()
1467
kelvin-onlabd3b64892015-01-20 13:26:24 -08001468 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001469 """
1470 Compare mn and onos switches
1471 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001473
Jon Hall7eb38402015-01-08 17:19:54 -08001474 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001476 output = { "switches": [] }
1477 # iterate through the MN topology and pull out switches and and port
1478 # info
1479 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001480 ports = []
1481 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001482 ports.append( { 'of_port': port.port_no,
1483 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001485 'name': port.name } )
1486 output[ 'switches' ].append( {
1487 "name": switch.name,
1488 "dpid": str( switch.dpid ).zfill( 16 ),
1489 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001490
Jon Hall7eb38402015-01-08 17:19:54 -08001491 # print "mn"
1492 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001494 # indent=4,
1495 # separators=( ',', ': ' ) )
1496 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 # print json.dumps( switchesJson,
1498 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001499 # indent=4,
1500 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001501
1502 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001503 mnDPIDs = []
1504 for switch in output[ 'switches' ]:
1505 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001506 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001507 # print "List of Mininet switch DPID's"
1508 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001510 main.log.error(
1511 self.name +
1512 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001513 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001514 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001515 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001516 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001517 if switch[ 'available' ]:
1518 onosDPIDs.append(
1519 switch[ 'id' ].replace(
1520 ":",
1521 '' ).replace(
1522 "of",
1523 '' ).lower() )
1524 # else:
1525 # print "Switch is unavailable:"
1526 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001527 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001528 # print "List of ONOS switch DPID's"
1529 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001530
Jon Hall7eb38402015-01-08 17:19:54 -08001531 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001533 main.log.report( "Switches in MN but not in ONOS:" )
1534 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1535 main.log.report( str( list1 ) )
1536 main.log.report( "Switches in ONOS but not in MN:" )
1537 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001538 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001539 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 switchResults = main.TRUE
1541 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001542
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001544 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001545 Compare mn and onos ports
1546 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001547 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001548
Jon Hallfbc828e2015-01-06 17:30:19 -08001549 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001550 1. This uses the sts TestONTopology object
1551 2. numpy - "sudo pip install numpy"
1552
Jon Hall7eb38402015-01-08 17:19:54 -08001553 """
1554 # FIXME: this does not look for extra ports in ONOS, only checks that
1555 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001556 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001558 output = { "switches": [] }
1559 # iterate through the MN topology and pull out switches and and port
1560 # info
1561 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001562 ports = []
1563 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001564 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001566 tmpPort[ 'of_port' ] = port.port_no
1567 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 tmpPort[ 'name' ] = port.name
1569 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001570
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 ports.append( tmpPort )
1572 tmpSwitch = {}
1573 tmpSwitch[ 'name' ] = switch.name
1574 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1575 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001576
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001578
Jon Hall7eb38402015-01-08 17:19:54 -08001579 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 for mnSwitch in output[ 'switches' ]:
1581 mnPorts = []
1582 onosPorts = []
1583 switchResult = main.TRUE
1584 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001585 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 mnPorts.append( port[ 'of_port' ] )
1587 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001588 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 # print onosSwitch
1590 if onosSwitch[ 'device' ][ 'available' ]:
1591 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001592 ':',
1593 '' ).replace(
1594 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 '' ) == mnSwitch[ 'dpid' ]:
1596 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001597 if port[ 'isEnabled' ]:
1598 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 # onosPorts.append( 'local' )
1600 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001603 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 mnPorts.sort( key=float )
1605 onosPorts.sort( key=float )
1606 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1607 # print "\tmn_ports[] = ", mnPorts
1608 # print "\tonos_ports[] = ", onosPorts
1609 mnPortsLog = mnPorts
1610 onosPortsLog = onosPorts
1611 mnPorts = [ x for x in mnPorts ]
1612 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001613
Jon Hall7eb38402015-01-08 17:19:54 -08001614 # TODO: handle other reserved port numbers besides LOCAL
1615 # NOTE: Reserved ports
1616 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1617 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 for mnPort in mnPortsLog:
1619 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001620 # don't set results to true here as this is just one of
1621 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 mnPorts.remove( mnPort )
1623 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001624 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001625 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001626 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 if 65534 in mnPorts:
1628 mnPorts.remove( 65534 )
1629 if long( uint64( -2 ) ) in onosPorts:
1630 onosPorts.remove( long( uint64( -2 ) ) )
1631 if len( mnPorts ): # the ports of this switch don't match
1632 switchResult = main.FALSE
1633 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1634 if len( onosPorts ): # the ports of this switch don't match
1635 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001636 main.log.warn(
1637 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 str( onosPorts ) )
1639 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001640 main.log.report(
1641 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1643 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1644 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1645 portsResults = portsResults and switchResult
1646 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001647
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001649 """
1650 Compare mn and onos links
1651 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001653
Jon Hall7eb38402015-01-08 17:19:54 -08001654 This uses the sts TestONTopology object"""
1655 # FIXME: this does not look for extra links in ONOS, only checks that
1656 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001658 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001660 # iterate through the MN topology and pull out switches and and port
1661 # info
1662 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001663 # print "Iterating though switches as seen by Mininet"
1664 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001665 ports = []
1666 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001667 # print port.hw_addr.toStr( separator='' )
1668 ports.append( { 'of_port': port.port_no,
1669 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001671 'name': port.name } )
1672 output[ 'switches' ].append( {
1673 "name": switch.name,
1674 "dpid": str( switch.dpid ).zfill( 16 ),
1675 "ports": ports } )
1676 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001677
kelvin-onlabd3b64892015-01-20 13:26:24 -08001678 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001679 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001680 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 if 2 * len( mnLinks ) == len( onos ):
1682 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001683 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001685 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001686 "Mininet has " + str( len( mnLinks ) ) +
1687 " bidirectional links and ONOS has " +
1688 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001689
Jon Hall7eb38402015-01-08 17:19:54 -08001690 # iterate through MN links and check if an ONOS link exists in
1691 # both directions
1692 # NOTE: Will currently only show mn links as down if they are
1693 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001695 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001696 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001697 # print "Link: %s" % link
1698 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001699 node1 = None
1700 port1 = None
1701 node2 = None
1702 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 firstDir = main.FALSE
1704 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001705 for switch in output[ 'switches' ]:
1706 # print "Switch: %s" % switch[ 'name' ]
1707 if switch[ 'name' ] == link.node1.name:
1708 node1 = switch[ 'dpid' ]
1709 for port in switch[ 'ports' ]:
1710 if str( port[ 'name' ] ) == str( link.port1 ):
1711 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001712 if node1 is not None and node2 is not None:
1713 break
Jon Hall7eb38402015-01-08 17:19:54 -08001714 if switch[ 'name' ] == link.node2.name:
1715 node2 = switch[ 'dpid' ]
1716 for port in switch[ 'ports' ]:
1717 if str( port[ 'name' ] ) == str( link.port2 ):
1718 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001719 if node1 is not None and node2 is not None:
1720 break
1721
kelvin-onlabd3b64892015-01-20 13:26:24 -08001722 for onosLink in onos:
1723 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001724 ":",
1725 '' ).replace(
1726 "of",
1727 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001728 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001729 ":",
1730 '' ).replace(
1731 "of",
1732 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 onosPort1 = onosLink[ 'src' ][ 'port' ]
1734 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001735
Jon Hall72cf1dc2014-10-20 21:04:50 -04001736 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001737 if str( onosNode1 ) == str( node1 ) and str(
1738 onosNode2 ) == str( node2 ):
1739 if int( onosPort1 ) == int( port1 ) and int(
1740 onosPort2 ) == int( port2 ):
1741 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001742 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001743 main.log.warn(
1744 'The port numbers do not match for ' +
1745 str( link ) +
1746 ' between ONOS and MN. When cheking ONOS for ' +
1747 'link %s/%s -> %s/%s' %
1748 ( node1,
1749 port1,
1750 node2,
1751 port2 ) +
1752 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001753 ( onosNode1,
1754 onosPort1,
1755 onosNode2,
1756 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001757
1758 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 elif ( str( onosNode1 ) == str( node2 ) and
1760 str( onosNode2 ) == str( node1 ) ):
1761 if ( int( onosPort1 ) == int( port2 )
1762 and int( onosPort2 ) == int( port1 ) ):
1763 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001764 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001765 main.log.warn(
1766 'The port numbers do not match for ' +
1767 str( link ) +
1768 ' between ONOS and MN. When cheking ONOS for ' +
1769 'link %s/%s -> %s/%s' %
1770 ( node2,
1771 port2,
1772 node1,
1773 port1 ) +
1774 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 ( onosNode2,
1776 onosPort2,
1777 onosNode1,
1778 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001779 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001780 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001782 main.log.report(
1783 'ONOS does not have the link %s/%s -> %s/%s' %
1784 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001786 main.log.report(
1787 'ONOS does not have the link %s/%s -> %s/%s' %
1788 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001789 linkResults = linkResults and firstDir and secondDir
1790 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001791
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001793 """
1794 Returns a list of all hosts
1795 Don't ask questions just use it"""
1796 self.handle.sendline( "" )
1797 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001798
Jon Hall7eb38402015-01-08 17:19:54 -08001799 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1800 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001801
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 handlePy = self.handle.before
1803 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1804 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001805
Jon Hall7eb38402015-01-08 17:19:54 -08001806 self.handle.sendline( "" )
1807 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001808
kelvin-onlabd3b64892015-01-20 13:26:24 -08001809 hostStr = handlePy.replace( "]", "" )
1810 hostStr = hostStr.replace( "'", "" )
1811 hostStr = hostStr.replace( "[", "" )
1812 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001813
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 return hostList
adminbae64d82013-08-01 10:50:15 -07001815
Jon Hall7eb38402015-01-08 17:19:54 -08001816 def update( self ):
1817 """
1818 updates the port address and status information for
1819 each port in mn"""
1820 # TODO: Add error checking. currently the mininet command has no output
1821 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001822 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001823 self.handle.sendline( "" )
1824 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001825
Jon Hall7eb38402015-01-08 17:19:54 -08001826 self.handle.sendline( "update" )
1827 self.handle.expect( "update" )
1828 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001829
Jon Hall7eb38402015-01-08 17:19:54 -08001830 self.handle.sendline( "" )
1831 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001832
Jon Hallb1290e82014-11-18 16:17:48 -05001833 return main.TRUE
1834 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001835 main.log.error( self.name + ": EOF exception found" )
1836 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001837 main.cleanup()
1838 main.exit()
1839
adminbae64d82013-08-01 10:50:15 -07001840if __name__ != "__main__":
1841 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001842 sys.modules[ __name__ ] = MininetCliDriver()