blob: b7dc847b6dffc6fda16908cf3bcd326c158a4e2b [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-onlaba0ce3222015-01-27 17:25:15 -080062 try:
63 for key in connectargs:
64 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080065
kelvin-onlaba0ce3222015-01-27 17:25:15 -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-onlaba0ce3222015-01-27 17:25:15 -080075 if self.handle:
kelvin-onlab5edb77f2015-01-28 16:27:12 -080076 main.log.info("Connection successful to the host " +
kelvin-onlaba0ce3222015-01-27 17:25:15 -080077 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
kelvin-onlab84135842015-02-06 11:03:28 -0800100<<<<<<< HEAD
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800101
kelvin-onlab97d64e72015-01-28 11:14:55 -0800102 def startNet( self, topoFile = '', args = '', timeout = 120 ):
kelvin-onlab84135842015-02-06 11:03:28 -0800103=======
104>>>>>>> 42efbd8869b8e52ac17c3f0966cdf12979e41e0f
Jon Hallfbc828e2015-01-06 17:30:19 -0800105
kelvin-onlaba1484582015-02-02 15:46:20 -0800106 def startNet( self, topoFile = '', args = '', timeout = 120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800107 """
108 Starts Mininet accepts a topology(.py) file and/or an optional
109 arguement ,to start the mininet, as a parameter.
110 Returns true if the mininet starts successfully
111 """
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800112 if self.handle:
113 main.log.info(
114 self.name +
115 ": Clearing any residual state or processes" )
116 self.handle.sendline( "sudo mn -c" )
117 i = self.handle.expect( [ 'password\sfor\s',
118 'Cleanup\scomplete',
119 pexpect.EOF,
120 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800121 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800122 if i == 0:
123 main.log.info( self.name + ": Sending sudo password" )
124 self.handle.sendline( self.pwd )
125 i = self.handle.expect( [ '%s:' % ( self.user ),
126 '\$',
Jon Hall7eb38402015-01-08 17:19:54 -0800127 pexpect.EOF,
128 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800129 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800130 if i == 1:
131 main.log.info( self.name + ": Clean" )
132 elif i == 2:
133 main.log.error( self.name + ": Connection terminated" )
134 elif i == 3: # timeout
135 main.log.error(
136 self.name +
137 ": Something while cleaning MN took too long... " )
kelvin-onlab97d64e72015-01-28 11:14:55 -0800138 if topoFile == '' and args == '':
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800139 main.log.info( self.name + ": building fresh mininet" )
140 # for reactive/PARP enabled tests
141 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
142 " " + self.options[ 'arg2' ] +\
143 " --mac --controller " +\
144 self.options[ 'controller' ] + " " +\
145 self.options[ 'arg3' ]
146
147 argList = self.options[ 'arg1' ].split( "," )
148 global topoArgList
149 topoArgList = argList[ 0 ].split( " " )
150 argList = map( int, argList[ 1: ] )
151 topoArgList = topoArgList[ 1: ] + argList
152
153 self.handle.sendline( cmdString )
154 self.handle.expect( [ "sudo mn",
155 pexpect.EOF,
156 pexpect.TIMEOUT ] )
157 while True:
158 i = self.handle.expect( [ 'mininet>',
159 '\*\*\*',
160 'Exception',
161 pexpect.EOF,
162 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800163 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800164 if i == 0:
165 main.log.info( self.name + ": mininet built" )
166 return main.TRUE
167 if i == 1:
168 self.handle.expect(
169 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
170 main.log.info( self.handle.before )
171 elif i == 2:
172 main.log.error(
173 self.name +
174 ": Launching mininet failed..." )
175 return main.FALSE
176 elif i == 3:
177 main.log.error( self.name + ": Connection timeout" )
178 return main.FALSE
179 elif i == 4: # timeout
180 main.log.error(
181 self.name +
182 ": Something took too long... " )
183 return main.FALSE
184 return main.TRUE
185 else:
kelvin-onlab97d64e72015-01-28 11:14:55 -0800186 main.log.info( "Starting topo file " + topoFile )
187 if args == None:
188 args = ''
189 else:
190 main.log.info( "args = " + args)
191 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800192 i = 1
193 i = self.handle.expect( [ 'mininet>',
194 pexpect.EOF ,
kelvin-onlab97d64e72015-01-28 11:14:55 -0800195 pexpect.TIMEOUT ],
196 timeout)
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800197 main.log.info(self.name + ": Network started")
198 return main.TRUE
199
Jon Hall7eb38402015-01-08 17:19:54 -0800200 else: # if no handle
201 main.log.error(
202 self.name +
203 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800204 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800205 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800206 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800207 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700208 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800209
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800210 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400211 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800212 # In tree topology, if fanout arg is not given, by default it is 2
213 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400214 fanout = 2
215 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500216 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800217 while( k <= depth - 1 ):
218 count = count + pow( fanout, k )
219 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800221 while( k <= depth - 2 ):
222 # depth-2 gives you only core links and not considering
223 # edge links as seen by ONOS. If all the links including
224 # edge links are required, do depth-1
225 count = count + pow( fanout, k )
226 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800228 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800230
Jon Hall7eb38402015-01-08 17:19:54 -0800231 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800233 # by default it is 1
234 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400235 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 numSwitches = depth
237 numHostsPerSw = fanout
238 totalNumHosts = numSwitches * numHostsPerSw
239 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800240 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400242 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800243 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 "num_switches": int( numSwitches ),
245 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400246 return topoDict
247
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 def calculateSwAndLinks( self ):
249 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400250 return topoDict
251
Jon Hall7eb38402015-01-08 17:19:54 -0800252 def pingall( self, timeout=300 ):
253 """
254 Verifies the reachability of the hosts using pingall command.
255 Optional parameter timeout allows you to specify how long to
256 wait for pingall to complete
257 Returns:
258 main.TRUE if pingall completes with no pings dropped
259 otherwise main.FALSE"""
260 if self.handle:
261 main.log.info(
262 self.name +
263 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700264 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800265 response = self.execute(
266 cmd="pingall",
267 prompt="mininet>",
268 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500269 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800270 main.log.error( self.name + ": EOF exception found" )
271 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500272 main.cleanup()
273 main.exit()
274 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800275 # We may not want to kill the test if pexpect times out
276 main.log.error( self.name + ": TIMEOUT exception found" )
277 main.log.error( self.name +
278 ": " +
279 str( self.handle.before ) )
280 # NOTE: mininet's pingall rounds, so we will check the number of
281 # passed and number of failed
282 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800284 if re.search( pattern, response ):
285 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700286 return main.TRUE
287 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800288 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800289 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800290 # NOTE: Send ctrl-c to make sure pingall is done
291 self.handle.send( "\x03" )
292 self.handle.expect( "Interrupt" )
293 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700294 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800295 else:
296 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500297 main.cleanup()
298 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700299
Jon Hall7eb38402015-01-08 17:19:54 -0800300 def fpingHost( self, **pingParams ):
301 """
302 Uses the fping package for faster pinging...
303 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800304 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800305 command = args[ "SRC" ] + \
306 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
307 self.handle.sendline( command )
308 self.handle.expect(
309 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
310 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
311 response = self.handle.before
312 if re.search( ":\s-", response ):
313 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700314 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800315 elif re.search( ":\s\d{1,2}\.\d\d", response ):
316 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700317 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800318 main.log.info( self.name + ": Install fping on mininet machine... " )
319 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700320 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800321
Jon Hall7eb38402015-01-08 17:19:54 -0800322 def pingHost( self, **pingParams ):
323 """
324 Ping from one mininet host to another
325 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800326 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800327 command = args[ "SRC" ] + " ping " + \
328 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700329 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800330 main.log.warn( "Sending: " + command )
331 self.handle.sendline( command )
332 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700333 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800334 main.log.error(
335 self.name +
336 ": timeout when waiting for response from mininet" )
337 main.log.error( "response: " + str( self.handle.before ) )
338 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700339 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800340 main.log.error(
341 self.name +
342 ": timeout when waiting for response from mininet" )
343 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700344 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800345 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800346 main.log.error( self.name + ": EOF exception found" )
347 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700348 main.cleanup()
349 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800350 main.log.info( self.name + ": Ping Response: " + response )
351 if re.search( ',\s0\%\spacket\sloss', response ):
352 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800353 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700354 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800355 else:
356 main.log.error(
357 self.name +
358 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800359 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700360 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800361
Jon Hall7eb38402015-01-08 17:19:54 -0800362 def checkIP( self, host ):
363 """
364 Verifies the host's ip configured or not."""
365 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700366 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800367 response = self.execute(
368 cmd=host +
369 " ifconfig",
370 prompt="mininet>",
371 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800372 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800373 main.log.error( self.name + ": EOF exception found" )
374 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700375 main.cleanup()
376 main.exit()
adminbae64d82013-08-01 10:50:15 -0700377
Jon Hall7eb38402015-01-08 17:19:54 -0800378 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800379 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
380 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
381 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
382 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
383 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800384 # pattern = "inet addr:10.0.0.6"
385 if re.search( pattern, response ):
386 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700387 return main.TRUE
388 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800389 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700390 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800391 else:
392 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800393
Jon Hall7eb38402015-01-08 17:19:54 -0800394 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700395 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800396 response = self.execute(
397 cmd="h1 /usr/sbin/sshd -D&",
398 prompt="mininet>",
399 timeout=10 )
400 response = self.execute(
401 cmd="h4 /usr/sbin/sshd -D&",
402 prompt="mininet>",
403 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700404 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800405 vars( self )[ key ] = connectargs[ key ]
406 response = self.execute(
407 cmd="xterm h1 h4 ",
408 prompt="mininet>",
409 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800410 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800411 main.log.error( self.name + ": EOF exception found" )
412 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700413 main.cleanup()
414 main.exit()
adminbae64d82013-08-01 10:50:15 -0700415 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800416 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700417 if self.flag == 0:
418 self.flag = 1
419 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800420 else:
adminbae64d82013-08-01 10:50:15 -0700421 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800422
shahshreya5ff90d12015-01-30 11:41:51 -0800423 def moveHost( self, host, oldSw, newSw, ):
424 """
425 Moves a host from one switch to another on the fly
426 Note: The intf between host and oldSw when detached
427 using detach(), will still show up in the 'net'
428 cmd, because switch.detach() doesn't affect switch.intfs[]
429 (which is correct behavior since the interfaces
430 haven't moved).
431 """
432 if self.handle:
433 try:
434 # Bring link between oldSw-host down
435 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
436 "'down')"
437 print "cmd1= ", cmd
438 response = self.execute(
439 cmd=cmd,
440 prompt="mininet>",
441 timeout=10 )
442
443 # Determine hostintf and Oldswitchintf
444 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
445 ")[0]"
446 print "cmd2= ", cmd
447 self.handle.sendline( cmd )
448 self.handle.expect( "mininet>" )
449
450 # Determine ipaddress of the host-oldSw interface
451 cmd = "px ipaddr = hintf.IP()"
452 print "cmd3= ", cmd
453 self.handle.sendline( cmd )
454 self.handle.expect( "mininet>" )
455
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>" )
486
487 cmd = "net"
488 print "cmd8 = ", cmd
489 self.handle.sendline( cmd )
490 self.handle.expect( "mininet>" )
491 print "output = ", self.handle.before
492
493 # Determine ipaddress of the host-newSw interface
494 cmd = "h1 ifconfig"
495 print "cmd9= ", cmd
496 self.handle.sendline( cmd )
497 self.handle.expect( "mininet>" )
498 print "ifconfig o/p = ", self.handle.before
499
500 return main.TRUE
501 except pexpect.EOF:
502 main.log.error( self.name + ": EOF exception found" )
503 main.log.error( self.name + ": " + self.handle.before )
504 return main.FALSE
505
Jon Hall7eb38402015-01-08 17:19:54 -0800506 def changeIP( self, host, intf, newIP, newNetmask ):
507 """
508 Changes the ip address of a host on the fly
509 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800510 if self.handle:
511 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800512 cmd = host + " ifconfig " + intf + " " + \
513 newIP + " " + 'netmask' + " " + newNetmask
514 self.handle.sendline( cmd )
515 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800516 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800517 main.log.info( "response = " + response )
518 main.log.info(
519 "Ip of host " +
520 host +
521 " changed to new IP " +
522 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800523 return main.TRUE
524 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800525 main.log.error( self.name + ": EOF exception found" )
526 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800527 return main.FALSE
528
Jon Hall7eb38402015-01-08 17:19:54 -0800529 def changeDefaultGateway( self, host, newGW ):
530 """
531 Changes the default gateway of a host
532 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800533 if self.handle:
534 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800535 cmd = host + " route add default gw " + newGW
536 self.handle.sendline( cmd )
537 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800538 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800539 main.log.info( "response = " + response )
540 main.log.info(
541 "Default gateway of host " +
542 host +
543 " changed to " +
544 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800545 return main.TRUE
546 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800549 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800550
Jon Hall7eb38402015-01-08 17:19:54 -0800551 def addStaticMACAddress( self, host, GW, macaddr ):
552 """
553 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800554 if self.handle:
555 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800556 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
557 cmd = host + " arp -s " + GW + " " + macaddr
558 self.handle.sendline( cmd )
559 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800560 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800561 main.log.info( "response = " + response )
562 main.log.info(
563 "Mac adrress of gateway " +
564 GW +
565 " changed to " +
566 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800567 return main.TRUE
568 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800569 main.log.error( self.name + ": EOF exception found" )
570 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800571 return main.FALSE
572
Jon Hall7eb38402015-01-08 17:19:54 -0800573 def verifyStaticGWandMAC( self, host ):
574 """
575 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800576 if self.handle:
577 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800578 # h1 arp -an
579 cmd = host + " arp -an "
580 self.handle.sendline( cmd )
581 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800582 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800583 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800584 return main.TRUE
585 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800586 main.log.error( self.name + ": EOF exception found" )
587 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800588 return main.FALSE
589
Jon Hall7eb38402015-01-08 17:19:54 -0800590 def getMacAddress( self, host ):
591 """
592 Verifies the host's ip configured or not."""
593 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700594 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800595 response = self.execute(
596 cmd=host +
597 " ifconfig",
598 prompt="mininet>",
599 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800600 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800601 main.log.error( self.name + ": EOF exception found" )
602 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700603 main.cleanup()
604 main.exit()
adminbae64d82013-08-01 10:50:15 -0700605
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700606 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 macAddressSearch = re.search( pattern, response, re.I )
608 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800609 main.log.info(
610 self.name +
611 ": Mac-Address of Host " +
612 host +
613 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 macAddress )
615 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700616 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800617 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700618
Jon Hall7eb38402015-01-08 17:19:54 -0800619 def getInterfaceMACAddress( self, host, interface ):
620 """
621 Return the IP address of the interface on the given host"""
622 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700623 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800624 response = self.execute( cmd=host + " ifconfig " + interface,
625 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800626 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800627 main.log.error( self.name + ": EOF exception found" )
628 main.log.error( self.name + ": " + self.handle.before )
629 main.cleanup()
630 main.exit()
631
632 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 macAddressSearch = re.search( pattern, response, re.I )
634 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800635 main.log.info( "No mac address found in %s" % response )
636 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800638 main.log.info(
639 "Mac-Address of " +
640 host +
641 ":" +
642 interface +
643 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800644 macAddress )
645 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800646 else:
647 main.log.error( "Connection failed to the host" )
648
649 def getIPAddress( self, host ):
650 """
651 Verifies the host's ip configured or not."""
652 if self.handle:
653 try:
654 response = self.execute(
655 cmd=host +
656 " ifconfig",
657 prompt="mininet>",
658 timeout=10 )
659 except pexpect.EOF:
660 main.log.error( self.name + ": EOF exception found" )
661 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700662 main.cleanup()
663 main.exit()
adminbae64d82013-08-01 10:50:15 -0700664
665 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800667 main.log.info(
668 self.name +
669 ": IP-Address of Host " +
670 host +
671 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 ipAddressSearch.group( 1 ) )
673 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800674 else:
675 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800676
Jon Hall7eb38402015-01-08 17:19:54 -0800677 def getSwitchDPID( self, switch ):
678 """
679 return the datapath ID of the switch"""
680 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700681 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700682 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800683 response = self.execute(
684 cmd=cmd,
685 prompt="mininet>",
686 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800687 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800688 main.log.error( self.name + ": EOF exception found" )
689 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700690 main.cleanup()
691 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800692 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800693 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700694 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800695 main.log.info(
696 "Couldn't find DPID for switch %s, found: %s" %
697 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700698 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800699 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700700 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800701 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700702
Jon Hall7eb38402015-01-08 17:19:54 -0800703 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700704 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800705 self.handle.sendline( "" )
706 self.expect( "mininet>" )
707 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700708 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800709 response = self.execute(
710 cmd=cmd,
711 prompt="mininet>",
712 timeout=10 )
713 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700714 response = self.handle.before
715 return response
716 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800717 main.log.error( self.name + ": EOF exception found" )
718 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700719 main.cleanup()
720 main.exit()
721
Jon Hall7eb38402015-01-08 17:19:54 -0800722 def getInterfaces( self, node ):
723 """
724 return information dict about interfaces connected to the node"""
725 if self.handle:
726 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800727 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700728 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700729 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800730 response = self.execute(
731 cmd=cmd,
732 prompt="mininet>",
733 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800734 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800735 main.log.error( self.name + ": EOF exception found" )
736 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700737 main.cleanup()
738 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700739 return response
740 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700742
Jon Hall7eb38402015-01-08 17:19:54 -0800743 def dump( self ):
744 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700745 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 response = self.execute(
747 cmd='dump',
748 prompt='mininet>',
749 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800750 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700753 main.cleanup()
754 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700755 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800756
Jon Hall7eb38402015-01-08 17:19:54 -0800757 def intfs( self ):
758 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700759 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800760 response = self.execute(
761 cmd='intfs',
762 prompt='mininet>',
763 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800764 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700767 main.cleanup()
768 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700769 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800770
Jon Hall7eb38402015-01-08 17:19:54 -0800771 def net( self ):
772 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700773 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800774 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800775 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800776 main.log.error( self.name + ": EOF exception found" )
777 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700778 main.cleanup()
779 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700780 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800781
782 def iperf( self, host1, host2 ):
783 main.log.info(
784 self.name +
785 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700786 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800787 cmd1 = 'iperf ' + host1 + " " + host2
788 self.handle.sendline( cmd1 )
789 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800790 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800791 if re.search( 'Results:', response ):
792 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800793 return main.TRUE
794 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800795 main.log.error( self.name + ": iperf test failed" )
796 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800797 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800800 main.cleanup()
801 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800802
Jon Hall7eb38402015-01-08 17:19:54 -0800803 def iperfudp( self ):
804 main.log.info(
805 self.name +
806 ": Simple iperf TCP test between two " +
807 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700808 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800809 response = self.execute(
810 cmd='iperfudp',
811 prompt='mininet>',
812 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800813 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 main.log.error( self.name + ": EOF exception found" )
815 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700816 main.cleanup()
817 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700818 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800819
Jon Hall7eb38402015-01-08 17:19:54 -0800820 def nodes( self ):
821 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700822 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800823 response = self.execute(
824 cmd='nodes',
825 prompt='mininet>',
826 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800827 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800828 main.log.error( self.name + ": EOF exception found" )
829 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700830 main.cleanup()
831 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700832 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800833
Jon Hall7eb38402015-01-08 17:19:54 -0800834 def pingpair( self ):
835 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700836 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800837 response = self.execute(
838 cmd='pingpair',
839 prompt='mininet>',
840 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800841 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800842 main.log.error( self.name + ": EOF exception found" )
843 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700844 main.cleanup()
845 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800846
Jon Hall7eb38402015-01-08 17:19:54 -0800847 if re.search( ',\s0\%\spacket\sloss', response ):
848 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700850 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800851 else:
852 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700854 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800855
Jon Hall7eb38402015-01-08 17:19:54 -0800856 def link( self, **linkargs ):
857 """
858 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800859 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800860 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
861 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
862 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
863 main.log.info(
864 "Bring link between '" +
865 end1 +
866 "' and '" +
867 end2 +
868 "' '" +
869 option +
870 "'" )
871 command = "link " + \
872 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700873 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800874 self.handle.sendline( command )
875 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800876 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800877 main.log.error( self.name + ": EOF exception found" )
878 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700879 main.cleanup()
880 main.exit()
adminbae64d82013-08-01 10:50:15 -0700881 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800882
Jon Hall7eb38402015-01-08 17:19:54 -0800883 def yank( self, **yankargs ):
884 """
885 yank a mininet switch interface to a host"""
886 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800887 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800888 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
889 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
890 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700891 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800892 response = self.execute(
893 cmd=command,
894 prompt="mininet>",
895 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800896 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700899 main.cleanup()
900 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700901 return main.TRUE
902
Jon Hall7eb38402015-01-08 17:19:54 -0800903 def plug( self, **plugargs ):
904 """
905 plug the yanked mininet switch interface to a switch"""
906 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800907 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800908 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
909 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
910 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700911 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800912 response = self.execute(
913 cmd=command,
914 prompt="mininet>",
915 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800916 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800917 main.log.error( self.name + ": EOF exception found" )
918 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700919 main.cleanup()
920 main.exit()
adminbae64d82013-08-01 10:50:15 -0700921 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800922
Jon Hall7eb38402015-01-08 17:19:54 -0800923 def dpctl( self, **dpctlargs ):
924 """
925 Run dpctl command on all switches."""
926 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800927 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800928 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
929 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
930 command = "dpctl " + cmd + " " + str( cmdargs )
931 try:
932 response = self.execute(
933 cmd=command,
934 prompt="mininet>",
935 timeout=10 )
936 except pexpect.EOF:
937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
939 main.cleanup()
940 main.exit()
941 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800942
kelvin-onlabd3b64892015-01-20 13:26:24 -0800943 def getVersion( self ):
944 fileInput = path + '/lib/Mininet/INSTALL'
945 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700946 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800948 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700949 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800950 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500951 return version
adminbae64d82013-08-01 10:50:15 -0700952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800954 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500955 Parameters:
956 sw: The name of an OVS switch. Example "s1"
957 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800958 The output of the command from the mininet cli
959 or main.FALSE on timeout"""
960 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700961 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800962 response = self.execute(
963 cmd=command,
964 prompt="mininet>",
965 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700966 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500967 return response
admin2a9548d2014-06-17 14:08:07 -0700968 else:
969 return main.FALSE
970 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800971 main.log.error( self.name + ": EOF exception found" )
972 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700973 main.cleanup()
974 main.exit()
adminbae64d82013-08-01 10:50:15 -0700975
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800977 """
978 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800979 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800980 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700981
982 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800983 for j in range( count ):
984 argstring = argstring + ",IP" + \
985 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800986 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700987
Jon Hall7eb38402015-01-08 17:19:54 -0800988 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
989 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800990 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800991 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800992
Jon Hall7eb38402015-01-08 17:19:54 -0800993 command = "sh ovs-vsctl set-controller s" + \
994 str( sw ) + " " + ptcpB + " "
995 for j in range( count ):
996 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800997 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -0800998 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
999 ip = args[
1000 "IP" +
1001 str( i ) ] if args[
1002 "IP" +
1003 str( i ) ] is not None else ""
1004 port = args[
1005 "PORT" +
1006 str( i ) ] if args[
1007 "PORT" +
1008 str( i ) ] is not None else ""
1009 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001010 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001011 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001012 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001013 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001014 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001015 main.log.error( self.name + ": EOF exception found" )
1016 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001017 main.cleanup()
1018 main.exit()
1019 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001020 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001021 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001022 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001023 main.cleanup()
1024 main.exit()
adminbae64d82013-08-01 10:50:15 -07001025
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001027 """
1028 Removes the controller target from sw"""
1029 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001030 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001031 response = self.execute(
1032 cmd=command,
1033 prompt="mininet>",
1034 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001035 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001036 main.log.error( self.name + ": EOF exception found" )
1037 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001038 main.cleanup()
1039 main.exit()
1040 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001041 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001042
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001044 """
Jon Hallb1290e82014-11-18 16:17:48 -05001045 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001046 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001047 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001048 NOTE: cannot currently specify what type of switch
1049 required params:
1050 switchname = name of the new switch as a string
1051 optional keyvalues:
1052 dpid = "dpid"
1053 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001054 """
1055 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001056 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001057 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001058 response = self.execute(
1059 cmd=command,
1060 prompt="mininet>",
1061 timeout=10 )
1062 if re.search( "already exists!", response ):
1063 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001064 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001065 elif re.search( "Error", response ):
1066 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001067 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001068 elif re.search( "usage:", response ):
1069 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001070 return main.FALSE
1071 else:
1072 return main.TRUE
1073 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001074 main.log.error( self.name + ": EOF exception found" )
1075 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001076 main.cleanup()
1077 main.exit()
1078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001080 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001081 delete a switch from the mininet topology
1082 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001083 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001084 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001085 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001086 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001087 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001088 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001089 response = self.execute(
1090 cmd=command,
1091 prompt="mininet>",
1092 timeout=10 )
1093 if re.search( "no switch named", response ):
1094 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001095 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001096 elif re.search( "Error", response ):
1097 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001098 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001099 elif re.search( "usage:", response ):
1100 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001101 return main.FALSE
1102 else:
1103 return main.TRUE
1104 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001105 main.log.error( self.name + ": EOF exception found" )
1106 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001107 main.cleanup()
1108 main.exit()
1109
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001111 """
1112 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001113 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001114 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001115 NOTE: cannot currently specify what type of link
1116 required params:
1117 node1 = the string node name of the first endpoint of the link
1118 node2 = the string node name of the second endpoint of the link
1119 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001120 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001121 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001122 response = self.execute(
1123 cmd=command,
1124 prompt="mininet>",
1125 timeout=10 )
1126 if re.search( "doesnt exist!", response ):
1127 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001128 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001129 elif re.search( "Error", response ):
1130 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001131 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001132 elif re.search( "usage:", response ):
1133 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001134 return main.FALSE
1135 else:
1136 return main.TRUE
1137 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001138 main.log.error( self.name + ": EOF exception found" )
1139 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001140 main.cleanup()
1141 main.exit()
1142
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001144 """
1145 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001146 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001147 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001148 required params:
1149 node1 = the string node name of the first endpoint of the link
1150 node2 = the string node name of the second endpoint of the link
1151 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001152 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001153 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001154 response = self.execute(
1155 cmd=command,
1156 prompt="mininet>",
1157 timeout=10 )
1158 if re.search( "no node named", response ):
1159 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001160 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001161 elif re.search( "Error", response ):
1162 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001163 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001164 elif re.search( "usage:", response ):
1165 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001166 return main.FALSE
1167 else:
1168 return main.TRUE
1169 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001170 main.log.error( self.name + ": EOF exception found" )
1171 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001172 main.cleanup()
1173 main.exit()
1174
kelvin-onlabd3b64892015-01-20 13:26:24 -08001175 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001176 """
Jon Hallb1290e82014-11-18 16:17:48 -05001177 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001178 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001179 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001180 NOTE: cannot currently specify what type of host
1181 required params:
1182 hostname = the string hostname
1183 optional key-value params
1184 switch = "switch name"
1185 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001186 """
1187 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001188 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001189 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001190 response = self.execute(
1191 cmd=command,
1192 prompt="mininet>",
1193 timeout=10 )
1194 if re.search( "already exists!", response ):
1195 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001196 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001197 elif re.search( "doesnt exists!", response ):
1198 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001199 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001200 elif re.search( "Error", 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( "usage:", response ):
1204 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001205 return main.FALSE
1206 else:
1207 return main.TRUE
1208 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001209 main.log.error( self.name + ": EOF exception found" )
1210 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001211 main.cleanup()
1212 main.exit()
1213
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001215 """
1216 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001217 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001218 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001219 NOTE: this uses a custom mn function
1220 required params:
1221 hostname = the string hostname
1222 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001223 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001224 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001225 response = self.execute(
1226 cmd=command,
1227 prompt="mininet>",
1228 timeout=10 )
1229 if re.search( "no host named", response ):
1230 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001231 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001232 elif re.search( "Error", response ):
1233 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001234 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001235 elif re.search( "usage:", response ):
1236 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001237 return main.FALSE
1238 else:
1239 return main.TRUE
1240 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 main.log.error( self.name + ": EOF exception found" )
1242 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001243 main.cleanup()
1244 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001245
Jon Hall7eb38402015-01-08 17:19:54 -08001246 def disconnect( self ):
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001247 """
kelvin-onlab84135842015-02-06 11:03:28 -08001248<<<<<<< HEAD
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001249 Called at the end of the test to disconnect the handle.
kelvin-onlab84135842015-02-06 11:03:28 -08001250=======
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001251 Called at the end of the test to stop the mininet and
1252 disconnect the handle.
kelvin-onlab84135842015-02-06 11:03:28 -08001253>>>>>>> 42efbd8869b8e52ac17c3f0966cdf12979e41e0f
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001254 """
1255 self.handle.sendline('')
1256 i = 1
1257 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1258 if i == 0:
1259 self.stopNet()
1260 response = ''
1261 # print "Disconnecting Mininet"
1262 if self.handle:
1263 self.handle.sendline( "exit" )
1264 self.handle.expect( "exit" )
1265 self.handle.expect( "(.*)" )
1266 main.log.info( "Mininet CLI is successfully disconnected" )
kelvin-onlab84135842015-02-06 11:03:28 -08001267<<<<<<< HEAD
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001268 response = self.handle.before
kelvin-onlab84135842015-02-06 11:03:28 -08001269=======
shahshreya26c3cea2015-02-05 10:17:41 -08001270 response = main.TRUE
kelvin-onlab84135842015-02-06 11:03:28 -08001271>>>>>>> 42efbd8869b8e52ac17c3f0966cdf12979e41e0f
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001272 else:
1273 main.log.error( "Connection failed to the host" )
1274 response = main.FALSE
1275
1276 return response
1277
1278 def stopNet( self ):
kelvin-onlab84135842015-02-06 11:03:28 -08001279<<<<<<< HEAD
1280=======
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001281 """
1282 Stops mininet. returns true if the mininet succesfully stops.
1283 """
1284
kelvin-onlab84135842015-02-06 11:03:28 -08001285>>>>>>> 42efbd8869b8e52ac17c3f0966cdf12979e41e0f
Jon Hall7eb38402015-01-08 17:19:54 -08001286 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001287 response = ''
1288 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001289 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001290 response = self.execute(
1291 cmd="exit",
1292 prompt="(.*)",
1293 timeout=120 )
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001294 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001295 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001296 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001297 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001298 main.log.error( self.name + ": EOF exception found" )
1299 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001300 main.cleanup()
1301 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001302 else:
1303 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001304 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001305 return response
1306
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001307
1308
Jon Hall7eb38402015-01-08 17:19:54 -08001309 def arping( self, src, dest, destmac ):
1310 self.handle.sendline( '' )
1311 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001312
Jon Hall7eb38402015-01-08 17:19:54 -08001313 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001314 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001315 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1316 main.log.info( self.name + ": ARP successful" )
1317 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001318 return main.TRUE
1319 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001320 main.log.warn( self.name + ": ARP FAILURE" )
1321 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001322 return main.FALSE
1323
Jon Hall7eb38402015-01-08 17:19:54 -08001324 def decToHex( self, num ):
1325 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001326
Jon Hall7eb38402015-01-08 17:19:54 -08001327 def getSwitchFlowCount( self, switch ):
1328 """
1329 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001330 if self.handle:
1331 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1332 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001333 response = self.execute(
1334 cmd=cmd,
1335 prompt="mininet>",
1336 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001337 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001338 main.log.error( self.name + ": EOF exception found" )
1339 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001340 main.cleanup()
1341 main.exit()
1342 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001343 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001344 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001345 main.log.info(
1346 "Couldn't find flows on switch %s, found: %s" %
1347 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001348 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001349 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001350 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001351 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001352
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 def checkFlows( self, sw, dumpFormat=None ):
1354 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001355 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001357 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001358 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001359 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001360 response = self.execute(
1361 cmd=command,
1362 prompt="mininet>",
1363 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001364 return response
1365 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.error( self.name + ": EOF exception found" )
1367 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001368 main.cleanup()
1369 main.exit()
1370 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001372
kelvin-onlabd3b64892015-01-20 13:26:24 -08001373 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001374 """
1375 Runs tpdump on an intferface and saves the file
1376 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001377 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001378 self.handle.sendline( "" )
1379 self.handle.expect( "mininet>" )
1380 self.handle.sendline(
1381 "sh sudo tcpdump -n -i " +
1382 intf +
1383 " " +
1384 port +
1385 " -w " +
1386 filename.strip() +
1387 " &" )
1388 self.handle.sendline( "" )
1389 i = self.handle.expect( [ 'No\ssuch\device',
1390 'listening\son',
1391 pexpect.TIMEOUT,
1392 "mininet>" ],
1393 timeout=10 )
1394 main.log.warn( self.handle.before + self.handle.after )
1395 self.handle.sendline( "" )
1396 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001397 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001398 main.log.error(
1399 self.name +
1400 ": tcpdump - No such device exists. " +
1401 "tcpdump attempted on: " +
1402 intf )
admin2a9548d2014-06-17 14:08:07 -07001403 return main.FALSE
1404 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001405 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001406 return main.TRUE
1407 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001408 main.log.error(
1409 self.name +
1410 ": tcpdump command timed out! Check interface name," +
1411 " given interface was: " +
1412 intf )
admin2a9548d2014-06-17 14:08:07 -07001413 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001414 elif i == 3:
1415 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001416 return main.TRUE
1417 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001418 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001419 return main.FALSE
1420 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 main.log.error( self.name + ": EOF exception found" )
1422 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001423 main.cleanup()
1424 main.exit()
1425 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001427 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001428 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001429 main.cleanup()
1430 main.exit()
1431
kelvin-onlabd3b64892015-01-20 13:26:24 -08001432 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001433 "pkills tcpdump"
1434 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001435 self.handle.sendline( "sh sudo pkill tcpdump" )
1436 self.handle.expect( "mininet>" )
1437 self.handle.sendline( "" )
1438 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001439 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001440 main.log.error( self.name + ": EOF exception found" )
1441 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001442 main.cleanup()
1443 main.exit()
1444 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001445 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001446 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001447 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001448 main.cleanup()
1449 main.exit()
1450
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001452 """
1453 Compare mn and onos switches
1454 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001456
Jon Hall7eb38402015-01-08 17:19:54 -08001457 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001459 output = { "switches": [] }
1460 # iterate through the MN topology and pull out switches and and port
1461 # info
1462 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001463 ports = []
1464 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001465 ports.append( { 'of_port': port.port_no,
1466 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001467 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001468 'name': port.name } )
1469 output[ 'switches' ].append( {
1470 "name": switch.name,
1471 "dpid": str( switch.dpid ).zfill( 16 ),
1472 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001473
Jon Hall7eb38402015-01-08 17:19:54 -08001474 # print "mn"
1475 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001476 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001477 # indent=4,
1478 # separators=( ',', ': ' ) )
1479 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 # print json.dumps( switchesJson,
1481 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001482 # indent=4,
1483 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001484
1485 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001486 mnDPIDs = []
1487 for switch in output[ 'switches' ]:
1488 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001489 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001490 # print "List of Mininet switch DPID's"
1491 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001493 main.log.error(
1494 self.name +
1495 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001496 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001498 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001499 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001500 if switch[ 'available' ]:
1501 onosDPIDs.append(
1502 switch[ 'id' ].replace(
1503 ":",
1504 '' ).replace(
1505 "of",
1506 '' ).lower() )
1507 # else:
1508 # print "Switch is unavailable:"
1509 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001510 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001511 # print "List of ONOS switch DPID's"
1512 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001513
Jon Hall7eb38402015-01-08 17:19:54 -08001514 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001516 main.log.report( "Switches in MN but not in ONOS:" )
1517 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1518 main.log.report( str( list1 ) )
1519 main.log.report( "Switches in ONOS but not in MN:" )
1520 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001521 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001522 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 switchResults = main.TRUE
1524 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001525
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001527 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001528 Compare mn and onos ports
1529 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001531
Jon Hallfbc828e2015-01-06 17:30:19 -08001532 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001533 1. This uses the sts TestONTopology object
1534 2. numpy - "sudo pip install numpy"
1535
Jon Hall7eb38402015-01-08 17:19:54 -08001536 """
1537 # FIXME: this does not look for extra ports in ONOS, only checks that
1538 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001539 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001541 output = { "switches": [] }
1542 # iterate through the MN topology and pull out switches and and port
1543 # info
1544 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001545 ports = []
1546 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001547 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001549 tmpPort[ 'of_port' ] = port.port_no
1550 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 tmpPort[ 'name' ] = port.name
1552 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001553
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 ports.append( tmpPort )
1555 tmpSwitch = {}
1556 tmpSwitch[ 'name' ] = switch.name
1557 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1558 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001559
kelvin-onlabd3b64892015-01-20 13:26:24 -08001560 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001561
Jon Hall7eb38402015-01-08 17:19:54 -08001562 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 for mnSwitch in output[ 'switches' ]:
1564 mnPorts = []
1565 onosPorts = []
1566 switchResult = main.TRUE
1567 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001568 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 mnPorts.append( port[ 'of_port' ] )
1570 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001571 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 # print onosSwitch
1573 if onosSwitch[ 'device' ][ 'available' ]:
1574 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001575 ':',
1576 '' ).replace(
1577 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001578 '' ) == mnSwitch[ 'dpid' ]:
1579 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001580 if port[ 'isEnabled' ]:
1581 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 # onosPorts.append( 'local' )
1583 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001584 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001586 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 mnPorts.sort( key=float )
1588 onosPorts.sort( key=float )
1589 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1590 # print "\tmn_ports[] = ", mnPorts
1591 # print "\tonos_ports[] = ", onosPorts
1592 mnPortsLog = mnPorts
1593 onosPortsLog = onosPorts
1594 mnPorts = [ x for x in mnPorts ]
1595 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001596
Jon Hall7eb38402015-01-08 17:19:54 -08001597 # TODO: handle other reserved port numbers besides LOCAL
1598 # NOTE: Reserved ports
1599 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1600 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 for mnPort in mnPortsLog:
1602 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001603 # don't set results to true here as this is just one of
1604 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 mnPorts.remove( mnPort )
1606 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001607 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001608 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001609 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 if 65534 in mnPorts:
1611 mnPorts.remove( 65534 )
1612 if long( uint64( -2 ) ) in onosPorts:
1613 onosPorts.remove( long( uint64( -2 ) ) )
1614 if len( mnPorts ): # the ports of this switch don't match
1615 switchResult = main.FALSE
1616 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1617 if len( onosPorts ): # the ports of this switch don't match
1618 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001619 main.log.warn(
1620 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 str( onosPorts ) )
1622 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001623 main.log.report(
1624 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1626 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1627 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1628 portsResults = portsResults and switchResult
1629 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001630
kelvin-onlabd3b64892015-01-20 13:26:24 -08001631 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001632 """
1633 Compare mn and onos links
1634 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001636
Jon Hall7eb38402015-01-08 17:19:54 -08001637 This uses the sts TestONTopology object"""
1638 # FIXME: this does not look for extra links in ONOS, only checks that
1639 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001641 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001643 # iterate through the MN topology and pull out switches and and port
1644 # info
1645 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001646 # print "Iterating though switches as seen by Mininet"
1647 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001648 ports = []
1649 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001650 # print port.hw_addr.toStr( separator='' )
1651 ports.append( { 'of_port': port.port_no,
1652 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001654 'name': port.name } )
1655 output[ 'switches' ].append( {
1656 "name": switch.name,
1657 "dpid": str( switch.dpid ).zfill( 16 ),
1658 "ports": ports } )
1659 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001660
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001662 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001663 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 if 2 * len( mnLinks ) == len( onos ):
1665 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001666 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001667 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001668 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001669 "Mininet has " + str( len( mnLinks ) ) +
1670 " bidirectional links and ONOS has " +
1671 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001672
Jon Hall7eb38402015-01-08 17:19:54 -08001673 # iterate through MN links and check if an ONOS link exists in
1674 # both directions
1675 # NOTE: Will currently only show mn links as down if they are
1676 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001678 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001680 # print "Link: %s" % link
1681 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001682 node1 = None
1683 port1 = None
1684 node2 = None
1685 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001686 firstDir = main.FALSE
1687 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001688 for switch in output[ 'switches' ]:
1689 # print "Switch: %s" % switch[ 'name' ]
1690 if switch[ 'name' ] == link.node1.name:
1691 node1 = switch[ 'dpid' ]
1692 for port in switch[ 'ports' ]:
1693 if str( port[ 'name' ] ) == str( link.port1 ):
1694 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001695 if node1 is not None and node2 is not None:
1696 break
Jon Hall7eb38402015-01-08 17:19:54 -08001697 if switch[ 'name' ] == link.node2.name:
1698 node2 = switch[ 'dpid' ]
1699 for port in switch[ 'ports' ]:
1700 if str( port[ 'name' ] ) == str( link.port2 ):
1701 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001702 if node1 is not None and node2 is not None:
1703 break
1704
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 for onosLink in onos:
1706 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001707 ":",
1708 '' ).replace(
1709 "of",
1710 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001712 ":",
1713 '' ).replace(
1714 "of",
1715 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 onosPort1 = onosLink[ 'src' ][ 'port' ]
1717 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001718
Jon Hall72cf1dc2014-10-20 21:04:50 -04001719 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001720 if str( onosNode1 ) == str( node1 ) and str(
1721 onosNode2 ) == str( node2 ):
1722 if int( onosPort1 ) == int( port1 ) and int(
1723 onosPort2 ) == int( port2 ):
1724 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001725 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001726 main.log.warn(
1727 'The port numbers do not match for ' +
1728 str( link ) +
1729 ' between ONOS and MN. When cheking ONOS for ' +
1730 'link %s/%s -> %s/%s' %
1731 ( node1,
1732 port1,
1733 node2,
1734 port2 ) +
1735 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001736 ( onosNode1,
1737 onosPort1,
1738 onosNode2,
1739 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001740
1741 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 elif ( str( onosNode1 ) == str( node2 ) and
1743 str( onosNode2 ) == str( node1 ) ):
1744 if ( int( onosPort1 ) == int( port2 )
1745 and int( onosPort2 ) == int( port1 ) ):
1746 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001747 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001748 main.log.warn(
1749 'The port numbers do not match for ' +
1750 str( link ) +
1751 ' between ONOS and MN. When cheking ONOS for ' +
1752 'link %s/%s -> %s/%s' %
1753 ( node2,
1754 port2,
1755 node1,
1756 port1 ) +
1757 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 ( onosNode2,
1759 onosPort2,
1760 onosNode1,
1761 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001762 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001763 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001765 main.log.report(
1766 'ONOS does not have the link %s/%s -> %s/%s' %
1767 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001769 main.log.report(
1770 'ONOS does not have the link %s/%s -> %s/%s' %
1771 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 linkResults = linkResults and firstDir and secondDir
1773 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001774
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001776 """
1777 Returns a list of all hosts
1778 Don't ask questions just use it"""
1779 self.handle.sendline( "" )
1780 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001781
Jon Hall7eb38402015-01-08 17:19:54 -08001782 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1783 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001784
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 handlePy = self.handle.before
1786 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1787 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001788
Jon Hall7eb38402015-01-08 17:19:54 -08001789 self.handle.sendline( "" )
1790 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001791
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 hostStr = handlePy.replace( "]", "" )
1793 hostStr = hostStr.replace( "'", "" )
1794 hostStr = hostStr.replace( "[", "" )
1795 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001796
kelvin-onlabd3b64892015-01-20 13:26:24 -08001797 return hostList
adminbae64d82013-08-01 10:50:15 -07001798
Jon Hall7eb38402015-01-08 17:19:54 -08001799 def update( self ):
1800 """
1801 updates the port address and status information for
1802 each port in mn"""
1803 # TODO: Add error checking. currently the mininet command has no output
1804 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001805 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001806 self.handle.sendline( "" )
1807 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001808
Jon Hall7eb38402015-01-08 17:19:54 -08001809 self.handle.sendline( "update" )
1810 self.handle.expect( "update" )
1811 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001812
Jon Hall7eb38402015-01-08 17:19:54 -08001813 self.handle.sendline( "" )
1814 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001815
Jon Hallb1290e82014-11-18 16:17:48 -05001816 return main.TRUE
1817 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001818 main.log.error( self.name + ": EOF exception found" )
1819 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001820 main.cleanup()
1821 main.exit()
1822
adminbae64d82013-08-01 10:50:15 -07001823if __name__ != "__main__":
1824 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001825 sys.modules[ __name__ ] = MininetCliDriver()