blob: fb1913716b7624d9dfc83817af80f37e40156b0a [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
Jon Hallfbc828e2015-01-06 17:30:19 -0800100
kelvin-onlaba1484582015-02-02 15:46:20 -0800101 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 """
kelvin-onlaba0ce3222015-01-27 17:25:15 -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-onlab97d64e72015-01-28 11:14:55 -0800116 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -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 '\$',
Jon Hall7eb38402015-01-08 17:19:54 -0800122 pexpect.EOF,
123 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800124 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -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-onlab97d64e72015-01-28 11:14:55 -0800133 if topoFile == '' and args == '':
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800134 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' ]
141
142 argList = self.options[ 'arg1' ].split( "," )
143 global topoArgList
144 topoArgList = argList[ 0 ].split( " " )
145 argList = map( int, argList[ 1: ] )
146 topoArgList = topoArgList[ 1: ] + argList
147
148 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 ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800158 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800159 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:
kelvin-onlab97d64e72015-01-28 11:14:55 -0800181 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)
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800187 i = 1
188 i = self.handle.expect( [ 'mininet>',
189 pexpect.EOF ,
kelvin-onlab97d64e72015-01-28 11:14:55 -0800190 pexpect.TIMEOUT ],
191 timeout)
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800192 if i == 0:
193 main.log.info(self.name + ": Network started")
194 return main.TRUE
195 if i == 1:
196 self.handle.expect(
197 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
198 main.log.info( self.handle.before )
199 elif i == 2:
200 main.log.error(
201 self.name +
202 ": Launching mininet failed..." )
203 return main.FALSE
204 elif i == 3:
205 main.log.error( self.name + ": Connection timeout" )
206 return main.FALSE
207 elif i == 4: # timeout
208 main.log.error(
209 self.name +
210 ": Something took too long... " )
211 return main.FALSE
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800212 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800213 else: # if no handle
214 main.log.error(
215 self.name +
216 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800217 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800218 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800219 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800220 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700221 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800222
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800223 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400224 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800225 # In tree topology, if fanout arg is not given, by default it is 2
226 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400227 fanout = 2
228 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500229 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800230 while( k <= depth - 1 ):
231 count = count + pow( fanout, k )
232 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800234 while( k <= depth - 2 ):
235 # depth-2 gives you only core links and not considering
236 # edge links as seen by ONOS. If all the links including
237 # edge links are required, do depth-1
238 count = count + pow( fanout, k )
239 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800241 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800243
Jon Hall7eb38402015-01-08 17:19:54 -0800244 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800246 # by default it is 1
247 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400248 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 numSwitches = depth
250 numHostsPerSw = fanout
251 totalNumHosts = numSwitches * numHostsPerSw
252 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800253 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400255 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800256 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 "num_switches": int( numSwitches ),
258 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400259 return topoDict
260
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 def calculateSwAndLinks( self ):
262 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400263 return topoDict
264
Jon Hall7eb38402015-01-08 17:19:54 -0800265 def pingall( self, timeout=300 ):
266 """
267 Verifies the reachability of the hosts using pingall command.
268 Optional parameter timeout allows you to specify how long to
269 wait for pingall to complete
270 Returns:
271 main.TRUE if pingall completes with no pings dropped
272 otherwise main.FALSE"""
273 if self.handle:
274 main.log.info(
275 self.name +
276 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700277 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800278 response = self.execute(
279 cmd="pingall",
280 prompt="mininet>",
281 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500282 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800283 main.log.error( self.name + ": EOF exception found" )
284 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500285 main.cleanup()
286 main.exit()
287 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800288 # We may not want to kill the test if pexpect times out
289 main.log.error( self.name + ": TIMEOUT exception found" )
290 main.log.error( self.name +
291 ": " +
292 str( self.handle.before ) )
293 # NOTE: mininet's pingall rounds, so we will check the number of
294 # passed and number of failed
295 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800296 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800297 if re.search( pattern, response ):
298 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700299 return main.TRUE
300 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800301 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800303 # NOTE: Send ctrl-c to make sure pingall is done
304 self.handle.send( "\x03" )
305 self.handle.expect( "Interrupt" )
306 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700307 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800308 else:
309 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500310 main.cleanup()
311 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700312
Jon Hall7eb38402015-01-08 17:19:54 -0800313 def fpingHost( self, **pingParams ):
314 """
315 Uses the fping package for faster pinging...
316 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800317 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800318 command = args[ "SRC" ] + \
319 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
320 self.handle.sendline( command )
321 self.handle.expect(
322 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
323 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
324 response = self.handle.before
325 if re.search( ":\s-", response ):
326 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700327 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800328 elif re.search( ":\s\d{1,2}\.\d\d", response ):
329 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700330 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800331 main.log.info( self.name + ": Install fping on mininet machine... " )
332 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700333 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800334
Jon Hall7eb38402015-01-08 17:19:54 -0800335 def pingHost( self, **pingParams ):
336 """
337 Ping from one mininet host to another
338 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800339 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800340 command = args[ "SRC" ] + " ping " + \
341 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700342 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800343 main.log.warn( "Sending: " + command )
344 self.handle.sendline( command )
345 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700346 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800347 main.log.error(
348 self.name +
349 ": timeout when waiting for response from mininet" )
350 main.log.error( "response: " + str( self.handle.before ) )
351 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700352 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800353 main.log.error(
354 self.name +
355 ": timeout when waiting for response from mininet" )
356 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700357 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800358 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800359 main.log.error( self.name + ": EOF exception found" )
360 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700361 main.cleanup()
362 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800363 main.log.info( self.name + ": Ping Response: " + response )
364 if re.search( ',\s0\%\spacket\sloss', response ):
365 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700367 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800368 else:
369 main.log.error(
370 self.name +
371 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800372 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700373 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800374
Jon Hall7eb38402015-01-08 17:19:54 -0800375 def checkIP( self, host ):
376 """
377 Verifies the host's ip configured or not."""
378 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700379 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800380 response = self.execute(
381 cmd=host +
382 " ifconfig",
383 prompt="mininet>",
384 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800385 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800386 main.log.error( self.name + ": EOF exception found" )
387 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700388 main.cleanup()
389 main.exit()
adminbae64d82013-08-01 10:50:15 -0700390
Jon Hall7eb38402015-01-08 17:19:54 -0800391 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800392 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
393 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
394 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
395 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
396 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800397 # pattern = "inet addr:10.0.0.6"
398 if re.search( pattern, response ):
399 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700400 return main.TRUE
401 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800402 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700403 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800404 else:
405 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800406
Jon Hall7eb38402015-01-08 17:19:54 -0800407 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700408 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800409 response = self.execute(
410 cmd="h1 /usr/sbin/sshd -D&",
411 prompt="mininet>",
412 timeout=10 )
413 response = self.execute(
414 cmd="h4 /usr/sbin/sshd -D&",
415 prompt="mininet>",
416 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700417 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800418 vars( self )[ key ] = connectargs[ key ]
419 response = self.execute(
420 cmd="xterm h1 h4 ",
421 prompt="mininet>",
422 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800423 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800424 main.log.error( self.name + ": EOF exception found" )
425 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700426 main.cleanup()
427 main.exit()
adminbae64d82013-08-01 10:50:15 -0700428 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800429 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700430 if self.flag == 0:
431 self.flag = 1
432 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800433 else:
adminbae64d82013-08-01 10:50:15 -0700434 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800435
shahshreya5ff90d12015-01-30 11:41:51 -0800436 def moveHost( self, host, oldSw, newSw, ):
437 """
438 Moves a host from one switch to another on the fly
439 Note: The intf between host and oldSw when detached
440 using detach(), will still show up in the 'net'
441 cmd, because switch.detach() doesn't affect switch.intfs[]
442 (which is correct behavior since the interfaces
443 haven't moved).
444 """
445 if self.handle:
446 try:
447 # Bring link between oldSw-host down
448 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
449 "'down')"
450 print "cmd1= ", cmd
451 response = self.execute(
452 cmd=cmd,
453 prompt="mininet>",
454 timeout=10 )
455
456 # Determine hostintf and Oldswitchintf
457 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
458 ")[0]"
459 print "cmd2= ", cmd
460 self.handle.sendline( cmd )
461 self.handle.expect( "mininet>" )
462
463 # Determine ipaddress of the host-oldSw interface
464 cmd = "px ipaddr = hintf.IP()"
465 print "cmd3= ", cmd
466 self.handle.sendline( cmd )
467 self.handle.expect( "mininet>" )
468
469 # Detach interface between oldSw-host
470 cmd = "px " + oldSw + ".detach( sintf )"
471 print "cmd4= ", cmd
472 self.handle.sendline( cmd )
473 self.handle.expect( "mininet>" )
474
475 # Add link between host-newSw
476 cmd = "py net.addLink(" + host + "," + newSw + ")"
477 print "cmd5= ", cmd
478 self.handle.sendline( cmd )
479 self.handle.expect( "mininet>" )
480
481 # Determine hostintf and Newswitchintf
482 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
483 ")[0]"
484 print "cmd6= ", cmd
485 self.handle.sendline( cmd )
486 self.handle.expect( "mininet>" )
487
488 # Attach interface between newSw-host
489 cmd = "px " + newSw + ".attach( sintf )"
490 print "cmd3= ", cmd
491 self.handle.sendline( cmd )
492 self.handle.expect( "mininet>" )
493
494 # Set ipaddress of the host-newSw interface
495 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
496 print "cmd7 = ", cmd
497 self.handle.sendline( cmd )
498 self.handle.expect( "mininet>" )
499
500 cmd = "net"
501 print "cmd8 = ", cmd
502 self.handle.sendline( cmd )
503 self.handle.expect( "mininet>" )
504 print "output = ", self.handle.before
505
506 # Determine ipaddress of the host-newSw interface
507 cmd = "h1 ifconfig"
508 print "cmd9= ", cmd
509 self.handle.sendline( cmd )
510 self.handle.expect( "mininet>" )
511 print "ifconfig o/p = ", self.handle.before
512
513 return main.TRUE
514 except pexpect.EOF:
515 main.log.error( self.name + ": EOF exception found" )
516 main.log.error( self.name + ": " + self.handle.before )
517 return main.FALSE
518
Jon Hall7eb38402015-01-08 17:19:54 -0800519 def changeIP( self, host, intf, newIP, newNetmask ):
520 """
521 Changes the ip address of a host on the fly
522 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800523 if self.handle:
524 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800525 cmd = host + " ifconfig " + intf + " " + \
526 newIP + " " + 'netmask' + " " + newNetmask
527 self.handle.sendline( cmd )
528 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800529 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800530 main.log.info( "response = " + response )
531 main.log.info(
532 "Ip of host " +
533 host +
534 " changed to new IP " +
535 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800536 return main.TRUE
537 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800538 main.log.error( self.name + ": EOF exception found" )
539 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800540 return main.FALSE
541
Jon Hall7eb38402015-01-08 17:19:54 -0800542 def changeDefaultGateway( self, host, newGW ):
543 """
544 Changes the default gateway of a host
545 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800546 if self.handle:
547 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800548 cmd = host + " route add default gw " + newGW
549 self.handle.sendline( cmd )
550 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800551 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800552 main.log.info( "response = " + response )
553 main.log.info(
554 "Default gateway of host " +
555 host +
556 " changed to " +
557 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800558 return main.TRUE
559 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800562 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800563
Jon Hall7eb38402015-01-08 17:19:54 -0800564 def addStaticMACAddress( self, host, GW, macaddr ):
565 """
566 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800567 if self.handle:
568 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800569 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
570 cmd = host + " arp -s " + GW + " " + macaddr
571 self.handle.sendline( cmd )
572 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800573 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800574 main.log.info( "response = " + response )
575 main.log.info(
576 "Mac adrress of gateway " +
577 GW +
578 " changed to " +
579 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800580 return main.TRUE
581 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800582 main.log.error( self.name + ": EOF exception found" )
583 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800584 return main.FALSE
585
Jon Hall7eb38402015-01-08 17:19:54 -0800586 def verifyStaticGWandMAC( self, host ):
587 """
588 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800589 if self.handle:
590 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800591 # h1 arp -an
592 cmd = host + " arp -an "
593 self.handle.sendline( cmd )
594 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800595 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800596 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800597 return main.TRUE
598 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800599 main.log.error( self.name + ": EOF exception found" )
600 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800601 return main.FALSE
602
Jon Hall7eb38402015-01-08 17:19:54 -0800603 def getMacAddress( self, host ):
604 """
605 Verifies the host's ip configured or not."""
606 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700607 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800608 response = self.execute(
609 cmd=host +
610 " ifconfig",
611 prompt="mininet>",
612 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800613 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800614 main.log.error( self.name + ": EOF exception found" )
615 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700616 main.cleanup()
617 main.exit()
adminbae64d82013-08-01 10:50:15 -0700618
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700619 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 macAddressSearch = re.search( pattern, response, re.I )
621 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800622 main.log.info(
623 self.name +
624 ": Mac-Address of Host " +
625 host +
626 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 macAddress )
628 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700629 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800630 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700631
Jon Hall7eb38402015-01-08 17:19:54 -0800632 def getInterfaceMACAddress( self, host, interface ):
633 """
634 Return the IP address of the interface on the given host"""
635 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700636 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800637 response = self.execute( cmd=host + " ifconfig " + interface,
638 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800639 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
642 main.cleanup()
643 main.exit()
644
645 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800646 macAddressSearch = re.search( pattern, response, re.I )
647 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800648 main.log.info( "No mac address found in %s" % response )
649 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800651 main.log.info(
652 "Mac-Address of " +
653 host +
654 ":" +
655 interface +
656 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800657 macAddress )
658 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800659 else:
660 main.log.error( "Connection failed to the host" )
661
662 def getIPAddress( self, host ):
663 """
664 Verifies the host's ip configured or not."""
665 if self.handle:
666 try:
667 response = self.execute(
668 cmd=host +
669 " ifconfig",
670 prompt="mininet>",
671 timeout=10 )
672 except pexpect.EOF:
673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700675 main.cleanup()
676 main.exit()
adminbae64d82013-08-01 10:50:15 -0700677
678 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800680 main.log.info(
681 self.name +
682 ": IP-Address of Host " +
683 host +
684 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 ipAddressSearch.group( 1 ) )
686 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800687 else:
688 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800689
Jon Hall7eb38402015-01-08 17:19:54 -0800690 def getSwitchDPID( self, switch ):
691 """
692 return the datapath ID of the switch"""
693 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700694 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700695 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800696 response = self.execute(
697 cmd=cmd,
698 prompt="mininet>",
699 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800700 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700703 main.cleanup()
704 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800705 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800706 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700707 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800708 main.log.info(
709 "Couldn't find DPID for switch %s, found: %s" %
710 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700711 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800712 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700713 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800714 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700715
Jon Hall7eb38402015-01-08 17:19:54 -0800716 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700717 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800718 self.handle.sendline( "" )
719 self.expect( "mininet>" )
720 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700721 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800722 response = self.execute(
723 cmd=cmd,
724 prompt="mininet>",
725 timeout=10 )
726 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700727 response = self.handle.before
728 return response
729 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700732 main.cleanup()
733 main.exit()
734
Jon Hall7eb38402015-01-08 17:19:54 -0800735 def getInterfaces( self, node ):
736 """
737 return information dict about interfaces connected to the node"""
738 if self.handle:
739 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800740 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700741 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700742 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800743 response = self.execute(
744 cmd=cmd,
745 prompt="mininet>",
746 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800747 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.error( self.name + ": EOF exception found" )
749 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700750 main.cleanup()
751 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700752 return response
753 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800754 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700755
Jon Hall7eb38402015-01-08 17:19:54 -0800756 def dump( self ):
757 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700758 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800759 response = self.execute(
760 cmd='dump',
761 prompt='mininet>',
762 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800763 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700766 main.cleanup()
767 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700768 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800769
Jon Hall7eb38402015-01-08 17:19:54 -0800770 def intfs( self ):
771 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700772 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800773 response = self.execute(
774 cmd='intfs',
775 prompt='mininet>',
776 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800777 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700780 main.cleanup()
781 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700782 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800783
Jon Hall7eb38402015-01-08 17:19:54 -0800784 def net( self ):
785 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700786 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800787 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800788 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700791 main.cleanup()
792 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700793 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800794
795 def iperf( self, host1, host2 ):
796 main.log.info(
797 self.name +
798 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700799 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 cmd1 = 'iperf ' + host1 + " " + host2
801 self.handle.sendline( cmd1 )
802 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800803 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800804 if re.search( 'Results:', response ):
805 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800806 return main.TRUE
807 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800808 main.log.error( self.name + ": iperf test failed" )
809 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800810 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800811 main.log.error( self.name + ": EOF exception found" )
812 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800813 main.cleanup()
814 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800815
Jon Hall7eb38402015-01-08 17:19:54 -0800816 def iperfudp( self ):
817 main.log.info(
818 self.name +
819 ": Simple iperf TCP test between two " +
820 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700821 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800822 response = self.execute(
823 cmd='iperfudp',
824 prompt='mininet>',
825 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800826 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800827 main.log.error( self.name + ": EOF exception found" )
828 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700829 main.cleanup()
830 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700831 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800832
Jon Hall7eb38402015-01-08 17:19:54 -0800833 def nodes( self ):
834 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700835 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800836 response = self.execute(
837 cmd='nodes',
838 prompt='mininet>',
839 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800840 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800841 main.log.error( self.name + ": EOF exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700843 main.cleanup()
844 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700845 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800846
Jon Hall7eb38402015-01-08 17:19:54 -0800847 def pingpair( self ):
848 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700849 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800850 response = self.execute(
851 cmd='pingpair',
852 prompt='mininet>',
853 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800854 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800855 main.log.error( self.name + ": EOF exception found" )
856 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700857 main.cleanup()
858 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800859
Jon Hall7eb38402015-01-08 17:19:54 -0800860 if re.search( ',\s0\%\spacket\sloss', response ):
861 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700863 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800864 else:
865 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800866 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700867 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800868
Jon Hall7eb38402015-01-08 17:19:54 -0800869 def link( self, **linkargs ):
870 """
871 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800872 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800873 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
874 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
875 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
876 main.log.info(
877 "Bring link between '" +
878 end1 +
879 "' and '" +
880 end2 +
881 "' '" +
882 option +
883 "'" )
884 command = "link " + \
885 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700886 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 self.handle.sendline( command )
888 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800889 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700892 main.cleanup()
893 main.exit()
adminbae64d82013-08-01 10:50:15 -0700894 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800895
Jon Hall7eb38402015-01-08 17:19:54 -0800896 def yank( self, **yankargs ):
897 """
898 yank a mininet switch interface to a host"""
899 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800900 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800901 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
902 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
903 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700904 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800905 response = self.execute(
906 cmd=command,
907 prompt="mininet>",
908 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800909 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800910 main.log.error( self.name + ": EOF exception found" )
911 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700912 main.cleanup()
913 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700914 return main.TRUE
915
Jon Hall7eb38402015-01-08 17:19:54 -0800916 def plug( self, **plugargs ):
917 """
918 plug the yanked mininet switch interface to a switch"""
919 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800920 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800921 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
922 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
923 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700924 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800925 response = self.execute(
926 cmd=command,
927 prompt="mininet>",
928 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800929 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700932 main.cleanup()
933 main.exit()
adminbae64d82013-08-01 10:50:15 -0700934 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800935
Jon Hall7eb38402015-01-08 17:19:54 -0800936 def dpctl( self, **dpctlargs ):
937 """
938 Run dpctl command on all switches."""
939 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800940 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800941 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
942 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
943 command = "dpctl " + cmd + " " + str( cmdargs )
944 try:
945 response = self.execute(
946 cmd=command,
947 prompt="mininet>",
948 timeout=10 )
949 except pexpect.EOF:
950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
952 main.cleanup()
953 main.exit()
954 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800955
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 def getVersion( self ):
957 fileInput = path + '/lib/Mininet/INSTALL'
958 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700959 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800961 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700962 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800963 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500964 return version
adminbae64d82013-08-01 10:50:15 -0700965
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800967 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500968 Parameters:
969 sw: The name of an OVS switch. Example "s1"
970 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800971 The output of the command from the mininet cli
972 or main.FALSE on timeout"""
973 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700974 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800975 response = self.execute(
976 cmd=command,
977 prompt="mininet>",
978 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700979 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500980 return response
admin2a9548d2014-06-17 14:08:07 -0700981 else:
982 return main.FALSE
983 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700986 main.cleanup()
987 main.exit()
adminbae64d82013-08-01 10:50:15 -0700988
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800990 """
991 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800992 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800993 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700994
995 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800996 for j in range( count ):
997 argstring = argstring + ",IP" + \
998 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800999 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001000
Jon Hall7eb38402015-01-08 17:19:54 -08001001 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1002 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001003 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001004 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001005
Jon Hall7eb38402015-01-08 17:19:54 -08001006 command = "sh ovs-vsctl set-controller s" + \
1007 str( sw ) + " " + ptcpB + " "
1008 for j in range( count ):
1009 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001010 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001011 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1012 ip = args[
1013 "IP" +
1014 str( i ) ] if args[
1015 "IP" +
1016 str( i ) ] is not None else ""
1017 port = args[
1018 "PORT" +
1019 str( i ) ] if args[
1020 "PORT" +
1021 str( i ) ] is not None else ""
1022 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001023 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001024 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001025 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001026 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001027 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001028 main.log.error( self.name + ": EOF exception found" )
1029 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001030 main.cleanup()
1031 main.exit()
1032 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001033 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001034 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001035 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001036 main.cleanup()
1037 main.exit()
adminbae64d82013-08-01 10:50:15 -07001038
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001040 """
1041 Removes the controller target from sw"""
1042 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001043 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001044 response = self.execute(
1045 cmd=command,
1046 prompt="mininet>",
1047 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001048 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001049 main.log.error( self.name + ": EOF exception found" )
1050 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001051 main.cleanup()
1052 main.exit()
1053 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001054 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001055
kelvin-onlabd3b64892015-01-20 13:26:24 -08001056 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001057 """
Jon Hallb1290e82014-11-18 16:17:48 -05001058 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001059 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001060 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001061 NOTE: cannot currently specify what type of switch
1062 required params:
1063 switchname = name of the new switch as a string
1064 optional keyvalues:
1065 dpid = "dpid"
1066 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001067 """
1068 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001069 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001070 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001071 response = self.execute(
1072 cmd=command,
1073 prompt="mininet>",
1074 timeout=10 )
1075 if re.search( "already exists!", response ):
1076 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001077 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001078 elif re.search( "Error", response ):
1079 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001080 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001081 elif re.search( "usage:", response ):
1082 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001083 return main.FALSE
1084 else:
1085 return main.TRUE
1086 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001087 main.log.error( self.name + ": EOF exception found" )
1088 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001089 main.cleanup()
1090 main.exit()
1091
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001093 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001094 delete a switch from the mininet topology
1095 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001096 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001097 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001098 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001099 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001100 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001101 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001102 response = self.execute(
1103 cmd=command,
1104 prompt="mininet>",
1105 timeout=10 )
1106 if re.search( "no switch named", response ):
1107 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001108 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001109 elif re.search( "Error", response ):
1110 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001111 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001112 elif re.search( "usage:", response ):
1113 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001114 return main.FALSE
1115 else:
1116 return main.TRUE
1117 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001118 main.log.error( self.name + ": EOF exception found" )
1119 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001120 main.cleanup()
1121 main.exit()
1122
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001124 """
1125 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001126 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001127 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001128 NOTE: cannot currently specify what type of link
1129 required params:
1130 node1 = the string node name of the first endpoint of the link
1131 node2 = the string node name of the second endpoint of the link
1132 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001133 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001134 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001135 response = self.execute(
1136 cmd=command,
1137 prompt="mininet>",
1138 timeout=10 )
1139 if re.search( "doesnt exist!", response ):
1140 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001141 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001142 elif re.search( "Error", response ):
1143 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001144 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001145 elif re.search( "usage:", response ):
1146 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001147 return main.FALSE
1148 else:
1149 return main.TRUE
1150 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001151 main.log.error( self.name + ": EOF exception found" )
1152 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001153 main.cleanup()
1154 main.exit()
1155
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001157 """
1158 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001159 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001160 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001161 required params:
1162 node1 = the string node name of the first endpoint of the link
1163 node2 = the string node name of the second endpoint of the link
1164 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001165 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001166 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001167 response = self.execute(
1168 cmd=command,
1169 prompt="mininet>",
1170 timeout=10 )
1171 if re.search( "no node named", response ):
1172 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001173 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001174 elif re.search( "Error", response ):
1175 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001176 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001177 elif re.search( "usage:", response ):
1178 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001179 return main.FALSE
1180 else:
1181 return main.TRUE
1182 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001183 main.log.error( self.name + ": EOF exception found" )
1184 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001185 main.cleanup()
1186 main.exit()
1187
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001189 """
Jon Hallb1290e82014-11-18 16:17:48 -05001190 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001191 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001192 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001193 NOTE: cannot currently specify what type of host
1194 required params:
1195 hostname = the string hostname
1196 optional key-value params
1197 switch = "switch name"
1198 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001199 """
1200 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001201 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001202 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001203 response = self.execute(
1204 cmd=command,
1205 prompt="mininet>",
1206 timeout=10 )
1207 if re.search( "already exists!", response ):
1208 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001209 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001210 elif re.search( "doesnt exists!", response ):
1211 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001212 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001213 elif re.search( "Error", response ):
1214 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001215 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001216 elif re.search( "usage:", response ):
1217 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001218 return main.FALSE
1219 else:
1220 return main.TRUE
1221 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001222 main.log.error( self.name + ": EOF exception found" )
1223 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001224 main.cleanup()
1225 main.exit()
1226
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001228 """
1229 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001230 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001231 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001232 NOTE: this uses a custom mn function
1233 required params:
1234 hostname = the string hostname
1235 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001236 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001237 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001238 response = self.execute(
1239 cmd=command,
1240 prompt="mininet>",
1241 timeout=10 )
1242 if re.search( "no host named", response ):
1243 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001244 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001245 elif re.search( "Error", response ):
1246 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001247 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001248 elif re.search( "usage:", response ):
1249 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001250 return main.FALSE
1251 else:
1252 return main.TRUE
1253 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001256 main.cleanup()
1257 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001258
Jon Hall7eb38402015-01-08 17:19:54 -08001259 def disconnect( self ):
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001260 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001261 Called at the end of the test to stop the mininet and
1262 disconnect the handle.
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001263 """
1264 self.handle.sendline('')
1265 i = 1
1266 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1267 if i == 0:
1268 self.stopNet()
1269 response = ''
1270 # print "Disconnecting Mininet"
1271 if self.handle:
1272 self.handle.sendline( "exit" )
1273 self.handle.expect( "exit" )
1274 self.handle.expect( "(.*)" )
1275 main.log.info( "Mininet CLI is successfully disconnected" )
shahshreya26c3cea2015-02-05 10:17:41 -08001276 response = main.TRUE
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001277 else:
1278 main.log.error( "Connection failed to the host" )
1279 response = main.FALSE
1280
1281 return response
1282
kelvin-onlab56a3f462015-02-06 14:04:43 -08001283 def stopNet( self , timeout = 5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001284 """
1285 Stops mininet. returns true if the mininet succesfully stops.
1286 """
1287
Jon Hall7eb38402015-01-08 17:19:54 -08001288 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001289 response = ''
1290 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001291 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001292 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001293 i = self.handle.expect( [ 'mininet>',
1294 '\$',
1295 pexpect.EOF,
1296 pexpect.TIMEOUT ],
1297 timeout )
1298 if i == 0:
1299 main.log.info( "Exiting mininet..." )
1300
Jon Hall7eb38402015-01-08 17:19:54 -08001301 response = self.execute(
1302 cmd="exit",
1303 prompt="(.*)",
1304 timeout=120 )
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001305 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001306 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001307 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08001308
1309 if i == 1:
1310 main.log.info( " Mininet trying to exit while not " +
1311 "in the mininet prompt" )
1312 elif i == 2:
1313 main.log.error( "Something went wrong exiting mininet" )
1314 elif i == 3: # timeout
1315 main.log.error( "Something went wrong exiting mininet " +
1316 "TIMEOUT" )
1317
Jon Hallfbc828e2015-01-06 17:30:19 -08001318 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001319 main.log.error( self.name + ": EOF exception found" )
1320 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001321 main.cleanup()
1322 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001323 else:
1324 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001325 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001326 return response
1327
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001328
1329
Jon Hall7eb38402015-01-08 17:19:54 -08001330 def arping( self, src, dest, destmac ):
1331 self.handle.sendline( '' )
1332 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001333
Jon Hall7eb38402015-01-08 17:19:54 -08001334 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001335 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001336 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1337 main.log.info( self.name + ": ARP successful" )
1338 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001339 return main.TRUE
1340 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001341 main.log.warn( self.name + ": ARP FAILURE" )
1342 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001343 return main.FALSE
1344
Jon Hall7eb38402015-01-08 17:19:54 -08001345 def decToHex( self, num ):
1346 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001347
Jon Hall7eb38402015-01-08 17:19:54 -08001348 def getSwitchFlowCount( self, switch ):
1349 """
1350 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001351 if self.handle:
1352 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1353 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001354 response = self.execute(
1355 cmd=cmd,
1356 prompt="mininet>",
1357 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001358 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001359 main.log.error( self.name + ": EOF exception found" )
1360 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001361 main.cleanup()
1362 main.exit()
1363 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001364 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001365 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.info(
1367 "Couldn't find flows on switch %s, found: %s" %
1368 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001369 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001370 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001371 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001372 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001373
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 def checkFlows( self, sw, dumpFormat=None ):
1375 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001377 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001378 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001379 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001380 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 response = self.execute(
1382 cmd=command,
1383 prompt="mininet>",
1384 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001385 return response
1386 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001387 main.log.error( self.name + ": EOF exception found" )
1388 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001389 main.cleanup()
1390 main.exit()
1391 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001392 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001393
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001395 """
1396 Runs tpdump on an intferface and saves the file
1397 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001398 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001399 self.handle.sendline( "" )
1400 self.handle.expect( "mininet>" )
1401 self.handle.sendline(
1402 "sh sudo tcpdump -n -i " +
1403 intf +
1404 " " +
1405 port +
1406 " -w " +
1407 filename.strip() +
1408 " &" )
1409 self.handle.sendline( "" )
1410 i = self.handle.expect( [ 'No\ssuch\device',
1411 'listening\son',
1412 pexpect.TIMEOUT,
1413 "mininet>" ],
1414 timeout=10 )
1415 main.log.warn( self.handle.before + self.handle.after )
1416 self.handle.sendline( "" )
1417 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001418 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001419 main.log.error(
1420 self.name +
1421 ": tcpdump - No such device exists. " +
1422 "tcpdump attempted on: " +
1423 intf )
admin2a9548d2014-06-17 14:08:07 -07001424 return main.FALSE
1425 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001426 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001427 return main.TRUE
1428 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 main.log.error(
1430 self.name +
1431 ": tcpdump command timed out! Check interface name," +
1432 " given interface was: " +
1433 intf )
admin2a9548d2014-06-17 14:08:07 -07001434 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001435 elif i == 3:
1436 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001437 return main.TRUE
1438 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001439 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001440 return main.FALSE
1441 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001442 main.log.error( self.name + ": EOF exception found" )
1443 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001444 main.cleanup()
1445 main.exit()
1446 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001447 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001448 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001449 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001450 main.cleanup()
1451 main.exit()
1452
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001454 "pkills tcpdump"
1455 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001456 self.handle.sendline( "sh sudo pkill tcpdump" )
1457 self.handle.expect( "mininet>" )
1458 self.handle.sendline( "" )
1459 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001460 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001461 main.log.error( self.name + ": EOF exception found" )
1462 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001463 main.cleanup()
1464 main.exit()
1465 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001466 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001467 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001468 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001469 main.cleanup()
1470 main.exit()
1471
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001473 """
1474 Compare mn and onos switches
1475 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001476 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001477
Jon Hall7eb38402015-01-08 17:19:54 -08001478 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001480 output = { "switches": [] }
1481 # iterate through the MN topology and pull out switches and and port
1482 # info
1483 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001484 ports = []
1485 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001486 ports.append( { 'of_port': port.port_no,
1487 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001489 'name': port.name } )
1490 output[ 'switches' ].append( {
1491 "name": switch.name,
1492 "dpid": str( switch.dpid ).zfill( 16 ),
1493 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001494
Jon Hall7eb38402015-01-08 17:19:54 -08001495 # print "mn"
1496 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001498 # indent=4,
1499 # separators=( ',', ': ' ) )
1500 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 # print json.dumps( switchesJson,
1502 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001503 # indent=4,
1504 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001505
1506 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001507 mnDPIDs = []
1508 for switch in output[ 'switches' ]:
1509 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001510 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001511 # print "List of Mininet switch DPID's"
1512 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001513 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001514 main.log.error(
1515 self.name +
1516 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001517 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001519 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001520 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001521 if switch[ 'available' ]:
1522 onosDPIDs.append(
1523 switch[ 'id' ].replace(
1524 ":",
1525 '' ).replace(
1526 "of",
1527 '' ).lower() )
1528 # else:
1529 # print "Switch is unavailable:"
1530 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001531 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001532 # print "List of ONOS switch DPID's"
1533 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001534
Jon Hall7eb38402015-01-08 17:19:54 -08001535 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001537 main.log.report( "Switches in MN but not in ONOS:" )
1538 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1539 main.log.report( str( list1 ) )
1540 main.log.report( "Switches in ONOS but not in MN:" )
1541 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001542 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001543 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 switchResults = main.TRUE
1545 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001546
kelvin-onlabd3b64892015-01-20 13:26:24 -08001547 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001548 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001549 Compare mn and onos ports
1550 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001552
Jon Hallfbc828e2015-01-06 17:30:19 -08001553 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001554 1. This uses the sts TestONTopology object
1555 2. numpy - "sudo pip install numpy"
1556
Jon Hall7eb38402015-01-08 17:19:54 -08001557 """
1558 # FIXME: this does not look for extra ports in ONOS, only checks that
1559 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001560 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001562 output = { "switches": [] }
1563 # iterate through the MN topology and pull out switches and and port
1564 # info
1565 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001566 ports = []
1567 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001568 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001570 tmpPort[ 'of_port' ] = port.port_no
1571 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 tmpPort[ 'name' ] = port.name
1573 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001574
kelvin-onlabd3b64892015-01-20 13:26:24 -08001575 ports.append( tmpPort )
1576 tmpSwitch = {}
1577 tmpSwitch[ 'name' ] = switch.name
1578 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1579 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001580
kelvin-onlabd3b64892015-01-20 13:26:24 -08001581 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001582
Jon Hall7eb38402015-01-08 17:19:54 -08001583 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 for mnSwitch in output[ 'switches' ]:
1585 mnPorts = []
1586 onosPorts = []
1587 switchResult = main.TRUE
1588 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001589 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 mnPorts.append( port[ 'of_port' ] )
1591 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001592 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 # print onosSwitch
1594 if onosSwitch[ 'device' ][ 'available' ]:
1595 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001596 ':',
1597 '' ).replace(
1598 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 '' ) == mnSwitch[ 'dpid' ]:
1600 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001601 if port[ 'isEnabled' ]:
1602 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 # onosPorts.append( 'local' )
1604 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001605 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001607 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 mnPorts.sort( key=float )
1609 onosPorts.sort( key=float )
1610 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1611 # print "\tmn_ports[] = ", mnPorts
1612 # print "\tonos_ports[] = ", onosPorts
1613 mnPortsLog = mnPorts
1614 onosPortsLog = onosPorts
1615 mnPorts = [ x for x in mnPorts ]
1616 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001617
Jon Hall7eb38402015-01-08 17:19:54 -08001618 # TODO: handle other reserved port numbers besides LOCAL
1619 # NOTE: Reserved ports
1620 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1621 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 for mnPort in mnPortsLog:
1623 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001624 # don't set results to true here as this is just one of
1625 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 mnPorts.remove( mnPort )
1627 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001628 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001629 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001630 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001631 if 65534 in mnPorts:
1632 mnPorts.remove( 65534 )
1633 if long( uint64( -2 ) ) in onosPorts:
1634 onosPorts.remove( long( uint64( -2 ) ) )
1635 if len( mnPorts ): # the ports of this switch don't match
1636 switchResult = main.FALSE
1637 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1638 if len( onosPorts ): # the ports of this switch don't match
1639 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001640 main.log.warn(
1641 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 str( onosPorts ) )
1643 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001644 main.log.report(
1645 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1647 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1648 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1649 portsResults = portsResults and switchResult
1650 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001651
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001653 """
1654 Compare mn and onos links
1655 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001657
Jon Hall7eb38402015-01-08 17:19:54 -08001658 This uses the sts TestONTopology object"""
1659 # FIXME: this does not look for extra links in ONOS, only checks that
1660 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001662 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001664 # iterate through the MN topology and pull out switches and and port
1665 # info
1666 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001667 # print "Iterating though switches as seen by Mininet"
1668 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001669 ports = []
1670 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001671 # print port.hw_addr.toStr( separator='' )
1672 ports.append( { 'of_port': port.port_no,
1673 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001675 'name': port.name } )
1676 output[ 'switches' ].append( {
1677 "name": switch.name,
1678 "dpid": str( switch.dpid ).zfill( 16 ),
1679 "ports": ports } )
1680 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001681
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001683 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001684 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 if 2 * len( mnLinks ) == len( onos ):
1686 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001687 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001688 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001689 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001690 "Mininet has " + str( len( mnLinks ) ) +
1691 " bidirectional links and ONOS has " +
1692 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001693
Jon Hall7eb38402015-01-08 17:19:54 -08001694 # iterate through MN links and check if an ONOS link exists in
1695 # both directions
1696 # NOTE: Will currently only show mn links as down if they are
1697 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001699 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001701 # print "Link: %s" % link
1702 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001703 node1 = None
1704 port1 = None
1705 node2 = None
1706 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001707 firstDir = main.FALSE
1708 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001709 for switch in output[ 'switches' ]:
1710 # print "Switch: %s" % switch[ 'name' ]
1711 if switch[ 'name' ] == link.node1.name:
1712 node1 = switch[ 'dpid' ]
1713 for port in switch[ 'ports' ]:
1714 if str( port[ 'name' ] ) == str( link.port1 ):
1715 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001716 if node1 is not None and node2 is not None:
1717 break
Jon Hall7eb38402015-01-08 17:19:54 -08001718 if switch[ 'name' ] == link.node2.name:
1719 node2 = switch[ 'dpid' ]
1720 for port in switch[ 'ports' ]:
1721 if str( port[ 'name' ] ) == str( link.port2 ):
1722 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001723 if node1 is not None and node2 is not None:
1724 break
1725
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 for onosLink in onos:
1727 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001728 ":",
1729 '' ).replace(
1730 "of",
1731 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001732 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001733 ":",
1734 '' ).replace(
1735 "of",
1736 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001737 onosPort1 = onosLink[ 'src' ][ 'port' ]
1738 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001739
Jon Hall72cf1dc2014-10-20 21:04:50 -04001740 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 if str( onosNode1 ) == str( node1 ) and str(
1742 onosNode2 ) == str( node2 ):
1743 if int( onosPort1 ) == int( port1 ) and int(
1744 onosPort2 ) == int( port2 ):
1745 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001746 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001747 main.log.warn(
1748 'The port numbers do not match for ' +
1749 str( link ) +
1750 ' between ONOS and MN. When cheking ONOS for ' +
1751 'link %s/%s -> %s/%s' %
1752 ( node1,
1753 port1,
1754 node2,
1755 port2 ) +
1756 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001757 ( onosNode1,
1758 onosPort1,
1759 onosNode2,
1760 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001761
1762 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001763 elif ( str( onosNode1 ) == str( node2 ) and
1764 str( onosNode2 ) == str( node1 ) ):
1765 if ( int( onosPort1 ) == int( port2 )
1766 and int( onosPort2 ) == int( port1 ) ):
1767 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001768 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001769 main.log.warn(
1770 'The port numbers do not match for ' +
1771 str( link ) +
1772 ' between ONOS and MN. When cheking ONOS for ' +
1773 'link %s/%s -> %s/%s' %
1774 ( node2,
1775 port2,
1776 node1,
1777 port1 ) +
1778 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 ( onosNode2,
1780 onosPort2,
1781 onosNode1,
1782 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001783 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001784 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001786 main.log.report(
1787 'ONOS does not have the link %s/%s -> %s/%s' %
1788 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001789 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001790 main.log.report(
1791 'ONOS does not have the link %s/%s -> %s/%s' %
1792 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 linkResults = linkResults and firstDir and secondDir
1794 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001795
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001797 """
1798 Returns a list of all hosts
1799 Don't ask questions just use it"""
1800 self.handle.sendline( "" )
1801 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001802
Jon Hall7eb38402015-01-08 17:19:54 -08001803 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1804 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001805
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 handlePy = self.handle.before
1807 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1808 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001809
Jon Hall7eb38402015-01-08 17:19:54 -08001810 self.handle.sendline( "" )
1811 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001812
kelvin-onlabd3b64892015-01-20 13:26:24 -08001813 hostStr = handlePy.replace( "]", "" )
1814 hostStr = hostStr.replace( "'", "" )
1815 hostStr = hostStr.replace( "[", "" )
1816 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001817
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 return hostList
adminbae64d82013-08-01 10:50:15 -07001819
Jon Hall7eb38402015-01-08 17:19:54 -08001820 def update( self ):
1821 """
1822 updates the port address and status information for
1823 each port in mn"""
1824 # TODO: Add error checking. currently the mininet command has no output
1825 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001826 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001827 self.handle.sendline( "" )
1828 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001829
Jon Hall7eb38402015-01-08 17:19:54 -08001830 self.handle.sendline( "update" )
1831 self.handle.expect( "update" )
1832 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001833
Jon Hall7eb38402015-01-08 17:19:54 -08001834 self.handle.sendline( "" )
1835 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001836
Jon Hallb1290e82014-11-18 16:17:48 -05001837 return main.TRUE
1838 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001839 main.log.error( self.name + ": EOF exception found" )
1840 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001841 main.cleanup()
1842 main.exit()
1843
adminbae64d82013-08-01 10:50:15 -07001844if __name__ != "__main__":
1845 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001846 sys.modules[ __name__ ] = MininetCliDriver()