blob: fbd863e643bfa5fd8f53d75f59274f0290471d5b [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 )
86 msin.log.error( "Failed to connect to the Mininet CLI" )
87 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 ):
960 fileInput = path + '/lib/Mininet/INSTALL'
961 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700962 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800964 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700965 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800966 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500967 return version
adminbae64d82013-08-01 10:50:15 -0700968
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800970 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500971 Parameters:
972 sw: The name of an OVS switch. Example "s1"
973 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800974 The output of the command from the mininet cli
975 or main.FALSE on timeout"""
976 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700977 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800978 response = self.execute(
979 cmd=command,
980 prompt="mininet>",
981 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700982 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500983 return response
admin2a9548d2014-06-17 14:08:07 -0700984 else:
985 return main.FALSE
986 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700989 main.cleanup()
990 main.exit()
adminbae64d82013-08-01 10:50:15 -0700991
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800993 """
994 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800995 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800996 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700997
998 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800999 for j in range( count ):
1000 argstring = argstring + ",IP" + \
1001 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001002 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001003
Jon Hall7eb38402015-01-08 17:19:54 -08001004 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1005 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001006 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001007 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001008
Jon Hall7eb38402015-01-08 17:19:54 -08001009 command = "sh ovs-vsctl set-controller s" + \
1010 str( sw ) + " " + ptcpB + " "
1011 for j in range( count ):
1012 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001013 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001014 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1015 ip = args[
1016 "IP" +
1017 str( i ) ] if args[
1018 "IP" +
1019 str( i ) ] is not None else ""
1020 port = args[
1021 "PORT" +
1022 str( i ) ] if args[
1023 "PORT" +
1024 str( i ) ] is not None else ""
1025 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001026 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001027 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001028 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001029 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001030 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001031 main.log.error( self.name + ": EOF exception found" )
1032 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001033 main.cleanup()
1034 main.exit()
1035 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001036 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001037 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001038 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001039 main.cleanup()
1040 main.exit()
adminbae64d82013-08-01 10:50:15 -07001041
kelvin-onlabd3b64892015-01-20 13:26:24 -08001042 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001043 """
1044 Removes the controller target from sw"""
1045 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001046 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001047 response = self.execute(
1048 cmd=command,
1049 prompt="mininet>",
1050 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001051 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001052 main.log.error( self.name + ": EOF exception found" )
1053 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001054 main.cleanup()
1055 main.exit()
1056 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001057 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001058
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001060 """
Jon Hallb1290e82014-11-18 16:17:48 -05001061 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001062 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001063 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001064 NOTE: cannot currently specify what type of switch
1065 required params:
1066 switchname = name of the new switch as a string
1067 optional keyvalues:
1068 dpid = "dpid"
1069 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001070 """
1071 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001072 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001073 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001074 response = self.execute(
1075 cmd=command,
1076 prompt="mininet>",
1077 timeout=10 )
1078 if re.search( "already exists!", response ):
1079 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001080 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001081 elif re.search( "Error", response ):
1082 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001083 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001084 elif re.search( "usage:", response ):
1085 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001086 return main.FALSE
1087 else:
1088 return main.TRUE
1089 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001090 main.log.error( self.name + ": EOF exception found" )
1091 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001092 main.cleanup()
1093 main.exit()
1094
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001096 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001097 delete a switch from the mininet topology
1098 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001099 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001100 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001101 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001102 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001103 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001104 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001105 response = self.execute(
1106 cmd=command,
1107 prompt="mininet>",
1108 timeout=10 )
1109 if re.search( "no switch named", response ):
1110 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001111 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001112 elif re.search( "Error", response ):
1113 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001114 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001115 elif re.search( "usage:", response ):
1116 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001117 return main.FALSE
1118 else:
1119 return main.TRUE
1120 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001121 main.log.error( self.name + ": EOF exception found" )
1122 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001123 main.cleanup()
1124 main.exit()
1125
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001127 """
1128 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001129 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001130 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001131 NOTE: cannot currently specify what type of link
1132 required params:
1133 node1 = the string node name of the first endpoint of the link
1134 node2 = the string node name of the second endpoint of the link
1135 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001136 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001137 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001138 response = self.execute(
1139 cmd=command,
1140 prompt="mininet>",
1141 timeout=10 )
1142 if re.search( "doesnt exist!", response ):
1143 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001144 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001145 elif re.search( "Error", response ):
1146 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001147 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001148 elif re.search( "usage:", response ):
1149 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001150 return main.FALSE
1151 else:
1152 return main.TRUE
1153 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001154 main.log.error( self.name + ": EOF exception found" )
1155 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001156 main.cleanup()
1157 main.exit()
1158
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001160 """
1161 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001162 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001163 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001164 required params:
1165 node1 = the string node name of the first endpoint of the link
1166 node2 = the string node name of the second endpoint of the link
1167 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001168 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001169 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001170 response = self.execute(
1171 cmd=command,
1172 prompt="mininet>",
1173 timeout=10 )
1174 if re.search( "no node named", response ):
1175 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001176 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001177 elif re.search( "Error", response ):
1178 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001179 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001180 elif re.search( "usage:", response ):
1181 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001182 return main.FALSE
1183 else:
1184 return main.TRUE
1185 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001188 main.cleanup()
1189 main.exit()
1190
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001192 """
Jon Hallb1290e82014-11-18 16:17:48 -05001193 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001194 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001195 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001196 NOTE: cannot currently specify what type of host
1197 required params:
1198 hostname = the string hostname
1199 optional key-value params
1200 switch = "switch name"
1201 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001202 """
1203 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001204 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001205 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001206 response = self.execute(
1207 cmd=command,
1208 prompt="mininet>",
1209 timeout=10 )
1210 if re.search( "already exists!", response ):
1211 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001212 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001213 elif re.search( "doesnt exists!", response ):
1214 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001215 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001216 elif re.search( "Error", response ):
1217 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001218 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001219 elif re.search( "usage:", response ):
1220 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001221 return main.FALSE
1222 else:
1223 return main.TRUE
1224 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001225 main.log.error( self.name + ": EOF exception found" )
1226 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001227 main.cleanup()
1228 main.exit()
1229
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001231 """
1232 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001233 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001234 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001235 NOTE: this uses a custom mn function
1236 required params:
1237 hostname = the string hostname
1238 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001239 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001240 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 response = self.execute(
1242 cmd=command,
1243 prompt="mininet>",
1244 timeout=10 )
1245 if re.search( "no host named", response ):
1246 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001247 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001248 elif re.search( "Error", response ):
1249 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001250 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001251 elif re.search( "usage:", response ):
1252 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001253 return main.FALSE
1254 else:
1255 return main.TRUE
1256 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001257 main.log.error( self.name + ": EOF exception found" )
1258 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001259 main.cleanup()
1260 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001261
Jon Hall7eb38402015-01-08 17:19:54 -08001262 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001263 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001264 Called at the end of the test to stop the mininet and
1265 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001266 """
1267 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001268 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
1269 timeout = 2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001270 if i == 0:
1271 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001272 elif i == 1:
1273 return main.TRUE
1274 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001275 # print "Disconnecting Mininet"
1276 if self.handle:
1277 self.handle.sendline( "exit" )
1278 self.handle.expect( "exit" )
1279 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001280 else:
1281 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001282 return response
1283
kelvin-onlab56a3f462015-02-06 14:04:43 -08001284 def stopNet( self , timeout = 5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001285 """
Jon Hall21270ac2015-02-16 17:59:55 -08001286 Stops mininet.
1287 Returns main.TRUE if the mininet succesfully stops and
1288 main.FALSE if the pexpect handle does not exist.
1289
Jon Halld61331b2015-02-17 16:35:47 -08001290 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001291 """
Jon Hall21270ac2015-02-16 17:59:55 -08001292
Jon Halld61331b2015-02-17 16:35:47 -08001293 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001294 response = ''
1295 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001296 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001297 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001298 i = self.handle.expect( [ 'mininet>',
1299 '\$',
1300 pexpect.EOF,
1301 pexpect.TIMEOUT ],
1302 timeout )
1303 if i == 0:
1304 main.log.info( "Exiting mininet..." )
1305
Jon Hall7eb38402015-01-08 17:19:54 -08001306 response = self.execute(
1307 cmd="exit",
1308 prompt="(.*)",
1309 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001310 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001311 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001312 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08001313
1314 if i == 1:
1315 main.log.info( " Mininet trying to exit while not " +
1316 "in the mininet prompt" )
1317 elif i == 2:
1318 main.log.error( "Something went wrong exiting mininet" )
1319 elif i == 3: # timeout
1320 main.log.error( "Something went wrong exiting mininet " +
1321 "TIMEOUT" )
1322
Jon Hallfbc828e2015-01-06 17:30:19 -08001323 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001324 main.log.error( self.name + ": EOF exception found" )
1325 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001326 main.cleanup()
1327 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001328 else:
1329 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001330 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001331 return response
1332
kelvin-onlaba1484582015-02-02 15:46:20 -08001333
1334
Jon Hall7eb38402015-01-08 17:19:54 -08001335 def arping( self, src, dest, destmac ):
1336 self.handle.sendline( '' )
1337 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001338
Jon Hall7eb38402015-01-08 17:19:54 -08001339 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001340 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001341 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1342 main.log.info( self.name + ": ARP successful" )
1343 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001344 return main.TRUE
1345 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001346 main.log.warn( self.name + ": ARP FAILURE" )
1347 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001348 return main.FALSE
1349
Jon Hall7eb38402015-01-08 17:19:54 -08001350 def decToHex( self, num ):
1351 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001352
Jon Hall7eb38402015-01-08 17:19:54 -08001353 def getSwitchFlowCount( self, switch ):
1354 """
1355 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001356 if self.handle:
1357 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1358 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001359 response = self.execute(
1360 cmd=cmd,
1361 prompt="mininet>",
1362 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001363 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001364 main.log.error( self.name + ": EOF exception found" )
1365 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001366 main.cleanup()
1367 main.exit()
1368 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001369 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001370 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 main.log.info(
1372 "Couldn't find flows on switch %s, found: %s" %
1373 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001374 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001375 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001376 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001377 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001378
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 def checkFlows( self, sw, dumpFormat=None ):
1380 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001383 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001384 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001385 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 response = self.execute(
1387 cmd=command,
1388 prompt="mininet>",
1389 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001390 return response
1391 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001392 main.log.error( self.name + ": EOF exception found" )
1393 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001394 main.cleanup()
1395 main.exit()
1396 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001397 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001398
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001400 """
1401 Runs tpdump on an intferface and saves the file
1402 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001403 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001404 self.handle.sendline( "" )
1405 self.handle.expect( "mininet>" )
1406 self.handle.sendline(
1407 "sh sudo tcpdump -n -i " +
1408 intf +
1409 " " +
1410 port +
1411 " -w " +
1412 filename.strip() +
1413 " &" )
1414 self.handle.sendline( "" )
1415 i = self.handle.expect( [ 'No\ssuch\device',
1416 'listening\son',
1417 pexpect.TIMEOUT,
1418 "mininet>" ],
1419 timeout=10 )
1420 main.log.warn( self.handle.before + self.handle.after )
1421 self.handle.sendline( "" )
1422 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001423 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 main.log.error(
1425 self.name +
1426 ": tcpdump - No such device exists. " +
1427 "tcpdump attempted on: " +
1428 intf )
admin2a9548d2014-06-17 14:08:07 -07001429 return main.FALSE
1430 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001431 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001432 return main.TRUE
1433 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001434 main.log.error(
1435 self.name +
1436 ": tcpdump command timed out! Check interface name," +
1437 " given interface was: " +
1438 intf )
admin2a9548d2014-06-17 14:08:07 -07001439 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001440 elif i == 3:
1441 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001442 return main.TRUE
1443 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001444 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001445 return main.FALSE
1446 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001447 main.log.error( self.name + ": EOF exception found" )
1448 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001449 main.cleanup()
1450 main.exit()
1451 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001452 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001453 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001454 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001455 main.cleanup()
1456 main.exit()
1457
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001459 "pkills tcpdump"
1460 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001461 self.handle.sendline( "sh sudo pkill tcpdump" )
1462 self.handle.expect( "mininet>" )
1463 self.handle.sendline( "" )
1464 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001465 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001466 main.log.error( self.name + ": EOF exception found" )
1467 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001468 main.cleanup()
1469 main.exit()
1470 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001471 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001472 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001473 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001474 main.cleanup()
1475 main.exit()
1476
kelvin-onlabd3b64892015-01-20 13:26:24 -08001477 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001478 """
1479 Compare mn and onos switches
1480 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001482
Jon Hall7eb38402015-01-08 17:19:54 -08001483 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001485 output = { "switches": [] }
1486 # iterate through the MN topology and pull out switches and and port
1487 # info
1488 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001489 ports = []
1490 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001491 ports.append( { 'of_port': port.port_no,
1492 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001494 'name': port.name } )
1495 output[ 'switches' ].append( {
1496 "name": switch.name,
1497 "dpid": str( switch.dpid ).zfill( 16 ),
1498 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001499
Jon Hall7eb38402015-01-08 17:19:54 -08001500 # print "mn"
1501 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001503 # indent=4,
1504 # separators=( ',', ': ' ) )
1505 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 # print json.dumps( switchesJson,
1507 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001508 # indent=4,
1509 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001510
1511 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001512 mnDPIDs = []
1513 for switch in output[ 'switches' ]:
1514 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001515 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001516 # print "List of Mininet switch DPID's"
1517 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001519 main.log.error(
1520 self.name +
1521 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001522 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001524 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001525 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001526 if switch[ 'available' ]:
1527 onosDPIDs.append(
1528 switch[ 'id' ].replace(
1529 ":",
1530 '' ).replace(
1531 "of",
1532 '' ).lower() )
1533 # else:
1534 # print "Switch is unavailable:"
1535 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001536 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001537 # print "List of ONOS switch DPID's"
1538 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001539
Jon Hall7eb38402015-01-08 17:19:54 -08001540 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001542 main.log.report( "Switches in MN but not in ONOS:" )
1543 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1544 main.log.report( str( list1 ) )
1545 main.log.report( "Switches in ONOS but not in MN:" )
1546 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001547 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001548 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 switchResults = main.TRUE
1550 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001551
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001553 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001554 Compare mn and onos ports
1555 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001557
Jon Hallfbc828e2015-01-06 17:30:19 -08001558 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001559 1. This uses the sts TestONTopology object
1560 2. numpy - "sudo pip install numpy"
1561
Jon Hall7eb38402015-01-08 17:19:54 -08001562 """
1563 # FIXME: this does not look for extra ports in ONOS, only checks that
1564 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001565 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001567 output = { "switches": [] }
1568 # iterate through the MN topology and pull out switches and and port
1569 # info
1570 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001571 ports = []
1572 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001573 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001575 tmpPort[ 'of_port' ] = port.port_no
1576 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 tmpPort[ 'name' ] = port.name
1578 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001579
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 ports.append( tmpPort )
1581 tmpSwitch = {}
1582 tmpSwitch[ 'name' ] = switch.name
1583 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1584 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001585
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001587
Jon Hall7eb38402015-01-08 17:19:54 -08001588 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 for mnSwitch in output[ 'switches' ]:
1590 mnPorts = []
1591 onosPorts = []
1592 switchResult = main.TRUE
1593 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001594 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 mnPorts.append( port[ 'of_port' ] )
1596 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001597 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001598 # print onosSwitch
1599 if onosSwitch[ 'device' ][ 'available' ]:
1600 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001601 ':',
1602 '' ).replace(
1603 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 '' ) == mnSwitch[ 'dpid' ]:
1605 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001606 if port[ 'isEnabled' ]:
1607 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 # onosPorts.append( 'local' )
1609 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001610 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001612 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 mnPorts.sort( key=float )
1614 onosPorts.sort( key=float )
1615 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1616 # print "\tmn_ports[] = ", mnPorts
1617 # print "\tonos_ports[] = ", onosPorts
1618 mnPortsLog = mnPorts
1619 onosPortsLog = onosPorts
1620 mnPorts = [ x for x in mnPorts ]
1621 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001622
Jon Hall7eb38402015-01-08 17:19:54 -08001623 # TODO: handle other reserved port numbers besides LOCAL
1624 # NOTE: Reserved ports
1625 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1626 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 for mnPort in mnPortsLog:
1628 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001629 # don't set results to true here as this is just one of
1630 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001631 mnPorts.remove( mnPort )
1632 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001633 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001634 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001635 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 if 65534 in mnPorts:
1637 mnPorts.remove( 65534 )
1638 if long( uint64( -2 ) ) in onosPorts:
1639 onosPorts.remove( long( uint64( -2 ) ) )
1640 if len( mnPorts ): # the ports of this switch don't match
1641 switchResult = main.FALSE
1642 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1643 if len( onosPorts ): # the ports of this switch don't match
1644 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001645 main.log.warn(
1646 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001647 str( onosPorts ) )
1648 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001649 main.log.report(
1650 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1652 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1653 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1654 portsResults = portsResults and switchResult
1655 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001656
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001658 """
1659 Compare mn and onos links
1660 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001662
Jon Hall7eb38402015-01-08 17:19:54 -08001663 This uses the sts TestONTopology object"""
1664 # FIXME: this does not look for extra links in ONOS, only checks that
1665 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001666 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001667 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001669 # iterate through the MN topology and pull out switches and and port
1670 # info
1671 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001672 # print "Iterating though switches as seen by Mininet"
1673 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001674 ports = []
1675 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001676 # print port.hw_addr.toStr( separator='' )
1677 ports.append( { 'of_port': port.port_no,
1678 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001680 'name': port.name } )
1681 output[ 'switches' ].append( {
1682 "name": switch.name,
1683 "dpid": str( switch.dpid ).zfill( 16 ),
1684 "ports": ports } )
1685 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001686
kelvin-onlabd3b64892015-01-20 13:26:24 -08001687 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001688 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001689 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001690 if 2 * len( mnLinks ) == len( onos ):
1691 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001692 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001693 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001694 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001695 "Mininet has " + str( len( mnLinks ) ) +
1696 " bidirectional links and ONOS has " +
1697 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001698
Jon Hall7eb38402015-01-08 17:19:54 -08001699 # iterate through MN links and check if an ONOS link exists in
1700 # both directions
1701 # NOTE: Will currently only show mn links as down if they are
1702 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001704 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001706 # print "Link: %s" % link
1707 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001708 node1 = None
1709 port1 = None
1710 node2 = None
1711 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001712 firstDir = main.FALSE
1713 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001714 for switch in output[ 'switches' ]:
1715 # print "Switch: %s" % switch[ 'name' ]
1716 if switch[ 'name' ] == link.node1.name:
1717 node1 = switch[ 'dpid' ]
1718 for port in switch[ 'ports' ]:
1719 if str( port[ 'name' ] ) == str( link.port1 ):
1720 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001721 if node1 is not None and node2 is not None:
1722 break
Jon Hall7eb38402015-01-08 17:19:54 -08001723 if switch[ 'name' ] == link.node2.name:
1724 node2 = switch[ 'dpid' ]
1725 for port in switch[ 'ports' ]:
1726 if str( port[ 'name' ] ) == str( link.port2 ):
1727 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001728 if node1 is not None and node2 is not None:
1729 break
1730
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 for onosLink in onos:
1732 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001733 ":",
1734 '' ).replace(
1735 "of",
1736 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001737 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001738 ":",
1739 '' ).replace(
1740 "of",
1741 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 onosPort1 = onosLink[ 'src' ][ 'port' ]
1743 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001744
Jon Hall72cf1dc2014-10-20 21:04:50 -04001745 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001746 if str( onosNode1 ) == str( node1 ) and str(
1747 onosNode2 ) == str( node2 ):
1748 if int( onosPort1 ) == int( port1 ) and int(
1749 onosPort2 ) == int( port2 ):
1750 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001751 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001752 main.log.warn(
1753 'The port numbers do not match for ' +
1754 str( link ) +
1755 ' between ONOS and MN. When cheking ONOS for ' +
1756 'link %s/%s -> %s/%s' %
1757 ( node1,
1758 port1,
1759 node2,
1760 port2 ) +
1761 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001762 ( onosNode1,
1763 onosPort1,
1764 onosNode2,
1765 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001766
1767 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 elif ( str( onosNode1 ) == str( node2 ) and
1769 str( onosNode2 ) == str( node1 ) ):
1770 if ( int( onosPort1 ) == int( port2 )
1771 and int( onosPort2 ) == int( port1 ) ):
1772 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001773 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001774 main.log.warn(
1775 'The port numbers do not match for ' +
1776 str( link ) +
1777 ' between ONOS and MN. When cheking ONOS for ' +
1778 'link %s/%s -> %s/%s' %
1779 ( node2,
1780 port2,
1781 node1,
1782 port1 ) +
1783 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 ( onosNode2,
1785 onosPort2,
1786 onosNode1,
1787 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001788 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001789 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001790 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001791 main.log.report(
1792 'ONOS does not have the link %s/%s -> %s/%s' %
1793 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001794 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001795 main.log.report(
1796 'ONOS does not have the link %s/%s -> %s/%s' %
1797 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001798 linkResults = linkResults and firstDir and secondDir
1799 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001800
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001802 """
1803 Returns a list of all hosts
1804 Don't ask questions just use it"""
1805 self.handle.sendline( "" )
1806 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001807
Jon Hall7eb38402015-01-08 17:19:54 -08001808 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1809 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001810
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 handlePy = self.handle.before
1812 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1813 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001814
Jon Hall7eb38402015-01-08 17:19:54 -08001815 self.handle.sendline( "" )
1816 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001817
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 hostStr = handlePy.replace( "]", "" )
1819 hostStr = hostStr.replace( "'", "" )
1820 hostStr = hostStr.replace( "[", "" )
1821 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001822
kelvin-onlabd3b64892015-01-20 13:26:24 -08001823 return hostList
adminbae64d82013-08-01 10:50:15 -07001824
Jon Hall7eb38402015-01-08 17:19:54 -08001825 def update( self ):
1826 """
1827 updates the port address and status information for
1828 each port in mn"""
1829 # TODO: Add error checking. currently the mininet command has no output
1830 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001831 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001832 self.handle.sendline( "" )
1833 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001834
Jon Hall7eb38402015-01-08 17:19:54 -08001835 self.handle.sendline( "update" )
1836 self.handle.expect( "update" )
1837 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001838
Jon Hall7eb38402015-01-08 17:19:54 -08001839 self.handle.sendline( "" )
1840 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001841
Jon Hallb1290e82014-11-18 16:17:48 -05001842 return main.TRUE
1843 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001844 main.log.error( self.name + ": EOF exception found" )
1845 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001846 main.cleanup()
1847 main.exit()
1848
adminbae64d82013-08-01 10:50:15 -07001849if __name__ != "__main__":
1850 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001851 sys.modules[ __name__ ] = MininetCliDriver()