blob: 4dd6d28bb504bce55b8d64afcb7554b5c74b33cb [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
Jon Hallbe6dfc42015-01-12 17:37:25 -080022MininetCliDriver is the basic driver which will handle the Mininet functions
23
Jon Hall272a4db2015-01-12 17:43:48 -080024Some functions rely on STS module. To install this,
25 git clone https://github.com/jhall11/sts.git
26
Jon Hallbe6dfc42015-01-12 17:37:25 -080027Some functions rely on a modified version of Mininet. These functions
28should all be noted in the comments. To get this MN version run these commands
29from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080030 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080032 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080033 git pull
34
Jon Hall272a4db2015-01-12 17:43:48 -080035
36 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080037changed when switching branches."""
admin2a9548d2014-06-17 14:08:07 -070038import traceback
adminbae64d82013-08-01 10:50:15 -070039import pexpect
adminbae64d82013-08-01 10:50:15 -070040import re
41import sys
Jon Hall7eb38402015-01-08 17:19:54 -080042sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040043from math import pow
adminbae64d82013-08-01 10:50:15 -070044from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
47class MininetCliDriver( Emulator ):
48
49 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
53 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
Jon Hall7eb38402015-01-08 17:19:54 -080055 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070056 self.flag = 0
57
Jon Hall7eb38402015-01-08 17:19:54 -080058 def connect( self, **connectargs ):
59 """
60 Here the main is the TestON instance after creating
61 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080062 try:
63 for key in connectargs:
64 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080065
kelvin-onlaba1484582015-02-02 15:46:20 -080066 self.name = self.options[ 'name' ]
67 self.handle = super(
68 MininetCliDriver,
69 self ).connect(
70 user_name=self.user_name,
71 ip_address=self.ip_address,
72 port=None,
73 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080074
kelvin-onlaba1484582015-02-02 15:46:20 -080075 if self.handle:
76 main.log.info("Connection successful to the host " +
77 self.user_name +
78 "@" +
79 self.ip_address )
80 return main.TRUE
81 else:
82 main.log.error( "Connection failed to the host " +
83 self.user_name +
84 "@" +
85 self.ip_address )
86 msin.log.error( "Failed to connect to the Mininet CLI" )
87 return main.FALSE
88 except pexpect.EOF:
89 main.log.error( self.name + ": EOF exception found" )
90 main.log.error( self.name + ": " + self.handle.before )
91 main.cleanup()
92 main.exit()
93 except:
94 main.log.info( self.name + ":::::::::::::::::::::::" )
95 main.log.error( traceback.print_exc() )
96 main.log.info( ":::::::::::::::::::::::" )
97 main.cleanup()
98 main.exit()
99
100
101 def startNet( self, topoFile = '', args = '', timeout = 120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800102 """
103 Starts Mininet accepts a topology(.py) file and/or an optional
104 arguement ,to start the mininet, as a parameter.
Jon Hall21270ac2015-02-16 17:59:55 -0800105 Returns main.TRUE if the mininet starts successfully and
106 main.FALSE otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800107 """
Jon Hall7eb38402015-01-08 17:19:54 -0800108 if self.handle:
109 main.log.info(
110 self.name +
111 ": Clearing any residual state or processes" )
112 self.handle.sendline( "sudo mn -c" )
113 i = self.handle.expect( [ 'password\sfor\s',
114 'Cleanup\scomplete',
115 pexpect.EOF,
116 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800117 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800118 if i == 0:
119 main.log.info( self.name + ": Sending sudo password" )
120 self.handle.sendline( self.pwd )
121 i = self.handle.expect( [ '%s:' % ( self.user ),
122 '\$',
123 pexpect.EOF,
124 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800125 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800126 if i == 1:
127 main.log.info( self.name + ": Clean" )
128 elif i == 2:
129 main.log.error( self.name + ": Connection terminated" )
130 elif i == 3: # timeout
131 main.log.error(
132 self.name +
133 ": Something while cleaning MN took too long... " )
kelvin-onlaba1484582015-02-02 15:46:20 -0800134 if topoFile == '' and args == '':
135 main.log.info( self.name + ": building fresh mininet" )
136 # for reactive/PARP enabled tests
137 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
138 " " + self.options[ 'arg2' ] +\
139 " --mac --controller " +\
140 self.options[ 'controller' ] + " " +\
141 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -0800142
kelvin-onlaba1484582015-02-02 15:46:20 -0800143 argList = self.options[ 'arg1' ].split( "," )
144 global topoArgList
145 topoArgList = argList[ 0 ].split( " " )
146 argList = map( int, argList[ 1: ] )
147 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800148
kelvin-onlaba1484582015-02-02 15:46:20 -0800149 self.handle.sendline( cmdString )
150 self.handle.expect( [ "sudo mn",
151 pexpect.EOF,
152 pexpect.TIMEOUT ] )
153 while True:
154 i = self.handle.expect( [ 'mininet>',
155 '\*\*\*',
156 'Exception',
157 pexpect.EOF,
158 pexpect.TIMEOUT ],
159 timeout )
160 if i == 0:
161 main.log.info( self.name + ": mininet built" )
162 return main.TRUE
163 if i == 1:
164 self.handle.expect(
165 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
166 main.log.info( self.handle.before )
167 elif i == 2:
168 main.log.error(
169 self.name +
170 ": Launching mininet failed..." )
171 return main.FALSE
172 elif i == 3:
173 main.log.error( self.name + ": Connection timeout" )
174 return main.FALSE
175 elif i == 4: # timeout
176 main.log.error(
177 self.name +
178 ": Something took too long... " )
179 return main.FALSE
180 return main.TRUE
181 else:
182 main.log.info( "Starting topo file " + topoFile )
183 if args == None:
184 args = ''
185 else:
186 main.log.info( "args = " + args)
187 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
188 i = 1
Jon Hall7eb38402015-01-08 17:19:54 -0800189 i = self.handle.expect( [ 'mininet>',
kelvin-onlaba1484582015-02-02 15:46:20 -0800190 pexpect.EOF ,
191 pexpect.TIMEOUT ],
192 timeout)
193 main.log.info(self.name + ": Network started")
194 return main.TRUE
195
Jon Hall7eb38402015-01-08 17:19:54 -0800196 else: # if no handle
197 main.log.error(
198 self.name +
199 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800200 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800201 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800202 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800203 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700204 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800205
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800206 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400207 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800208 # In tree topology, if fanout arg is not given, by default it is 2
209 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400210 fanout = 2
211 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500212 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800213 while( k <= depth - 1 ):
214 count = count + pow( fanout, k )
215 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800217 while( k <= depth - 2 ):
218 # depth-2 gives you only core links and not considering
219 # edge links as seen by ONOS. If all the links including
220 # edge links are required, do depth-1
221 count = count + pow( fanout, k )
222 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800224 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800225 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800226
Jon Hall7eb38402015-01-08 17:19:54 -0800227 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800229 # by default it is 1
230 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400231 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 numSwitches = depth
233 numHostsPerSw = fanout
234 totalNumHosts = numSwitches * numHostsPerSw
235 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800236 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400238 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800239 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 "num_switches": int( numSwitches ),
241 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400242 return topoDict
243
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 def calculateSwAndLinks( self ):
245 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400246 return topoDict
247
Jon Hall7eb38402015-01-08 17:19:54 -0800248 def pingall( self, timeout=300 ):
249 """
250 Verifies the reachability of the hosts using pingall command.
251 Optional parameter timeout allows you to specify how long to
252 wait for pingall to complete
253 Returns:
254 main.TRUE if pingall completes with no pings dropped
255 otherwise main.FALSE"""
256 if self.handle:
257 main.log.info(
258 self.name +
259 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700260 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800261 response = self.execute(
262 cmd="pingall",
263 prompt="mininet>",
264 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500265 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800266 main.log.error( self.name + ": EOF exception found" )
267 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500268 main.cleanup()
269 main.exit()
270 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800271 # We may not want to kill the test if pexpect times out
272 main.log.error( self.name + ": TIMEOUT exception found" )
273 main.log.error( self.name +
274 ": " +
275 str( self.handle.before ) )
276 # NOTE: mininet's pingall rounds, so we will check the number of
277 # passed and number of failed
278 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800280 if re.search( pattern, response ):
281 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700282 return main.TRUE
283 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800284 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800286 # NOTE: Send ctrl-c to make sure pingall is done
287 self.handle.send( "\x03" )
288 self.handle.expect( "Interrupt" )
289 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700290 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800291 else:
292 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500293 main.cleanup()
294 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700295
Jon Hall7eb38402015-01-08 17:19:54 -0800296 def fpingHost( self, **pingParams ):
297 """
298 Uses the fping package for faster pinging...
299 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800300 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800301 command = args[ "SRC" ] + \
302 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
303 self.handle.sendline( command )
304 self.handle.expect(
305 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
306 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
307 response = self.handle.before
308 if re.search( ":\s-", response ):
309 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700310 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800311 elif re.search( ":\s\d{1,2}\.\d\d", response ):
312 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700313 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800314 main.log.info( self.name + ": Install fping on mininet machine... " )
315 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700316 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800317
Jon Hall7eb38402015-01-08 17:19:54 -0800318 def pingHost( self, **pingParams ):
319 """
320 Ping from one mininet host to another
321 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800322 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800323 command = args[ "SRC" ] + " ping " + \
324 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700325 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800326 main.log.warn( "Sending: " + command )
327 self.handle.sendline( command )
328 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700329 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800330 main.log.error(
331 self.name +
332 ": timeout when waiting for response from mininet" )
333 main.log.error( "response: " + str( self.handle.before ) )
334 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700335 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800336 main.log.error(
337 self.name +
338 ": timeout when waiting for response from mininet" )
339 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700340 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800341 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800342 main.log.error( self.name + ": EOF exception found" )
343 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700344 main.cleanup()
345 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800346 main.log.info( self.name + ": Ping Response: " + response )
347 if re.search( ',\s0\%\spacket\sloss', response ):
348 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800349 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700350 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800351 else:
352 main.log.error(
353 self.name +
354 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800355 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700356 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800357
Jon Hall7eb38402015-01-08 17:19:54 -0800358 def checkIP( self, host ):
359 """
360 Verifies the host's ip configured or not."""
361 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700362 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800363 response = self.execute(
364 cmd=host +
365 " ifconfig",
366 prompt="mininet>",
367 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800368 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800369 main.log.error( self.name + ": EOF exception found" )
370 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700371 main.cleanup()
372 main.exit()
adminbae64d82013-08-01 10:50:15 -0700373
Jon Hall7eb38402015-01-08 17:19:54 -0800374 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800375 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
376 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
377 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
378 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
379 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800380 # pattern = "inet addr:10.0.0.6"
381 if re.search( pattern, response ):
382 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700383 return main.TRUE
384 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800385 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700386 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800387 else:
388 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800389
Jon Hall7eb38402015-01-08 17:19:54 -0800390 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700391 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800392 response = self.execute(
393 cmd="h1 /usr/sbin/sshd -D&",
394 prompt="mininet>",
395 timeout=10 )
396 response = self.execute(
397 cmd="h4 /usr/sbin/sshd -D&",
398 prompt="mininet>",
399 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700400 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800401 vars( self )[ key ] = connectargs[ key ]
402 response = self.execute(
403 cmd="xterm h1 h4 ",
404 prompt="mininet>",
405 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800406 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800407 main.log.error( self.name + ": EOF exception found" )
408 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700409 main.cleanup()
410 main.exit()
adminbae64d82013-08-01 10:50:15 -0700411 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800412 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700413 if self.flag == 0:
414 self.flag = 1
415 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800416 else:
adminbae64d82013-08-01 10:50:15 -0700417 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800418
kelvin-onlaba1484582015-02-02 15:46:20 -0800419 def moveHost( self, host, oldSw, newSw, ):
420 """
421 Moves a host from one switch to another on the fly
422 Note: The intf between host and oldSw when detached
423 using detach(), will still show up in the 'net'
424 cmd, because switch.detach() doesn't affect switch.intfs[]
425 (which is correct behavior since the interfaces
426 haven't moved).
427 """
428 if self.handle:
429 try:
430 # Bring link between oldSw-host down
431 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
432 "'down')"
433 print "cmd1= ", cmd
434 response = self.execute(
435 cmd=cmd,
436 prompt="mininet>",
437 timeout=10 )
438
439 # Determine hostintf and Oldswitchintf
440 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
441 ")[0]"
442 print "cmd2= ", cmd
443 self.handle.sendline( cmd )
444 self.handle.expect( "mininet>" )
445
shahshreya73537862015-02-11 15:15:24 -0800446 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800447 cmd = "px ipaddr = hintf.IP()"
448 print "cmd3= ", cmd
449 self.handle.sendline( cmd )
450 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800451
452 cmd = "px macaddr = hintf.MAC()"
453 print "cmd3= ", cmd
454 self.handle.sendline( cmd )
455 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800456
457 # Detach interface between oldSw-host
458 cmd = "px " + oldSw + ".detach( sintf )"
459 print "cmd4= ", cmd
460 self.handle.sendline( cmd )
461 self.handle.expect( "mininet>" )
462
463 # Add link between host-newSw
464 cmd = "py net.addLink(" + host + "," + newSw + ")"
465 print "cmd5= ", cmd
466 self.handle.sendline( cmd )
467 self.handle.expect( "mininet>" )
468
469 # Determine hostintf and Newswitchintf
470 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
471 ")[0]"
472 print "cmd6= ", cmd
473 self.handle.sendline( cmd )
474 self.handle.expect( "mininet>" )
475
476 # Attach interface between newSw-host
477 cmd = "px " + newSw + ".attach( sintf )"
478 print "cmd3= ", cmd
479 self.handle.sendline( cmd )
480 self.handle.expect( "mininet>" )
481
482 # Set ipaddress of the host-newSw interface
483 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
484 print "cmd7 = ", cmd
485 self.handle.sendline( cmd )
486 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800487
488 # Set macaddress of the host-newSw interface
489 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
490 print "cmd8 = ", cmd
491 self.handle.sendline( cmd )
492 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800493
494 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800495 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800496 self.handle.sendline( cmd )
497 self.handle.expect( "mininet>" )
498 print "output = ", self.handle.before
499
500 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800501 cmd = host + " ifconfig"
502 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800503 self.handle.sendline( cmd )
504 self.handle.expect( "mininet>" )
505 print "ifconfig o/p = ", self.handle.before
506
507 return main.TRUE
508 except pexpect.EOF:
509 main.log.error( self.name + ": EOF exception found" )
510 main.log.error( self.name + ": " + self.handle.before )
511 return main.FALSE
512
Jon Hall7eb38402015-01-08 17:19:54 -0800513 def changeIP( self, host, intf, newIP, newNetmask ):
514 """
515 Changes the ip address of a host on the fly
516 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800517 if self.handle:
518 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800519 cmd = host + " ifconfig " + intf + " " + \
520 newIP + " " + 'netmask' + " " + newNetmask
521 self.handle.sendline( cmd )
522 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800523 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800524 main.log.info( "response = " + response )
525 main.log.info(
526 "Ip of host " +
527 host +
528 " changed to new IP " +
529 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800530 return main.TRUE
531 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800532 main.log.error( self.name + ": EOF exception found" )
533 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800534 return main.FALSE
535
Jon Hall7eb38402015-01-08 17:19:54 -0800536 def changeDefaultGateway( self, host, newGW ):
537 """
538 Changes the default gateway of a host
539 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800540 if self.handle:
541 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800542 cmd = host + " route add default gw " + newGW
543 self.handle.sendline( cmd )
544 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800545 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800546 main.log.info( "response = " + response )
547 main.log.info(
548 "Default gateway of host " +
549 host +
550 " changed to " +
551 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800552 return main.TRUE
553 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800554 main.log.error( self.name + ": EOF exception found" )
555 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800556 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800557
Jon Hall7eb38402015-01-08 17:19:54 -0800558 def addStaticMACAddress( self, host, GW, macaddr ):
559 """
560 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800561 if self.handle:
562 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800563 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
564 cmd = host + " arp -s " + GW + " " + macaddr
565 self.handle.sendline( cmd )
566 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800567 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800568 main.log.info( "response = " + response )
569 main.log.info(
570 "Mac adrress of gateway " +
571 GW +
572 " changed to " +
573 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800574 return main.TRUE
575 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800576 main.log.error( self.name + ": EOF exception found" )
577 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800578 return main.FALSE
579
Jon Hall7eb38402015-01-08 17:19:54 -0800580 def verifyStaticGWandMAC( self, host ):
581 """
582 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800583 if self.handle:
584 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800585 # h1 arp -an
586 cmd = host + " arp -an "
587 self.handle.sendline( cmd )
588 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800589 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800590 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800591 return main.TRUE
592 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800595 return main.FALSE
596
Jon Hall7eb38402015-01-08 17:19:54 -0800597 def getMacAddress( self, host ):
598 """
599 Verifies the host's ip configured or not."""
600 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700601 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800602 response = self.execute(
603 cmd=host +
604 " ifconfig",
605 prompt="mininet>",
606 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800607 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800608 main.log.error( self.name + ": EOF exception found" )
609 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700610 main.cleanup()
611 main.exit()
adminbae64d82013-08-01 10:50:15 -0700612
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700613 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 macAddressSearch = re.search( pattern, response, re.I )
615 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800616 main.log.info(
617 self.name +
618 ": Mac-Address of Host " +
619 host +
620 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 macAddress )
622 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700623 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800624 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700625
Jon Hall7eb38402015-01-08 17:19:54 -0800626 def getInterfaceMACAddress( self, host, interface ):
627 """
628 Return the IP address of the interface on the given host"""
629 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700630 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800631 response = self.execute( cmd=host + " ifconfig " + interface,
632 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800633 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800634 main.log.error( self.name + ": EOF exception found" )
635 main.log.error( self.name + ": " + self.handle.before )
636 main.cleanup()
637 main.exit()
638
639 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 macAddressSearch = re.search( pattern, response, re.I )
641 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800642 main.log.info( "No mac address found in %s" % response )
643 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800644 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800645 main.log.info(
646 "Mac-Address of " +
647 host +
648 ":" +
649 interface +
650 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800651 macAddress )
652 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800653 else:
654 main.log.error( "Connection failed to the host" )
655
656 def getIPAddress( self, host ):
657 """
658 Verifies the host's ip configured or not."""
659 if self.handle:
660 try:
661 response = self.execute(
662 cmd=host +
663 " ifconfig",
664 prompt="mininet>",
665 timeout=10 )
666 except pexpect.EOF:
667 main.log.error( self.name + ": EOF exception found" )
668 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700669 main.cleanup()
670 main.exit()
adminbae64d82013-08-01 10:50:15 -0700671
672 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800673 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800674 main.log.info(
675 self.name +
676 ": IP-Address of Host " +
677 host +
678 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 ipAddressSearch.group( 1 ) )
680 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800681 else:
682 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800683
Jon Hall7eb38402015-01-08 17:19:54 -0800684 def getSwitchDPID( self, switch ):
685 """
686 return the datapath ID of the switch"""
687 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700688 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700689 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800690 response = self.execute(
691 cmd=cmd,
692 prompt="mininet>",
693 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800694 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800695 main.log.error( self.name + ": EOF exception found" )
696 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700697 main.cleanup()
698 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800699 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800700 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700701 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800702 main.log.info(
703 "Couldn't find DPID for switch %s, found: %s" %
704 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700705 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800706 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700707 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800708 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700709
Jon Hall7eb38402015-01-08 17:19:54 -0800710 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700711 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800712 self.handle.sendline( "" )
713 self.expect( "mininet>" )
714 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700715 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800716 response = self.execute(
717 cmd=cmd,
718 prompt="mininet>",
719 timeout=10 )
720 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700721 response = self.handle.before
722 return response
723 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800724 main.log.error( self.name + ": EOF exception found" )
725 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700726 main.cleanup()
727 main.exit()
728
Jon Hall7eb38402015-01-08 17:19:54 -0800729 def getInterfaces( self, node ):
730 """
731 return information dict about interfaces connected to the node"""
732 if self.handle:
733 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800734 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700735 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700736 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800737 response = self.execute(
738 cmd=cmd,
739 prompt="mininet>",
740 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800741 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800742 main.log.error( self.name + ": EOF exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700744 main.cleanup()
745 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700746 return response
747 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700749
Jon Hall7eb38402015-01-08 17:19:54 -0800750 def dump( self ):
751 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700752 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800753 response = self.execute(
754 cmd='dump',
755 prompt='mininet>',
756 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800757 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800758 main.log.error( self.name + ": EOF exception found" )
759 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700760 main.cleanup()
761 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700762 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800763
Jon Hall7eb38402015-01-08 17:19:54 -0800764 def intfs( self ):
765 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700766 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800767 response = self.execute(
768 cmd='intfs',
769 prompt='mininet>',
770 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800771 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700774 main.cleanup()
775 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700776 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800777
Jon Hall7eb38402015-01-08 17:19:54 -0800778 def net( self ):
779 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700780 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800781 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800782 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700785 main.cleanup()
786 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700787 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800788
789 def iperf( self, host1, host2 ):
790 main.log.info(
791 self.name +
792 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700793 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800794 cmd1 = 'iperf ' + host1 + " " + host2
795 self.handle.sendline( cmd1 )
796 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800797 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800798 if re.search( 'Results:', response ):
799 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800800 return main.TRUE
801 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800802 main.log.error( self.name + ": iperf test failed" )
803 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800804 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800807 main.cleanup()
808 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800809
Jon Hall7eb38402015-01-08 17:19:54 -0800810 def iperfudp( self ):
811 main.log.info(
812 self.name +
813 ": Simple iperf TCP test between two " +
814 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700815 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800816 response = self.execute(
817 cmd='iperfudp',
818 prompt='mininet>',
819 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800820 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800821 main.log.error( self.name + ": EOF exception found" )
822 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700823 main.cleanup()
824 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700825 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800826
Jon Hall7eb38402015-01-08 17:19:54 -0800827 def nodes( self ):
828 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700829 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800830 response = self.execute(
831 cmd='nodes',
832 prompt='mininet>',
833 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800834 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800835 main.log.error( self.name + ": EOF exception found" )
836 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700837 main.cleanup()
838 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700839 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800840
Jon Hall7eb38402015-01-08 17:19:54 -0800841 def pingpair( self ):
842 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700843 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800844 response = self.execute(
845 cmd='pingpair',
846 prompt='mininet>',
847 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800848 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700851 main.cleanup()
852 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800853
Jon Hall7eb38402015-01-08 17:19:54 -0800854 if re.search( ',\s0\%\spacket\sloss', response ):
855 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700857 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800858 else:
859 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700861 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800862
Jon Hall7eb38402015-01-08 17:19:54 -0800863 def link( self, **linkargs ):
864 """
865 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800866 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800867 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
868 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
869 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
870 main.log.info(
871 "Bring link between '" +
872 end1 +
873 "' and '" +
874 end2 +
875 "' '" +
876 option +
877 "'" )
878 command = "link " + \
879 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700880 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800881 self.handle.sendline( command )
882 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800883 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800884 main.log.error( self.name + ": EOF exception found" )
885 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700886 main.cleanup()
887 main.exit()
adminbae64d82013-08-01 10:50:15 -0700888 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800889
Jon Hall7eb38402015-01-08 17:19:54 -0800890 def yank( self, **yankargs ):
891 """
892 yank a mininet switch interface to a host"""
893 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800894 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800895 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
896 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
897 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700898 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800899 response = self.execute(
900 cmd=command,
901 prompt="mininet>",
902 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800903 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800904 main.log.error( self.name + ": EOF exception found" )
905 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700906 main.cleanup()
907 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700908 return main.TRUE
909
Jon Hall7eb38402015-01-08 17:19:54 -0800910 def plug( self, **plugargs ):
911 """
912 plug the yanked mininet switch interface to a switch"""
913 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800914 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800915 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
916 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
917 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700918 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800919 response = self.execute(
920 cmd=command,
921 prompt="mininet>",
922 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800923 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800924 main.log.error( self.name + ": EOF exception found" )
925 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700926 main.cleanup()
927 main.exit()
adminbae64d82013-08-01 10:50:15 -0700928 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800929
Jon Hall7eb38402015-01-08 17:19:54 -0800930 def dpctl( self, **dpctlargs ):
931 """
932 Run dpctl command on all switches."""
933 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800934 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800935 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
936 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
937 command = "dpctl " + cmd + " " + str( cmdargs )
938 try:
939 response = self.execute(
940 cmd=command,
941 prompt="mininet>",
942 timeout=10 )
943 except pexpect.EOF:
944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
946 main.cleanup()
947 main.exit()
948 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800949
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 def getVersion( self ):
951 fileInput = path + '/lib/Mininet/INSTALL'
952 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700953 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800955 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700956 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800957 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500958 return version
adminbae64d82013-08-01 10:50:15 -0700959
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800961 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500962 Parameters:
963 sw: The name of an OVS switch. Example "s1"
964 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800965 The output of the command from the mininet cli
966 or main.FALSE on timeout"""
967 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700968 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800969 response = self.execute(
970 cmd=command,
971 prompt="mininet>",
972 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700973 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500974 return response
admin2a9548d2014-06-17 14:08:07 -0700975 else:
976 return main.FALSE
977 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800978 main.log.error( self.name + ": EOF exception found" )
979 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700980 main.cleanup()
981 main.exit()
adminbae64d82013-08-01 10:50:15 -0700982
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800984 """
985 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800986 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800987 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700988
989 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800990 for j in range( count ):
991 argstring = argstring + ",IP" + \
992 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800993 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700994
Jon Hall7eb38402015-01-08 17:19:54 -0800995 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
996 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800997 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800998 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800999
Jon Hall7eb38402015-01-08 17:19:54 -08001000 command = "sh ovs-vsctl set-controller s" + \
1001 str( sw ) + " " + ptcpB + " "
1002 for j in range( count ):
1003 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001004 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001005 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1006 ip = args[
1007 "IP" +
1008 str( i ) ] if args[
1009 "IP" +
1010 str( i ) ] is not None else ""
1011 port = args[
1012 "PORT" +
1013 str( i ) ] if args[
1014 "PORT" +
1015 str( i ) ] is not None else ""
1016 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001017 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001018 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001019 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001020 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001021 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001022 main.log.error( self.name + ": EOF exception found" )
1023 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001024 main.cleanup()
1025 main.exit()
1026 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001027 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001028 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001029 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001030 main.cleanup()
1031 main.exit()
adminbae64d82013-08-01 10:50:15 -07001032
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001034 """
1035 Removes the controller target from sw"""
1036 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001037 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001038 response = self.execute(
1039 cmd=command,
1040 prompt="mininet>",
1041 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001042 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001043 main.log.error( self.name + ": EOF exception found" )
1044 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001045 main.cleanup()
1046 main.exit()
1047 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001048 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001049
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001051 """
Jon Hallb1290e82014-11-18 16:17:48 -05001052 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001053 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001054 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001055 NOTE: cannot currently specify what type of switch
1056 required params:
1057 switchname = name of the new switch as a string
1058 optional keyvalues:
1059 dpid = "dpid"
1060 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001061 """
1062 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001063 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001064 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001065 response = self.execute(
1066 cmd=command,
1067 prompt="mininet>",
1068 timeout=10 )
1069 if re.search( "already exists!", response ):
1070 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001071 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001072 elif re.search( "Error", 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( "usage:", response ):
1076 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001077 return main.FALSE
1078 else:
1079 return main.TRUE
1080 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001081 main.log.error( self.name + ": EOF exception found" )
1082 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001083 main.cleanup()
1084 main.exit()
1085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001087 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001088 delete a switch from the mininet topology
1089 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001090 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001091 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001092 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001093 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001094 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001095 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001096 response = self.execute(
1097 cmd=command,
1098 prompt="mininet>",
1099 timeout=10 )
1100 if re.search( "no switch named", response ):
1101 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001102 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001103 elif re.search( "Error", 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( "usage:", response ):
1107 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001108 return main.FALSE
1109 else:
1110 return main.TRUE
1111 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001112 main.log.error( self.name + ": EOF exception found" )
1113 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001114 main.cleanup()
1115 main.exit()
1116
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001118 """
1119 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001120 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001121 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001122 NOTE: cannot currently specify what type of link
1123 required params:
1124 node1 = the string node name of the first endpoint of the link
1125 node2 = the string node name of the second endpoint of the link
1126 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001127 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001128 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001129 response = self.execute(
1130 cmd=command,
1131 prompt="mininet>",
1132 timeout=10 )
1133 if re.search( "doesnt exist!", response ):
1134 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001135 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001136 elif re.search( "Error", 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( "usage:", response ):
1140 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001141 return main.FALSE
1142 else:
1143 return main.TRUE
1144 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001145 main.log.error( self.name + ": EOF exception found" )
1146 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001147 main.cleanup()
1148 main.exit()
1149
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001151 """
1152 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001153 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001154 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001155 required params:
1156 node1 = the string node name of the first endpoint of the link
1157 node2 = the string node name of the second endpoint of the link
1158 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001159 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001160 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001161 response = self.execute(
1162 cmd=command,
1163 prompt="mininet>",
1164 timeout=10 )
1165 if re.search( "no node named", response ):
1166 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001167 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001168 elif re.search( "Error", 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( "usage:", response ):
1172 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001173 return main.FALSE
1174 else:
1175 return main.TRUE
1176 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001177 main.log.error( self.name + ": EOF exception found" )
1178 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001179 main.cleanup()
1180 main.exit()
1181
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001183 """
Jon Hallb1290e82014-11-18 16:17:48 -05001184 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001185 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001186 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001187 NOTE: cannot currently specify what type of host
1188 required params:
1189 hostname = the string hostname
1190 optional key-value params
1191 switch = "switch name"
1192 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001193 """
1194 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001195 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001196 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001197 response = self.execute(
1198 cmd=command,
1199 prompt="mininet>",
1200 timeout=10 )
1201 if re.search( "already exists!", response ):
1202 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001203 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001204 elif re.search( "doesnt 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( "Error", 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( "usage:", response ):
1211 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001212 return main.FALSE
1213 else:
1214 return main.TRUE
1215 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 main.log.error( self.name + ": EOF exception found" )
1217 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001218 main.cleanup()
1219 main.exit()
1220
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001222 """
1223 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001224 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001225 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001226 NOTE: this uses a custom mn function
1227 required params:
1228 hostname = the string hostname
1229 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001230 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001231 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001232 response = self.execute(
1233 cmd=command,
1234 prompt="mininet>",
1235 timeout=10 )
1236 if re.search( "no host named", response ):
1237 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001238 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001239 elif re.search( "Error", 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( "usage:", response ):
1243 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001244 return main.FALSE
1245 else:
1246 return main.TRUE
1247 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001248 main.log.error( self.name + ": EOF exception found" )
1249 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001250 main.cleanup()
1251 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001252
Jon Hall7eb38402015-01-08 17:19:54 -08001253 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001254 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001255 Called at the end of the test to stop the mininet and
1256 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001257 """
1258 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001259 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
1260 timeout = 2)
kelvin-onlaba1484582015-02-02 15:46:20 -08001261 if i == 0:
1262 self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001263 elif i == 1:
1264 return main.TRUE
1265 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001266 # print "Disconnecting Mininet"
1267 if self.handle:
1268 self.handle.sendline( "exit" )
1269 self.handle.expect( "exit" )
1270 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001271 else:
1272 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001273 return response
1274
1275 def stopNet( self ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001276 """
Jon Hall21270ac2015-02-16 17:59:55 -08001277 Stops mininet.
1278 Returns main.TRUE if the mininet succesfully stops and
1279 main.FALSE if the pexpect handle does not exist.
1280
Jon Halld61331b2015-02-17 16:35:47 -08001281 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001282 """
Jon Hall21270ac2015-02-16 17:59:55 -08001283
Jon Halld61331b2015-02-17 16:35:47 -08001284 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001285 response = ''
1286 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001287 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001288 response = self.execute(
1289 cmd="exit",
1290 prompt="(.*)",
1291 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001292 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001293 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001294 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001295 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001296 main.log.error( self.name + ": EOF exception found" )
1297 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001298 main.cleanup()
1299 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001300 else:
1301 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001302 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001303 return response
1304
kelvin-onlaba1484582015-02-02 15:46:20 -08001305
1306
Jon Hall7eb38402015-01-08 17:19:54 -08001307 def arping( self, src, dest, destmac ):
1308 self.handle.sendline( '' )
1309 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001310
Jon Hall7eb38402015-01-08 17:19:54 -08001311 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001312 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001313 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1314 main.log.info( self.name + ": ARP successful" )
1315 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001316 return main.TRUE
1317 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001318 main.log.warn( self.name + ": ARP FAILURE" )
1319 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001320 return main.FALSE
1321
Jon Hall7eb38402015-01-08 17:19:54 -08001322 def decToHex( self, num ):
1323 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001324
Jon Hall7eb38402015-01-08 17:19:54 -08001325 def getSwitchFlowCount( self, switch ):
1326 """
1327 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001328 if self.handle:
1329 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1330 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001331 response = self.execute(
1332 cmd=cmd,
1333 prompt="mininet>",
1334 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001335 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001336 main.log.error( self.name + ": EOF exception found" )
1337 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001338 main.cleanup()
1339 main.exit()
1340 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001341 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001342 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001343 main.log.info(
1344 "Couldn't find flows on switch %s, found: %s" %
1345 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001346 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001347 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001348 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001349 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001350
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 def checkFlows( self, sw, dumpFormat=None ):
1352 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001353 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001355 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001356 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001357 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001358 response = self.execute(
1359 cmd=command,
1360 prompt="mininet>",
1361 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001362 return response
1363 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001364 main.log.error( self.name + ": EOF exception found" )
1365 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001366 main.cleanup()
1367 main.exit()
1368 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001369 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001370
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001372 """
1373 Runs tpdump on an intferface and saves the file
1374 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001375 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 self.handle.sendline( "" )
1377 self.handle.expect( "mininet>" )
1378 self.handle.sendline(
1379 "sh sudo tcpdump -n -i " +
1380 intf +
1381 " " +
1382 port +
1383 " -w " +
1384 filename.strip() +
1385 " &" )
1386 self.handle.sendline( "" )
1387 i = self.handle.expect( [ 'No\ssuch\device',
1388 'listening\son',
1389 pexpect.TIMEOUT,
1390 "mininet>" ],
1391 timeout=10 )
1392 main.log.warn( self.handle.before + self.handle.after )
1393 self.handle.sendline( "" )
1394 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001395 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001396 main.log.error(
1397 self.name +
1398 ": tcpdump - No such device exists. " +
1399 "tcpdump attempted on: " +
1400 intf )
admin2a9548d2014-06-17 14:08:07 -07001401 return main.FALSE
1402 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001403 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001404 return main.TRUE
1405 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001406 main.log.error(
1407 self.name +
1408 ": tcpdump command timed out! Check interface name," +
1409 " given interface was: " +
1410 intf )
admin2a9548d2014-06-17 14:08:07 -07001411 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001412 elif i == 3:
1413 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001414 return main.TRUE
1415 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001416 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001417 return main.FALSE
1418 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001419 main.log.error( self.name + ": EOF exception found" )
1420 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001421 main.cleanup()
1422 main.exit()
1423 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001425 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001426 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001427 main.cleanup()
1428 main.exit()
1429
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001431 "pkills tcpdump"
1432 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001433 self.handle.sendline( "sh sudo pkill tcpdump" )
1434 self.handle.expect( "mininet>" )
1435 self.handle.sendline( "" )
1436 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001437 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001438 main.log.error( self.name + ": EOF exception found" )
1439 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001440 main.cleanup()
1441 main.exit()
1442 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001443 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001444 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001445 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001446 main.cleanup()
1447 main.exit()
1448
kelvin-onlabd3b64892015-01-20 13:26:24 -08001449 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001450 """
1451 Compare mn and onos switches
1452 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001454
Jon Hall7eb38402015-01-08 17:19:54 -08001455 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001456 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001457 output = { "switches": [] }
1458 # iterate through the MN topology and pull out switches and and port
1459 # info
1460 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001461 ports = []
1462 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001463 ports.append( { 'of_port': port.port_no,
1464 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001466 'name': port.name } )
1467 output[ 'switches' ].append( {
1468 "name": switch.name,
1469 "dpid": str( switch.dpid ).zfill( 16 ),
1470 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001471
Jon Hall7eb38402015-01-08 17:19:54 -08001472 # print "mn"
1473 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001474 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001475 # indent=4,
1476 # separators=( ',', ': ' ) )
1477 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 # print json.dumps( switchesJson,
1479 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001480 # indent=4,
1481 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001482
1483 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001484 mnDPIDs = []
1485 for switch in output[ 'switches' ]:
1486 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001487 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001488 # print "List of Mininet switch DPID's"
1489 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001491 main.log.error(
1492 self.name +
1493 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001494 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001496 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001497 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001498 if switch[ 'available' ]:
1499 onosDPIDs.append(
1500 switch[ 'id' ].replace(
1501 ":",
1502 '' ).replace(
1503 "of",
1504 '' ).lower() )
1505 # else:
1506 # print "Switch is unavailable:"
1507 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001508 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001509 # print "List of ONOS switch DPID's"
1510 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001511
Jon Hall7eb38402015-01-08 17:19:54 -08001512 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001513 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001514 main.log.report( "Switches in MN but not in ONOS:" )
1515 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1516 main.log.report( str( list1 ) )
1517 main.log.report( "Switches in ONOS but not in MN:" )
1518 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001519 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001520 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 switchResults = main.TRUE
1522 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001523
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001525 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001526 Compare mn and onos ports
1527 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001529
Jon Hallfbc828e2015-01-06 17:30:19 -08001530 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001531 1. This uses the sts TestONTopology object
1532 2. numpy - "sudo pip install numpy"
1533
Jon Hall7eb38402015-01-08 17:19:54 -08001534 """
1535 # FIXME: this does not look for extra ports in ONOS, only checks that
1536 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001537 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001539 output = { "switches": [] }
1540 # iterate through the MN topology and pull out switches and and port
1541 # info
1542 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001543 ports = []
1544 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001545 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001547 tmpPort[ 'of_port' ] = port.port_no
1548 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 tmpPort[ 'name' ] = port.name
1550 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001551
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 ports.append( tmpPort )
1553 tmpSwitch = {}
1554 tmpSwitch[ 'name' ] = switch.name
1555 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1556 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001557
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001559
Jon Hall7eb38402015-01-08 17:19:54 -08001560 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 for mnSwitch in output[ 'switches' ]:
1562 mnPorts = []
1563 onosPorts = []
1564 switchResult = main.TRUE
1565 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001566 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 mnPorts.append( port[ 'of_port' ] )
1568 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001569 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001570 # print onosSwitch
1571 if onosSwitch[ 'device' ][ 'available' ]:
1572 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001573 ':',
1574 '' ).replace(
1575 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 '' ) == mnSwitch[ 'dpid' ]:
1577 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001578 if port[ 'isEnabled' ]:
1579 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 # onosPorts.append( 'local' )
1581 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001582 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001584 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 mnPorts.sort( key=float )
1586 onosPorts.sort( key=float )
1587 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1588 # print "\tmn_ports[] = ", mnPorts
1589 # print "\tonos_ports[] = ", onosPorts
1590 mnPortsLog = mnPorts
1591 onosPortsLog = onosPorts
1592 mnPorts = [ x for x in mnPorts ]
1593 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001594
Jon Hall7eb38402015-01-08 17:19:54 -08001595 # TODO: handle other reserved port numbers besides LOCAL
1596 # NOTE: Reserved ports
1597 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1598 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 for mnPort in mnPortsLog:
1600 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001601 # don't set results to true here as this is just one of
1602 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 mnPorts.remove( mnPort )
1604 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001605 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001606 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001607 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 if 65534 in mnPorts:
1609 mnPorts.remove( 65534 )
1610 if long( uint64( -2 ) ) in onosPorts:
1611 onosPorts.remove( long( uint64( -2 ) ) )
1612 if len( mnPorts ): # the ports of this switch don't match
1613 switchResult = main.FALSE
1614 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1615 if len( onosPorts ): # the ports of this switch don't match
1616 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001617 main.log.warn(
1618 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001619 str( onosPorts ) )
1620 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001621 main.log.report(
1622 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1624 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1625 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1626 portsResults = portsResults and switchResult
1627 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001628
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001630 """
1631 Compare mn and onos links
1632 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001633 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001634
Jon Hall7eb38402015-01-08 17:19:54 -08001635 This uses the sts TestONTopology object"""
1636 # FIXME: this does not look for extra links in ONOS, only checks that
1637 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001639 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001641 # iterate through the MN topology and pull out switches and and port
1642 # info
1643 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001644 # print "Iterating though switches as seen by Mininet"
1645 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001646 ports = []
1647 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001648 # print port.hw_addr.toStr( separator='' )
1649 ports.append( { 'of_port': port.port_no,
1650 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001652 'name': port.name } )
1653 output[ 'switches' ].append( {
1654 "name": switch.name,
1655 "dpid": str( switch.dpid ).zfill( 16 ),
1656 "ports": ports } )
1657 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001658
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001660 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001661 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 if 2 * len( mnLinks ) == len( onos ):
1663 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001664 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001665 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001666 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001667 "Mininet has " + str( len( mnLinks ) ) +
1668 " bidirectional links and ONOS has " +
1669 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001670
Jon Hall7eb38402015-01-08 17:19:54 -08001671 # iterate through MN links and check if an ONOS link exists in
1672 # both directions
1673 # NOTE: Will currently only show mn links as down if they are
1674 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001675 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001676 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001678 # print "Link: %s" % link
1679 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001680 node1 = None
1681 port1 = None
1682 node2 = None
1683 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 firstDir = main.FALSE
1685 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001686 for switch in output[ 'switches' ]:
1687 # print "Switch: %s" % switch[ 'name' ]
1688 if switch[ 'name' ] == link.node1.name:
1689 node1 = switch[ 'dpid' ]
1690 for port in switch[ 'ports' ]:
1691 if str( port[ 'name' ] ) == str( link.port1 ):
1692 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001693 if node1 is not None and node2 is not None:
1694 break
Jon Hall7eb38402015-01-08 17:19:54 -08001695 if switch[ 'name' ] == link.node2.name:
1696 node2 = switch[ 'dpid' ]
1697 for port in switch[ 'ports' ]:
1698 if str( port[ 'name' ] ) == str( link.port2 ):
1699 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001700 if node1 is not None and node2 is not None:
1701 break
1702
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 for onosLink in onos:
1704 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001705 ":",
1706 '' ).replace(
1707 "of",
1708 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001709 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001710 ":",
1711 '' ).replace(
1712 "of",
1713 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001714 onosPort1 = onosLink[ 'src' ][ 'port' ]
1715 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001716
Jon Hall72cf1dc2014-10-20 21:04:50 -04001717 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001718 if str( onosNode1 ) == str( node1 ) and str(
1719 onosNode2 ) == str( node2 ):
1720 if int( onosPort1 ) == int( port1 ) and int(
1721 onosPort2 ) == int( port2 ):
1722 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001723 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001724 main.log.warn(
1725 'The port numbers do not match for ' +
1726 str( link ) +
1727 ' between ONOS and MN. When cheking ONOS for ' +
1728 'link %s/%s -> %s/%s' %
1729 ( node1,
1730 port1,
1731 node2,
1732 port2 ) +
1733 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001734 ( onosNode1,
1735 onosPort1,
1736 onosNode2,
1737 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001738
1739 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 elif ( str( onosNode1 ) == str( node2 ) and
1741 str( onosNode2 ) == str( node1 ) ):
1742 if ( int( onosPort1 ) == int( port2 )
1743 and int( onosPort2 ) == int( port1 ) ):
1744 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001745 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001746 main.log.warn(
1747 'The port numbers do not match for ' +
1748 str( link ) +
1749 ' between ONOS and MN. When cheking ONOS for ' +
1750 'link %s/%s -> %s/%s' %
1751 ( node2,
1752 port2,
1753 node1,
1754 port1 ) +
1755 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001756 ( onosNode2,
1757 onosPort2,
1758 onosNode1,
1759 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001760 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001761 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001762 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001763 main.log.report(
1764 'ONOS does not have the link %s/%s -> %s/%s' %
1765 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001766 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001767 main.log.report(
1768 'ONOS does not have the link %s/%s -> %s/%s' %
1769 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 linkResults = linkResults and firstDir and secondDir
1771 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001772
kelvin-onlabd3b64892015-01-20 13:26:24 -08001773 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001774 """
1775 Returns a list of all hosts
1776 Don't ask questions just use it"""
1777 self.handle.sendline( "" )
1778 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001779
Jon Hall7eb38402015-01-08 17:19:54 -08001780 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1781 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001782
kelvin-onlabd3b64892015-01-20 13:26:24 -08001783 handlePy = self.handle.before
1784 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1785 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001786
Jon Hall7eb38402015-01-08 17:19:54 -08001787 self.handle.sendline( "" )
1788 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001789
kelvin-onlabd3b64892015-01-20 13:26:24 -08001790 hostStr = handlePy.replace( "]", "" )
1791 hostStr = hostStr.replace( "'", "" )
1792 hostStr = hostStr.replace( "[", "" )
1793 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001794
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 return hostList
adminbae64d82013-08-01 10:50:15 -07001796
Jon Hall7eb38402015-01-08 17:19:54 -08001797 def update( self ):
1798 """
1799 updates the port address and status information for
1800 each port in mn"""
1801 # TODO: Add error checking. currently the mininet command has no output
1802 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001803 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001804 self.handle.sendline( "" )
1805 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001806
Jon Hall7eb38402015-01-08 17:19:54 -08001807 self.handle.sendline( "update" )
1808 self.handle.expect( "update" )
1809 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001810
Jon Hall7eb38402015-01-08 17:19:54 -08001811 self.handle.sendline( "" )
1812 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001813
Jon Hallb1290e82014-11-18 16:17:48 -05001814 return main.TRUE
1815 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001816 main.log.error( self.name + ": EOF exception found" )
1817 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001818 main.cleanup()
1819 main.exit()
1820
adminbae64d82013-08-01 10:50:15 -07001821if __name__ != "__main__":
1822 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001823 sys.modules[ __name__ ] = MininetCliDriver()