blob: 52b11308dbc84cd43a179f481d64834205d90e2e [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
shahshreya73537862015-02-11 15:15:24 -0800445 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800446 cmd = "px ipaddr = hintf.IP()"
447 print "cmd3= ", cmd
448 self.handle.sendline( cmd )
449 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800450
451 cmd = "px macaddr = hintf.MAC()"
452 print "cmd3= ", cmd
453 self.handle.sendline( cmd )
454 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800455
456 # Detach interface between oldSw-host
457 cmd = "px " + oldSw + ".detach( sintf )"
458 print "cmd4= ", cmd
459 self.handle.sendline( cmd )
460 self.handle.expect( "mininet>" )
461
462 # Add link between host-newSw
463 cmd = "py net.addLink(" + host + "," + newSw + ")"
464 print "cmd5= ", cmd
465 self.handle.sendline( cmd )
466 self.handle.expect( "mininet>" )
467
468 # Determine hostintf and Newswitchintf
469 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
470 ")[0]"
471 print "cmd6= ", cmd
472 self.handle.sendline( cmd )
473 self.handle.expect( "mininet>" )
474
475 # Attach interface between newSw-host
476 cmd = "px " + newSw + ".attach( sintf )"
477 print "cmd3= ", cmd
478 self.handle.sendline( cmd )
479 self.handle.expect( "mininet>" )
480
481 # Set ipaddress of the host-newSw interface
482 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
483 print "cmd7 = ", cmd
484 self.handle.sendline( cmd )
485 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800486
487 # Set macaddress of the host-newSw interface
488 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
489 print "cmd8 = ", cmd
490 self.handle.sendline( cmd )
491 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800492
493 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800494 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800495 self.handle.sendline( cmd )
496 self.handle.expect( "mininet>" )
497 print "output = ", self.handle.before
498
499 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800500 cmd = host + " ifconfig"
501 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800502 self.handle.sendline( cmd )
503 self.handle.expect( "mininet>" )
504 print "ifconfig o/p = ", self.handle.before
505
506 return main.TRUE
507 except pexpect.EOF:
508 main.log.error( self.name + ": EOF exception found" )
509 main.log.error( self.name + ": " + self.handle.before )
510 return main.FALSE
511
Jon Hall7eb38402015-01-08 17:19:54 -0800512 def changeIP( self, host, intf, newIP, newNetmask ):
513 """
514 Changes the ip address of a host on the fly
515 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800516 if self.handle:
517 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800518 cmd = host + " ifconfig " + intf + " " + \
519 newIP + " " + 'netmask' + " " + newNetmask
520 self.handle.sendline( cmd )
521 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800522 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800523 main.log.info( "response = " + response )
524 main.log.info(
525 "Ip of host " +
526 host +
527 " changed to new IP " +
528 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800529 return main.TRUE
530 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800531 main.log.error( self.name + ": EOF exception found" )
532 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800533 return main.FALSE
534
Jon Hall7eb38402015-01-08 17:19:54 -0800535 def changeDefaultGateway( self, host, newGW ):
536 """
537 Changes the default gateway of a host
538 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800539 if self.handle:
540 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800541 cmd = host + " route add default gw " + newGW
542 self.handle.sendline( cmd )
543 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800544 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800545 main.log.info( "response = " + response )
546 main.log.info(
547 "Default gateway of host " +
548 host +
549 " changed to " +
550 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800551 return main.TRUE
552 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800553 main.log.error( self.name + ": EOF exception found" )
554 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800555 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800556
Jon Hall7eb38402015-01-08 17:19:54 -0800557 def addStaticMACAddress( self, host, GW, macaddr ):
558 """
559 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800560 if self.handle:
561 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800562 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
563 cmd = host + " arp -s " + GW + " " + macaddr
564 self.handle.sendline( cmd )
565 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800566 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800567 main.log.info( "response = " + response )
568 main.log.info(
569 "Mac adrress of gateway " +
570 GW +
571 " changed to " +
572 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800573 return main.TRUE
574 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800575 main.log.error( self.name + ": EOF exception found" )
576 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800577 return main.FALSE
578
Jon Hall7eb38402015-01-08 17:19:54 -0800579 def verifyStaticGWandMAC( self, host ):
580 """
581 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800582 if self.handle:
583 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800584 # h1 arp -an
585 cmd = host + " arp -an "
586 self.handle.sendline( cmd )
587 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800588 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800589 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800590 return main.TRUE
591 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800594 return main.FALSE
595
Jon Hall7eb38402015-01-08 17:19:54 -0800596 def getMacAddress( self, host ):
597 """
598 Verifies the host's ip configured or not."""
599 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700600 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800601 response = self.execute(
602 cmd=host +
603 " ifconfig",
604 prompt="mininet>",
605 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800606 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800607 main.log.error( self.name + ": EOF exception found" )
608 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700609 main.cleanup()
610 main.exit()
adminbae64d82013-08-01 10:50:15 -0700611
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700612 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800613 macAddressSearch = re.search( pattern, response, re.I )
614 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800615 main.log.info(
616 self.name +
617 ": Mac-Address of Host " +
618 host +
619 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 macAddress )
621 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700622 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800623 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700624
Jon Hall7eb38402015-01-08 17:19:54 -0800625 def getInterfaceMACAddress( self, host, interface ):
626 """
627 Return the IP address of the interface on the given host"""
628 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700629 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800630 response = self.execute( cmd=host + " ifconfig " + interface,
631 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800632 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800633 main.log.error( self.name + ": EOF exception found" )
634 main.log.error( self.name + ": " + self.handle.before )
635 main.cleanup()
636 main.exit()
637
638 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 macAddressSearch = re.search( pattern, response, re.I )
640 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800641 main.log.info( "No mac address found in %s" % response )
642 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800644 main.log.info(
645 "Mac-Address of " +
646 host +
647 ":" +
648 interface +
649 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 macAddress )
651 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800652 else:
653 main.log.error( "Connection failed to the host" )
654
655 def getIPAddress( self, host ):
656 """
657 Verifies the host's ip configured or not."""
658 if self.handle:
659 try:
660 response = self.execute(
661 cmd=host +
662 " ifconfig",
663 prompt="mininet>",
664 timeout=10 )
665 except pexpect.EOF:
666 main.log.error( self.name + ": EOF exception found" )
667 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700668 main.cleanup()
669 main.exit()
adminbae64d82013-08-01 10:50:15 -0700670
671 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800673 main.log.info(
674 self.name +
675 ": IP-Address of Host " +
676 host +
677 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 ipAddressSearch.group( 1 ) )
679 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800680 else:
681 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800682
Jon Hall7eb38402015-01-08 17:19:54 -0800683 def getSwitchDPID( self, switch ):
684 """
685 return the datapath ID of the switch"""
686 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700687 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700688 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800689 response = self.execute(
690 cmd=cmd,
691 prompt="mininet>",
692 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800693 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800694 main.log.error( self.name + ": EOF exception found" )
695 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700696 main.cleanup()
697 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800698 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800699 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700700 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800701 main.log.info(
702 "Couldn't find DPID for switch %s, found: %s" %
703 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700704 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800705 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700706 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800707 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700708
Jon Hall7eb38402015-01-08 17:19:54 -0800709 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700710 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 self.handle.sendline( "" )
712 self.expect( "mininet>" )
713 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700714 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800715 response = self.execute(
716 cmd=cmd,
717 prompt="mininet>",
718 timeout=10 )
719 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700720 response = self.handle.before
721 return response
722 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700725 main.cleanup()
726 main.exit()
727
Jon Hall7eb38402015-01-08 17:19:54 -0800728 def getInterfaces( self, node ):
729 """
730 return information dict about interfaces connected to the node"""
731 if self.handle:
732 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800733 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700734 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700735 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800736 response = self.execute(
737 cmd=cmd,
738 prompt="mininet>",
739 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800740 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 main.log.error( self.name + ": EOF exception found" )
742 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700743 main.cleanup()
744 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700745 return response
746 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700748
Jon Hall7eb38402015-01-08 17:19:54 -0800749 def dump( self ):
750 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700751 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800752 response = self.execute(
753 cmd='dump',
754 prompt='mininet>',
755 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800756 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800757 main.log.error( self.name + ": EOF exception found" )
758 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700759 main.cleanup()
760 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700761 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800762
Jon Hall7eb38402015-01-08 17:19:54 -0800763 def intfs( self ):
764 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700765 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800766 response = self.execute(
767 cmd='intfs',
768 prompt='mininet>',
769 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 Hallfbc828e2015-01-06 17:30:19 -0800776
Jon Hall7eb38402015-01-08 17:19:54 -0800777 def net( self ):
778 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700779 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800780 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800781 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700784 main.cleanup()
785 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700786 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800787
788 def iperf( self, host1, host2 ):
789 main.log.info(
790 self.name +
791 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700792 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800793 cmd1 = 'iperf ' + host1 + " " + host2
794 self.handle.sendline( cmd1 )
795 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800796 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800797 if re.search( 'Results:', response ):
798 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800799 return main.TRUE
800 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800801 main.log.error( self.name + ": iperf test failed" )
802 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800803 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800804 main.log.error( self.name + ": EOF exception found" )
805 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800806 main.cleanup()
807 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800808
Jon Hall7eb38402015-01-08 17:19:54 -0800809 def iperfudp( self ):
810 main.log.info(
811 self.name +
812 ": Simple iperf TCP test between two " +
813 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700814 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800815 response = self.execute(
816 cmd='iperfudp',
817 prompt='mininet>',
818 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800819 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800820 main.log.error( self.name + ": EOF exception found" )
821 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700822 main.cleanup()
823 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700824 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800825
Jon Hall7eb38402015-01-08 17:19:54 -0800826 def nodes( self ):
827 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700828 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800829 response = self.execute(
830 cmd='nodes',
831 prompt='mininet>',
832 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800833 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700836 main.cleanup()
837 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700838 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800839
Jon Hall7eb38402015-01-08 17:19:54 -0800840 def pingpair( self ):
841 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700842 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800843 response = self.execute(
844 cmd='pingpair',
845 prompt='mininet>',
846 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800847 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800848 main.log.error( self.name + ": EOF exception found" )
849 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700850 main.cleanup()
851 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800852
Jon Hall7eb38402015-01-08 17:19:54 -0800853 if re.search( ',\s0\%\spacket\sloss', response ):
854 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800855 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700856 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800857 else:
858 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700860 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800861
Jon Hall7eb38402015-01-08 17:19:54 -0800862 def link( self, **linkargs ):
863 """
864 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800865 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800866 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
867 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
868 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
869 main.log.info(
870 "Bring link between '" +
871 end1 +
872 "' and '" +
873 end2 +
874 "' '" +
875 option +
876 "'" )
877 command = "link " + \
878 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700879 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800880 self.handle.sendline( command )
881 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800882 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800883 main.log.error( self.name + ": EOF exception found" )
884 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700885 main.cleanup()
886 main.exit()
adminbae64d82013-08-01 10:50:15 -0700887 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800888
Jon Hall7eb38402015-01-08 17:19:54 -0800889 def yank( self, **yankargs ):
890 """
891 yank a mininet switch interface to a host"""
892 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800893 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800894 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
895 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
896 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700897 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800898 response = self.execute(
899 cmd=command,
900 prompt="mininet>",
901 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800902 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800903 main.log.error( self.name + ": EOF exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700905 main.cleanup()
906 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700907 return main.TRUE
908
Jon Hall7eb38402015-01-08 17:19:54 -0800909 def plug( self, **plugargs ):
910 """
911 plug the yanked mininet switch interface to a switch"""
912 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800913 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800914 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
915 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
916 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700917 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800918 response = self.execute(
919 cmd=command,
920 prompt="mininet>",
921 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800922 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700925 main.cleanup()
926 main.exit()
adminbae64d82013-08-01 10:50:15 -0700927 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800928
Jon Hall7eb38402015-01-08 17:19:54 -0800929 def dpctl( self, **dpctlargs ):
930 """
931 Run dpctl command on all switches."""
932 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800933 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800934 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
935 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
936 command = "dpctl " + cmd + " " + str( cmdargs )
937 try:
938 response = self.execute(
939 cmd=command,
940 prompt="mininet>",
941 timeout=10 )
942 except pexpect.EOF:
943 main.log.error( self.name + ": EOF exception found" )
944 main.log.error( self.name + ": " + self.handle.before )
945 main.cleanup()
946 main.exit()
947 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800948
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 def getVersion( self ):
950 fileInput = path + '/lib/Mininet/INSTALL'
951 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700952 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800954 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700955 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800956 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500957 return version
adminbae64d82013-08-01 10:50:15 -0700958
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800960 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500961 Parameters:
962 sw: The name of an OVS switch. Example "s1"
963 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800964 The output of the command from the mininet cli
965 or main.FALSE on timeout"""
966 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700967 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800968 response = self.execute(
969 cmd=command,
970 prompt="mininet>",
971 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700972 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500973 return response
admin2a9548d2014-06-17 14:08:07 -0700974 else:
975 return main.FALSE
976 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800977 main.log.error( self.name + ": EOF exception found" )
978 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700979 main.cleanup()
980 main.exit()
adminbae64d82013-08-01 10:50:15 -0700981
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800983 """
984 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800985 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800986 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700987
988 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800989 for j in range( count ):
990 argstring = argstring + ",IP" + \
991 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800992 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700993
Jon Hall7eb38402015-01-08 17:19:54 -0800994 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
995 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800996 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800997 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800998
Jon Hall7eb38402015-01-08 17:19:54 -0800999 command = "sh ovs-vsctl set-controller s" + \
1000 str( sw ) + " " + ptcpB + " "
1001 for j in range( count ):
1002 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001003 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001004 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1005 ip = args[
1006 "IP" +
1007 str( i ) ] if args[
1008 "IP" +
1009 str( i ) ] is not None else ""
1010 port = args[
1011 "PORT" +
1012 str( i ) ] if args[
1013 "PORT" +
1014 str( i ) ] is not None else ""
1015 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001016 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001017 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001018 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001019 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001020 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001021 main.log.error( self.name + ": EOF exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001023 main.cleanup()
1024 main.exit()
1025 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001026 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001027 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001028 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001029 main.cleanup()
1030 main.exit()
adminbae64d82013-08-01 10:50:15 -07001031
kelvin-onlabd3b64892015-01-20 13:26:24 -08001032 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001033 """
1034 Removes the controller target from sw"""
1035 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001036 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001037 response = self.execute(
1038 cmd=command,
1039 prompt="mininet>",
1040 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001041 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001042 main.log.error( self.name + ": EOF exception found" )
1043 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001044 main.cleanup()
1045 main.exit()
1046 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001047 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001048
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001050 """
Jon Hallb1290e82014-11-18 16:17:48 -05001051 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001052 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001053 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001054 NOTE: cannot currently specify what type of switch
1055 required params:
1056 switchname = name of the new switch as a string
1057 optional keyvalues:
1058 dpid = "dpid"
1059 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001060 """
1061 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001062 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001063 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001064 response = self.execute(
1065 cmd=command,
1066 prompt="mininet>",
1067 timeout=10 )
1068 if re.search( "already exists!", response ):
1069 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001070 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001071 elif re.search( "Error", response ):
1072 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001073 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001074 elif re.search( "usage:", response ):
1075 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001076 return main.FALSE
1077 else:
1078 return main.TRUE
1079 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001080 main.log.error( self.name + ": EOF exception found" )
1081 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001082 main.cleanup()
1083 main.exit()
1084
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001086 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001087 delete a switch from the mininet topology
1088 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001089 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001090 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001091 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001092 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001093 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001094 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001095 response = self.execute(
1096 cmd=command,
1097 prompt="mininet>",
1098 timeout=10 )
1099 if re.search( "no switch named", response ):
1100 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001101 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001102 elif re.search( "Error", response ):
1103 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001104 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001105 elif re.search( "usage:", response ):
1106 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001107 return main.FALSE
1108 else:
1109 return main.TRUE
1110 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001111 main.log.error( self.name + ": EOF exception found" )
1112 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001113 main.cleanup()
1114 main.exit()
1115
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001117 """
1118 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001119 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001120 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001121 NOTE: cannot currently specify what type of link
1122 required params:
1123 node1 = the string node name of the first endpoint of the link
1124 node2 = the string node name of the second endpoint of the link
1125 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001126 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001127 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001128 response = self.execute(
1129 cmd=command,
1130 prompt="mininet>",
1131 timeout=10 )
1132 if re.search( "doesnt exist!", response ):
1133 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001134 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001135 elif re.search( "Error", response ):
1136 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001137 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001138 elif re.search( "usage:", response ):
1139 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001140 return main.FALSE
1141 else:
1142 return main.TRUE
1143 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001144 main.log.error( self.name + ": EOF exception found" )
1145 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001146 main.cleanup()
1147 main.exit()
1148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001150 """
1151 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001152 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001153 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001154 required params:
1155 node1 = the string node name of the first endpoint of the link
1156 node2 = the string node name of the second endpoint of the link
1157 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001158 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001159 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001160 response = self.execute(
1161 cmd=command,
1162 prompt="mininet>",
1163 timeout=10 )
1164 if re.search( "no node named", response ):
1165 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001166 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001167 elif re.search( "Error", response ):
1168 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001169 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001170 elif re.search( "usage:", response ):
1171 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001172 return main.FALSE
1173 else:
1174 return main.TRUE
1175 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001176 main.log.error( self.name + ": EOF exception found" )
1177 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001178 main.cleanup()
1179 main.exit()
1180
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001182 """
Jon Hallb1290e82014-11-18 16:17:48 -05001183 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001184 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001185 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001186 NOTE: cannot currently specify what type of host
1187 required params:
1188 hostname = the string hostname
1189 optional key-value params
1190 switch = "switch name"
1191 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001192 """
1193 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001194 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001195 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001196 response = self.execute(
1197 cmd=command,
1198 prompt="mininet>",
1199 timeout=10 )
1200 if re.search( "already exists!", response ):
1201 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001202 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001203 elif re.search( "doesnt exists!", response ):
1204 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001205 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001206 elif re.search( "Error", response ):
1207 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001208 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001209 elif re.search( "usage:", response ):
1210 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001211 return main.FALSE
1212 else:
1213 return main.TRUE
1214 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001215 main.log.error( self.name + ": EOF exception found" )
1216 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001217 main.cleanup()
1218 main.exit()
1219
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001221 """
1222 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001223 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001224 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001225 NOTE: this uses a custom mn function
1226 required params:
1227 hostname = the string hostname
1228 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001229 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001230 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001231 response = self.execute(
1232 cmd=command,
1233 prompt="mininet>",
1234 timeout=10 )
1235 if re.search( "no host named", response ):
1236 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001237 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001238 elif re.search( "Error", response ):
1239 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001240 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001241 elif re.search( "usage:", response ):
1242 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001243 return main.FALSE
1244 else:
1245 return main.TRUE
1246 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001247 main.log.error( self.name + ": EOF exception found" )
1248 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001249 main.cleanup()
1250 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001251
Jon Hall7eb38402015-01-08 17:19:54 -08001252 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001253 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001254 Called at the end of the test to stop the mininet and
1255 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001256 """
1257 self.handle.sendline('')
1258 i = 1
1259 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1260 if i == 0:
1261 self.stopNet()
1262 response = ''
1263 # print "Disconnecting Mininet"
1264 if self.handle:
1265 self.handle.sendline( "exit" )
1266 self.handle.expect( "exit" )
1267 self.handle.expect( "(.*)" )
1268 main.log.info( "Mininet CLI is successfully disconnected" )
shahshreya26c3cea2015-02-05 10:17:41 -08001269 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001270 else:
1271 main.log.error( "Connection failed to the host" )
1272 response = main.FALSE
1273
1274 return response
1275
1276 def stopNet( self ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001277 """
1278 Stops mininet. returns true if the mininet succesfully stops.
1279 """
1280
Jon Hall7eb38402015-01-08 17:19:54 -08001281 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001282 response = ''
1283 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001284 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001285 response = self.execute(
1286 cmd="exit",
1287 prompt="(.*)",
1288 timeout=120 )
kelvin-onlaba1484582015-02-02 15:46:20 -08001289 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001290 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001291 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001292 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001293 main.log.error( self.name + ": EOF exception found" )
1294 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001295 main.cleanup()
1296 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001297 else:
1298 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001299 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001300 return response
1301
kelvin-onlaba1484582015-02-02 15:46:20 -08001302
1303
Jon Hall7eb38402015-01-08 17:19:54 -08001304 def arping( self, src, dest, destmac ):
1305 self.handle.sendline( '' )
1306 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001307
Jon Hall7eb38402015-01-08 17:19:54 -08001308 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001309 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001310 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1311 main.log.info( self.name + ": ARP successful" )
1312 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001313 return main.TRUE
1314 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001315 main.log.warn( self.name + ": ARP FAILURE" )
1316 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001317 return main.FALSE
1318
Jon Hall7eb38402015-01-08 17:19:54 -08001319 def decToHex( self, num ):
1320 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001321
Jon Hall7eb38402015-01-08 17:19:54 -08001322 def getSwitchFlowCount( self, switch ):
1323 """
1324 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001325 if self.handle:
1326 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1327 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001328 response = self.execute(
1329 cmd=cmd,
1330 prompt="mininet>",
1331 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001332 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001333 main.log.error( self.name + ": EOF exception found" )
1334 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001335 main.cleanup()
1336 main.exit()
1337 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001338 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001339 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001340 main.log.info(
1341 "Couldn't find flows on switch %s, found: %s" %
1342 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001343 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001344 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001345 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001346 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001347
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 def checkFlows( self, sw, dumpFormat=None ):
1349 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001352 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001353 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001354 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001355 response = self.execute(
1356 cmd=command,
1357 prompt="mininet>",
1358 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001359 return response
1360 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001361 main.log.error( self.name + ": EOF exception found" )
1362 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001363 main.cleanup()
1364 main.exit()
1365 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001367
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001369 """
1370 Runs tpdump on an intferface and saves the file
1371 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001372 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001373 self.handle.sendline( "" )
1374 self.handle.expect( "mininet>" )
1375 self.handle.sendline(
1376 "sh sudo tcpdump -n -i " +
1377 intf +
1378 " " +
1379 port +
1380 " -w " +
1381 filename.strip() +
1382 " &" )
1383 self.handle.sendline( "" )
1384 i = self.handle.expect( [ 'No\ssuch\device',
1385 'listening\son',
1386 pexpect.TIMEOUT,
1387 "mininet>" ],
1388 timeout=10 )
1389 main.log.warn( self.handle.before + self.handle.after )
1390 self.handle.sendline( "" )
1391 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001392 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001393 main.log.error(
1394 self.name +
1395 ": tcpdump - No such device exists. " +
1396 "tcpdump attempted on: " +
1397 intf )
admin2a9548d2014-06-17 14:08:07 -07001398 return main.FALSE
1399 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001400 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001401 return main.TRUE
1402 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001403 main.log.error(
1404 self.name +
1405 ": tcpdump command timed out! Check interface name," +
1406 " given interface was: " +
1407 intf )
admin2a9548d2014-06-17 14:08:07 -07001408 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001409 elif i == 3:
1410 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001411 return main.TRUE
1412 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001413 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001414 return main.FALSE
1415 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001416 main.log.error( self.name + ": EOF exception found" )
1417 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001418 main.cleanup()
1419 main.exit()
1420 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001422 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001423 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001424 main.cleanup()
1425 main.exit()
1426
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001428 "pkills tcpdump"
1429 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001430 self.handle.sendline( "sh sudo pkill tcpdump" )
1431 self.handle.expect( "mininet>" )
1432 self.handle.sendline( "" )
1433 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001434 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001437 main.cleanup()
1438 main.exit()
1439 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001440 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001441 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001442 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001443 main.cleanup()
1444 main.exit()
1445
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001447 """
1448 Compare mn and onos switches
1449 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001451
Jon Hall7eb38402015-01-08 17:19:54 -08001452 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001454 output = { "switches": [] }
1455 # iterate through the MN topology and pull out switches and and port
1456 # info
1457 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001458 ports = []
1459 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001460 ports.append( { 'of_port': port.port_no,
1461 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001462 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001463 'name': port.name } )
1464 output[ 'switches' ].append( {
1465 "name": switch.name,
1466 "dpid": str( switch.dpid ).zfill( 16 ),
1467 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001468
Jon Hall7eb38402015-01-08 17:19:54 -08001469 # print "mn"
1470 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001471 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001472 # indent=4,
1473 # separators=( ',', ': ' ) )
1474 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 # print json.dumps( switchesJson,
1476 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001477 # indent=4,
1478 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001479
1480 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001481 mnDPIDs = []
1482 for switch in output[ 'switches' ]:
1483 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001484 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001485 # print "List of Mininet switch DPID's"
1486 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001488 main.log.error(
1489 self.name +
1490 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001491 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001493 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001494 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001495 if switch[ 'available' ]:
1496 onosDPIDs.append(
1497 switch[ 'id' ].replace(
1498 ":",
1499 '' ).replace(
1500 "of",
1501 '' ).lower() )
1502 # else:
1503 # print "Switch is unavailable:"
1504 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001505 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001506 # print "List of ONOS switch DPID's"
1507 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001508
Jon Hall7eb38402015-01-08 17:19:54 -08001509 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001511 main.log.report( "Switches in MN but not in ONOS:" )
1512 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1513 main.log.report( str( list1 ) )
1514 main.log.report( "Switches in ONOS but not in MN:" )
1515 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001516 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001517 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 switchResults = main.TRUE
1519 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001522 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001523 Compare mn and onos ports
1524 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001526
Jon Hallfbc828e2015-01-06 17:30:19 -08001527 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001528 1. This uses the sts TestONTopology object
1529 2. numpy - "sudo pip install numpy"
1530
Jon Hall7eb38402015-01-08 17:19:54 -08001531 """
1532 # FIXME: this does not look for extra ports in ONOS, only checks that
1533 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001534 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001536 output = { "switches": [] }
1537 # iterate through the MN topology and pull out switches and and port
1538 # info
1539 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001540 ports = []
1541 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001542 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001544 tmpPort[ 'of_port' ] = port.port_no
1545 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 tmpPort[ 'name' ] = port.name
1547 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001548
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 ports.append( tmpPort )
1550 tmpSwitch = {}
1551 tmpSwitch[ 'name' ] = switch.name
1552 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1553 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001554
kelvin-onlabd3b64892015-01-20 13:26:24 -08001555 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001556
Jon Hall7eb38402015-01-08 17:19:54 -08001557 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 for mnSwitch in output[ 'switches' ]:
1559 mnPorts = []
1560 onosPorts = []
1561 switchResult = main.TRUE
1562 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001563 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 mnPorts.append( port[ 'of_port' ] )
1565 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001566 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 # print onosSwitch
1568 if onosSwitch[ 'device' ][ 'available' ]:
1569 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001570 ':',
1571 '' ).replace(
1572 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001573 '' ) == mnSwitch[ 'dpid' ]:
1574 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001575 if port[ 'isEnabled' ]:
1576 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 # onosPorts.append( 'local' )
1578 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001579 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001581 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 mnPorts.sort( key=float )
1583 onosPorts.sort( key=float )
1584 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1585 # print "\tmn_ports[] = ", mnPorts
1586 # print "\tonos_ports[] = ", onosPorts
1587 mnPortsLog = mnPorts
1588 onosPortsLog = onosPorts
1589 mnPorts = [ x for x in mnPorts ]
1590 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001591
Jon Hall7eb38402015-01-08 17:19:54 -08001592 # TODO: handle other reserved port numbers besides LOCAL
1593 # NOTE: Reserved ports
1594 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1595 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 for mnPort in mnPortsLog:
1597 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001598 # don't set results to true here as this is just one of
1599 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 mnPorts.remove( mnPort )
1601 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001602 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001603 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001604 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 if 65534 in mnPorts:
1606 mnPorts.remove( 65534 )
1607 if long( uint64( -2 ) ) in onosPorts:
1608 onosPorts.remove( long( uint64( -2 ) ) )
1609 if len( mnPorts ): # the ports of this switch don't match
1610 switchResult = main.FALSE
1611 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1612 if len( onosPorts ): # the ports of this switch don't match
1613 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001614 main.log.warn(
1615 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001616 str( onosPorts ) )
1617 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001618 main.log.report(
1619 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1621 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1622 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1623 portsResults = portsResults and switchResult
1624 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001625
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001627 """
1628 Compare mn and onos links
1629 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001631
Jon Hall7eb38402015-01-08 17:19:54 -08001632 This uses the sts TestONTopology object"""
1633 # FIXME: this does not look for extra links in ONOS, only checks that
1634 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001636 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001637 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001638 # iterate through the MN topology and pull out switches and and port
1639 # info
1640 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001641 # print "Iterating though switches as seen by Mininet"
1642 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001643 ports = []
1644 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001645 # print port.hw_addr.toStr( separator='' )
1646 ports.append( { 'of_port': port.port_no,
1647 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001649 'name': port.name } )
1650 output[ 'switches' ].append( {
1651 "name": switch.name,
1652 "dpid": str( switch.dpid ).zfill( 16 ),
1653 "ports": ports } )
1654 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001655
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001657 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001658 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 if 2 * len( mnLinks ) == len( onos ):
1660 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001661 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001663 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001664 "Mininet has " + str( len( mnLinks ) ) +
1665 " bidirectional links and ONOS has " +
1666 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001667
Jon Hall7eb38402015-01-08 17:19:54 -08001668 # iterate through MN links and check if an ONOS link exists in
1669 # both directions
1670 # NOTE: Will currently only show mn links as down if they are
1671 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001673 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001675 # print "Link: %s" % link
1676 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001677 node1 = None
1678 port1 = None
1679 node2 = None
1680 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 firstDir = main.FALSE
1682 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001683 for switch in output[ 'switches' ]:
1684 # print "Switch: %s" % switch[ 'name' ]
1685 if switch[ 'name' ] == link.node1.name:
1686 node1 = switch[ 'dpid' ]
1687 for port in switch[ 'ports' ]:
1688 if str( port[ 'name' ] ) == str( link.port1 ):
1689 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001690 if node1 is not None and node2 is not None:
1691 break
Jon Hall7eb38402015-01-08 17:19:54 -08001692 if switch[ 'name' ] == link.node2.name:
1693 node2 = switch[ 'dpid' ]
1694 for port in switch[ 'ports' ]:
1695 if str( port[ 'name' ] ) == str( link.port2 ):
1696 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001697 if node1 is not None and node2 is not None:
1698 break
1699
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 for onosLink in onos:
1701 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001702 ":",
1703 '' ).replace(
1704 "of",
1705 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001706 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001707 ":",
1708 '' ).replace(
1709 "of",
1710 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 onosPort1 = onosLink[ 'src' ][ 'port' ]
1712 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001713
Jon Hall72cf1dc2014-10-20 21:04:50 -04001714 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001715 if str( onosNode1 ) == str( node1 ) and str(
1716 onosNode2 ) == str( node2 ):
1717 if int( onosPort1 ) == int( port1 ) and int(
1718 onosPort2 ) == int( port2 ):
1719 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001720 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001721 main.log.warn(
1722 'The port numbers do not match for ' +
1723 str( link ) +
1724 ' between ONOS and MN. When cheking ONOS for ' +
1725 'link %s/%s -> %s/%s' %
1726 ( node1,
1727 port1,
1728 node2,
1729 port2 ) +
1730 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 ( onosNode1,
1732 onosPort1,
1733 onosNode2,
1734 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001735
1736 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001737 elif ( str( onosNode1 ) == str( node2 ) and
1738 str( onosNode2 ) == str( node1 ) ):
1739 if ( int( onosPort1 ) == int( port2 )
1740 and int( onosPort2 ) == int( port1 ) ):
1741 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001742 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001743 main.log.warn(
1744 'The port numbers do not match for ' +
1745 str( link ) +
1746 ' between ONOS and MN. When cheking ONOS for ' +
1747 'link %s/%s -> %s/%s' %
1748 ( node2,
1749 port2,
1750 node1,
1751 port1 ) +
1752 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001753 ( onosNode2,
1754 onosPort2,
1755 onosNode1,
1756 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001757 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001758 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001760 main.log.report(
1761 'ONOS does not have the link %s/%s -> %s/%s' %
1762 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001763 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001764 main.log.report(
1765 'ONOS does not have the link %s/%s -> %s/%s' %
1766 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 linkResults = linkResults and firstDir and secondDir
1768 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001769
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001771 """
1772 Returns a list of all hosts
1773 Don't ask questions just use it"""
1774 self.handle.sendline( "" )
1775 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001776
Jon Hall7eb38402015-01-08 17:19:54 -08001777 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1778 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001779
kelvin-onlabd3b64892015-01-20 13:26:24 -08001780 handlePy = self.handle.before
1781 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1782 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001783
Jon Hall7eb38402015-01-08 17:19:54 -08001784 self.handle.sendline( "" )
1785 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001786
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 hostStr = handlePy.replace( "]", "" )
1788 hostStr = hostStr.replace( "'", "" )
1789 hostStr = hostStr.replace( "[", "" )
1790 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001791
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 return hostList
adminbae64d82013-08-01 10:50:15 -07001793
Jon Hall7eb38402015-01-08 17:19:54 -08001794 def update( self ):
1795 """
1796 updates the port address and status information for
1797 each port in mn"""
1798 # TODO: Add error checking. currently the mininet command has no output
1799 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001800 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001801 self.handle.sendline( "" )
1802 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001803
Jon Hall7eb38402015-01-08 17:19:54 -08001804 self.handle.sendline( "update" )
1805 self.handle.expect( "update" )
1806 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001807
Jon Hall7eb38402015-01-08 17:19:54 -08001808 self.handle.sendline( "" )
1809 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001810
Jon Hallb1290e82014-11-18 16:17:48 -05001811 return main.TRUE
1812 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001813 main.log.error( self.name + ": EOF exception found" )
1814 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001815 main.cleanup()
1816 main.exit()
1817
adminbae64d82013-08-01 10:50:15 -07001818if __name__ != "__main__":
1819 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001820 sys.modules[ __name__ ] = MininetCliDriver()