blob: acef039c9ba2b86f6687919afb8ded940b30fc78 [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.
105 Returns true if the mininet starts successfully
106 """
Jon Hall7eb38402015-01-08 17:19:54 -0800107 if self.handle:
108 main.log.info(
109 self.name +
110 ": Clearing any residual state or processes" )
111 self.handle.sendline( "sudo mn -c" )
112 i = self.handle.expect( [ 'password\sfor\s',
113 'Cleanup\scomplete',
114 pexpect.EOF,
115 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800116 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800117 if i == 0:
118 main.log.info( self.name + ": Sending sudo password" )
119 self.handle.sendline( self.pwd )
120 i = self.handle.expect( [ '%s:' % ( self.user ),
121 '\$',
122 pexpect.EOF,
123 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800124 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800125 if i == 1:
126 main.log.info( self.name + ": Clean" )
127 elif i == 2:
128 main.log.error( self.name + ": Connection terminated" )
129 elif i == 3: # timeout
130 main.log.error(
131 self.name +
132 ": Something while cleaning MN took too long... " )
kelvin-onlaba1484582015-02-02 15:46:20 -0800133 if topoFile == '' and args == '':
134 main.log.info( self.name + ": building fresh mininet" )
135 # for reactive/PARP enabled tests
136 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
137 " " + self.options[ 'arg2' ] +\
138 " --mac --controller " +\
139 self.options[ 'controller' ] + " " +\
140 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -0800141
kelvin-onlaba1484582015-02-02 15:46:20 -0800142 argList = self.options[ 'arg1' ].split( "," )
143 global topoArgList
144 topoArgList = argList[ 0 ].split( " " )
145 argList = map( int, argList[ 1: ] )
146 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800147
kelvin-onlaba1484582015-02-02 15:46:20 -0800148 self.handle.sendline( cmdString )
149 self.handle.expect( [ "sudo mn",
150 pexpect.EOF,
151 pexpect.TIMEOUT ] )
152 while True:
153 i = self.handle.expect( [ 'mininet>',
154 '\*\*\*',
155 'Exception',
156 pexpect.EOF,
157 pexpect.TIMEOUT ],
158 timeout )
159 if i == 0:
160 main.log.info( self.name + ": mininet built" )
161 return main.TRUE
162 if i == 1:
163 self.handle.expect(
164 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
165 main.log.info( self.handle.before )
166 elif i == 2:
167 main.log.error(
168 self.name +
169 ": Launching mininet failed..." )
170 return main.FALSE
171 elif i == 3:
172 main.log.error( self.name + ": Connection timeout" )
173 return main.FALSE
174 elif i == 4: # timeout
175 main.log.error(
176 self.name +
177 ": Something took too long... " )
178 return main.FALSE
179 return main.TRUE
180 else:
181 main.log.info( "Starting topo file " + topoFile )
182 if args == None:
183 args = ''
184 else:
185 main.log.info( "args = " + args)
186 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
187 i = 1
Jon Hall7eb38402015-01-08 17:19:54 -0800188 i = self.handle.expect( [ 'mininet>',
kelvin-onlaba1484582015-02-02 15:46:20 -0800189 pexpect.EOF ,
190 pexpect.TIMEOUT ],
191 timeout)
192 main.log.info(self.name + ": Network started")
193 return main.TRUE
194
Jon Hall7eb38402015-01-08 17:19:54 -0800195 else: # if no handle
196 main.log.error(
197 self.name +
198 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800199 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800200 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800201 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800202 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700203 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800204
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800205 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400206 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800207 # In tree topology, if fanout arg is not given, by default it is 2
208 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400209 fanout = 2
210 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500211 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800212 while( k <= depth - 1 ):
213 count = count + pow( fanout, k )
214 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800216 while( k <= depth - 2 ):
217 # depth-2 gives you only core links and not considering
218 # edge links as seen by ONOS. If all the links including
219 # edge links are required, do depth-1
220 count = count + pow( fanout, k )
221 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800223 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800225
Jon Hall7eb38402015-01-08 17:19:54 -0800226 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800228 # by default it is 1
229 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400230 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 numSwitches = depth
232 numHostsPerSw = fanout
233 totalNumHosts = numSwitches * numHostsPerSw
234 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800235 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400237 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800238 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 "num_switches": int( numSwitches ),
240 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400241 return topoDict
242
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 def calculateSwAndLinks( self ):
244 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400245 return topoDict
246
Jon Hall7eb38402015-01-08 17:19:54 -0800247 def pingall( self, timeout=300 ):
248 """
249 Verifies the reachability of the hosts using pingall command.
250 Optional parameter timeout allows you to specify how long to
251 wait for pingall to complete
252 Returns:
253 main.TRUE if pingall completes with no pings dropped
254 otherwise main.FALSE"""
255 if self.handle:
256 main.log.info(
257 self.name +
258 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700259 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800260 response = self.execute(
261 cmd="pingall",
262 prompt="mininet>",
263 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500264 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800265 main.log.error( self.name + ": EOF exception found" )
266 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500267 main.cleanup()
268 main.exit()
269 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800270 # We may not want to kill the test if pexpect times out
271 main.log.error( self.name + ": TIMEOUT exception found" )
272 main.log.error( self.name +
273 ": " +
274 str( self.handle.before ) )
275 # NOTE: mininet's pingall rounds, so we will check the number of
276 # passed and number of failed
277 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800279 if re.search( pattern, response ):
280 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700281 return main.TRUE
282 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800283 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800284 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800285 # NOTE: Send ctrl-c to make sure pingall is done
286 self.handle.send( "\x03" )
287 self.handle.expect( "Interrupt" )
288 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700289 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800290 else:
291 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500292 main.cleanup()
293 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700294
Jon Hall7eb38402015-01-08 17:19:54 -0800295 def fpingHost( self, **pingParams ):
296 """
297 Uses the fping package for faster pinging...
298 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800299 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800300 command = args[ "SRC" ] + \
301 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
302 self.handle.sendline( command )
303 self.handle.expect(
304 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
305 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
306 response = self.handle.before
307 if re.search( ":\s-", response ):
308 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700309 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800310 elif re.search( ":\s\d{1,2}\.\d\d", response ):
311 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700312 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800313 main.log.info( self.name + ": Install fping on mininet machine... " )
314 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700315 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800316
Jon Hall7eb38402015-01-08 17:19:54 -0800317 def pingHost( self, **pingParams ):
318 """
319 Ping from one mininet host to another
320 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800321 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800322 command = args[ "SRC" ] + " ping " + \
323 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700324 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800325 main.log.warn( "Sending: " + command )
326 self.handle.sendline( command )
327 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700328 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800329 main.log.error(
330 self.name +
331 ": timeout when waiting for response from mininet" )
332 main.log.error( "response: " + str( self.handle.before ) )
333 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700334 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800335 main.log.error(
336 self.name +
337 ": timeout when waiting for response from mininet" )
338 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700339 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800340 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800341 main.log.error( self.name + ": EOF exception found" )
342 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700343 main.cleanup()
344 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800345 main.log.info( self.name + ": Ping Response: " + response )
346 if re.search( ',\s0\%\spacket\sloss', response ):
347 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800348 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700349 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800350 else:
351 main.log.error(
352 self.name +
353 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800354 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700355 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800356
Jon Hall7eb38402015-01-08 17:19:54 -0800357 def checkIP( self, host ):
358 """
359 Verifies the host's ip configured or not."""
360 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700361 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800362 response = self.execute(
363 cmd=host +
364 " ifconfig",
365 prompt="mininet>",
366 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800367 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800368 main.log.error( self.name + ": EOF exception found" )
369 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700370 main.cleanup()
371 main.exit()
adminbae64d82013-08-01 10:50:15 -0700372
Jon Hall7eb38402015-01-08 17:19:54 -0800373 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800374 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
375 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
376 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
377 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
378 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800379 # pattern = "inet addr:10.0.0.6"
380 if re.search( pattern, response ):
381 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700382 return main.TRUE
383 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800384 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700385 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800386 else:
387 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800388
Jon Hall7eb38402015-01-08 17:19:54 -0800389 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700390 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800391 response = self.execute(
392 cmd="h1 /usr/sbin/sshd -D&",
393 prompt="mininet>",
394 timeout=10 )
395 response = self.execute(
396 cmd="h4 /usr/sbin/sshd -D&",
397 prompt="mininet>",
398 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700399 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800400 vars( self )[ key ] = connectargs[ key ]
401 response = self.execute(
402 cmd="xterm h1 h4 ",
403 prompt="mininet>",
404 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800405 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800406 main.log.error( self.name + ": EOF exception found" )
407 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700408 main.cleanup()
409 main.exit()
adminbae64d82013-08-01 10:50:15 -0700410 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800411 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700412 if self.flag == 0:
413 self.flag = 1
414 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800415 else:
adminbae64d82013-08-01 10:50:15 -0700416 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800417
kelvin-onlaba1484582015-02-02 15:46:20 -0800418 def moveHost( self, host, oldSw, newSw, ):
419 """
420 Moves a host from one switch to another on the fly
421 Note: The intf between host and oldSw when detached
422 using detach(), will still show up in the 'net'
423 cmd, because switch.detach() doesn't affect switch.intfs[]
424 (which is correct behavior since the interfaces
425 haven't moved).
426 """
427 if self.handle:
428 try:
429 # Bring link between oldSw-host down
430 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
431 "'down')"
432 print "cmd1= ", cmd
433 response = self.execute(
434 cmd=cmd,
435 prompt="mininet>",
436 timeout=10 )
437
438 # Determine hostintf and Oldswitchintf
439 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
440 ")[0]"
441 print "cmd2= ", cmd
442 self.handle.sendline( cmd )
443 self.handle.expect( "mininet>" )
444
445 # Determine ipaddress of the host-oldSw interface
446 cmd = "px ipaddr = hintf.IP()"
447 print "cmd3= ", cmd
448 self.handle.sendline( cmd )
449 self.handle.expect( "mininet>" )
450
451 # Detach interface between oldSw-host
452 cmd = "px " + oldSw + ".detach( sintf )"
453 print "cmd4= ", cmd
454 self.handle.sendline( cmd )
455 self.handle.expect( "mininet>" )
456
457 # Add link between host-newSw
458 cmd = "py net.addLink(" + host + "," + newSw + ")"
459 print "cmd5= ", cmd
460 self.handle.sendline( cmd )
461 self.handle.expect( "mininet>" )
462
463 # Determine hostintf and Newswitchintf
464 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
465 ")[0]"
466 print "cmd6= ", cmd
467 self.handle.sendline( cmd )
468 self.handle.expect( "mininet>" )
469
470 # Attach interface between newSw-host
471 cmd = "px " + newSw + ".attach( sintf )"
472 print "cmd3= ", cmd
473 self.handle.sendline( cmd )
474 self.handle.expect( "mininet>" )
475
476 # Set ipaddress of the host-newSw interface
477 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
478 print "cmd7 = ", cmd
479 self.handle.sendline( cmd )
480 self.handle.expect( "mininet>" )
481
482 cmd = "net"
483 print "cmd8 = ", cmd
484 self.handle.sendline( cmd )
485 self.handle.expect( "mininet>" )
486 print "output = ", self.handle.before
487
488 # Determine ipaddress of the host-newSw interface
489 cmd = "h1 ifconfig"
490 print "cmd9= ", cmd
491 self.handle.sendline( cmd )
492 self.handle.expect( "mininet>" )
493 print "ifconfig o/p = ", self.handle.before
494
495 return main.TRUE
496 except pexpect.EOF:
497 main.log.error( self.name + ": EOF exception found" )
498 main.log.error( self.name + ": " + self.handle.before )
499 return main.FALSE
500
Jon Hall7eb38402015-01-08 17:19:54 -0800501 def changeIP( self, host, intf, newIP, newNetmask ):
502 """
503 Changes the ip address of a host on the fly
504 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800505 if self.handle:
506 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800507 cmd = host + " ifconfig " + intf + " " + \
508 newIP + " " + 'netmask' + " " + newNetmask
509 self.handle.sendline( cmd )
510 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800511 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800512 main.log.info( "response = " + response )
513 main.log.info(
514 "Ip of host " +
515 host +
516 " changed to new IP " +
517 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800518 return main.TRUE
519 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800520 main.log.error( self.name + ": EOF exception found" )
521 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800522 return main.FALSE
523
Jon Hall7eb38402015-01-08 17:19:54 -0800524 def changeDefaultGateway( self, host, newGW ):
525 """
526 Changes the default gateway of a host
527 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800528 if self.handle:
529 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800530 cmd = host + " route add default gw " + newGW
531 self.handle.sendline( cmd )
532 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800533 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800534 main.log.info( "response = " + response )
535 main.log.info(
536 "Default gateway of host " +
537 host +
538 " changed to " +
539 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800540 return main.TRUE
541 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800542 main.log.error( self.name + ": EOF exception found" )
543 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800544 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800545
Jon Hall7eb38402015-01-08 17:19:54 -0800546 def addStaticMACAddress( self, host, GW, macaddr ):
547 """
548 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800549 if self.handle:
550 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800551 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
552 cmd = host + " arp -s " + GW + " " + macaddr
553 self.handle.sendline( cmd )
554 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800555 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800556 main.log.info( "response = " + response )
557 main.log.info(
558 "Mac adrress of gateway " +
559 GW +
560 " changed to " +
561 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800562 return main.TRUE
563 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800564 main.log.error( self.name + ": EOF exception found" )
565 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800566 return main.FALSE
567
Jon Hall7eb38402015-01-08 17:19:54 -0800568 def verifyStaticGWandMAC( self, host ):
569 """
570 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800571 if self.handle:
572 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800573 # h1 arp -an
574 cmd = host + " arp -an "
575 self.handle.sendline( cmd )
576 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800577 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800578 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800579 return main.TRUE
580 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800581 main.log.error( self.name + ": EOF exception found" )
582 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800583 return main.FALSE
584
Jon Hall7eb38402015-01-08 17:19:54 -0800585 def getMacAddress( self, host ):
586 """
587 Verifies the host's ip configured or not."""
588 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700589 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800590 response = self.execute(
591 cmd=host +
592 " ifconfig",
593 prompt="mininet>",
594 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800595 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 )
Jon Hall6094a362014-04-11 14:46:56 -0700598 main.cleanup()
599 main.exit()
adminbae64d82013-08-01 10:50:15 -0700600
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700601 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 macAddressSearch = re.search( pattern, response, re.I )
603 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800604 main.log.info(
605 self.name +
606 ": Mac-Address of Host " +
607 host +
608 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800609 macAddress )
610 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700611 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800612 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700613
Jon Hall7eb38402015-01-08 17:19:54 -0800614 def getInterfaceMACAddress( self, host, interface ):
615 """
616 Return the IP address of the interface on the given host"""
617 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700618 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800619 response = self.execute( cmd=host + " ifconfig " + interface,
620 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800621 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800622 main.log.error( self.name + ": EOF exception found" )
623 main.log.error( self.name + ": " + self.handle.before )
624 main.cleanup()
625 main.exit()
626
627 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 macAddressSearch = re.search( pattern, response, re.I )
629 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800630 main.log.info( "No mac address found in %s" % response )
631 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800633 main.log.info(
634 "Mac-Address of " +
635 host +
636 ":" +
637 interface +
638 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 macAddress )
640 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800641 else:
642 main.log.error( "Connection failed to the host" )
643
644 def getIPAddress( self, host ):
645 """
646 Verifies the host's ip configured or not."""
647 if self.handle:
648 try:
649 response = self.execute(
650 cmd=host +
651 " ifconfig",
652 prompt="mininet>",
653 timeout=10 )
654 except pexpect.EOF:
655 main.log.error( self.name + ": EOF exception found" )
656 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700657 main.cleanup()
658 main.exit()
adminbae64d82013-08-01 10:50:15 -0700659
660 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800662 main.log.info(
663 self.name +
664 ": IP-Address of Host " +
665 host +
666 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800667 ipAddressSearch.group( 1 ) )
668 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800669 else:
670 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800671
Jon Hall7eb38402015-01-08 17:19:54 -0800672 def getSwitchDPID( self, switch ):
673 """
674 return the datapath ID of the switch"""
675 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700676 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700677 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800678 response = self.execute(
679 cmd=cmd,
680 prompt="mininet>",
681 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800682 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800683 main.log.error( self.name + ": EOF exception found" )
684 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700685 main.cleanup()
686 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800687 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800688 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700689 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800690 main.log.info(
691 "Couldn't find DPID for switch %s, found: %s" %
692 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700693 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800694 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700695 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800696 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700697
Jon Hall7eb38402015-01-08 17:19:54 -0800698 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700699 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800700 self.handle.sendline( "" )
701 self.expect( "mininet>" )
702 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700703 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800704 response = self.execute(
705 cmd=cmd,
706 prompt="mininet>",
707 timeout=10 )
708 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700709 response = self.handle.before
710 return response
711 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800712 main.log.error( self.name + ": EOF exception found" )
713 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700714 main.cleanup()
715 main.exit()
716
Jon Hall7eb38402015-01-08 17:19:54 -0800717 def getInterfaces( self, node ):
718 """
719 return information dict about interfaces connected to the node"""
720 if self.handle:
721 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800722 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700723 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700724 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800725 response = self.execute(
726 cmd=cmd,
727 prompt="mininet>",
728 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800729 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700732 main.cleanup()
733 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700734 return response
735 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800736 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700737
Jon Hall7eb38402015-01-08 17:19:54 -0800738 def dump( self ):
739 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700740 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 response = self.execute(
742 cmd='dump',
743 prompt='mininet>',
744 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800745 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 main.log.error( self.name + ": EOF exception found" )
747 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700748 main.cleanup()
749 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700750 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800751
Jon Hall7eb38402015-01-08 17:19:54 -0800752 def intfs( self ):
753 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700754 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800755 response = self.execute(
756 cmd='intfs',
757 prompt='mininet>',
758 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800759 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700762 main.cleanup()
763 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700764 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800765
Jon Hall7eb38402015-01-08 17:19:54 -0800766 def net( self ):
767 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700768 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800769 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800770 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800771 main.log.error( self.name + ": EOF exception found" )
772 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700773 main.cleanup()
774 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700775 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800776
777 def iperf( self, host1, host2 ):
778 main.log.info(
779 self.name +
780 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700781 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800782 cmd1 = 'iperf ' + host1 + " " + host2
783 self.handle.sendline( cmd1 )
784 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800785 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800786 if re.search( 'Results:', response ):
787 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800788 return main.TRUE
789 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800790 main.log.error( self.name + ": iperf test failed" )
791 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800792 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800793 main.log.error( self.name + ": EOF exception found" )
794 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800795 main.cleanup()
796 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800797
Jon Hall7eb38402015-01-08 17:19:54 -0800798 def iperfudp( self ):
799 main.log.info(
800 self.name +
801 ": Simple iperf TCP test between two " +
802 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700803 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800804 response = self.execute(
805 cmd='iperfudp',
806 prompt='mininet>',
807 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800808 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800809 main.log.error( self.name + ": EOF exception found" )
810 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700811 main.cleanup()
812 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700813 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800814
Jon Hall7eb38402015-01-08 17:19:54 -0800815 def nodes( self ):
816 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700817 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800818 response = self.execute(
819 cmd='nodes',
820 prompt='mininet>',
821 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800822 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800823 main.log.error( self.name + ": EOF exception found" )
824 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700825 main.cleanup()
826 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700827 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800828
Jon Hall7eb38402015-01-08 17:19:54 -0800829 def pingpair( self ):
830 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700831 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800832 response = self.execute(
833 cmd='pingpair',
834 prompt='mininet>',
835 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800836 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800837 main.log.error( self.name + ": EOF exception found" )
838 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700839 main.cleanup()
840 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800841
Jon Hall7eb38402015-01-08 17:19:54 -0800842 if re.search( ',\s0\%\spacket\sloss', response ):
843 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800844 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700845 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800846 else:
847 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800848 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700849 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800850
Jon Hall7eb38402015-01-08 17:19:54 -0800851 def link( self, **linkargs ):
852 """
853 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800854 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800855 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
856 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
857 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
858 main.log.info(
859 "Bring link between '" +
860 end1 +
861 "' and '" +
862 end2 +
863 "' '" +
864 option +
865 "'" )
866 command = "link " + \
867 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700868 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800869 self.handle.sendline( command )
870 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800871 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800872 main.log.error( self.name + ": EOF exception found" )
873 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700874 main.cleanup()
875 main.exit()
adminbae64d82013-08-01 10:50:15 -0700876 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800877
Jon Hall7eb38402015-01-08 17:19:54 -0800878 def yank( self, **yankargs ):
879 """
880 yank a mininet switch interface to a host"""
881 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800882 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800883 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
884 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
885 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700886 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 response = self.execute(
888 cmd=command,
889 prompt="mininet>",
890 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800891 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800892 main.log.error( self.name + ": EOF exception found" )
893 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700894 main.cleanup()
895 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700896 return main.TRUE
897
Jon Hall7eb38402015-01-08 17:19:54 -0800898 def plug( self, **plugargs ):
899 """
900 plug the yanked mininet switch interface to a switch"""
901 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800902 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800903 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
904 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
905 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700906 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800907 response = self.execute(
908 cmd=command,
909 prompt="mininet>",
910 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800911 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800912 main.log.error( self.name + ": EOF exception found" )
913 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700914 main.cleanup()
915 main.exit()
adminbae64d82013-08-01 10:50:15 -0700916 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800917
Jon Hall7eb38402015-01-08 17:19:54 -0800918 def dpctl( self, **dpctlargs ):
919 """
920 Run dpctl command on all switches."""
921 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800922 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800923 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
924 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
925 command = "dpctl " + cmd + " " + str( cmdargs )
926 try:
927 response = self.execute(
928 cmd=command,
929 prompt="mininet>",
930 timeout=10 )
931 except pexpect.EOF:
932 main.log.error( self.name + ": EOF exception found" )
933 main.log.error( self.name + ": " + self.handle.before )
934 main.cleanup()
935 main.exit()
936 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800937
kelvin-onlabd3b64892015-01-20 13:26:24 -0800938 def getVersion( self ):
939 fileInput = path + '/lib/Mininet/INSTALL'
940 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700941 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800943 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700944 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800945 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500946 return version
adminbae64d82013-08-01 10:50:15 -0700947
kelvin-onlabd3b64892015-01-20 13:26:24 -0800948 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800949 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500950 Parameters:
951 sw: The name of an OVS switch. Example "s1"
952 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800953 The output of the command from the mininet cli
954 or main.FALSE on timeout"""
955 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700956 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800957 response = self.execute(
958 cmd=command,
959 prompt="mininet>",
960 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700961 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500962 return response
admin2a9548d2014-06-17 14:08:07 -0700963 else:
964 return main.FALSE
965 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700968 main.cleanup()
969 main.exit()
adminbae64d82013-08-01 10:50:15 -0700970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800972 """
973 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800974 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800975 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700976
977 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800978 for j in range( count ):
979 argstring = argstring + ",IP" + \
980 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800981 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700982
Jon Hall7eb38402015-01-08 17:19:54 -0800983 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
984 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800985 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800986 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800987
Jon Hall7eb38402015-01-08 17:19:54 -0800988 command = "sh ovs-vsctl set-controller s" + \
989 str( sw ) + " " + ptcpB + " "
990 for j in range( count ):
991 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800992 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -0800993 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
994 ip = args[
995 "IP" +
996 str( i ) ] if args[
997 "IP" +
998 str( i ) ] is not None else ""
999 port = args[
1000 "PORT" +
1001 str( i ) ] if args[
1002 "PORT" +
1003 str( i ) ] is not None else ""
1004 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001005 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001006 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001007 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001008 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001009 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001012 main.cleanup()
1013 main.exit()
1014 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001015 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001016 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001017 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001018 main.cleanup()
1019 main.exit()
adminbae64d82013-08-01 10:50:15 -07001020
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001022 """
1023 Removes the controller target from sw"""
1024 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001025 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001026 response = self.execute(
1027 cmd=command,
1028 prompt="mininet>",
1029 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001030 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001031 main.log.error( self.name + ": EOF exception found" )
1032 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001033 main.cleanup()
1034 main.exit()
1035 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001036 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001037
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001039 """
Jon Hallb1290e82014-11-18 16:17:48 -05001040 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001041 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001042 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001043 NOTE: cannot currently specify what type of switch
1044 required params:
1045 switchname = name of the new switch as a string
1046 optional keyvalues:
1047 dpid = "dpid"
1048 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001049 """
1050 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001051 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001052 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001053 response = self.execute(
1054 cmd=command,
1055 prompt="mininet>",
1056 timeout=10 )
1057 if re.search( "already exists!", response ):
1058 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001059 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001060 elif re.search( "Error", response ):
1061 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001062 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001063 elif re.search( "usage:", response ):
1064 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001065 return main.FALSE
1066 else:
1067 return main.TRUE
1068 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001069 main.log.error( self.name + ": EOF exception found" )
1070 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001071 main.cleanup()
1072 main.exit()
1073
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001075 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001076 delete a switch from the mininet topology
1077 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001078 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001079 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001080 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001081 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001082 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001083 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001084 response = self.execute(
1085 cmd=command,
1086 prompt="mininet>",
1087 timeout=10 )
1088 if re.search( "no switch named", response ):
1089 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001090 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001091 elif re.search( "Error", response ):
1092 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001093 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001094 elif re.search( "usage:", response ):
1095 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001096 return main.FALSE
1097 else:
1098 return main.TRUE
1099 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001102 main.cleanup()
1103 main.exit()
1104
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001106 """
1107 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001108 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001109 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001110 NOTE: cannot currently specify what type of link
1111 required params:
1112 node1 = the string node name of the first endpoint of the link
1113 node2 = the string node name of the second endpoint of the link
1114 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001115 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001116 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 response = self.execute(
1118 cmd=command,
1119 prompt="mininet>",
1120 timeout=10 )
1121 if re.search( "doesnt exist!", response ):
1122 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001123 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001124 elif re.search( "Error", response ):
1125 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001126 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001127 elif re.search( "usage:", response ):
1128 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001129 return main.FALSE
1130 else:
1131 return main.TRUE
1132 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 main.log.error( self.name + ": EOF exception found" )
1134 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001135 main.cleanup()
1136 main.exit()
1137
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001139 """
1140 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001141 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001142 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001143 required params:
1144 node1 = the string node name of the first endpoint of the link
1145 node2 = the string node name of the second endpoint of the link
1146 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001147 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001148 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001149 response = self.execute(
1150 cmd=command,
1151 prompt="mininet>",
1152 timeout=10 )
1153 if re.search( "no node named", response ):
1154 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001155 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001156 elif re.search( "Error", response ):
1157 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001158 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001159 elif re.search( "usage:", response ):
1160 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001161 return main.FALSE
1162 else:
1163 return main.TRUE
1164 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001165 main.log.error( self.name + ": EOF exception found" )
1166 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001167 main.cleanup()
1168 main.exit()
1169
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001171 """
Jon Hallb1290e82014-11-18 16:17:48 -05001172 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001173 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001174 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001175 NOTE: cannot currently specify what type of host
1176 required params:
1177 hostname = the string hostname
1178 optional key-value params
1179 switch = "switch name"
1180 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001181 """
1182 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001183 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001184 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001185 response = self.execute(
1186 cmd=command,
1187 prompt="mininet>",
1188 timeout=10 )
1189 if re.search( "already exists!", response ):
1190 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001191 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001192 elif re.search( "doesnt exists!", response ):
1193 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001194 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001195 elif re.search( "Error", response ):
1196 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001197 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001198 elif re.search( "usage:", response ):
1199 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001200 return main.FALSE
1201 else:
1202 return main.TRUE
1203 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001204 main.log.error( self.name + ": EOF exception found" )
1205 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001206 main.cleanup()
1207 main.exit()
1208
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001210 """
1211 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001212 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001213 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001214 NOTE: this uses a custom mn function
1215 required params:
1216 hostname = the string hostname
1217 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001218 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001219 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001220 response = self.execute(
1221 cmd=command,
1222 prompt="mininet>",
1223 timeout=10 )
1224 if re.search( "no host named", response ):
1225 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001226 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001227 elif re.search( "Error", response ):
1228 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001229 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001230 elif re.search( "usage:", response ):
1231 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001232 return main.FALSE
1233 else:
1234 return main.TRUE
1235 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 main.log.error( self.name + ": EOF exception found" )
1237 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001238 main.cleanup()
1239 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001240
Jon Hall7eb38402015-01-08 17:19:54 -08001241 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001242 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001243 Called at the end of the test to stop the mininet and
1244 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001245 """
1246 self.handle.sendline('')
1247 i = 1
1248 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1249 if i == 0:
1250 self.stopNet()
1251 response = ''
1252 # print "Disconnecting Mininet"
1253 if self.handle:
1254 self.handle.sendline( "exit" )
1255 self.handle.expect( "exit" )
1256 self.handle.expect( "(.*)" )
1257 main.log.info( "Mininet CLI is successfully disconnected" )
1258 response = self.handle.before
1259 else:
1260 main.log.error( "Connection failed to the host" )
1261 response = main.FALSE
1262
1263 return response
1264
1265 def stopNet( self ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001266 """
1267 Stops mininet. returns true if the mininet succesfully stops.
1268 """
1269
Jon Hall7eb38402015-01-08 17:19:54 -08001270 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001271 response = ''
1272 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001273 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001274 response = self.execute(
1275 cmd="exit",
1276 prompt="(.*)",
1277 timeout=120 )
kelvin-onlaba1484582015-02-02 15:46:20 -08001278 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001279 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001280 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001281 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001282 main.log.error( self.name + ": EOF exception found" )
1283 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001284 main.cleanup()
1285 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001286 else:
1287 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001288 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001289 return response
1290
kelvin-onlaba1484582015-02-02 15:46:20 -08001291
1292
Jon Hall7eb38402015-01-08 17:19:54 -08001293 def arping( self, src, dest, destmac ):
1294 self.handle.sendline( '' )
1295 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001296
Jon Hall7eb38402015-01-08 17:19:54 -08001297 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001298 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001299 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1300 main.log.info( self.name + ": ARP successful" )
1301 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001302 return main.TRUE
1303 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001304 main.log.warn( self.name + ": ARP FAILURE" )
1305 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001306 return main.FALSE
1307
Jon Hall7eb38402015-01-08 17:19:54 -08001308 def decToHex( self, num ):
1309 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001310
Jon Hall7eb38402015-01-08 17:19:54 -08001311 def getSwitchFlowCount( self, switch ):
1312 """
1313 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001314 if self.handle:
1315 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1316 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001317 response = self.execute(
1318 cmd=cmd,
1319 prompt="mininet>",
1320 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001321 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001324 main.cleanup()
1325 main.exit()
1326 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001327 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001328 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001329 main.log.info(
1330 "Couldn't find flows on switch %s, found: %s" %
1331 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001332 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001333 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001334 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001335 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001336
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 def checkFlows( self, sw, dumpFormat=None ):
1338 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001339 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001341 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001342 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001343 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001344 response = self.execute(
1345 cmd=command,
1346 prompt="mininet>",
1347 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001348 return response
1349 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 main.log.error( self.name + ": EOF exception found" )
1351 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001352 main.cleanup()
1353 main.exit()
1354 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001355 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001356
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001358 """
1359 Runs tpdump on an intferface and saves the file
1360 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001361 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001362 self.handle.sendline( "" )
1363 self.handle.expect( "mininet>" )
1364 self.handle.sendline(
1365 "sh sudo tcpdump -n -i " +
1366 intf +
1367 " " +
1368 port +
1369 " -w " +
1370 filename.strip() +
1371 " &" )
1372 self.handle.sendline( "" )
1373 i = self.handle.expect( [ 'No\ssuch\device',
1374 'listening\son',
1375 pexpect.TIMEOUT,
1376 "mininet>" ],
1377 timeout=10 )
1378 main.log.warn( self.handle.before + self.handle.after )
1379 self.handle.sendline( "" )
1380 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001381 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001382 main.log.error(
1383 self.name +
1384 ": tcpdump - No such device exists. " +
1385 "tcpdump attempted on: " +
1386 intf )
admin2a9548d2014-06-17 14:08:07 -07001387 return main.FALSE
1388 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001389 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001390 return main.TRUE
1391 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001392 main.log.error(
1393 self.name +
1394 ": tcpdump command timed out! Check interface name," +
1395 " given interface was: " +
1396 intf )
admin2a9548d2014-06-17 14:08:07 -07001397 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001398 elif i == 3:
1399 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001400 return main.TRUE
1401 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001402 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001403 return main.FALSE
1404 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001405 main.log.error( self.name + ": EOF exception found" )
1406 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001407 main.cleanup()
1408 main.exit()
1409 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001410 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001411 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001412 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001413 main.cleanup()
1414 main.exit()
1415
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001417 "pkills tcpdump"
1418 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001419 self.handle.sendline( "sh sudo pkill tcpdump" )
1420 self.handle.expect( "mininet>" )
1421 self.handle.sendline( "" )
1422 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001423 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 main.log.error( self.name + ": EOF exception found" )
1425 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001426 main.cleanup()
1427 main.exit()
1428 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001430 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001431 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001432 main.cleanup()
1433 main.exit()
1434
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001436 """
1437 Compare mn and onos switches
1438 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001439 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001440
Jon Hall7eb38402015-01-08 17:19:54 -08001441 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001443 output = { "switches": [] }
1444 # iterate through the MN topology and pull out switches and and port
1445 # info
1446 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001447 ports = []
1448 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001449 ports.append( { 'of_port': port.port_no,
1450 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001452 'name': port.name } )
1453 output[ 'switches' ].append( {
1454 "name": switch.name,
1455 "dpid": str( switch.dpid ).zfill( 16 ),
1456 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001457
Jon Hall7eb38402015-01-08 17:19:54 -08001458 # print "mn"
1459 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001461 # indent=4,
1462 # separators=( ',', ': ' ) )
1463 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 # print json.dumps( switchesJson,
1465 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001466 # indent=4,
1467 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001468
1469 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001470 mnDPIDs = []
1471 for switch in output[ 'switches' ]:
1472 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001473 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001474 # print "List of Mininet switch DPID's"
1475 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001476 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001477 main.log.error(
1478 self.name +
1479 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001480 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001482 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001483 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001484 if switch[ 'available' ]:
1485 onosDPIDs.append(
1486 switch[ 'id' ].replace(
1487 ":",
1488 '' ).replace(
1489 "of",
1490 '' ).lower() )
1491 # else:
1492 # print "Switch is unavailable:"
1493 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001494 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001495 # print "List of ONOS switch DPID's"
1496 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001497
Jon Hall7eb38402015-01-08 17:19:54 -08001498 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001499 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001500 main.log.report( "Switches in MN but not in ONOS:" )
1501 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1502 main.log.report( str( list1 ) )
1503 main.log.report( "Switches in ONOS but not in MN:" )
1504 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001505 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001506 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 switchResults = main.TRUE
1508 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001509
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001511 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001512 Compare mn and onos ports
1513 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001514 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001515
Jon Hallfbc828e2015-01-06 17:30:19 -08001516 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001517 1. This uses the sts TestONTopology object
1518 2. numpy - "sudo pip install numpy"
1519
Jon Hall7eb38402015-01-08 17:19:54 -08001520 """
1521 # FIXME: this does not look for extra ports in ONOS, only checks that
1522 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001523 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001525 output = { "switches": [] }
1526 # iterate through the MN topology and pull out switches and and port
1527 # info
1528 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001529 ports = []
1530 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001531 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001533 tmpPort[ 'of_port' ] = port.port_no
1534 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 tmpPort[ 'name' ] = port.name
1536 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001537
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 ports.append( tmpPort )
1539 tmpSwitch = {}
1540 tmpSwitch[ 'name' ] = switch.name
1541 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1542 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001543
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001545
Jon Hall7eb38402015-01-08 17:19:54 -08001546 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001547 for mnSwitch in output[ 'switches' ]:
1548 mnPorts = []
1549 onosPorts = []
1550 switchResult = main.TRUE
1551 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001552 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001553 mnPorts.append( port[ 'of_port' ] )
1554 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001555 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 # print onosSwitch
1557 if onosSwitch[ 'device' ][ 'available' ]:
1558 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001559 ':',
1560 '' ).replace(
1561 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001562 '' ) == mnSwitch[ 'dpid' ]:
1563 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001564 if port[ 'isEnabled' ]:
1565 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 # onosPorts.append( 'local' )
1567 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001568 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001570 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 mnPorts.sort( key=float )
1572 onosPorts.sort( key=float )
1573 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1574 # print "\tmn_ports[] = ", mnPorts
1575 # print "\tonos_ports[] = ", onosPorts
1576 mnPortsLog = mnPorts
1577 onosPortsLog = onosPorts
1578 mnPorts = [ x for x in mnPorts ]
1579 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001580
Jon Hall7eb38402015-01-08 17:19:54 -08001581 # TODO: handle other reserved port numbers besides LOCAL
1582 # NOTE: Reserved ports
1583 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1584 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 for mnPort in mnPortsLog:
1586 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001587 # don't set results to true here as this is just one of
1588 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 mnPorts.remove( mnPort )
1590 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001591 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001592 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001593 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 if 65534 in mnPorts:
1595 mnPorts.remove( 65534 )
1596 if long( uint64( -2 ) ) in onosPorts:
1597 onosPorts.remove( long( uint64( -2 ) ) )
1598 if len( mnPorts ): # the ports of this switch don't match
1599 switchResult = main.FALSE
1600 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1601 if len( onosPorts ): # the ports of this switch don't match
1602 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001603 main.log.warn(
1604 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 str( onosPorts ) )
1606 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001607 main.log.report(
1608 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1610 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1611 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1612 portsResults = portsResults and switchResult
1613 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001614
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001616 """
1617 Compare mn and onos links
1618 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001619 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001620
Jon Hall7eb38402015-01-08 17:19:54 -08001621 This uses the sts TestONTopology object"""
1622 # FIXME: this does not look for extra links in ONOS, only checks that
1623 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001624 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001625 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001627 # iterate through the MN topology and pull out switches and and port
1628 # info
1629 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001630 # print "Iterating though switches as seen by Mininet"
1631 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001632 ports = []
1633 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001634 # print port.hw_addr.toStr( separator='' )
1635 ports.append( { 'of_port': port.port_no,
1636 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001637 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001638 'name': port.name } )
1639 output[ 'switches' ].append( {
1640 "name": switch.name,
1641 "dpid": str( switch.dpid ).zfill( 16 ),
1642 "ports": ports } )
1643 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001644
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001646 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001647 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 if 2 * len( mnLinks ) == len( onos ):
1649 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001650 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001652 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001653 "Mininet has " + str( len( mnLinks ) ) +
1654 " bidirectional links and ONOS has " +
1655 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001656
Jon Hall7eb38402015-01-08 17:19:54 -08001657 # iterate through MN links and check if an ONOS link exists in
1658 # both directions
1659 # NOTE: Will currently only show mn links as down if they are
1660 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001662 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001664 # print "Link: %s" % link
1665 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001666 node1 = None
1667 port1 = None
1668 node2 = None
1669 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 firstDir = main.FALSE
1671 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001672 for switch in output[ 'switches' ]:
1673 # print "Switch: %s" % switch[ 'name' ]
1674 if switch[ 'name' ] == link.node1.name:
1675 node1 = switch[ 'dpid' ]
1676 for port in switch[ 'ports' ]:
1677 if str( port[ 'name' ] ) == str( link.port1 ):
1678 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001679 if node1 is not None and node2 is not None:
1680 break
Jon Hall7eb38402015-01-08 17:19:54 -08001681 if switch[ 'name' ] == link.node2.name:
1682 node2 = switch[ 'dpid' ]
1683 for port in switch[ 'ports' ]:
1684 if str( port[ 'name' ] ) == str( link.port2 ):
1685 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001686 if node1 is not None and node2 is not None:
1687 break
1688
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 for onosLink in onos:
1690 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001691 ":",
1692 '' ).replace(
1693 "of",
1694 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001695 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001696 ":",
1697 '' ).replace(
1698 "of",
1699 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 onosPort1 = onosLink[ 'src' ][ 'port' ]
1701 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001702
Jon Hall72cf1dc2014-10-20 21:04:50 -04001703 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001704 if str( onosNode1 ) == str( node1 ) and str(
1705 onosNode2 ) == str( node2 ):
1706 if int( onosPort1 ) == int( port1 ) and int(
1707 onosPort2 ) == int( port2 ):
1708 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001709 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001710 main.log.warn(
1711 'The port numbers do not match for ' +
1712 str( link ) +
1713 ' between ONOS and MN. When cheking ONOS for ' +
1714 'link %s/%s -> %s/%s' %
1715 ( node1,
1716 port1,
1717 node2,
1718 port2 ) +
1719 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001720 ( onosNode1,
1721 onosPort1,
1722 onosNode2,
1723 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001724
1725 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 elif ( str( onosNode1 ) == str( node2 ) and
1727 str( onosNode2 ) == str( node1 ) ):
1728 if ( int( onosPort1 ) == int( port2 )
1729 and int( onosPort2 ) == int( port1 ) ):
1730 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001731 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001732 main.log.warn(
1733 'The port numbers do not match for ' +
1734 str( link ) +
1735 ' between ONOS and MN. When cheking ONOS for ' +
1736 'link %s/%s -> %s/%s' %
1737 ( node2,
1738 port2,
1739 node1,
1740 port1 ) +
1741 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 ( onosNode2,
1743 onosPort2,
1744 onosNode1,
1745 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001746 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001747 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001749 main.log.report(
1750 'ONOS does not have the link %s/%s -> %s/%s' %
1751 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001752 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001753 main.log.report(
1754 'ONOS does not have the link %s/%s -> %s/%s' %
1755 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001756 linkResults = linkResults and firstDir and secondDir
1757 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001758
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001760 """
1761 Returns a list of all hosts
1762 Don't ask questions just use it"""
1763 self.handle.sendline( "" )
1764 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001765
Jon Hall7eb38402015-01-08 17:19:54 -08001766 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1767 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001768
kelvin-onlabd3b64892015-01-20 13:26:24 -08001769 handlePy = self.handle.before
1770 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1771 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001772
Jon Hall7eb38402015-01-08 17:19:54 -08001773 self.handle.sendline( "" )
1774 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 hostStr = handlePy.replace( "]", "" )
1777 hostStr = hostStr.replace( "'", "" )
1778 hostStr = hostStr.replace( "[", "" )
1779 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001780
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 return hostList
adminbae64d82013-08-01 10:50:15 -07001782
Jon Hall7eb38402015-01-08 17:19:54 -08001783 def update( self ):
1784 """
1785 updates the port address and status information for
1786 each port in mn"""
1787 # TODO: Add error checking. currently the mininet command has no output
1788 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001789 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001790 self.handle.sendline( "" )
1791 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001792
Jon Hall7eb38402015-01-08 17:19:54 -08001793 self.handle.sendline( "update" )
1794 self.handle.expect( "update" )
1795 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001796
Jon Hall7eb38402015-01-08 17:19:54 -08001797 self.handle.sendline( "" )
1798 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001799
Jon Hallb1290e82014-11-18 16:17:48 -05001800 return main.TRUE
1801 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001802 main.log.error( self.name + ": EOF exception found" )
1803 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001804 main.cleanup()
1805 main.exit()
1806
adminbae64d82013-08-01 10:50:15 -07001807if __name__ != "__main__":
1808 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001809 sys.modules[ __name__ ] = MininetCliDriver()