blob: a6436caad7d2c1ced54821ce2e00fd16d1fdc668 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
Jon Hallbe6dfc42015-01-12 17:37:25 -080022MininetCliDriver is the basic driver which will handle the Mininet functions
23
Jon Hall272a4db2015-01-12 17:43:48 -080024Some functions rely on STS module. To install this,
25 git clone https://github.com/jhall11/sts.git
26
Jon Hallbe6dfc42015-01-12 17:37:25 -080027Some functions rely on a modified version of Mininet. These functions
28should all be noted in the comments. To get this MN version run these commands
29from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080030 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080032 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080033 git pull
34
Jon Hall272a4db2015-01-12 17:43:48 -080035
36 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080037changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070038import pexpect
adminbae64d82013-08-01 10:50:15 -070039import re
40import sys
Jon Hall7eb38402015-01-08 17:19:54 -080041sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040042from math import pow
adminbae64d82013-08-01 10:50:15 -070043from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070044
Jon Hall7eb38402015-01-08 17:19:54 -080045
46class MininetCliDriver( Emulator ):
47
48 """
49 MininetCliDriver is the basic driver which will handle
50 the Mininet functions"""
51 def __init__( self ):
52 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070053 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080054 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080055 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070056 self.flag = 0
57
Jon Hall7eb38402015-01-08 17:19:54 -080058 def connect( self, **connectargs ):
59 """
60 Here the main is the TestON instance after creating
61 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080062 try:
63 for key in connectargs:
64 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080065
kelvin-onlaba1484582015-02-02 15:46:20 -080066 self.name = self.options[ 'name' ]
67 self.handle = super(
68 MininetCliDriver,
69 self ).connect(
70 user_name=self.user_name,
71 ip_address=self.ip_address,
72 port=None,
73 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080074
kelvin-onlaba1484582015-02-02 15:46:20 -080075 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080076 main.log.info( "Connection successful to the host " +
77 self.user_name +
78 "@" +
79 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080080 return main.TRUE
81 else:
82 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080083 self.user_name +
84 "@" +
85 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080086 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -080087 return main.FALSE
88 except pexpect.EOF:
89 main.log.error( self.name + ": EOF exception found" )
90 main.log.error( self.name + ": " + self.handle.before )
91 main.cleanup()
92 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080093 except Exception:
94 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -080095 main.cleanup()
96 main.exit()
97
Jon Hallefbd9792015-03-05 16:11:36 -080098 def startNet( self, topoFile='', args='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -080099 """
100 Starts Mininet accepts a topology(.py) file and/or an optional
Jon Hallefbd9792015-03-05 16:11:36 -0800101 argument ,to start the mininet, as a parameter.
Jon Hall21270ac2015-02-16 17:59:55 -0800102 Returns main.TRUE if the mininet starts successfully and
103 main.FALSE otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800104 """
Jon Hall7eb38402015-01-08 17:19:54 -0800105 if self.handle:
106 main.log.info(
107 self.name +
108 ": Clearing any residual state or processes" )
109 self.handle.sendline( "sudo mn -c" )
110 i = self.handle.expect( [ 'password\sfor\s',
111 'Cleanup\scomplete',
112 pexpect.EOF,
113 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800114 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800115 if i == 0:
116 main.log.info( self.name + ": Sending sudo password" )
117 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800118 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800119 '\$',
120 pexpect.EOF,
121 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800122 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800123 if i == 1:
124 main.log.info( self.name + ": Clean" )
125 elif i == 2:
126 main.log.error( self.name + ": Connection terminated" )
127 elif i == 3: # timeout
128 main.log.error(
129 self.name +
130 ": Something while cleaning MN took too long... " )
Jon Hallefbd9792015-03-05 16:11:36 -0800131 if topoFile == '' and args == '':
kelvin-onlaba1484582015-02-02 15:46:20 -0800132 main.log.info( self.name + ": building fresh mininet" )
133 # for reactive/PARP enabled tests
134 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
135 " " + self.options[ 'arg2' ] +\
136 " --mac --controller " +\
137 self.options[ 'controller' ] + " " +\
138 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -0800139
kelvin-onlaba1484582015-02-02 15:46:20 -0800140 argList = self.options[ 'arg1' ].split( "," )
141 global topoArgList
142 topoArgList = argList[ 0 ].split( " " )
143 argList = map( int, argList[ 1: ] )
144 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800145
kelvin-onlaba1484582015-02-02 15:46:20 -0800146 self.handle.sendline( cmdString )
147 self.handle.expect( [ "sudo mn",
148 pexpect.EOF,
149 pexpect.TIMEOUT ] )
150 while True:
151 i = self.handle.expect( [ 'mininet>',
152 '\*\*\*',
153 'Exception',
154 pexpect.EOF,
155 pexpect.TIMEOUT ],
156 timeout )
157 if i == 0:
158 main.log.info( self.name + ": mininet built" )
159 return main.TRUE
160 if i == 1:
161 self.handle.expect(
162 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
163 main.log.info( self.handle.before )
164 elif i == 2:
165 main.log.error(
166 self.name +
167 ": Launching mininet failed..." )
168 return main.FALSE
169 elif i == 3:
170 main.log.error( self.name + ": Connection timeout" )
171 return main.FALSE
172 elif i == 4: # timeout
173 main.log.error(
174 self.name +
175 ": Something took too long... " )
176 return main.FALSE
177 return main.TRUE
178 else:
179 main.log.info( "Starting topo file " + topoFile )
Jon Hallefbd9792015-03-05 16:11:36 -0800180 if args is None:
kelvin-onlaba1484582015-02-02 15:46:20 -0800181 args = ''
182 else:
183 main.log.info( "args = " + args)
184 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
Jon Hall7eb38402015-01-08 17:19:54 -0800185 i = self.handle.expect( [ 'mininet>',
Jon Hallefbd9792015-03-05 16:11:36 -0800186 pexpect.EOF,
187 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800188 timeout)
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800189 if i == 0:
190 main.log.info(self.name + ": Network started")
191 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800192 elif i == 1:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800193 main.log.error( self.name + ": Connection timeout" )
194 return main.FALSE
kelvin-onlabec228b82015-02-09 15:45:55 -0800195 elif i == 2: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800196 main.log.error(
197 self.name +
198 ": Something took too long... " )
199 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800200 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800201 else: # if no handle
202 main.log.error(
203 self.name +
204 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800205 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800206 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800207 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800208 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700209 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800210
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800211 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400212 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800213 # In tree topology, if fanout arg is not given, by default it is 2
214 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400215 fanout = 2
216 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500217 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800218 while( k <= depth - 1 ):
219 count = count + pow( fanout, k )
220 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800222 while( k <= depth - 2 ):
223 # depth-2 gives you only core links and not considering
224 # edge links as seen by ONOS. If all the links including
225 # edge links are required, do depth-1
226 count = count + pow( fanout, k )
227 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800229 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800230 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800231
Jon Hall7eb38402015-01-08 17:19:54 -0800232 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800234 # by default it is 1
235 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400236 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 numSwitches = depth
238 numHostsPerSw = fanout
239 totalNumHosts = numSwitches * numHostsPerSw
240 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800241 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800243 topoDict = { "num_switches": int( numSwitches ),
244 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400245 return topoDict
246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 def calculateSwAndLinks( self ):
248 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400249 return topoDict
250
Jon Hall7eb38402015-01-08 17:19:54 -0800251 def pingall( self, timeout=300 ):
252 """
253 Verifies the reachability of the hosts using pingall command.
254 Optional parameter timeout allows you to specify how long to
255 wait for pingall to complete
256 Returns:
257 main.TRUE if pingall completes with no pings dropped
258 otherwise main.FALSE"""
259 if self.handle:
260 main.log.info(
261 self.name +
262 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700263 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800264 response = self.execute(
265 cmd="pingall",
266 prompt="mininet>",
267 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500268 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800269 main.log.error( self.name + ": EOF exception found" )
270 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500271 main.cleanup()
272 main.exit()
273 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800274 # We may not want to kill the test if pexpect times out
275 main.log.error( self.name + ": TIMEOUT exception found" )
276 main.log.error( self.name +
277 ": " +
278 str( self.handle.before ) )
279 # NOTE: mininet's pingall rounds, so we will check the number of
280 # passed and number of failed
281 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800283 if re.search( pattern, response ):
284 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700285 return main.TRUE
286 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800287 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800289 # NOTE: Send ctrl-c to make sure pingall is done
290 self.handle.send( "\x03" )
291 self.handle.expect( "Interrupt" )
292 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700293 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800294 else:
295 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500296 main.cleanup()
297 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700298
Jon Hall7eb38402015-01-08 17:19:54 -0800299 def fpingHost( self, **pingParams ):
300 """
301 Uses the fping package for faster pinging...
302 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800303 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800304 command = args[ "SRC" ] + \
305 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
306 self.handle.sendline( command )
307 self.handle.expect(
308 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
309 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
310 response = self.handle.before
311 if re.search( ":\s-", response ):
312 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700313 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800314 elif re.search( ":\s\d{1,2}\.\d\d", response ):
315 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700316 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800317 main.log.info( self.name + ": Install fping on mininet machine... " )
318 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700319 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800320
Jon Hall7eb38402015-01-08 17:19:54 -0800321 def pingHost( self, **pingParams ):
322 """
323 Ping from one mininet host to another
324 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800325 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800326 command = args[ "SRC" ] + " ping " + \
327 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700328 try:
Jon Hall61282e32015-03-19 11:34:11 -0700329 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800330 self.handle.sendline( command )
331 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700332 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800333 main.log.error(
334 self.name +
335 ": timeout when waiting for response from mininet" )
336 main.log.error( "response: " + str( self.handle.before ) )
337 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700338 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800339 main.log.error(
340 self.name +
341 ": timeout when waiting for response from mininet" )
342 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700343 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800344 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800345 main.log.error( self.name + ": EOF exception found" )
346 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700347 main.cleanup()
348 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800349 main.log.info( self.name + ": Ping Response: " + response )
350 if re.search( ',\s0\%\spacket\sloss', response ):
351 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800352 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700353 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800354 else:
355 main.log.error(
356 self.name +
357 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700359 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800360
Jon Hall7eb38402015-01-08 17:19:54 -0800361 def checkIP( self, host ):
362 """
363 Verifies the host's ip configured or not."""
364 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700365 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800366 response = self.execute(
367 cmd=host +
368 " ifconfig",
369 prompt="mininet>",
370 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800371 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800372 main.log.error( self.name + ": EOF exception found" )
373 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700374 main.cleanup()
375 main.exit()
adminbae64d82013-08-01 10:50:15 -0700376
Jon Hall7eb38402015-01-08 17:19:54 -0800377 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800378 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
379 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
380 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
381 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
382 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800383 # pattern = "inet addr:10.0.0.6"
384 if re.search( pattern, response ):
385 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700386 return main.TRUE
387 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800388 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700389 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800390 else:
391 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800392
Jon Hall7eb38402015-01-08 17:19:54 -0800393 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800394 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700395 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800396 response = self.execute(
397 cmd="h1 /usr/sbin/sshd -D&",
398 prompt="mininet>",
399 timeout=10 )
400 response = self.execute(
401 cmd="h4 /usr/sbin/sshd -D&",
402 prompt="mininet>",
403 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700404 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800405 vars( self )[ key ] = connectargs[ key ]
406 response = self.execute(
407 cmd="xterm h1 h4 ",
408 prompt="mininet>",
409 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800410 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800411 main.log.error( self.name + ": EOF exception found" )
412 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700413 main.cleanup()
414 main.exit()
adminbae64d82013-08-01 10:50:15 -0700415 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800416 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700417 if self.flag == 0:
418 self.flag = 1
419 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800420 else:
adminbae64d82013-08-01 10:50:15 -0700421 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800422
kelvin-onlaba1484582015-02-02 15:46:20 -0800423 def moveHost( self, host, oldSw, newSw, ):
424 """
425 Moves a host from one switch to another on the fly
426 Note: The intf between host and oldSw when detached
427 using detach(), will still show up in the 'net'
428 cmd, because switch.detach() doesn't affect switch.intfs[]
429 (which is correct behavior since the interfaces
430 haven't moved).
431 """
432 if self.handle:
433 try:
434 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800435 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
436 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800437 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800438 response = self.execute( cmd=cmd,
439 prompt="mininet>",
440 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800441
442 # Determine hostintf and Oldswitchintf
443 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800444 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800445 print "cmd2= ", cmd
446 self.handle.sendline( cmd )
447 self.handle.expect( "mininet>" )
448
shahshreya73537862015-02-11 15:15:24 -0800449 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800450 cmd = "px ipaddr = hintf.IP()"
451 print "cmd3= ", cmd
452 self.handle.sendline( cmd )
453 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800454
455 cmd = "px macaddr = hintf.MAC()"
456 print "cmd3= ", cmd
457 self.handle.sendline( cmd )
458 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800459
460 # Detach interface between oldSw-host
461 cmd = "px " + oldSw + ".detach( sintf )"
462 print "cmd4= ", cmd
463 self.handle.sendline( cmd )
464 self.handle.expect( "mininet>" )
465
466 # Add link between host-newSw
467 cmd = "py net.addLink(" + host + "," + newSw + ")"
468 print "cmd5= ", cmd
469 self.handle.sendline( cmd )
470 self.handle.expect( "mininet>" )
471
472 # Determine hostintf and Newswitchintf
473 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800474 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800475 print "cmd6= ", cmd
476 self.handle.sendline( cmd )
477 self.handle.expect( "mininet>" )
478
479 # Attach interface between newSw-host
480 cmd = "px " + newSw + ".attach( sintf )"
481 print "cmd3= ", cmd
482 self.handle.sendline( cmd )
483 self.handle.expect( "mininet>" )
484
485 # Set ipaddress of the host-newSw interface
486 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
487 print "cmd7 = ", cmd
488 self.handle.sendline( cmd )
489 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800490
491 # Set macaddress of the host-newSw interface
492 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
493 print "cmd8 = ", cmd
494 self.handle.sendline( cmd )
495 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800496
497 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800498 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800499 self.handle.sendline( cmd )
500 self.handle.expect( "mininet>" )
501 print "output = ", self.handle.before
502
503 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800504 cmd = host + " ifconfig"
505 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800506 self.handle.sendline( cmd )
507 self.handle.expect( "mininet>" )
508 print "ifconfig o/p = ", self.handle.before
509
510 return main.TRUE
511 except pexpect.EOF:
512 main.log.error( self.name + ": EOF exception found" )
513 main.log.error( self.name + ": " + self.handle.before )
514 return main.FALSE
515
Jon Hall7eb38402015-01-08 17:19:54 -0800516 def changeIP( self, host, intf, newIP, newNetmask ):
517 """
518 Changes the ip address of a host on the fly
519 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800520 if self.handle:
521 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800522 cmd = host + " ifconfig " + intf + " " + \
523 newIP + " " + 'netmask' + " " + newNetmask
524 self.handle.sendline( cmd )
525 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800526 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800527 main.log.info( "response = " + response )
528 main.log.info(
529 "Ip of host " +
530 host +
531 " changed to new IP " +
532 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800533 return main.TRUE
534 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800535 main.log.error( self.name + ": EOF exception found" )
536 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800537 return main.FALSE
538
Jon Hall7eb38402015-01-08 17:19:54 -0800539 def changeDefaultGateway( self, host, newGW ):
540 """
541 Changes the default gateway of a host
542 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800543 if self.handle:
544 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800545 cmd = host + " route add default gw " + newGW
546 self.handle.sendline( cmd )
547 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800548 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800549 main.log.info( "response = " + response )
550 main.log.info(
551 "Default gateway of host " +
552 host +
553 " changed to " +
554 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800555 return main.TRUE
556 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800557 main.log.error( self.name + ": EOF exception found" )
558 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800559 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800560
Jon Hall7eb38402015-01-08 17:19:54 -0800561 def addStaticMACAddress( self, host, GW, macaddr ):
562 """
Jon Hallefbd9792015-03-05 16:11:36 -0800563 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800564 if self.handle:
565 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800566 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
567 cmd = host + " arp -s " + GW + " " + macaddr
568 self.handle.sendline( cmd )
569 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800570 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800571 main.log.info( "response = " + response )
572 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800573 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800574 GW +
575 " changed to " +
576 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800577 return main.TRUE
578 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800579 main.log.error( self.name + ": EOF exception found" )
580 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800581 return main.FALSE
582
Jon Hall7eb38402015-01-08 17:19:54 -0800583 def verifyStaticGWandMAC( self, host ):
584 """
585 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800586 if self.handle:
587 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800588 # h1 arp -an
589 cmd = host + " arp -an "
590 self.handle.sendline( cmd )
591 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800592 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800593 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800594 return main.TRUE
595 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800596 main.log.error( self.name + ": EOF exception found" )
597 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800598 return main.FALSE
599
Jon Hall7eb38402015-01-08 17:19:54 -0800600 def getMacAddress( self, host ):
601 """
602 Verifies the host's ip configured or not."""
603 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700604 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800605 response = self.execute(
606 cmd=host +
607 " ifconfig",
608 prompt="mininet>",
609 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800610 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700613 main.cleanup()
614 main.exit()
adminbae64d82013-08-01 10:50:15 -0700615
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700616 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 macAddressSearch = re.search( pattern, response, re.I )
618 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800619 main.log.info(
620 self.name +
621 ": Mac-Address of Host " +
622 host +
623 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 macAddress )
625 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700626 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800627 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700628
Jon Hall7eb38402015-01-08 17:19:54 -0800629 def getInterfaceMACAddress( self, host, interface ):
630 """
631 Return the IP address of the interface on the given host"""
632 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700633 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800634 response = self.execute( cmd=host + " ifconfig " + interface,
635 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800636 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800637 main.log.error( self.name + ": EOF exception found" )
638 main.log.error( self.name + ": " + self.handle.before )
639 main.cleanup()
640 main.exit()
641
642 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 macAddressSearch = re.search( pattern, response, re.I )
644 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800645 main.log.info( "No mac address found in %s" % response )
646 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800647 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800648 main.log.info(
649 "Mac-Address of " +
650 host +
651 ":" +
652 interface +
653 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 macAddress )
655 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800656 else:
657 main.log.error( "Connection failed to the host" )
658
659 def getIPAddress( self, host ):
660 """
661 Verifies the host's ip configured or not."""
662 if self.handle:
663 try:
664 response = self.execute(
665 cmd=host +
666 " ifconfig",
667 prompt="mininet>",
668 timeout=10 )
669 except pexpect.EOF:
670 main.log.error( self.name + ": EOF exception found" )
671 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700672 main.cleanup()
673 main.exit()
adminbae64d82013-08-01 10:50:15 -0700674
675 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800677 main.log.info(
678 self.name +
679 ": IP-Address of Host " +
680 host +
681 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 ipAddressSearch.group( 1 ) )
683 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800684 else:
685 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800686
Jon Hall7eb38402015-01-08 17:19:54 -0800687 def getSwitchDPID( self, switch ):
688 """
689 return the datapath ID of the switch"""
690 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700691 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700692 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800693 response = self.execute(
694 cmd=cmd,
695 prompt="mininet>",
696 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800697 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700700 main.cleanup()
701 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800702 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800703 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700704 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800705 main.log.info(
706 "Couldn't find DPID for switch %s, found: %s" %
707 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700708 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800709 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700710 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700712
Jon Hall7eb38402015-01-08 17:19:54 -0800713 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700714 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800715 self.handle.sendline( "" )
716 self.expect( "mininet>" )
717 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700718 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800719 response = self.execute(
720 cmd=cmd,
721 prompt="mininet>",
722 timeout=10 )
723 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700724 response = self.handle.before
725 return response
726 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700729 main.cleanup()
730 main.exit()
731
Jon Hall7eb38402015-01-08 17:19:54 -0800732 def getInterfaces( self, node ):
733 """
734 return information dict about interfaces connected to the node"""
735 if self.handle:
736 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800737 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700738 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700739 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 response = self.execute(
741 cmd=cmd,
742 prompt="mininet>",
743 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800744 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800745 main.log.error( self.name + ": EOF exception found" )
746 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700747 main.cleanup()
748 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700749 return response
750 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800751 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700752
Jon Hall7eb38402015-01-08 17:19:54 -0800753 def dump( self ):
754 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700755 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800756 response = self.execute(
757 cmd='dump',
758 prompt='mininet>',
759 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800760 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700763 main.cleanup()
764 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700765 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800766
Jon Hall7eb38402015-01-08 17:19:54 -0800767 def intfs( self ):
768 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700769 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800770 response = self.execute(
771 cmd='intfs',
772 prompt='mininet>',
773 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800774 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800775 main.log.error( self.name + ": EOF exception found" )
776 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700777 main.cleanup()
778 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700779 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800780
Jon Hall7eb38402015-01-08 17:19:54 -0800781 def net( self ):
782 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700783 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800784 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800785 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800786 main.log.error( self.name + ": EOF exception found" )
787 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700788 main.cleanup()
789 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700790 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800791
792 def iperf( self, host1, host2 ):
793 main.log.info(
794 self.name +
795 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700796 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800797 cmd1 = 'iperf ' + host1 + " " + host2
798 self.handle.sendline( cmd1 )
799 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800800 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800801 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800802 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800803 return main.TRUE
804 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 main.log.error( self.name + ": iperf test failed" )
806 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800807 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800808 main.log.error( self.name + ": EOF exception found" )
809 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800810 main.cleanup()
811 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800812
Jon Hall7eb38402015-01-08 17:19:54 -0800813 def iperfudp( self ):
814 main.log.info(
815 self.name +
816 ": Simple iperf TCP test between two " +
817 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700818 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 response = self.execute(
820 cmd='iperfudp',
821 prompt='mininet>',
822 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800823 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800824 main.log.error( self.name + ": EOF exception found" )
825 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700826 main.cleanup()
827 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700828 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800829
Jon Hall7eb38402015-01-08 17:19:54 -0800830 def nodes( self ):
831 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700832 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 response = self.execute(
834 cmd='nodes',
835 prompt='mininet>',
836 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800837 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800838 main.log.error( self.name + ": EOF exception found" )
839 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700840 main.cleanup()
841 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700842 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800843
Jon Hall7eb38402015-01-08 17:19:54 -0800844 def pingpair( self ):
845 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700846 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800847 response = self.execute(
848 cmd='pingpair',
849 prompt='mininet>',
850 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800851 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800852 main.log.error( self.name + ": EOF exception found" )
853 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700854 main.cleanup()
855 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800856
Jon Hall7eb38402015-01-08 17:19:54 -0800857 if re.search( ',\s0\%\spacket\sloss', response ):
858 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700860 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800861 else:
862 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700864 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800865
Jon Hall7eb38402015-01-08 17:19:54 -0800866 def link( self, **linkargs ):
867 """
868 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800869 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800870 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
871 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
872 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
873 main.log.info(
874 "Bring link between '" +
875 end1 +
876 "' and '" +
877 end2 +
878 "' '" +
879 option +
880 "'" )
881 command = "link " + \
882 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700883 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800884 self.handle.sendline( command )
885 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800886 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( self.name + ": EOF exception found" )
888 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700889 main.cleanup()
890 main.exit()
adminbae64d82013-08-01 10:50:15 -0700891 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800892
Jon Hall7eb38402015-01-08 17:19:54 -0800893 def yank( self, **yankargs ):
894 """
895 yank a mininet switch interface to a host"""
896 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800897 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800898 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
899 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
900 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700901 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800902 response = self.execute(
903 cmd=command,
904 prompt="mininet>",
905 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800906 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700909 main.cleanup()
910 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700911 return main.TRUE
912
Jon Hall7eb38402015-01-08 17:19:54 -0800913 def plug( self, **plugargs ):
914 """
915 plug the yanked mininet switch interface to a switch"""
916 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800917 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800918 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
919 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
920 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700921 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800922 response = self.execute(
923 cmd=command,
924 prompt="mininet>",
925 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800926 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800927 main.log.error( self.name + ": EOF exception found" )
928 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700929 main.cleanup()
930 main.exit()
adminbae64d82013-08-01 10:50:15 -0700931 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800932
Jon Hall7eb38402015-01-08 17:19:54 -0800933 def dpctl( self, **dpctlargs ):
934 """
935 Run dpctl command on all switches."""
936 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800937 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800938 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
939 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
940 command = "dpctl " + cmd + " " + str( cmdargs )
941 try:
942 response = self.execute(
943 cmd=command,
944 prompt="mininet>",
945 timeout=10 )
946 except pexpect.EOF:
947 main.log.error( self.name + ": EOF exception found" )
948 main.log.error( self.name + ": " + self.handle.before )
949 main.cleanup()
950 main.exit()
951 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -0800954 #FIXME: What uses this? This should be refactored to get
955 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 fileInput = path + '/lib/Mininet/INSTALL'
957 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700958 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800960 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700961 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800962 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500963 return version
adminbae64d82013-08-01 10:50:15 -0700964
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800966 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500967 Parameters:
968 sw: The name of an OVS switch. Example "s1"
969 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800970 The output of the command from the mininet cli
971 or main.FALSE on timeout"""
972 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700973 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800974 response = self.execute(
975 cmd=command,
976 prompt="mininet>",
977 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700978 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500979 return response
admin2a9548d2014-06-17 14:08:07 -0700980 else:
981 return main.FALSE
982 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800983 main.log.error( self.name + ": EOF exception found" )
984 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700985 main.cleanup()
986 main.exit()
adminbae64d82013-08-01 10:50:15 -0700987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800989 """
990 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800991 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800992 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700993
994 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800995 for j in range( count ):
996 argstring = argstring + ",IP" + \
997 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800998 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700999
Jon Hall7eb38402015-01-08 17:19:54 -08001000 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1001 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001002 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001003 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001004
Jon Hall7eb38402015-01-08 17:19:54 -08001005 command = "sh ovs-vsctl set-controller s" + \
1006 str( sw ) + " " + ptcpB + " "
1007 for j in range( count ):
1008 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001009 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001010 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1011 ip = args[
1012 "IP" +
1013 str( i ) ] if args[
1014 "IP" +
1015 str( i ) ] is not None else ""
1016 port = args[
1017 "PORT" +
1018 str( i ) ] if args[
1019 "PORT" +
1020 str( i ) ] is not None else ""
1021 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001022 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001023 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001024 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001025 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001026 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001029 main.cleanup()
1030 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001031 except Exception:
1032 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001033 main.cleanup()
1034 main.exit()
adminbae64d82013-08-01 10:50:15 -07001035
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001037 """
1038 Removes the controller target from sw"""
1039 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001040 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001041 response = self.execute(
1042 cmd=command,
1043 prompt="mininet>",
1044 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001045 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001046 main.log.error( self.name + ": EOF exception found" )
1047 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001048 main.cleanup()
1049 main.exit()
1050 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001051 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001052
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001054 """
Jon Hallb1290e82014-11-18 16:17:48 -05001055 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001056 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001057 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001058 NOTE: cannot currently specify what type of switch
1059 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001060 sw = name of the new switch as a string
1061 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001062 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001063 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001064 """
1065 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001066 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001067 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001068 response = self.execute(
1069 cmd=command,
1070 prompt="mininet>",
1071 timeout=10 )
1072 if re.search( "already exists!", response ):
1073 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001074 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001075 elif re.search( "Error", response ):
1076 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001077 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001078 elif re.search( "usage:", response ):
1079 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001080 return main.FALSE
1081 else:
1082 return main.TRUE
1083 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001084 main.log.error( self.name + ": EOF exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001086 main.cleanup()
1087 main.exit()
1088
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001090 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001091 delete a switch from the mininet topology
1092 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001093 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001094 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001095 sw = name of the switch as a string
1096 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001097 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001098 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001099 response = self.execute(
1100 cmd=command,
1101 prompt="mininet>",
1102 timeout=10 )
1103 if re.search( "no switch named", response ):
1104 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001105 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001106 elif re.search( "Error", response ):
1107 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001108 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001109 elif re.search( "usage:", response ):
1110 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001111 return main.FALSE
1112 else:
1113 return main.TRUE
1114 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001115 main.log.error( self.name + ": EOF exception found" )
1116 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001117 main.cleanup()
1118 main.exit()
1119
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001121 """
1122 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001123 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001124 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001125 NOTE: cannot currently specify what type of link
1126 required params:
1127 node1 = the string node name of the first endpoint of the link
1128 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001129 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001130 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001131 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001132 response = self.execute(
1133 cmd=command,
1134 prompt="mininet>",
1135 timeout=10 )
1136 if re.search( "doesnt exist!", response ):
1137 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001138 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001139 elif re.search( "Error", response ):
1140 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001141 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001142 elif re.search( "usage:", response ):
1143 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001144 return main.FALSE
1145 else:
1146 return main.TRUE
1147 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001148 main.log.error( self.name + ": EOF exception found" )
1149 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001150 main.cleanup()
1151 main.exit()
1152
kelvin-onlabd3b64892015-01-20 13:26:24 -08001153 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001154 """
1155 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001156 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001157 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001158 required params:
1159 node1 = the string node name of the first endpoint of the link
1160 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001161 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001162 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001163 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001164 response = self.execute(
1165 cmd=command,
1166 prompt="mininet>",
1167 timeout=10 )
1168 if re.search( "no node named", response ):
1169 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001170 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001171 elif re.search( "Error", response ):
1172 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001173 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001174 elif re.search( "usage:", response ):
1175 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001176 return main.FALSE
1177 else:
1178 return main.TRUE
1179 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001180 main.log.error( self.name + ": EOF exception found" )
1181 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001182 main.cleanup()
1183 main.exit()
1184
kelvin-onlabd3b64892015-01-20 13:26:24 -08001185 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001186 """
Jon Hallb1290e82014-11-18 16:17:48 -05001187 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001188 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001189 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001190 NOTE: cannot currently specify what type of host
1191 required params:
1192 hostname = the string hostname
1193 optional key-value params
1194 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001195 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001196 """
1197 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001198 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001199 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001200 response = self.execute(
1201 cmd=command,
1202 prompt="mininet>",
1203 timeout=10 )
1204 if re.search( "already exists!", response ):
1205 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001206 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001207 elif re.search( "doesnt exists!", response ):
1208 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001209 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001210 elif re.search( "Error", 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( "usage:", response ):
1214 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001215 return main.FALSE
1216 else:
1217 return main.TRUE
1218 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001219 main.log.error( self.name + ": EOF exception found" )
1220 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001221 main.cleanup()
1222 main.exit()
1223
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001225 """
1226 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001227 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001228 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001229 NOTE: this uses a custom mn function
1230 required params:
1231 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001232 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001233 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001234 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001235 response = self.execute(
1236 cmd=command,
1237 prompt="mininet>",
1238 timeout=10 )
1239 if re.search( "no host named", response ):
1240 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001241 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001242 elif re.search( "Error", response ):
1243 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001244 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001245 elif re.search( "usage:", response ):
1246 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001247 return main.FALSE
1248 else:
1249 return main.TRUE
1250 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001253 main.cleanup()
1254 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001255
Jon Hall7eb38402015-01-08 17:19:54 -08001256 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001257 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001258 Called at the end of the test to stop the mininet and
1259 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001260 """
1261 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001262 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001263 timeout=2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001264 if i == 0:
1265 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001266 elif i == 1:
1267 return main.TRUE
1268 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001269 # print "Disconnecting Mininet"
1270 if self.handle:
1271 self.handle.sendline( "exit" )
1272 self.handle.expect( "exit" )
1273 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001274 else:
1275 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001276 return response
1277
Jon Hallefbd9792015-03-05 16:11:36 -08001278 def stopNet( self, timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001279 """
Jon Hall21270ac2015-02-16 17:59:55 -08001280 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001281 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001282 main.FALSE if the pexpect handle does not exist.
1283
Jon Halld61331b2015-02-17 16:35:47 -08001284 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001285 """
Jon Hall21270ac2015-02-16 17:59:55 -08001286
Jon Halld61331b2015-02-17 16:35:47 -08001287 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001288 response = ''
1289 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001290 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001291 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001292 i = self.handle.expect( [ 'mininet>',
1293 '\$',
1294 pexpect.EOF,
1295 pexpect.TIMEOUT ],
1296 timeout )
1297 if i == 0:
1298 main.log.info( "Exiting mininet..." )
1299
Jon Hall7eb38402015-01-08 17:19:54 -08001300 response = self.execute(
1301 cmd="exit",
1302 prompt="(.*)",
1303 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001304 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001305 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001306 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08001307
1308 if i == 1:
1309 main.log.info( " Mininet trying to exit while not " +
1310 "in the mininet prompt" )
1311 elif i == 2:
1312 main.log.error( "Something went wrong exiting mininet" )
1313 elif i == 3: # timeout
1314 main.log.error( "Something went wrong exiting mininet " +
1315 "TIMEOUT" )
1316
Jon Hallfbc828e2015-01-06 17:30:19 -08001317 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001318 main.log.error( self.name + ": EOF exception found" )
1319 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001320 main.cleanup()
1321 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001322 else:
1323 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001324 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001325 return response
1326
Jon Hall7eb38402015-01-08 17:19:54 -08001327 def arping( self, src, dest, destmac ):
1328 self.handle.sendline( '' )
1329 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001330
Jon Hall7eb38402015-01-08 17:19:54 -08001331 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001332 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001333 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1334 main.log.info( self.name + ": ARP successful" )
1335 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001336 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001337 except Exception:
Jon Hall7eb38402015-01-08 17:19:54 -08001338 main.log.warn( self.name + ": ARP FAILURE" )
1339 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001340 return main.FALSE
1341
Jon Hall7eb38402015-01-08 17:19:54 -08001342 def decToHex( self, num ):
1343 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001344
Jon Hall7eb38402015-01-08 17:19:54 -08001345 def getSwitchFlowCount( self, switch ):
1346 """
1347 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001348 if self.handle:
1349 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1350 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001351 response = self.execute(
1352 cmd=cmd,
1353 prompt="mininet>",
1354 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001355 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001356 main.log.error( self.name + ": EOF exception found" )
1357 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001358 main.cleanup()
1359 main.exit()
1360 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001361 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001362 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001363 main.log.info(
1364 "Couldn't find flows on switch %s, found: %s" %
1365 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001366 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001367 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001368 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001369 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001370
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 def checkFlows( self, sw, dumpFormat=None ):
1372 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001373 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001375 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001377 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001378 response = self.execute(
1379 cmd=command,
1380 prompt="mininet>",
1381 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001382 return response
1383 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001384 main.log.error( self.name + ": EOF exception found" )
1385 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001386 main.cleanup()
1387 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001388
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001390 """
Jon Hallefbd9792015-03-05 16:11:36 -08001391 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001392 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001393 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001394 self.handle.sendline( "" )
1395 self.handle.expect( "mininet>" )
1396 self.handle.sendline(
1397 "sh sudo tcpdump -n -i " +
1398 intf +
1399 " " +
1400 port +
1401 " -w " +
1402 filename.strip() +
1403 " &" )
1404 self.handle.sendline( "" )
1405 i = self.handle.expect( [ 'No\ssuch\device',
1406 'listening\son',
1407 pexpect.TIMEOUT,
1408 "mininet>" ],
1409 timeout=10 )
1410 main.log.warn( self.handle.before + self.handle.after )
1411 self.handle.sendline( "" )
1412 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001413 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001414 main.log.error(
1415 self.name +
1416 ": tcpdump - No such device exists. " +
1417 "tcpdump attempted on: " +
1418 intf )
admin2a9548d2014-06-17 14:08:07 -07001419 return main.FALSE
1420 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001422 return main.TRUE
1423 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 main.log.error(
1425 self.name +
1426 ": tcpdump command timed out! Check interface name," +
1427 " given interface was: " +
1428 intf )
admin2a9548d2014-06-17 14:08:07 -07001429 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001430 elif i == 3:
1431 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001432 return main.TRUE
1433 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001434 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001435 return main.FALSE
1436 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001437 main.log.error( self.name + ": EOF exception found" )
1438 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001439 main.cleanup()
1440 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001441 except Exception:
1442 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001443 main.cleanup()
1444 main.exit()
1445
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001447 """
1448 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001449 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001450 self.handle.sendline( "sh sudo pkill tcpdump" )
1451 self.handle.expect( "mininet>" )
1452 self.handle.sendline( "" )
1453 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001454 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001455 main.log.error( self.name + ": EOF exception found" )
1456 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001457 main.cleanup()
1458 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001459 except Exception:
1460 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001461 main.cleanup()
1462 main.exit()
1463
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001465 """
1466 Compare mn and onos switches
1467 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001468 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001469
Jon Hall7eb38402015-01-08 17:19:54 -08001470 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001471 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001472 output = { "switches": [] }
1473 # iterate through the MN topology and pull out switches and and port
1474 # info
1475 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001476 ports = []
1477 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001478 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001479 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001480 'name': port.name } )
1481 output[ 'switches' ].append( {
1482 "name": switch.name,
1483 "dpid": str( switch.dpid ).zfill( 16 ),
1484 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001485
Jon Hall7eb38402015-01-08 17:19:54 -08001486 # print "mn"
1487 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001488 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001489 # indent=4,
1490 # separators=( ',', ': ' ) )
1491 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001493 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001494 # indent=4,
1495 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001496
1497 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001498 mnDPIDs = []
1499 for switch in output[ 'switches' ]:
1500 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001501 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001502 # print "List of Mininet switch DPID's"
1503 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001504 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001505 main.log.error(
1506 self.name +
1507 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001508 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001510 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001511 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001512 if switch[ 'available' ]:
1513 onosDPIDs.append(
1514 switch[ 'id' ].replace(
1515 ":",
1516 '' ).replace(
1517 "of",
1518 '' ).lower() )
1519 # else:
1520 # print "Switch is unavailable:"
1521 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001522 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001523 # print "List of ONOS switch DPID's"
1524 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001525
Jon Hall7eb38402015-01-08 17:19:54 -08001526 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001528 main.log.report( "Switches in MN but not in ONOS:" )
1529 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1530 main.log.report( str( list1 ) )
1531 main.log.report( "Switches in ONOS but not in MN:" )
1532 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001533 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001534 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 switchResults = main.TRUE
1536 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001537
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001539 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001540 Compare mn and onos ports
1541 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001542 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001543
Jon Hallfbc828e2015-01-06 17:30:19 -08001544 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001545 1. This uses the sts TestONTopology object
1546 2. numpy - "sudo pip install numpy"
1547
Jon Hall7eb38402015-01-08 17:19:54 -08001548 """
1549 # FIXME: this does not look for extra ports in ONOS, only checks that
1550 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001551 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001553 output = { "switches": [] }
1554 # iterate through the MN topology and pull out switches and and port
1555 # info
1556 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001557 ports = []
1558 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001559 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001560 tmpPort = { 'of_port': port.port_no,
1561 'mac': str( port.hw_addr ).replace( '\'', '' ),
1562 'name': port.name,
1563 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001564
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001566 tmpSwitch = { 'name': switch.name,
1567 'dpid': str( switch.dpid ).zfill( 16 ),
1568 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001569
kelvin-onlabd3b64892015-01-20 13:26:24 -08001570 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001571
Jon Hall7eb38402015-01-08 17:19:54 -08001572 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001573 for mnSwitch in output[ 'switches' ]:
1574 mnPorts = []
1575 onosPorts = []
1576 switchResult = main.TRUE
1577 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001578 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 mnPorts.append( port[ 'of_port' ] )
1580 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001581 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 # print onosSwitch
1583 if onosSwitch[ 'device' ][ 'available' ]:
1584 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001585 ':',
1586 '' ).replace(
1587 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001588 '' ) == mnSwitch[ 'dpid' ]:
1589 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001590 if port[ 'isEnabled' ]:
1591 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 # onosPorts.append( 'local' )
1593 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001594 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001596 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 mnPorts.sort( key=float )
1598 onosPorts.sort( key=float )
1599 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1600 # print "\tmn_ports[] = ", mnPorts
1601 # print "\tonos_ports[] = ", onosPorts
1602 mnPortsLog = mnPorts
1603 onosPortsLog = onosPorts
1604 mnPorts = [ x for x in mnPorts ]
1605 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001606
Jon Hall7eb38402015-01-08 17:19:54 -08001607 # TODO: handle other reserved port numbers besides LOCAL
1608 # NOTE: Reserved ports
1609 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1610 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 for mnPort in mnPortsLog:
1612 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001613 # don't set results to true here as this is just one of
1614 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 mnPorts.remove( mnPort )
1616 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001617 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001618 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001619 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 if 65534 in mnPorts:
1621 mnPorts.remove( 65534 )
1622 if long( uint64( -2 ) ) in onosPorts:
1623 onosPorts.remove( long( uint64( -2 ) ) )
1624 if len( mnPorts ): # the ports of this switch don't match
1625 switchResult = main.FALSE
1626 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1627 if len( onosPorts ): # the ports of this switch don't match
1628 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001629 main.log.warn(
1630 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001631 str( onosPorts ) )
1632 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001633 main.log.report(
1634 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1636 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1637 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1638 portsResults = portsResults and switchResult
1639 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001640
kelvin-onlabd3b64892015-01-20 13:26:24 -08001641 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001642 """
1643 Compare mn and onos links
1644 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001646
Jon Hall7eb38402015-01-08 17:19:54 -08001647 This uses the sts TestONTopology object"""
1648 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001649 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001650 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001652 # iterate through the MN topology and pull out switches and and port
1653 # info
1654 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001655 # print "Iterating though switches as seen by Mininet"
1656 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001657 ports = []
1658 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001659 # print port.hw_addr.toStr( separator='' )
1660 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001661 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001662 'name': port.name } )
1663 output[ 'switches' ].append( {
1664 "name": switch.name,
1665 "dpid": str( switch.dpid ).zfill( 16 ),
1666 "ports": ports } )
1667 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001668
kelvin-onlabd3b64892015-01-20 13:26:24 -08001669 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001670 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001671 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 if 2 * len( mnLinks ) == len( onos ):
1673 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001674 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001675 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001676 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001677 "Mininet has " + str( len( mnLinks ) ) +
1678 " bidirectional links and ONOS has " +
1679 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001680
Jon Hall7eb38402015-01-08 17:19:54 -08001681 # iterate through MN links and check if an ONOS link exists in
1682 # both directions
1683 # NOTE: Will currently only show mn links as down if they are
1684 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001686 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001687 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001688 # print "Link: %s" % link
1689 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001690 node1 = None
1691 port1 = None
1692 node2 = None
1693 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 firstDir = main.FALSE
1695 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001696 for switch in output[ 'switches' ]:
1697 # print "Switch: %s" % switch[ 'name' ]
1698 if switch[ 'name' ] == link.node1.name:
1699 node1 = switch[ 'dpid' ]
1700 for port in switch[ 'ports' ]:
1701 if str( port[ 'name' ] ) == str( link.port1 ):
1702 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001703 if node1 is not None and node2 is not None:
1704 break
Jon Hall7eb38402015-01-08 17:19:54 -08001705 if switch[ 'name' ] == link.node2.name:
1706 node2 = switch[ 'dpid' ]
1707 for port in switch[ 'ports' ]:
1708 if str( port[ 'name' ] ) == str( link.port2 ):
1709 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001710 if node1 is not None and node2 is not None:
1711 break
1712
kelvin-onlabd3b64892015-01-20 13:26:24 -08001713 for onosLink in onos:
1714 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001715 ":",
1716 '' ).replace(
1717 "of",
1718 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001719 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001720 ":",
1721 '' ).replace(
1722 "of",
1723 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001724 onosPort1 = onosLink[ 'src' ][ 'port' ]
1725 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001726
Jon Hall72cf1dc2014-10-20 21:04:50 -04001727 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001728 if str( onosNode1 ) == str( node1 ) and str(
1729 onosNode2 ) == str( node2 ):
1730 if int( onosPort1 ) == int( port1 ) and int(
1731 onosPort2 ) == int( port2 ):
1732 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001733 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001734 main.log.warn(
1735 'The port numbers do not match for ' +
1736 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001737 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001738 'link %s/%s -> %s/%s' %
1739 ( node1,
1740 port1,
1741 node2,
1742 port2 ) +
1743 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 ( onosNode1,
1745 onosPort1,
1746 onosNode2,
1747 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001748
1749 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 elif ( str( onosNode1 ) == str( node2 ) and
1751 str( onosNode2 ) == str( node1 ) ):
1752 if ( int( onosPort1 ) == int( port2 )
1753 and int( onosPort2 ) == int( port1 ) ):
1754 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001755 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001756 main.log.warn(
1757 'The port numbers do not match for ' +
1758 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001759 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001760 'link %s/%s -> %s/%s' %
1761 ( node2,
1762 port2,
1763 node1,
1764 port1 ) +
1765 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001766 ( onosNode2,
1767 onosPort2,
1768 onosNode1,
1769 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001770 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001771 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001773 main.log.report(
1774 'ONOS does not have the link %s/%s -> %s/%s' %
1775 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001777 main.log.report(
1778 'ONOS does not have the link %s/%s -> %s/%s' %
1779 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001780 linkResults = linkResults and firstDir and secondDir
1781 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001782
Jon Hallff6b4b22015-02-23 09:25:15 -08001783 def compareHosts( self, topo, hostsJson ):
1784 """
1785 Compare mn and onos Hosts.
1786 Since Mininet hosts are quiet, ONOS will only know of them when they
1787 speak. For this reason, we will only check that the hosts in ONOS
1788 stores are in Mininet, and not vice versa.
1789 topo: sts TestONTopology object
1790 hostsJson: parsed json object from the onos hosts api
1791
1792 This uses the sts TestONTopology object"""
1793 import json
1794 hostResults = main.TRUE
1795 hosts = []
1796 # iterate through the MN topology and pull out hosts
1797 for mnHost in topo.graph.hosts:
1798 interfaces = []
1799 for intf in mnHost.interfaces:
1800 interfaces.append( {
1801 "name": intf.name, # str
1802 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1803 # hw_addr is of type EthAddr, Not JSON serializable
1804 "hw_addr": str( intf.hw_addr ) } )
1805 hosts.append( {
1806 "name": mnHost.name, # str
1807 "interfaces": interfaces } ) # list
1808 for onosHost in hostsJson:
1809 onosMAC = onosHost[ 'mac' ].lower()
1810 match = False
1811 for mnHost in hosts:
1812 for mnIntf in mnHost[ 'interfaces' ]:
1813 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1814 match = True
1815 for ip in mnIntf[ 'ips' ]:
1816 if ip in onosHost[ 'ips' ]:
1817 pass # all is well
1818 else:
1819 # misssing ip
1820 main.log.error( "ONOS host " + onosHost[ 'id' ]
1821 + " has a different IP than " +
1822 "the Mininet host." )
1823 output = json.dumps(
1824 onosHost,
1825 sort_keys=True,
1826 indent=4,
1827 separators=( ',', ': ' ) )
1828 main.log.info( output )
1829 hostResults = main.FALSE
1830 if not match:
1831 hostResults = main.FALSE
1832 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1833 "corresponding Mininet host." )
1834 output = json.dumps( onosHost,
1835 sort_keys=True,
1836 indent=4,
1837 separators=( ',', ': ' ) )
1838 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001839 return hostResults
1840
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001842 """
1843 Returns a list of all hosts
1844 Don't ask questions just use it"""
1845 self.handle.sendline( "" )
1846 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001847
Jon Hall7eb38402015-01-08 17:19:54 -08001848 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1849 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001850
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 handlePy = self.handle.before
1852 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1853 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001854
Jon Hall7eb38402015-01-08 17:19:54 -08001855 self.handle.sendline( "" )
1856 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001857
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 hostStr = handlePy.replace( "]", "" )
1859 hostStr = hostStr.replace( "'", "" )
1860 hostStr = hostStr.replace( "[", "" )
1861 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001862
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 return hostList
adminbae64d82013-08-01 10:50:15 -07001864
Jon Hall7eb38402015-01-08 17:19:54 -08001865 def update( self ):
1866 """
1867 updates the port address and status information for
1868 each port in mn"""
1869 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08001870 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001871 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001872 self.handle.sendline( "" )
1873 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001874
Jon Hall7eb38402015-01-08 17:19:54 -08001875 self.handle.sendline( "update" )
1876 self.handle.expect( "update" )
1877 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001878
Jon Hall7eb38402015-01-08 17:19:54 -08001879 self.handle.sendline( "" )
1880 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001881
Jon Hallb1290e82014-11-18 16:17:48 -05001882 return main.TRUE
1883 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001884 main.log.error( self.name + ": EOF exception found" )
1885 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001886 main.cleanup()
1887 main.exit()
1888
adminbae64d82013-08-01 10:50:15 -07001889if __name__ != "__main__":
1890 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001891 sys.modules[ __name__ ] = MininetCliDriver()