blob: 8399546efd227d8b770fd19d49cbce7dec5f690c [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."""
admin2a9548d2014-06-17 14:08:07 -070038import traceback
adminbae64d82013-08-01 10:50:15 -070039import pexpect
adminbae64d82013-08-01 10:50:15 -070040import re
41import sys
Jon Hall7eb38402015-01-08 17:19:54 -080042sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040043from math import pow
adminbae64d82013-08-01 10:50:15 -070044from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
47class MininetCliDriver( Emulator ):
48
49 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
53 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
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:
76 main.log.info("Connection successful to the host " +
77 self.user_name +
78 "@" +
79 self.ip_address )
80 return main.TRUE
81 else:
82 main.log.error( "Connection failed to the host " +
83 self.user_name +
84 "@" +
85 self.ip_address )
Jon Hallff6b4b22015-02-23 09:25:15 -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()
93 except:
94 main.log.info( self.name + ":::::::::::::::::::::::" )
95 main.log.error( traceback.print_exc() )
96 main.log.info( ":::::::::::::::::::::::" )
97 main.cleanup()
98 main.exit()
99
100
101 def startNet( self, topoFile = '', args = '', timeout = 120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800102 """
103 Starts Mininet accepts a topology(.py) file and/or an optional
104 arguement ,to start the mininet, as a parameter.
Jon Hall21270ac2015-02-16 17:59:55 -0800105 Returns main.TRUE if the mininet starts successfully and
106 main.FALSE otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800107 """
Jon Hall7eb38402015-01-08 17:19:54 -0800108 if self.handle:
109 main.log.info(
110 self.name +
111 ": Clearing any residual state or processes" )
112 self.handle.sendline( "sudo mn -c" )
113 i = self.handle.expect( [ 'password\sfor\s',
114 'Cleanup\scomplete',
115 pexpect.EOF,
116 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800117 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800118 if i == 0:
119 main.log.info( self.name + ": Sending sudo password" )
120 self.handle.sendline( self.pwd )
121 i = self.handle.expect( [ '%s:' % ( self.user ),
122 '\$',
123 pexpect.EOF,
124 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800125 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800126 if i == 1:
127 main.log.info( self.name + ": Clean" )
128 elif i == 2:
129 main.log.error( self.name + ": Connection terminated" )
130 elif i == 3: # timeout
131 main.log.error(
132 self.name +
133 ": Something while cleaning MN took too long... " )
kelvin-onlaba1484582015-02-02 15:46:20 -0800134 if topoFile == '' and args == '':
135 main.log.info( self.name + ": building fresh mininet" )
136 # for reactive/PARP enabled tests
137 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
138 " " + self.options[ 'arg2' ] +\
139 " --mac --controller " +\
140 self.options[ 'controller' ] + " " +\
141 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -0800142
kelvin-onlaba1484582015-02-02 15:46:20 -0800143 argList = self.options[ 'arg1' ].split( "," )
144 global topoArgList
145 topoArgList = argList[ 0 ].split( " " )
146 argList = map( int, argList[ 1: ] )
147 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800148
kelvin-onlaba1484582015-02-02 15:46:20 -0800149 self.handle.sendline( cmdString )
150 self.handle.expect( [ "sudo mn",
151 pexpect.EOF,
152 pexpect.TIMEOUT ] )
153 while True:
154 i = self.handle.expect( [ 'mininet>',
155 '\*\*\*',
156 'Exception',
157 pexpect.EOF,
158 pexpect.TIMEOUT ],
159 timeout )
160 if i == 0:
161 main.log.info( self.name + ": mininet built" )
162 return main.TRUE
163 if i == 1:
164 self.handle.expect(
165 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
166 main.log.info( self.handle.before )
167 elif i == 2:
168 main.log.error(
169 self.name +
170 ": Launching mininet failed..." )
171 return main.FALSE
172 elif i == 3:
173 main.log.error( self.name + ": Connection timeout" )
174 return main.FALSE
175 elif i == 4: # timeout
176 main.log.error(
177 self.name +
178 ": Something took too long... " )
179 return main.FALSE
180 return main.TRUE
181 else:
182 main.log.info( "Starting topo file " + topoFile )
183 if args == None:
184 args = ''
185 else:
186 main.log.info( "args = " + args)
187 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
188 i = 1
Jon Hall7eb38402015-01-08 17:19:54 -0800189 i = self.handle.expect( [ 'mininet>',
kelvin-onlaba1484582015-02-02 15:46:20 -0800190 pexpect.EOF ,
191 pexpect.TIMEOUT ],
192 timeout)
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800193 if i == 0:
194 main.log.info(self.name + ": Network started")
195 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800196 elif i == 1:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800197 main.log.error( self.name + ": Connection timeout" )
198 return main.FALSE
kelvin-onlabec228b82015-02-09 15:45:55 -0800199 elif i == 2: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800200 main.log.error(
201 self.name +
202 ": Something took too long... " )
203 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800204 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800205 else: # if no handle
206 main.log.error(
207 self.name +
208 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800209 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800210 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800211 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800212 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700213 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800214
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800215 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400216 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800217 # In tree topology, if fanout arg is not given, by default it is 2
218 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400219 fanout = 2
220 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500221 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800222 while( k <= depth - 1 ):
223 count = count + pow( fanout, k )
224 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800225 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800226 while( k <= depth - 2 ):
227 # depth-2 gives you only core links and not considering
228 # edge links as seen by ONOS. If all the links including
229 # edge links are required, do depth-1
230 count = count + pow( fanout, k )
231 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800233 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800235
Jon Hall7eb38402015-01-08 17:19:54 -0800236 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800238 # by default it is 1
239 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400240 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 numSwitches = depth
242 numHostsPerSw = fanout
243 totalNumHosts = numSwitches * numHostsPerSw
244 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800245 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400247 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800248 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 "num_switches": int( numSwitches ),
250 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400251 return topoDict
252
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 def calculateSwAndLinks( self ):
254 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400255 return topoDict
256
Jon Hall7eb38402015-01-08 17:19:54 -0800257 def pingall( self, timeout=300 ):
258 """
259 Verifies the reachability of the hosts using pingall command.
260 Optional parameter timeout allows you to specify how long to
261 wait for pingall to complete
262 Returns:
263 main.TRUE if pingall completes with no pings dropped
264 otherwise main.FALSE"""
265 if self.handle:
266 main.log.info(
267 self.name +
268 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700269 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800270 response = self.execute(
271 cmd="pingall",
272 prompt="mininet>",
273 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500274 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800275 main.log.error( self.name + ": EOF exception found" )
276 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500277 main.cleanup()
278 main.exit()
279 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800280 # We may not want to kill the test if pexpect times out
281 main.log.error( self.name + ": TIMEOUT exception found" )
282 main.log.error( self.name +
283 ": " +
284 str( self.handle.before ) )
285 # NOTE: mininet's pingall rounds, so we will check the number of
286 # passed and number of failed
287 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800289 if re.search( pattern, response ):
290 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700291 return main.TRUE
292 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800293 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800295 # NOTE: Send ctrl-c to make sure pingall is done
296 self.handle.send( "\x03" )
297 self.handle.expect( "Interrupt" )
298 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700299 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800300 else:
301 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500302 main.cleanup()
303 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700304
Jon Hall7eb38402015-01-08 17:19:54 -0800305 def fpingHost( self, **pingParams ):
306 """
307 Uses the fping package for faster pinging...
308 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800309 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800310 command = args[ "SRC" ] + \
311 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
312 self.handle.sendline( command )
313 self.handle.expect(
314 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
315 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
316 response = self.handle.before
317 if re.search( ":\s-", response ):
318 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700319 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800320 elif re.search( ":\s\d{1,2}\.\d\d", response ):
321 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700322 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800323 main.log.info( self.name + ": Install fping on mininet machine... " )
324 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700325 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800326
Jon Hall7eb38402015-01-08 17:19:54 -0800327 def pingHost( self, **pingParams ):
328 """
329 Ping from one mininet host to another
330 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800331 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800332 command = args[ "SRC" ] + " ping " + \
333 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700334 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800335 main.log.warn( "Sending: " + command )
336 self.handle.sendline( command )
337 i = self.handle.expect( [ command, 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 ) )
343 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700344 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800345 main.log.error(
346 self.name +
347 ": timeout when waiting for response from mininet" )
348 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700349 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800350 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800351 main.log.error( self.name + ": EOF exception found" )
352 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700353 main.cleanup()
354 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800355 main.log.info( self.name + ": Ping Response: " + response )
356 if re.search( ',\s0\%\spacket\sloss', response ):
357 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700359 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800360 else:
361 main.log.error(
362 self.name +
363 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800364 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700365 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800366
Jon Hall7eb38402015-01-08 17:19:54 -0800367 def checkIP( self, host ):
368 """
369 Verifies the host's ip configured or not."""
370 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700371 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800372 response = self.execute(
373 cmd=host +
374 " ifconfig",
375 prompt="mininet>",
376 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800377 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800378 main.log.error( self.name + ": EOF exception found" )
379 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700380 main.cleanup()
381 main.exit()
adminbae64d82013-08-01 10:50:15 -0700382
Jon Hall7eb38402015-01-08 17:19:54 -0800383 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800384 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
385 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
386 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
387 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
388 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800389 # pattern = "inet addr:10.0.0.6"
390 if re.search( pattern, response ):
391 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700392 return main.TRUE
393 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800394 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700395 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800396 else:
397 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800398
Jon Hall7eb38402015-01-08 17:19:54 -0800399 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700400 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800401 response = self.execute(
402 cmd="h1 /usr/sbin/sshd -D&",
403 prompt="mininet>",
404 timeout=10 )
405 response = self.execute(
406 cmd="h4 /usr/sbin/sshd -D&",
407 prompt="mininet>",
408 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700409 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800410 vars( self )[ key ] = connectargs[ key ]
411 response = self.execute(
412 cmd="xterm h1 h4 ",
413 prompt="mininet>",
414 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800415 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800416 main.log.error( self.name + ": EOF exception found" )
417 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700418 main.cleanup()
419 main.exit()
adminbae64d82013-08-01 10:50:15 -0700420 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800421 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700422 if self.flag == 0:
423 self.flag = 1
424 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800425 else:
adminbae64d82013-08-01 10:50:15 -0700426 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800427
kelvin-onlaba1484582015-02-02 15:46:20 -0800428 def moveHost( self, host, oldSw, newSw, ):
429 """
430 Moves a host from one switch to another on the fly
431 Note: The intf between host and oldSw when detached
432 using detach(), will still show up in the 'net'
433 cmd, because switch.detach() doesn't affect switch.intfs[]
434 (which is correct behavior since the interfaces
435 haven't moved).
436 """
437 if self.handle:
438 try:
439 # Bring link between oldSw-host down
440 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
441 "'down')"
442 print "cmd1= ", cmd
443 response = self.execute(
444 cmd=cmd,
445 prompt="mininet>",
446 timeout=10 )
447
448 # Determine hostintf and Oldswitchintf
449 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
450 ")[0]"
451 print "cmd2= ", cmd
452 self.handle.sendline( cmd )
453 self.handle.expect( "mininet>" )
454
shahshreya73537862015-02-11 15:15:24 -0800455 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800456 cmd = "px ipaddr = hintf.IP()"
457 print "cmd3= ", cmd
458 self.handle.sendline( cmd )
459 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800460
461 cmd = "px macaddr = hintf.MAC()"
462 print "cmd3= ", cmd
463 self.handle.sendline( cmd )
464 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800465
466 # Detach interface between oldSw-host
467 cmd = "px " + oldSw + ".detach( sintf )"
468 print "cmd4= ", cmd
469 self.handle.sendline( cmd )
470 self.handle.expect( "mininet>" )
471
472 # Add link between host-newSw
473 cmd = "py net.addLink(" + host + "," + newSw + ")"
474 print "cmd5= ", cmd
475 self.handle.sendline( cmd )
476 self.handle.expect( "mininet>" )
477
478 # Determine hostintf and Newswitchintf
479 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
480 ")[0]"
481 print "cmd6= ", cmd
482 self.handle.sendline( cmd )
483 self.handle.expect( "mininet>" )
484
485 # Attach interface between newSw-host
486 cmd = "px " + newSw + ".attach( sintf )"
487 print "cmd3= ", cmd
488 self.handle.sendline( cmd )
489 self.handle.expect( "mininet>" )
490
491 # Set ipaddress of the host-newSw interface
492 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
493 print "cmd7 = ", cmd
494 self.handle.sendline( cmd )
495 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800496
497 # Set macaddress of the host-newSw interface
498 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
499 print "cmd8 = ", cmd
500 self.handle.sendline( cmd )
501 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800502
503 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800504 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800505 self.handle.sendline( cmd )
506 self.handle.expect( "mininet>" )
507 print "output = ", self.handle.before
508
509 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800510 cmd = host + " ifconfig"
511 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800512 self.handle.sendline( cmd )
513 self.handle.expect( "mininet>" )
514 print "ifconfig o/p = ", self.handle.before
515
516 return main.TRUE
517 except pexpect.EOF:
518 main.log.error( self.name + ": EOF exception found" )
519 main.log.error( self.name + ": " + self.handle.before )
520 return main.FALSE
521
Jon Hall7eb38402015-01-08 17:19:54 -0800522 def changeIP( self, host, intf, newIP, newNetmask ):
523 """
524 Changes the ip address of a host on the fly
525 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800526 if self.handle:
527 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800528 cmd = host + " ifconfig " + intf + " " + \
529 newIP + " " + 'netmask' + " " + newNetmask
530 self.handle.sendline( cmd )
531 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800532 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800533 main.log.info( "response = " + response )
534 main.log.info(
535 "Ip of host " +
536 host +
537 " changed to new IP " +
538 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800539 return main.TRUE
540 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800541 main.log.error( self.name + ": EOF exception found" )
542 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800543 return main.FALSE
544
Jon Hall7eb38402015-01-08 17:19:54 -0800545 def changeDefaultGateway( self, host, newGW ):
546 """
547 Changes the default gateway of a host
548 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800549 if self.handle:
550 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800551 cmd = host + " route add default gw " + newGW
552 self.handle.sendline( cmd )
553 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800554 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800555 main.log.info( "response = " + response )
556 main.log.info(
557 "Default gateway of host " +
558 host +
559 " changed to " +
560 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800561 return main.TRUE
562 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800563 main.log.error( self.name + ": EOF exception found" )
564 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800565 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800566
Jon Hall7eb38402015-01-08 17:19:54 -0800567 def addStaticMACAddress( self, host, GW, macaddr ):
568 """
569 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800570 if self.handle:
571 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800572 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
573 cmd = host + " arp -s " + GW + " " + macaddr
574 self.handle.sendline( cmd )
575 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800576 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800577 main.log.info( "response = " + response )
578 main.log.info(
579 "Mac adrress of gateway " +
580 GW +
581 " changed to " +
582 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800583 return main.TRUE
584 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800585 main.log.error( self.name + ": EOF exception found" )
586 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800587 return main.FALSE
588
Jon Hall7eb38402015-01-08 17:19:54 -0800589 def verifyStaticGWandMAC( self, host ):
590 """
591 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800592 if self.handle:
593 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800594 # h1 arp -an
595 cmd = host + " arp -an "
596 self.handle.sendline( cmd )
597 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800598 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800599 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800600 return main.TRUE
601 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800602 main.log.error( self.name + ": EOF exception found" )
603 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800604 return main.FALSE
605
Jon Hall7eb38402015-01-08 17:19:54 -0800606 def getMacAddress( self, host ):
607 """
608 Verifies the host's ip configured or not."""
609 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700610 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800611 response = self.execute(
612 cmd=host +
613 " ifconfig",
614 prompt="mininet>",
615 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800616 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800617 main.log.error( self.name + ": EOF exception found" )
618 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700619 main.cleanup()
620 main.exit()
adminbae64d82013-08-01 10:50:15 -0700621
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700622 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 macAddressSearch = re.search( pattern, response, re.I )
624 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800625 main.log.info(
626 self.name +
627 ": Mac-Address of Host " +
628 host +
629 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 macAddress )
631 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700632 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800633 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700634
Jon Hall7eb38402015-01-08 17:19:54 -0800635 def getInterfaceMACAddress( self, host, interface ):
636 """
637 Return the IP address of the interface on the given host"""
638 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700639 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800640 response = self.execute( cmd=host + " ifconfig " + interface,
641 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800642 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
645 main.cleanup()
646 main.exit()
647
648 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 macAddressSearch = re.search( pattern, response, re.I )
650 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800651 main.log.info( "No mac address found in %s" % response )
652 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800653 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800654 main.log.info(
655 "Mac-Address of " +
656 host +
657 ":" +
658 interface +
659 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 macAddress )
661 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800662 else:
663 main.log.error( "Connection failed to the host" )
664
665 def getIPAddress( self, host ):
666 """
667 Verifies the host's ip configured or not."""
668 if self.handle:
669 try:
670 response = self.execute(
671 cmd=host +
672 " ifconfig",
673 prompt="mininet>",
674 timeout=10 )
675 except pexpect.EOF:
676 main.log.error( self.name + ": EOF exception found" )
677 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700678 main.cleanup()
679 main.exit()
adminbae64d82013-08-01 10:50:15 -0700680
681 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800683 main.log.info(
684 self.name +
685 ": IP-Address of Host " +
686 host +
687 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 ipAddressSearch.group( 1 ) )
689 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800690 else:
691 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800692
Jon Hall7eb38402015-01-08 17:19:54 -0800693 def getSwitchDPID( self, switch ):
694 """
695 return the datapath ID of the switch"""
696 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700697 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700698 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800699 response = self.execute(
700 cmd=cmd,
701 prompt="mininet>",
702 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800703 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800704 main.log.error( self.name + ": EOF exception found" )
705 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700706 main.cleanup()
707 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800708 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800709 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700710 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 main.log.info(
712 "Couldn't find DPID for switch %s, found: %s" %
713 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700714 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800715 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700716 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800717 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700718
Jon Hall7eb38402015-01-08 17:19:54 -0800719 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700720 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800721 self.handle.sendline( "" )
722 self.expect( "mininet>" )
723 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700724 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800725 response = self.execute(
726 cmd=cmd,
727 prompt="mininet>",
728 timeout=10 )
729 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700730 response = self.handle.before
731 return response
732 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700735 main.cleanup()
736 main.exit()
737
Jon Hall7eb38402015-01-08 17:19:54 -0800738 def getInterfaces( self, node ):
739 """
740 return information dict about interfaces connected to the node"""
741 if self.handle:
742 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800743 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700744 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700745 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 response = self.execute(
747 cmd=cmd,
748 prompt="mininet>",
749 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800750 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700753 main.cleanup()
754 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700755 return response
756 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800757 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700758
Jon Hall7eb38402015-01-08 17:19:54 -0800759 def dump( self ):
760 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700761 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800762 response = self.execute(
763 cmd='dump',
764 prompt='mininet>',
765 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800766 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800767 main.log.error( self.name + ": EOF exception found" )
768 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700769 main.cleanup()
770 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700771 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800772
Jon Hall7eb38402015-01-08 17:19:54 -0800773 def intfs( self ):
774 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700775 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800776 response = self.execute(
777 cmd='intfs',
778 prompt='mininet>',
779 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800780 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800781 main.log.error( self.name + ": EOF exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700783 main.cleanup()
784 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700785 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800786
Jon Hall7eb38402015-01-08 17:19:54 -0800787 def net( self ):
788 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700789 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800790 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800791 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800792 main.log.error( self.name + ": EOF exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700794 main.cleanup()
795 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700796 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800797
798 def iperf( self, host1, host2 ):
799 main.log.info(
800 self.name +
801 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700802 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800803 cmd1 = 'iperf ' + host1 + " " + host2
804 self.handle.sendline( cmd1 )
805 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800806 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800807 if re.search( 'Results:', response ):
808 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800809 return main.TRUE
810 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800811 main.log.error( self.name + ": iperf test failed" )
812 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800813 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 main.log.error( self.name + ": EOF exception found" )
815 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800816 main.cleanup()
817 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800818
Jon Hall7eb38402015-01-08 17:19:54 -0800819 def iperfudp( self ):
820 main.log.info(
821 self.name +
822 ": Simple iperf TCP test between two " +
823 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700824 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800825 response = self.execute(
826 cmd='iperfudp',
827 prompt='mininet>',
828 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800829 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800830 main.log.error( self.name + ": EOF exception found" )
831 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700832 main.cleanup()
833 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700834 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800835
Jon Hall7eb38402015-01-08 17:19:54 -0800836 def nodes( self ):
837 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700838 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800839 response = self.execute(
840 cmd='nodes',
841 prompt='mininet>',
842 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800843 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800844 main.log.error( self.name + ": EOF exception found" )
845 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700846 main.cleanup()
847 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700848 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800849
Jon Hall7eb38402015-01-08 17:19:54 -0800850 def pingpair( self ):
851 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700852 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800853 response = self.execute(
854 cmd='pingpair',
855 prompt='mininet>',
856 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800857 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800858 main.log.error( self.name + ": EOF exception found" )
859 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700860 main.cleanup()
861 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800862
Jon Hall7eb38402015-01-08 17:19:54 -0800863 if re.search( ',\s0\%\spacket\sloss', response ):
864 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700866 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800867 else:
868 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700870 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800871
Jon Hall7eb38402015-01-08 17:19:54 -0800872 def link( self, **linkargs ):
873 """
874 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800875 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800876 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
877 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
878 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
879 main.log.info(
880 "Bring link between '" +
881 end1 +
882 "' and '" +
883 end2 +
884 "' '" +
885 option +
886 "'" )
887 command = "link " + \
888 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700889 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800890 self.handle.sendline( command )
891 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800892 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800893 main.log.error( self.name + ": EOF exception found" )
894 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700895 main.cleanup()
896 main.exit()
adminbae64d82013-08-01 10:50:15 -0700897 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800898
Jon Hall7eb38402015-01-08 17:19:54 -0800899 def yank( self, **yankargs ):
900 """
901 yank a mininet switch interface to a host"""
902 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800903 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800904 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
905 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
906 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700907 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800908 response = self.execute(
909 cmd=command,
910 prompt="mininet>",
911 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800912 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800913 main.log.error( self.name + ": EOF exception found" )
914 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700915 main.cleanup()
916 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700917 return main.TRUE
918
Jon Hall7eb38402015-01-08 17:19:54 -0800919 def plug( self, **plugargs ):
920 """
921 plug the yanked mininet switch interface to a switch"""
922 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800923 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800924 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
925 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
926 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700927 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800928 response = self.execute(
929 cmd=command,
930 prompt="mininet>",
931 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800932 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800933 main.log.error( self.name + ": EOF exception found" )
934 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700935 main.cleanup()
936 main.exit()
adminbae64d82013-08-01 10:50:15 -0700937 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800938
Jon Hall7eb38402015-01-08 17:19:54 -0800939 def dpctl( self, **dpctlargs ):
940 """
941 Run dpctl command on all switches."""
942 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800943 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800944 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
945 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
946 command = "dpctl " + cmd + " " + str( cmdargs )
947 try:
948 response = self.execute(
949 cmd=command,
950 prompt="mininet>",
951 timeout=10 )
952 except pexpect.EOF:
953 main.log.error( self.name + ": EOF exception found" )
954 main.log.error( self.name + ": " + self.handle.before )
955 main.cleanup()
956 main.exit()
957 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800958
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -0800960 #FIXME: What uses this? This should be refactored to get
961 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800962 fileInput = path + '/lib/Mininet/INSTALL'
963 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700964 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800966 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700967 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800968 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500969 return version
adminbae64d82013-08-01 10:50:15 -0700970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800972 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500973 Parameters:
974 sw: The name of an OVS switch. Example "s1"
975 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800976 The output of the command from the mininet cli
977 or main.FALSE on timeout"""
978 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700979 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800980 response = self.execute(
981 cmd=command,
982 prompt="mininet>",
983 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700984 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500985 return response
admin2a9548d2014-06-17 14:08:07 -0700986 else:
987 return main.FALSE
988 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800989 main.log.error( self.name + ": EOF exception found" )
990 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700991 main.cleanup()
992 main.exit()
adminbae64d82013-08-01 10:50:15 -0700993
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800995 """
996 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800997 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800998 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700999
1000 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001001 for j in range( count ):
1002 argstring = argstring + ",IP" + \
1003 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001004 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001005
Jon Hall7eb38402015-01-08 17:19:54 -08001006 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1007 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001008 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001009 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001010
Jon Hall7eb38402015-01-08 17:19:54 -08001011 command = "sh ovs-vsctl set-controller s" + \
1012 str( sw ) + " " + ptcpB + " "
1013 for j in range( count ):
1014 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001015 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001016 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1017 ip = args[
1018 "IP" +
1019 str( i ) ] if args[
1020 "IP" +
1021 str( i ) ] is not None else ""
1022 port = args[
1023 "PORT" +
1024 str( i ) ] if args[
1025 "PORT" +
1026 str( i ) ] is not None else ""
1027 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001028 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001029 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001030 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001031 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001032 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001033 main.log.error( self.name + ": EOF exception found" )
1034 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001035 main.cleanup()
1036 main.exit()
1037 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001038 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001039 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001040 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001041 main.cleanup()
1042 main.exit()
adminbae64d82013-08-01 10:50:15 -07001043
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001045 """
1046 Removes the controller target from sw"""
1047 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001048 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001049 response = self.execute(
1050 cmd=command,
1051 prompt="mininet>",
1052 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001053 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001054 main.log.error( self.name + ": EOF exception found" )
1055 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001056 main.cleanup()
1057 main.exit()
1058 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001059 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001060
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001062 """
Jon Hallb1290e82014-11-18 16:17:48 -05001063 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001064 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001065 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001066 NOTE: cannot currently specify what type of switch
1067 required params:
1068 switchname = name of the new switch as a string
1069 optional keyvalues:
1070 dpid = "dpid"
1071 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001072 """
1073 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001074 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001075 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001076 response = self.execute(
1077 cmd=command,
1078 prompt="mininet>",
1079 timeout=10 )
1080 if re.search( "already exists!", response ):
1081 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001082 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001083 elif re.search( "Error", response ):
1084 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001085 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001086 elif re.search( "usage:", response ):
1087 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001088 return main.FALSE
1089 else:
1090 return main.TRUE
1091 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001092 main.log.error( self.name + ": EOF exception found" )
1093 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001094 main.cleanup()
1095 main.exit()
1096
kelvin-onlabd3b64892015-01-20 13:26:24 -08001097 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001098 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001099 delete a switch from the mininet topology
1100 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001101 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001102 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001103 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001104 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001105 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001106 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001107 response = self.execute(
1108 cmd=command,
1109 prompt="mininet>",
1110 timeout=10 )
1111 if re.search( "no switch named", response ):
1112 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001113 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001114 elif re.search( "Error", response ):
1115 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001116 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001117 elif re.search( "usage:", response ):
1118 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001119 return main.FALSE
1120 else:
1121 return main.TRUE
1122 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001123 main.log.error( self.name + ": EOF exception found" )
1124 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001125 main.cleanup()
1126 main.exit()
1127
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001129 """
1130 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001131 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001132 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001133 NOTE: cannot currently specify what type of link
1134 required params:
1135 node1 = the string node name of the first endpoint of the link
1136 node2 = the string node name of the second endpoint of the link
1137 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001138 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001139 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001140 response = self.execute(
1141 cmd=command,
1142 prompt="mininet>",
1143 timeout=10 )
1144 if re.search( "doesnt exist!", response ):
1145 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001146 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001147 elif re.search( "Error", response ):
1148 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001149 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001150 elif re.search( "usage:", response ):
1151 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001152 return main.FALSE
1153 else:
1154 return main.TRUE
1155 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001156 main.log.error( self.name + ": EOF exception found" )
1157 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001158 main.cleanup()
1159 main.exit()
1160
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001162 """
1163 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001164 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001165 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001166 required params:
1167 node1 = the string node name of the first endpoint of the link
1168 node2 = the string node name of the second endpoint of the link
1169 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001170 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001171 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001172 response = self.execute(
1173 cmd=command,
1174 prompt="mininet>",
1175 timeout=10 )
1176 if re.search( "no node named", response ):
1177 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001178 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001179 elif re.search( "Error", response ):
1180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001181 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001182 elif re.search( "usage:", response ):
1183 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001184 return main.FALSE
1185 else:
1186 return main.TRUE
1187 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001188 main.log.error( self.name + ": EOF exception found" )
1189 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001190 main.cleanup()
1191 main.exit()
1192
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001194 """
Jon Hallb1290e82014-11-18 16:17:48 -05001195 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001196 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001197 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001198 NOTE: cannot currently specify what type of host
1199 required params:
1200 hostname = the string hostname
1201 optional key-value params
1202 switch = "switch name"
1203 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001204 """
1205 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001206 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001207 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001208 response = self.execute(
1209 cmd=command,
1210 prompt="mininet>",
1211 timeout=10 )
1212 if re.search( "already exists!", response ):
1213 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001214 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001215 elif re.search( "doesnt exists!", response ):
1216 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001217 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001218 elif re.search( "Error", response ):
1219 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001220 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001221 elif re.search( "usage:", response ):
1222 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001223 return main.FALSE
1224 else:
1225 return main.TRUE
1226 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001227 main.log.error( self.name + ": EOF exception found" )
1228 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001229 main.cleanup()
1230 main.exit()
1231
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001233 """
1234 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001235 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001236 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001237 NOTE: this uses a custom mn function
1238 required params:
1239 hostname = the string hostname
1240 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001241 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001242 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001243 response = self.execute(
1244 cmd=command,
1245 prompt="mininet>",
1246 timeout=10 )
1247 if re.search( "no host named", response ):
1248 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001249 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001250 elif re.search( "Error", response ):
1251 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001252 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001253 elif re.search( "usage:", response ):
1254 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001255 return main.FALSE
1256 else:
1257 return main.TRUE
1258 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001261 main.cleanup()
1262 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001263
Jon Hall7eb38402015-01-08 17:19:54 -08001264 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001265 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001266 Called at the end of the test to stop the mininet and
1267 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001268 """
1269 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001270 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
1271 timeout = 2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001272 if i == 0:
1273 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001274 elif i == 1:
1275 return main.TRUE
1276 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001277 # print "Disconnecting Mininet"
1278 if self.handle:
1279 self.handle.sendline( "exit" )
1280 self.handle.expect( "exit" )
1281 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001282 else:
1283 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001284 return response
1285
kelvin-onlab56a3f462015-02-06 14:04:43 -08001286 def stopNet( self , timeout = 5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001287 """
Jon Hall21270ac2015-02-16 17:59:55 -08001288 Stops mininet.
1289 Returns main.TRUE if the mininet succesfully stops and
1290 main.FALSE if the pexpect handle does not exist.
1291
Jon Halld61331b2015-02-17 16:35:47 -08001292 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001293 """
Jon Hall21270ac2015-02-16 17:59:55 -08001294
Jon Halld61331b2015-02-17 16:35:47 -08001295 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001296 response = ''
1297 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001298 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001299 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001300 i = self.handle.expect( [ 'mininet>',
1301 '\$',
1302 pexpect.EOF,
1303 pexpect.TIMEOUT ],
1304 timeout )
1305 if i == 0:
1306 main.log.info( "Exiting mininet..." )
1307
Jon Hall7eb38402015-01-08 17:19:54 -08001308 response = self.execute(
1309 cmd="exit",
1310 prompt="(.*)",
1311 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001312 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001313 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001314 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08001315
1316 if i == 1:
1317 main.log.info( " Mininet trying to exit while not " +
1318 "in the mininet prompt" )
1319 elif i == 2:
1320 main.log.error( "Something went wrong exiting mininet" )
1321 elif i == 3: # timeout
1322 main.log.error( "Something went wrong exiting mininet " +
1323 "TIMEOUT" )
1324
Jon Hallfbc828e2015-01-06 17:30:19 -08001325 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001326 main.log.error( self.name + ": EOF exception found" )
1327 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001328 main.cleanup()
1329 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001330 else:
1331 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001332 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001333 return response
1334
kelvin-onlaba1484582015-02-02 15:46:20 -08001335
1336
Jon Hall7eb38402015-01-08 17:19:54 -08001337 def arping( self, src, dest, destmac ):
1338 self.handle.sendline( '' )
1339 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001340
Jon Hall7eb38402015-01-08 17:19:54 -08001341 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001342 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001343 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1344 main.log.info( self.name + ": ARP successful" )
1345 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001346 return main.TRUE
1347 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001348 main.log.warn( self.name + ": ARP FAILURE" )
1349 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001350 return main.FALSE
1351
Jon Hall7eb38402015-01-08 17:19:54 -08001352 def decToHex( self, num ):
1353 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001354
Jon Hall7eb38402015-01-08 17:19:54 -08001355 def getSwitchFlowCount( self, switch ):
1356 """
1357 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001358 if self.handle:
1359 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1360 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001361 response = self.execute(
1362 cmd=cmd,
1363 prompt="mininet>",
1364 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001365 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.error( self.name + ": EOF exception found" )
1367 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001368 main.cleanup()
1369 main.exit()
1370 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001371 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001372 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001373 main.log.info(
1374 "Couldn't find flows on switch %s, found: %s" %
1375 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001376 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001377 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001378 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001379 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001380
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 def checkFlows( self, sw, dumpFormat=None ):
1382 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001383 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001385 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001387 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001388 response = self.execute(
1389 cmd=command,
1390 prompt="mininet>",
1391 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001392 return response
1393 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001394 main.log.error( self.name + ": EOF exception found" )
1395 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001396 main.cleanup()
1397 main.exit()
1398 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001399 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001400
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001402 """
1403 Runs tpdump on an intferface and saves the file
1404 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001405 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001406 self.handle.sendline( "" )
1407 self.handle.expect( "mininet>" )
1408 self.handle.sendline(
1409 "sh sudo tcpdump -n -i " +
1410 intf +
1411 " " +
1412 port +
1413 " -w " +
1414 filename.strip() +
1415 " &" )
1416 self.handle.sendline( "" )
1417 i = self.handle.expect( [ 'No\ssuch\device',
1418 'listening\son',
1419 pexpect.TIMEOUT,
1420 "mininet>" ],
1421 timeout=10 )
1422 main.log.warn( self.handle.before + self.handle.after )
1423 self.handle.sendline( "" )
1424 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001425 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 main.log.error(
1427 self.name +
1428 ": tcpdump - No such device exists. " +
1429 "tcpdump attempted on: " +
1430 intf )
admin2a9548d2014-06-17 14:08:07 -07001431 return main.FALSE
1432 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001433 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001434 return main.TRUE
1435 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001436 main.log.error(
1437 self.name +
1438 ": tcpdump command timed out! Check interface name," +
1439 " given interface was: " +
1440 intf )
admin2a9548d2014-06-17 14:08:07 -07001441 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001442 elif i == 3:
1443 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001444 return main.TRUE
1445 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001446 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001447 return main.FALSE
1448 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001449 main.log.error( self.name + ": EOF exception found" )
1450 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001451 main.cleanup()
1452 main.exit()
1453 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001454 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001455 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001456 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001457 main.cleanup()
1458 main.exit()
1459
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001461 "pkills tcpdump"
1462 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001463 self.handle.sendline( "sh sudo pkill tcpdump" )
1464 self.handle.expect( "mininet>" )
1465 self.handle.sendline( "" )
1466 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001467 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001468 main.log.error( self.name + ": EOF exception found" )
1469 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001470 main.cleanup()
1471 main.exit()
1472 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001473 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001474 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001475 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001476 main.cleanup()
1477 main.exit()
1478
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001480 """
1481 Compare mn and onos switches
1482 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001484
Jon Hall7eb38402015-01-08 17:19:54 -08001485 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001486 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001487 output = { "switches": [] }
1488 # iterate through the MN topology and pull out switches and and port
1489 # info
1490 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001491 ports = []
1492 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001493 ports.append( { 'of_port': port.port_no,
1494 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001496 'name': port.name } )
1497 output[ 'switches' ].append( {
1498 "name": switch.name,
1499 "dpid": str( switch.dpid ).zfill( 16 ),
1500 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001501
Jon Hall7eb38402015-01-08 17:19:54 -08001502 # print "mn"
1503 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001504 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001505 # indent=4,
1506 # separators=( ',', ': ' ) )
1507 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001509 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001510 # indent=4,
1511 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001512
1513 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001514 mnDPIDs = []
1515 for switch in output[ 'switches' ]:
1516 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001517 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001518 # print "List of Mininet switch DPID's"
1519 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001520 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001521 main.log.error(
1522 self.name +
1523 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001524 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001526 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001527 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001528 if switch[ 'available' ]:
1529 onosDPIDs.append(
1530 switch[ 'id' ].replace(
1531 ":",
1532 '' ).replace(
1533 "of",
1534 '' ).lower() )
1535 # else:
1536 # print "Switch is unavailable:"
1537 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001538 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001539 # print "List of ONOS switch DPID's"
1540 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001541
Jon Hall7eb38402015-01-08 17:19:54 -08001542 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001544 main.log.report( "Switches in MN but not in ONOS:" )
1545 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1546 main.log.report( str( list1 ) )
1547 main.log.report( "Switches in ONOS but not in MN:" )
1548 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001549 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001550 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 switchResults = main.TRUE
1552 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001553
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001555 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001556 Compare mn and onos ports
1557 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001559
Jon Hallfbc828e2015-01-06 17:30:19 -08001560 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001561 1. This uses the sts TestONTopology object
1562 2. numpy - "sudo pip install numpy"
1563
Jon Hall7eb38402015-01-08 17:19:54 -08001564 """
1565 # FIXME: this does not look for extra ports in ONOS, only checks that
1566 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001567 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001569 output = { "switches": [] }
1570 # iterate through the MN topology and pull out switches and and port
1571 # info
1572 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001573 ports = []
1574 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001575 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001577 tmpPort[ 'of_port' ] = port.port_no
1578 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 tmpPort[ 'name' ] = port.name
1580 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001581
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 ports.append( tmpPort )
1583 tmpSwitch = {}
1584 tmpSwitch[ 'name' ] = switch.name
1585 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1586 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001587
kelvin-onlabd3b64892015-01-20 13:26:24 -08001588 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001589
Jon Hall7eb38402015-01-08 17:19:54 -08001590 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 for mnSwitch in output[ 'switches' ]:
1592 mnPorts = []
1593 onosPorts = []
1594 switchResult = main.TRUE
1595 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001596 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 mnPorts.append( port[ 'of_port' ] )
1598 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001599 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 # print onosSwitch
1601 if onosSwitch[ 'device' ][ 'available' ]:
1602 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001603 ':',
1604 '' ).replace(
1605 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 '' ) == mnSwitch[ 'dpid' ]:
1607 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001608 if port[ 'isEnabled' ]:
1609 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 # onosPorts.append( 'local' )
1611 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001612 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001614 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 mnPorts.sort( key=float )
1616 onosPorts.sort( key=float )
1617 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1618 # print "\tmn_ports[] = ", mnPorts
1619 # print "\tonos_ports[] = ", onosPorts
1620 mnPortsLog = mnPorts
1621 onosPortsLog = onosPorts
1622 mnPorts = [ x for x in mnPorts ]
1623 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001624
Jon Hall7eb38402015-01-08 17:19:54 -08001625 # TODO: handle other reserved port numbers besides LOCAL
1626 # NOTE: Reserved ports
1627 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1628 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 for mnPort in mnPortsLog:
1630 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001631 # don't set results to true here as this is just one of
1632 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001633 mnPorts.remove( mnPort )
1634 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001635 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001636 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001637 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 if 65534 in mnPorts:
1639 mnPorts.remove( 65534 )
1640 if long( uint64( -2 ) ) in onosPorts:
1641 onosPorts.remove( long( uint64( -2 ) ) )
1642 if len( mnPorts ): # the ports of this switch don't match
1643 switchResult = main.FALSE
1644 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1645 if len( onosPorts ): # the ports of this switch don't match
1646 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001647 main.log.warn(
1648 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 str( onosPorts ) )
1650 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001651 main.log.report(
1652 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1654 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1655 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1656 portsResults = portsResults and switchResult
1657 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001658
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001660 """
1661 Compare mn and onos links
1662 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001664
Jon Hall7eb38402015-01-08 17:19:54 -08001665 This uses the sts TestONTopology object"""
1666 # FIXME: this does not look for extra links in ONOS, only checks that
1667 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001669 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001671 # iterate through the MN topology and pull out switches and and port
1672 # info
1673 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001674 # print "Iterating though switches as seen by Mininet"
1675 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001676 ports = []
1677 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001678 # print port.hw_addr.toStr( separator='' )
1679 ports.append( { 'of_port': port.port_no,
1680 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001682 'name': port.name } )
1683 output[ 'switches' ].append( {
1684 "name": switch.name,
1685 "dpid": str( switch.dpid ).zfill( 16 ),
1686 "ports": ports } )
1687 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001688
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001690 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001691 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 if 2 * len( mnLinks ) == len( onos ):
1693 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001694 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001695 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001696 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001697 "Mininet has " + str( len( mnLinks ) ) +
1698 " bidirectional links and ONOS has " +
1699 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001700
Jon Hall7eb38402015-01-08 17:19:54 -08001701 # iterate through MN links and check if an ONOS link exists in
1702 # both directions
1703 # NOTE: Will currently only show mn links as down if they are
1704 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001706 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001707 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001708 # print "Link: %s" % link
1709 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001710 node1 = None
1711 port1 = None
1712 node2 = None
1713 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001714 firstDir = main.FALSE
1715 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001716 for switch in output[ 'switches' ]:
1717 # print "Switch: %s" % switch[ 'name' ]
1718 if switch[ 'name' ] == link.node1.name:
1719 node1 = switch[ 'dpid' ]
1720 for port in switch[ 'ports' ]:
1721 if str( port[ 'name' ] ) == str( link.port1 ):
1722 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001723 if node1 is not None and node2 is not None:
1724 break
Jon Hall7eb38402015-01-08 17:19:54 -08001725 if switch[ 'name' ] == link.node2.name:
1726 node2 = switch[ 'dpid' ]
1727 for port in switch[ 'ports' ]:
1728 if str( port[ 'name' ] ) == str( link.port2 ):
1729 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001730 if node1 is not None and node2 is not None:
1731 break
1732
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 for onosLink in onos:
1734 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001735 ":",
1736 '' ).replace(
1737 "of",
1738 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001739 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001740 ":",
1741 '' ).replace(
1742 "of",
1743 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 onosPort1 = onosLink[ 'src' ][ 'port' ]
1745 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001746
Jon Hall72cf1dc2014-10-20 21:04:50 -04001747 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 if str( onosNode1 ) == str( node1 ) and str(
1749 onosNode2 ) == str( node2 ):
1750 if int( onosPort1 ) == int( port1 ) and int(
1751 onosPort2 ) == int( port2 ):
1752 firstDir = 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 ) +
1757 ' between ONOS and MN. When cheking ONOS for ' +
1758 'link %s/%s -> %s/%s' %
1759 ( node1,
1760 port1,
1761 node2,
1762 port2 ) +
1763 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 ( onosNode1,
1765 onosPort1,
1766 onosNode2,
1767 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001768
1769 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 elif ( str( onosNode1 ) == str( node2 ) and
1771 str( onosNode2 ) == str( node1 ) ):
1772 if ( int( onosPort1 ) == int( port2 )
1773 and int( onosPort2 ) == int( port1 ) ):
1774 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001775 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001776 main.log.warn(
1777 'The port numbers do not match for ' +
1778 str( link ) +
1779 ' between ONOS and MN. When cheking ONOS for ' +
1780 'link %s/%s -> %s/%s' %
1781 ( node2,
1782 port2,
1783 node1,
1784 port1 ) +
1785 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 ( onosNode2,
1787 onosPort2,
1788 onosNode1,
1789 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001790 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001791 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001793 main.log.report(
1794 'ONOS does not have the link %s/%s -> %s/%s' %
1795 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001797 main.log.report(
1798 'ONOS does not have the link %s/%s -> %s/%s' %
1799 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001800 linkResults = linkResults and firstDir and secondDir
1801 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001802
Jon Hallff6b4b22015-02-23 09:25:15 -08001803 def compareHosts( self, topo, hostsJson ):
1804 """
1805 Compare mn and onos Hosts.
1806 Since Mininet hosts are quiet, ONOS will only know of them when they
1807 speak. For this reason, we will only check that the hosts in ONOS
1808 stores are in Mininet, and not vice versa.
1809 topo: sts TestONTopology object
1810 hostsJson: parsed json object from the onos hosts api
1811
1812 This uses the sts TestONTopology object"""
1813 import json
1814 hostResults = main.TRUE
1815 hosts = []
1816 # iterate through the MN topology and pull out hosts
1817 for mnHost in topo.graph.hosts:
1818 interfaces = []
1819 for intf in mnHost.interfaces:
1820 interfaces.append( {
1821 "name": intf.name, # str
1822 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1823 # hw_addr is of type EthAddr, Not JSON serializable
1824 "hw_addr": str( intf.hw_addr ) } )
1825 hosts.append( {
1826 "name": mnHost.name, # str
1827 "interfaces": interfaces } ) # list
1828 for onosHost in hostsJson:
1829 onosMAC = onosHost[ 'mac' ].lower()
1830 match = False
1831 for mnHost in hosts:
1832 for mnIntf in mnHost[ 'interfaces' ]:
1833 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1834 match = True
1835 for ip in mnIntf[ 'ips' ]:
1836 if ip in onosHost[ 'ips' ]:
1837 pass # all is well
1838 else:
1839 # misssing ip
1840 main.log.error( "ONOS host " + onosHost[ 'id' ]
1841 + " has a different IP than " +
1842 "the Mininet host." )
1843 output = json.dumps(
1844 onosHost,
1845 sort_keys=True,
1846 indent=4,
1847 separators=( ',', ': ' ) )
1848 main.log.info( output )
1849 hostResults = main.FALSE
1850 if not match:
1851 hostResults = main.FALSE
1852 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1853 "corresponding Mininet host." )
1854 output = json.dumps( onosHost,
1855 sort_keys=True,
1856 indent=4,
1857 separators=( ',', ': ' ) )
1858 main.log.info( output )
1859 # DEBUG
1860 main.log.debug( "mn hosts" )
1861 for h in hosts:
1862 main.log.debug( h )
1863 main.log.debug( "onos hosts" )
1864 main.log.debug( hostsJson )
1865 # /DEBUG
1866 return hostResults
1867
kelvin-onlabd3b64892015-01-20 13:26:24 -08001868 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001869 """
1870 Returns a list of all hosts
1871 Don't ask questions just use it"""
1872 self.handle.sendline( "" )
1873 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001874
Jon Hall7eb38402015-01-08 17:19:54 -08001875 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1876 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001877
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 handlePy = self.handle.before
1879 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1880 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001881
Jon Hall7eb38402015-01-08 17:19:54 -08001882 self.handle.sendline( "" )
1883 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001884
kelvin-onlabd3b64892015-01-20 13:26:24 -08001885 hostStr = handlePy.replace( "]", "" )
1886 hostStr = hostStr.replace( "'", "" )
1887 hostStr = hostStr.replace( "[", "" )
1888 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001889
kelvin-onlabd3b64892015-01-20 13:26:24 -08001890 return hostList
adminbae64d82013-08-01 10:50:15 -07001891
Jon Hall7eb38402015-01-08 17:19:54 -08001892 def update( self ):
1893 """
1894 updates the port address and status information for
1895 each port in mn"""
1896 # TODO: Add error checking. currently the mininet command has no output
1897 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001898 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001899 self.handle.sendline( "" )
1900 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001901
Jon Hall7eb38402015-01-08 17:19:54 -08001902 self.handle.sendline( "update" )
1903 self.handle.expect( "update" )
1904 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001905
Jon Hall7eb38402015-01-08 17:19:54 -08001906 self.handle.sendline( "" )
1907 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001908
Jon Hallb1290e82014-11-18 16:17:48 -05001909 return main.TRUE
1910 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001911 main.log.error( self.name + ": EOF exception found" )
1912 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001913 main.cleanup()
1914 main.exit()
1915
adminbae64d82013-08-01 10:50:15 -07001916if __name__ != "__main__":
1917 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001918 sys.modules[ __name__ ] = MininetCliDriver()