blob: bc0fcc553608ef53c4425faa74dedbacaf869bcb [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 Hall7eb38402015-01-08 17:19:54 -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 Hall7eb38402015-01-08 17:19:54 -080022MininetCliDriver is the basic driver which will handle the Mininet functions"""
admin2a9548d2014-06-17 14:08:07 -070023import traceback
adminbae64d82013-08-01 10:50:15 -070024import pexpect
adminbae64d82013-08-01 10:50:15 -070025import re
26import sys
Jon Hall7eb38402015-01-08 17:19:54 -080027sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040028from math import pow
adminbae64d82013-08-01 10:50:15 -070029from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070030
Jon Hall7eb38402015-01-08 17:19:54 -080031
32class MininetCliDriver( Emulator ):
33
34 """
35 MininetCliDriver is the basic driver which will handle
36 the Mininet functions"""
37 def __init__( self ):
38 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070039 self.handle = self
Jon Hall7eb38402015-01-08 17:19:54 -080040 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070041 self.flag = 0
42
Jon Hall7eb38402015-01-08 17:19:54 -080043 def connect( self, **connectargs ):
44 """
45 Here the main is the TestON instance after creating
46 all the log handles."""
adminbae64d82013-08-01 10:50:15 -070047 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -080048 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080049
Jon Hall7eb38402015-01-08 17:19:54 -080050 self.name = self.options[ 'name' ]
51 self.handle = super(
52 MininetCliDriver,
53 self ).connect(
54 user_name=self.user_name,
55 ip_address=self.ip_address,
56 port=None,
57 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080058
adminbae64d82013-08-01 10:50:15 -070059 self.ssh_handle = self.handle
Jon Hallfbc828e2015-01-06 17:30:19 -080060
Jon Hall7eb38402015-01-08 17:19:54 -080061 if self.handle:
62 main.log.info(
63 self.name +
64 ": Clearing any residual state or processes" )
65 self.handle.sendline( "sudo mn -c" )
66 i = self.handle.expect( [ 'password\sfor\s',
67 'Cleanup\scomplete',
68 pexpect.EOF,
69 pexpect.TIMEOUT ],
70 120 )
71 if i == 0:
72 main.log.info( self.name + ": Sending sudo password" )
73 self.handle.sendline( self.pwd )
74 i = self.handle.expect( [ '%s:' % ( self.user ),
75 '\$',
76 pexpect.EOF,
77 pexpect.TIMEOUT ],
78 120 )
79 if i == 1:
80 main.log.info( self.name + ": Clean" )
81 elif i == 2:
82 main.log.error( self.name + ": Connection terminated" )
83 elif i == 3: # timeout
84 main.log.error(
85 self.name +
86 ": Something while cleaning MN took too long... " )
Jon Hallfbc828e2015-01-06 17:30:19 -080087
Jon Hall7eb38402015-01-08 17:19:54 -080088 main.log.info( self.name + ": building fresh mininet" )
89 # for reactive/PARP enabled tests
90 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
kelvin-onlabedcff052015-01-16 12:53:55 -080091 " " + self.options[ 'arg2' ] +\
92 " --mac --controller " +\
93 self.options[ 'controller' ] + " " +\
94 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -080095
Jon Hall7eb38402015-01-08 17:19:54 -080096 argList = self.options[ 'arg1' ].split( "," )
Jon Hall1ccf82c2014-10-15 14:55:16 -040097 global topoArgList
Jon Hall7eb38402015-01-08 17:19:54 -080098 topoArgList = argList[ 0 ].split( " " )
99 argList = map( int, argList[ 1: ] )
100 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800101
Jon Hall7eb38402015-01-08 17:19:54 -0800102 self.handle.sendline( cmdString )
103 self.handle.expect( [ "sudo mn", pexpect.EOF, pexpect.TIMEOUT ] )
104 while True:
105 i = self.handle.expect( [ 'mininet>',
106 '\*\*\*',
107 'Exception',
108 pexpect.EOF,
109 pexpect.TIMEOUT ],
110 300 )
111 if i == 0:
112 main.log.info( self.name + ": mininet built" )
adminbae64d82013-08-01 10:50:15 -0700113 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800114 if i == 1:
115 self.handle.expect(
116 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
117 main.log.info( self.handle.before )
118 elif i == 2:
119 main.log.error(
120 self.name +
121 ": Launching mininet failed..." )
adminbae64d82013-08-01 10:50:15 -0700122 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800123 elif i == 3:
124 main.log.error( self.name + ": Connection timeout" )
adminbae64d82013-08-01 10:50:15 -0700125 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800126 elif i == 4: # timeout
127 main.log.error(
128 self.name +
129 ": Something took too long... " )
adminbae64d82013-08-01 10:50:15 -0700130 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700131 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800132 else: # if no handle
133 main.log.error(
134 self.name +
135 ": Connection failed to the host " +
136 self.user_name +
137 "@" +
138 self.ip_address )
139 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700140 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800141
Jon Hall7eb38402015-01-08 17:19:54 -0800142 def num_switches_n_links( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400143 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800144 # In tree topology, if fanout arg is not given, by default it is 2
145 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400146 fanout = 2
147 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500148 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800149 while( k <= depth - 1 ):
150 count = count + pow( fanout, k )
151 k = k + 1
Jon Hall38481722014-11-04 16:50:05 -0500152 num_switches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800153 while( k <= depth - 2 ):
154 # depth-2 gives you only core links and not considering
155 # edge links as seen by ONOS. If all the links including
156 # edge links are required, do depth-1
157 count = count + pow( fanout, k )
158 k = k + 1
Jon Hall38481722014-11-04 16:50:05 -0500159 num_links = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800160 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
161 # topoType,depth,fanout,num_switches,num_links )
Jon Hallfbc828e2015-01-06 17:30:19 -0800162
Jon Hall7eb38402015-01-08 17:19:54 -0800163 elif topoType == 'linear':
164 # In linear topology, if fanout or num_hosts_per_sw is not given,
165 # by default it is 1
166 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400167 fanout = 1
168 num_switches = depth
169 num_hosts_per_sw = fanout
170 total_num_hosts = num_switches * num_hosts_per_sw
Jon Hall7eb38402015-01-08 17:19:54 -0800171 num_links = total_num_hosts + ( num_switches - 1 )
172 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabedcff052015-01-16 12:53:55 -0800173 ( topoType, depth, fanout, num_switches, num_links )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400174 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800175 topoDict = {
176 "num_switches": int( num_switches ),
177 "num_corelinks": int( num_links ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400178 return topoDict
179
Jon Hall7eb38402015-01-08 17:19:54 -0800180 def calculate_sw_and_links( self ):
181 topoDict = self.num_switches_n_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400182 return topoDict
183
Jon Hall7eb38402015-01-08 17:19:54 -0800184 def pingall( self, timeout=300 ):
185 """
186 Verifies the reachability of the hosts using pingall command.
187 Optional parameter timeout allows you to specify how long to
188 wait for pingall to complete
189 Returns:
190 main.TRUE if pingall completes with no pings dropped
191 otherwise main.FALSE"""
192 if self.handle:
193 main.log.info(
194 self.name +
195 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700196 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800197 response = self.execute(
198 cmd="pingall",
199 prompt="mininet>",
200 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500201 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800202 main.log.error( self.name + ": EOF exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500204 main.cleanup()
205 main.exit()
206 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800207 # We may not want to kill the test if pexpect times out
208 main.log.error( self.name + ": TIMEOUT exception found" )
209 main.log.error( self.name +
210 ": " +
211 str( self.handle.before ) )
212 # NOTE: mininet's pingall rounds, so we will check the number of
213 # passed and number of failed
214 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800215 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800216 if re.search( pattern, response ):
217 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700218 return main.TRUE
219 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800220 main.log.error( self.name + ": Unable to reach all the hosts" )
221 main.log.info( "Pingall ouput: " + str( response ) )
222 # NOTE: Send ctrl-c to make sure pingall is done
223 self.handle.send( "\x03" )
224 self.handle.expect( "Interrupt" )
225 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700226 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800227 else:
228 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500229 main.cleanup()
230 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700231
Jon Hall7eb38402015-01-08 17:19:54 -0800232 def fpingHost( self, **pingParams ):
233 """
234 Uses the fping package for faster pinging...
235 *requires fping to be installed on machine running mininet"""
236 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
237 command = args[ "SRC" ] + \
238 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
239 self.handle.sendline( command )
240 self.handle.expect(
241 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
242 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
243 response = self.handle.before
244 if re.search( ":\s-", response ):
245 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700246 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800247 elif re.search( ":\s\d{1,2}\.\d\d", response ):
248 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700249 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800250 main.log.info( self.name + ": Install fping on mininet machine... " )
251 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700252 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800253
Jon Hall7eb38402015-01-08 17:19:54 -0800254 def pingHost( self, **pingParams ):
255 """
256 Ping from one mininet host to another
257 Currently the only supported Params: SRC and TARGET"""
258 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
259 command = args[ "SRC" ] + " ping " + \
260 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700261 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800262 main.log.warn( "Sending: " + command )
263 self.handle.sendline( command )
264 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700265 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800266 main.log.error(
267 self.name +
268 ": timeout when waiting for response from mininet" )
269 main.log.error( "response: " + str( self.handle.before ) )
270 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700271 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800272 main.log.error(
273 self.name +
274 ": timeout when waiting for response from mininet" )
275 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700276 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800277 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800278 main.log.error( self.name + ": EOF exception found" )
279 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700280 main.cleanup()
281 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800282 main.log.info( self.name + ": Ping Response: " + response )
283 if re.search( ',\s0\%\spacket\sloss', response ):
284 main.log.info( self.name + ": no packets lost, host is reachable" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800285 main.last_result = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700286 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800287 else:
288 main.log.error(
289 self.name +
290 ": PACKET LOST, HOST IS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -0700291 main.last_result = main.FALSE
292 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800293
Jon Hall7eb38402015-01-08 17:19:54 -0800294 def checkIP( self, host ):
295 """
296 Verifies the host's ip configured or not."""
297 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700298 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800299 response = self.execute(
300 cmd=host +
301 " ifconfig",
302 prompt="mininet>",
303 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800304 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800305 main.log.error( self.name + ": EOF exception found" )
306 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700307 main.cleanup()
308 main.exit()
adminbae64d82013-08-01 10:50:15 -0700309
Jon Hall7eb38402015-01-08 17:19:54 -0800310 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800311 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
312 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
313 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
314 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
315 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800316 # pattern = "inet addr:10.0.0.6"
317 if re.search( pattern, response ):
318 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700319 return main.TRUE
320 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800321 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700322 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800323 else:
324 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800325
Jon Hall7eb38402015-01-08 17:19:54 -0800326 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700327 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800328 response = self.execute(
329 cmd="h1 /usr/sbin/sshd -D&",
330 prompt="mininet>",
331 timeout=10 )
332 response = self.execute(
333 cmd="h4 /usr/sbin/sshd -D&",
334 prompt="mininet>",
335 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700336 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800337 vars( self )[ key ] = connectargs[ key ]
338 response = self.execute(
339 cmd="xterm h1 h4 ",
340 prompt="mininet>",
341 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800342 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800343 main.log.error( self.name + ": EOF exception found" )
344 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700345 main.cleanup()
346 main.exit()
adminbae64d82013-08-01 10:50:15 -0700347 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800348 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700349 if self.flag == 0:
350 self.flag = 1
351 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800352 else:
adminbae64d82013-08-01 10:50:15 -0700353 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800354
Jon Hall7eb38402015-01-08 17:19:54 -0800355 def changeIP( self, host, intf, newIP, newNetmask ):
356 """
357 Changes the ip address of a host on the fly
358 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800359 if self.handle:
360 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800361 cmd = host + " ifconfig " + intf + " " + \
362 newIP + " " + 'netmask' + " " + newNetmask
363 self.handle.sendline( cmd )
364 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800365 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800366 main.log.info( "response = " + response )
367 main.log.info(
368 "Ip of host " +
369 host +
370 " changed to new IP " +
371 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800372 return main.TRUE
373 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800374 main.log.error( self.name + ": EOF exception found" )
375 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800376 return main.FALSE
377
Jon Hall7eb38402015-01-08 17:19:54 -0800378 def changeDefaultGateway( self, host, newGW ):
379 """
380 Changes the default gateway of a host
381 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800382 if self.handle:
383 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800384 cmd = host + " route add default gw " + newGW
385 self.handle.sendline( cmd )
386 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800387 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800388 main.log.info( "response = " + response )
389 main.log.info(
390 "Default gateway of host " +
391 host +
392 " changed to " +
393 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800394 return main.TRUE
395 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800396 main.log.error( self.name + ": EOF exception found" )
397 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800398 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800399
Jon Hall7eb38402015-01-08 17:19:54 -0800400 def addStaticMACAddress( self, host, GW, macaddr ):
401 """
402 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800403 if self.handle:
404 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800405 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
406 cmd = host + " arp -s " + GW + " " + macaddr
407 self.handle.sendline( cmd )
408 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800409 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800410 main.log.info( "response = " + response )
411 main.log.info(
412 "Mac adrress of gateway " +
413 GW +
414 " changed to " +
415 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800416 return main.TRUE
417 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800418 main.log.error( self.name + ": EOF exception found" )
419 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800420 return main.FALSE
421
Jon Hall7eb38402015-01-08 17:19:54 -0800422 def verifyStaticGWandMAC( self, host ):
423 """
424 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800425 if self.handle:
426 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800427 # h1 arp -an
428 cmd = host + " arp -an "
429 self.handle.sendline( cmd )
430 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800431 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800432 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800433 return main.TRUE
434 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800435 main.log.error( self.name + ": EOF exception found" )
436 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800437 return main.FALSE
438
Jon Hall7eb38402015-01-08 17:19:54 -0800439 def getMacAddress( self, host ):
440 """
441 Verifies the host's ip configured or not."""
442 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700443 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800444 response = self.execute(
445 cmd=host +
446 " ifconfig",
447 prompt="mininet>",
448 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800449 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800450 main.log.error( self.name + ": EOF exception found" )
451 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700452 main.cleanup()
453 main.exit()
adminbae64d82013-08-01 10:50:15 -0700454
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700455 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
Jon Hall7eb38402015-01-08 17:19:54 -0800456 mac_address_search = re.search( pattern, response, re.I )
457 mac_address = mac_address_search.group().split( " " )[ 1 ]
458 main.log.info(
459 self.name +
460 ": Mac-Address of Host " +
461 host +
462 " is " +
463 mac_address )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700464 return mac_address
465 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800466 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700467
Jon Hall7eb38402015-01-08 17:19:54 -0800468 def getInterfaceMACAddress( self, host, interface ):
469 """
470 Return the IP address of the interface on the given host"""
471 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700472 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800473 response = self.execute( cmd=host + " ifconfig " + interface,
474 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800475 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800476 main.log.error( self.name + ": EOF exception found" )
477 main.log.error( self.name + ": " + self.handle.before )
478 main.cleanup()
479 main.exit()
480
481 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
482 mac_address_search = re.search( pattern, response, re.I )
483 if mac_address_search is None:
484 main.log.info( "No mac address found in %s" % response )
485 return main.FALSE
486 mac_address = mac_address_search.group().split( " " )[ 1 ]
487 main.log.info(
488 "Mac-Address of " +
489 host +
490 ":" +
491 interface +
492 " is " +
493 mac_address )
494 return mac_address
495 else:
496 main.log.error( "Connection failed to the host" )
497
498 def getIPAddress( self, host ):
499 """
500 Verifies the host's ip configured or not."""
501 if self.handle:
502 try:
503 response = self.execute(
504 cmd=host +
505 " ifconfig",
506 prompt="mininet>",
507 timeout=10 )
508 except pexpect.EOF:
509 main.log.error( self.name + ": EOF exception found" )
510 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700511 main.cleanup()
512 main.exit()
adminbae64d82013-08-01 10:50:15 -0700513
514 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -0800515 ip_address_search = re.search( pattern, response )
516 main.log.info(
517 self.name +
518 ": IP-Address of Host " +
519 host +
520 " is " +
521 ip_address_search.group( 1 ) )
522 return ip_address_search.group( 1 )
523 else:
524 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800525
Jon Hall7eb38402015-01-08 17:19:54 -0800526 def getSwitchDPID( self, switch ):
527 """
528 return the datapath ID of the switch"""
529 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700530 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700531 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800532 response = self.execute(
533 cmd=cmd,
534 prompt="mininet>",
535 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800536 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800537 main.log.error( self.name + ": EOF exception found" )
538 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700539 main.cleanup()
540 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800541 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800542 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700543 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800544 main.log.info(
545 "Couldn't find DPID for switch %s, found: %s" %
546 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700547 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800548 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700549 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800550 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700551
Jon Hall7eb38402015-01-08 17:19:54 -0800552 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700553 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800554 self.handle.sendline( "" )
555 self.expect( "mininet>" )
556 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700557 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800558 response = self.execute(
559 cmd=cmd,
560 prompt="mininet>",
561 timeout=10 )
562 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700563 response = self.handle.before
564 return response
565 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800566 main.log.error( self.name + ": EOF exception found" )
567 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700568 main.cleanup()
569 main.exit()
570
Jon Hall7eb38402015-01-08 17:19:54 -0800571 def getInterfaces( self, node ):
572 """
573 return information dict about interfaces connected to the node"""
574 if self.handle:
575 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800576 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700577 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700578 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800579 response = self.execute(
580 cmd=cmd,
581 prompt="mininet>",
582 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800583 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800584 main.log.error( self.name + ": EOF exception found" )
585 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700586 main.cleanup()
587 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700588 return response
589 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800590 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700591
Jon Hall7eb38402015-01-08 17:19:54 -0800592 def dump( self ):
593 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700594 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800595 response = self.execute(
596 cmd='dump',
597 prompt='mininet>',
598 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800599 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800600 main.log.error( self.name + ": EOF exception found" )
601 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700602 main.cleanup()
603 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700604 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800605
Jon Hall7eb38402015-01-08 17:19:54 -0800606 def intfs( self ):
607 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700608 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800609 response = self.execute(
610 cmd='intfs',
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()
Jon Hall668ed802014-04-08 17:17:59 -0700618 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800619
Jon Hall7eb38402015-01-08 17:19:54 -0800620 def net( self ):
621 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700622 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800623 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800624 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800625 main.log.error( self.name + ": EOF exception found" )
626 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700627 main.cleanup()
628 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700629 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800630
631 def iperf( self, host1, host2 ):
632 main.log.info(
633 self.name +
634 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700635 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800636 cmd1 = 'iperf ' + host1 + " " + host2
637 self.handle.sendline( cmd1 )
638 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800639 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800640 if re.search( 'Results:', response ):
641 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800642 return main.TRUE
643 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800644 main.log.error( self.name + ": iperf test failed" )
645 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800646 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800647 main.log.error( self.name + ": EOF exception found" )
648 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800649 main.cleanup()
650 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800651
Jon Hall7eb38402015-01-08 17:19:54 -0800652 def iperfudp( self ):
653 main.log.info(
654 self.name +
655 ": Simple iperf TCP test between two " +
656 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700657 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800658 response = self.execute(
659 cmd='iperfudp',
660 prompt='mininet>',
661 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800662 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800663 main.log.error( self.name + ": EOF exception found" )
664 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700665 main.cleanup()
666 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700667 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800668
Jon Hall7eb38402015-01-08 17:19:54 -0800669 def nodes( self ):
670 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700671 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800672 response = self.execute(
673 cmd='nodes',
674 prompt='mininet>',
675 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800676 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800677 main.log.error( self.name + ": EOF exception found" )
678 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700679 main.cleanup()
680 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700681 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800682
Jon Hall7eb38402015-01-08 17:19:54 -0800683 def pingpair( self ):
684 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700685 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800686 response = self.execute(
687 cmd='pingpair',
688 prompt='mininet>',
689 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800690 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800691 main.log.error( self.name + ": EOF exception found" )
692 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700693 main.cleanup()
694 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800695
Jon Hall7eb38402015-01-08 17:19:54 -0800696 if re.search( ',\s0\%\spacket\sloss', response ):
697 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800698 main.last_result = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700699 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800700 else:
701 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -0700702 main.last_result = main.FALSE
703 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800704
Jon Hall7eb38402015-01-08 17:19:54 -0800705 def link( self, **linkargs ):
706 """
707 Bring link( s ) between two nodes up or down"""
708 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
709 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
710 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
711 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
712 main.log.info(
713 "Bring link between '" +
714 end1 +
715 "' and '" +
716 end2 +
717 "' '" +
718 option +
719 "'" )
720 command = "link " + \
721 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700722 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800723 self.handle.sendline( command )
724 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800725 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800726 main.log.error( self.name + ": EOF exception found" )
727 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700728 main.cleanup()
729 main.exit()
adminbae64d82013-08-01 10:50:15 -0700730 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800731
Jon Hall7eb38402015-01-08 17:19:54 -0800732 def yank( self, **yankargs ):
733 """
734 yank a mininet switch interface to a host"""
735 main.log.info( 'Yank the switch interface attached to a host' )
736 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
737 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
738 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
739 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700740 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 response = self.execute(
742 cmd=command,
743 prompt="mininet>",
744 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800745 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 main.log.error( self.name + ": EOF exception found" )
747 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700748 main.cleanup()
749 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700750 return main.TRUE
751
Jon Hall7eb38402015-01-08 17:19:54 -0800752 def plug( self, **plugargs ):
753 """
754 plug the yanked mininet switch interface to a switch"""
755 main.log.info( 'Plug the switch interface attached to a switch' )
756 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
757 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
758 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
759 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700760 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800761 response = self.execute(
762 cmd=command,
763 prompt="mininet>",
764 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800765 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800766 main.log.error( self.name + ": EOF exception found" )
767 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700768 main.cleanup()
769 main.exit()
adminbae64d82013-08-01 10:50:15 -0700770 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800771
Jon Hall7eb38402015-01-08 17:19:54 -0800772 def dpctl( self, **dpctlargs ):
773 """
774 Run dpctl command on all switches."""
775 main.log.info( 'Run dpctl command on all switches' )
776 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
777 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
778 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
779 command = "dpctl " + cmd + " " + str( cmdargs )
780 try:
781 response = self.execute(
782 cmd=command,
783 prompt="mininet>",
784 timeout=10 )
785 except pexpect.EOF:
786 main.log.error( self.name + ": EOF exception found" )
787 main.log.error( self.name + ": " + self.handle.before )
788 main.cleanup()
789 main.exit()
790 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800791
Jon Hall7eb38402015-01-08 17:19:54 -0800792 def get_version( self ):
793 file_input = path + '/lib/Mininet/INSTALL'
794 version = super( Mininet, self ).get_version()
adminbae64d82013-08-01 10:50:15 -0700795 pattern = 'Mininet\s\w\.\w\.\w\w*'
Jon Hall7eb38402015-01-08 17:19:54 -0800796 for line in open( file_input, 'r' ).readlines():
797 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700798 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800799 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500800 return version
adminbae64d82013-08-01 10:50:15 -0700801
Jon Hall7eb38402015-01-08 17:19:54 -0800802 def get_sw_controller( self, sw ):
803 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500804 Parameters:
805 sw: The name of an OVS switch. Example "s1"
806 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800807 The output of the command from the mininet cli
808 or main.FALSE on timeout"""
809 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700810 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800811 response = self.execute(
812 cmd=command,
813 prompt="mininet>",
814 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700815 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500816 return response
admin2a9548d2014-06-17 14:08:07 -0700817 else:
818 return main.FALSE
819 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800820 main.log.error( self.name + ": EOF exception found" )
821 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700822 main.cleanup()
823 main.exit()
adminbae64d82013-08-01 10:50:15 -0700824
Jon Hall7eb38402015-01-08 17:19:54 -0800825 def assign_sw_controller( self, **kwargs ):
826 """
827 count is only needed if there is more than 1 controller"""
828 args = utilities.parse_args( [ "COUNT" ], **kwargs )
829 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700830
831 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800832 for j in range( count ):
833 argstring = argstring + ",IP" + \
834 str( j + 1 ) + ",PORT" + str( j + 1 )
835 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700836
Jon Hall7eb38402015-01-08 17:19:54 -0800837 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
838 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800839 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800840 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800841
Jon Hall7eb38402015-01-08 17:19:54 -0800842 command = "sh ovs-vsctl set-controller s" + \
843 str( sw ) + " " + ptcpB + " "
844 for j in range( count ):
845 i = j + 1
846 args = utilities.parse_args(
847 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
848 ip = args[
849 "IP" +
850 str( i ) ] if args[
851 "IP" +
852 str( i ) ] is not None else ""
853 port = args[
854 "PORT" +
855 str( i ) ] if args[
856 "PORT" +
857 str( i ) ] is not None else ""
858 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800859 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -0700860 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -0700861 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800862 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -0700863 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800864 main.log.error( self.name + ": EOF exception found" )
865 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700866 main.cleanup()
867 main.exit()
868 except:
Jon Hall7eb38402015-01-08 17:19:54 -0800869 main.log.info( self.name + ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -0700870 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -0800871 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -0700872 main.cleanup()
873 main.exit()
adminbae64d82013-08-01 10:50:15 -0700874
Jon Hall7eb38402015-01-08 17:19:54 -0800875 def delete_sw_controller( self, sw ):
876 """
877 Removes the controller target from sw"""
878 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -0700879 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800880 response = self.execute(
881 cmd=command,
882 prompt="mininet>",
883 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800884 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800885 main.log.error( self.name + ": EOF exception found" )
886 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -0700887 main.cleanup()
888 main.exit()
889 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800890 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -0700891
Jon Hallb1290e82014-11-18 16:17:48 -0500892 def add_switch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800893 """
Jon Hallb1290e82014-11-18 16:17:48 -0500894 adds a switch to the mininet topology
895 NOTE: this uses a custom mn function
896 NOTE: cannot currently specify what type of switch
897 required params:
898 switchname = name of the new switch as a string
899 optional keyvalues:
900 dpid = "dpid"
901 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800902 """
903 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -0800904 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -0500905 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800906 response = self.execute(
907 cmd=command,
908 prompt="mininet>",
909 timeout=10 )
910 if re.search( "already exists!", response ):
911 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500912 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800913 elif re.search( "Error", response ):
914 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500915 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800916 elif re.search( "usage:", response ):
917 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500918 return main.FALSE
919 else:
920 return main.TRUE
921 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800922 main.log.error( self.name + ": EOF exception found" )
923 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500924 main.cleanup()
925 main.exit()
926
927 def del_switch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800928 """
929 delete a switch from the mininet topology
930 NOTE: this uses a custom mn function
931 required params:
Jon Hallb1290e82014-11-18 16:17:48 -0500932 switchname = name of the switch as a string
Jon Hall7eb38402015-01-08 17:19:54 -0800933 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -0800934 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -0500935 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800936 response = self.execute(
937 cmd=command,
938 prompt="mininet>",
939 timeout=10 )
940 if re.search( "no switch named", response ):
941 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500942 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800943 elif re.search( "Error", response ):
944 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500945 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800946 elif re.search( "usage:", response ):
947 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500948 return main.FALSE
949 else:
950 return main.TRUE
951 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800952 main.log.error( self.name + ": EOF exception found" )
953 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500954 main.cleanup()
955 main.exit()
956
957 def add_link( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800958 """
959 add a link to the mininet topology
960 NOTE: this uses a custom mn function
961 NOTE: cannot currently specify what type of link
962 required params:
963 node1 = the string node name of the first endpoint of the link
964 node2 = the string node name of the second endpoint of the link
965 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -0800966 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -0500967 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800968 response = self.execute(
969 cmd=command,
970 prompt="mininet>",
971 timeout=10 )
972 if re.search( "doesnt exist!", response ):
973 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500974 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800975 elif re.search( "Error", response ):
976 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500977 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800978 elif re.search( "usage:", response ):
979 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -0500980 return main.FALSE
981 else:
982 return main.TRUE
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 )
Jon Hallb1290e82014-11-18 16:17:48 -0500986 main.cleanup()
987 main.exit()
988
989 def del_link( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800990 """
991 delete a link from the mininet topology
992 NOTE: this uses a custom mn function
993 required params:
994 node1 = the string node name of the first endpoint of the link
995 node2 = the string node name of the second endpoint of the link
996 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -0800997 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -0500998 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800999 response = self.execute(
1000 cmd=command,
1001 prompt="mininet>",
1002 timeout=10 )
1003 if re.search( "no node named", response ):
1004 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001005 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001006 elif re.search( "Error", response ):
1007 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001008 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001009 elif re.search( "usage:", response ):
1010 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001011 return main.FALSE
1012 else:
1013 return main.TRUE
1014 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 Hallb1290e82014-11-18 16:17:48 -05001017 main.cleanup()
1018 main.exit()
1019
1020 def add_host( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001021 """
Jon Hallb1290e82014-11-18 16:17:48 -05001022 Add a host to the mininet topology
1023 NOTE: this uses a custom mn function
1024 NOTE: cannot currently specify what type of host
1025 required params:
1026 hostname = the string hostname
1027 optional key-value params
1028 switch = "switch name"
1029 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001030 """
1031 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001032 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001033 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001034 response = self.execute(
1035 cmd=command,
1036 prompt="mininet>",
1037 timeout=10 )
1038 if re.search( "already exists!", response ):
1039 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001040 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001041 elif re.search( "doesnt exists!", response ):
1042 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001043 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001044 elif re.search( "Error", response ):
1045 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001046 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001047 elif re.search( "usage:", response ):
1048 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001049 return main.FALSE
1050 else:
1051 return main.TRUE
1052 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001053 main.log.error( self.name + ": EOF exception found" )
1054 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001055 main.cleanup()
1056 main.exit()
1057
1058 def del_host( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001059 """
1060 delete a host from the mininet topology
1061 NOTE: this uses a custom mn function
1062 required params:
1063 hostname = the string hostname
1064 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001065 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001066 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001067 response = self.execute(
1068 cmd=command,
1069 prompt="mininet>",
1070 timeout=10 )
1071 if re.search( "no host named", response ):
1072 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001073 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001074 elif re.search( "Error", response ):
1075 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001076 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001077 elif re.search( "usage:", response ):
1078 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001079 return main.FALSE
1080 else:
1081 return main.TRUE
1082 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001083 main.log.error( self.name + ": EOF exception found" )
1084 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001085 main.cleanup()
1086 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001087
Jon Hall7eb38402015-01-08 17:19:54 -08001088 def disconnect( self ):
1089 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001090 response = ''
1091 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001092 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001093 response = self.execute(
1094 cmd="exit",
1095 prompt="(.*)",
1096 timeout=120 )
1097 response = self.execute(
1098 cmd="exit",
1099 prompt="(.*)",
1100 timeout=120 )
1101 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001102 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001103 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001106 main.cleanup()
1107 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001108 else:
1109 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001110 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001111 return response
1112
Jon Hall7eb38402015-01-08 17:19:54 -08001113 def arping( self, src, dest, destmac ):
1114 self.handle.sendline( '' )
1115 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001116
Jon Hall7eb38402015-01-08 17:19:54 -08001117 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001118 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001119 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1120 main.log.info( self.name + ": ARP successful" )
1121 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001122 return main.TRUE
1123 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001124 main.log.warn( self.name + ": ARP FAILURE" )
1125 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001126 return main.FALSE
1127
Jon Hall7eb38402015-01-08 17:19:54 -08001128 def decToHex( self, num ):
1129 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001130
Jon Hall7eb38402015-01-08 17:19:54 -08001131 def getSwitchFlowCount( self, switch ):
1132 """
1133 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001134 if self.handle:
1135 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1136 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001137 response = self.execute(
1138 cmd=cmd,
1139 prompt="mininet>",
1140 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001141 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001142 main.log.error( self.name + ": EOF exception found" )
1143 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001144 main.cleanup()
1145 main.exit()
1146 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001147 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001148 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001149 main.log.info(
1150 "Couldn't find flows on switch %s, found: %s" %
1151 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001152 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001153 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001154 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001155 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001156
Jon Hall7eb38402015-01-08 17:19:54 -08001157 def check_flows( self, sw, dump_format=None ):
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001158 if dump_format:
Jon Hall7eb38402015-01-08 17:19:54 -08001159 command = "sh ovs-ofctl -F " + \
1160 dump_format + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001161 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001162 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001163 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001164 response = self.execute(
1165 cmd=command,
1166 prompt="mininet>",
1167 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001168 return response
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 )
admin2a9548d2014-06-17 14:08:07 -07001172 main.cleanup()
1173 main.exit()
1174 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001175 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001176
Jon Hall7eb38402015-01-08 17:19:54 -08001177 def start_tcpdump( self, filename, intf="eth0", port="port 6633" ):
1178 """
1179 Runs tpdump on an intferface and saves the file
1180 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001181 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001182 self.handle.sendline( "" )
1183 self.handle.expect( "mininet>" )
1184 self.handle.sendline(
1185 "sh sudo tcpdump -n -i " +
1186 intf +
1187 " " +
1188 port +
1189 " -w " +
1190 filename.strip() +
1191 " &" )
1192 self.handle.sendline( "" )
1193 i = self.handle.expect( [ 'No\ssuch\device',
1194 'listening\son',
1195 pexpect.TIMEOUT,
1196 "mininet>" ],
1197 timeout=10 )
1198 main.log.warn( self.handle.before + self.handle.after )
1199 self.handle.sendline( "" )
1200 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001201 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001202 main.log.error(
1203 self.name +
1204 ": tcpdump - No such device exists. " +
1205 "tcpdump attempted on: " +
1206 intf )
admin2a9548d2014-06-17 14:08:07 -07001207 return main.FALSE
1208 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001209 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001210 return main.TRUE
1211 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001212 main.log.error(
1213 self.name +
1214 ": tcpdump command timed out! Check interface name," +
1215 " given interface was: " +
1216 intf )
admin2a9548d2014-06-17 14:08:07 -07001217 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001218 elif i == 3:
1219 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001220 return main.TRUE
1221 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001222 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001223 return main.FALSE
1224 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001225 main.log.error( self.name + ": EOF exception found" )
1226 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001227 main.cleanup()
1228 main.exit()
1229 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001230 main.log.info( self.name + ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001231 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001232 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001233 main.cleanup()
1234 main.exit()
1235
Jon Hall7eb38402015-01-08 17:19:54 -08001236 def stop_tcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001237 "pkills tcpdump"
1238 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001239 self.handle.sendline( "sh sudo pkill tcpdump" )
1240 self.handle.expect( "mininet>" )
1241 self.handle.sendline( "" )
1242 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001243 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001244 main.log.error( self.name + ": EOF exception found" )
1245 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001246 main.cleanup()
1247 main.exit()
1248 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 main.log.info( self.name + ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001250 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001251 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001252 main.cleanup()
1253 main.exit()
1254
Jon Hall7eb38402015-01-08 17:19:54 -08001255 def compare_switches( self, topo, switches_json ):
1256 """
1257 Compare mn and onos switches
1258 topo: sts TestONTopology object
1259 switches_json: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001260
Jon Hall7eb38402015-01-08 17:19:54 -08001261 This uses the sts TestONTopology object"""
1262 # main.log.debug( "Switches_json string: ", switches_json )
1263 output = { "switches": [] }
1264 # iterate through the MN topology and pull out switches and and port
1265 # info
1266 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001267 ports = []
1268 for port in switch.ports.values():
Jon Hall7eb38402015-01-08 17:19:54 -08001269 ports.append( { 'of_port': port.port_no,
1270 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabedcff052015-01-16 12:53:55 -08001271 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001272 'name': port.name } )
1273 output[ 'switches' ].append( {
1274 "name": switch.name,
1275 "dpid": str( switch.dpid ).zfill( 16 ),
1276 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001277
Jon Hall7eb38402015-01-08 17:19:54 -08001278 # print "mn"
1279 # print json.dumps( output,
1280 # sort_keys=True,
1281 # indent=4,
1282 # separators=( ',', ': ' ) )
1283 # print "onos"
1284 # print json.dumps( switches_json,
1285 # sort_keys=True,
1286 # indent=4,
1287 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001288
1289 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001290 mnDPIDs = []
1291 for switch in output[ 'switches' ]:
1292 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001293 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001294 # print "List of Mininet switch DPID's"
1295 # print mnDPIDs
1296 if switches_json == "": # if rest call fails
1297 main.log.error(
1298 self.name +
1299 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001300 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001301 onos = switches_json
1302 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001303 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001304 if switch[ 'available' ]:
1305 onosDPIDs.append(
1306 switch[ 'id' ].replace(
1307 ":",
1308 '' ).replace(
1309 "of",
1310 '' ).lower() )
1311 # else:
1312 # print "Switch is unavailable:"
1313 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001314 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001315 # print "List of ONOS switch DPID's"
1316 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001317
Jon Hall7eb38402015-01-08 17:19:54 -08001318 if mnDPIDs != onosDPIDs:
Jon Hall3d87d502014-10-17 18:37:42 -04001319 switch_results = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001320 main.log.report( "Switches in MN but not in ONOS:" )
1321 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1322 main.log.report( str( list1 ) )
1323 main.log.report( "Switches in ONOS but not in MN:" )
1324 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001325 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001326 else: # list of dpid's match in onos and mn
Jon Hall3d87d502014-10-17 18:37:42 -04001327 switch_results = main.TRUE
1328 return switch_results
1329
Jon Hall7eb38402015-01-08 17:19:54 -08001330 def compare_ports( self, topo, ports_json ):
1331 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001332 Compare mn and onos ports
1333 topo: sts TestONTopology object
1334 ports_json: parsed json object from the onos ports api
1335
Jon Hallfbc828e2015-01-06 17:30:19 -08001336 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001337 1. This uses the sts TestONTopology object
1338 2. numpy - "sudo pip install numpy"
1339
Jon Hall7eb38402015-01-08 17:19:54 -08001340 """
1341 # FIXME: this does not look for extra ports in ONOS, only checks that
1342 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001343 from numpy import uint64
Jon Hallb1290e82014-11-18 16:17:48 -05001344 ports_results = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001345 output = { "switches": [] }
1346 # iterate through the MN topology and pull out switches and and port
1347 # info
1348 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001349 ports = []
1350 for port in switch.ports.values():
Jon Hall7eb38402015-01-08 17:19:54 -08001351 # print port.hw_addr.toStr( separator='' )
Jon Hall39f29df2014-11-04 19:30:21 -05001352 tmp_port = {}
Jon Hall7eb38402015-01-08 17:19:54 -08001353 tmp_port[ 'of_port' ] = port.port_no
1354 tmp_port[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
1355 tmp_port[ 'name' ] = port.name
1356 tmp_port[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001357
Jon Hall7eb38402015-01-08 17:19:54 -08001358 ports.append( tmp_port )
Jon Hall39f29df2014-11-04 19:30:21 -05001359 tmp_switch = {}
Jon Hall7eb38402015-01-08 17:19:54 -08001360 tmp_switch[ 'name' ] = switch.name
1361 tmp_switch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1362 tmp_switch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001363
Jon Hall7eb38402015-01-08 17:19:54 -08001364 output[ 'switches' ].append( tmp_switch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001365
Jon Hall7eb38402015-01-08 17:19:54 -08001366 # PORTS
1367 for mn_switch in output[ 'switches' ]:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001368 mn_ports = []
1369 onos_ports = []
Jon Hallb1290e82014-11-18 16:17:48 -05001370 switch_result = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001371 for port in mn_switch[ 'ports' ]:
1372 if port[ 'enabled' ]:
1373 mn_ports.append( port[ 'of_port' ] )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001374 for onos_switch in ports_json:
Jon Hall7eb38402015-01-08 17:19:54 -08001375 # print "Iterating through a new switch as seen by ONOS"
1376 # print onos_switch
1377 if onos_switch[ 'device' ][ 'available' ]:
1378 if onos_switch[ 'device' ][ 'id' ].replace(
1379 ':',
1380 '' ).replace(
1381 "of",
1382 '' ) == mn_switch[ 'dpid' ]:
1383 for port in onos_switch[ 'ports' ]:
1384 if port[ 'isEnabled' ]:
1385 if port[ 'port' ] == 'local':
1386 # onos_ports.append( 'local' )
1387 onos_ports.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001388 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001389 onos_ports.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001390 break
Jon Hall7eb38402015-01-08 17:19:54 -08001391 mn_ports.sort( key=float )
1392 onos_ports.sort( key=float )
1393 # print "\nPorts for Switch %s:" % ( mn_switch[ 'name' ] )
1394 # print "\tmn_ports[] = ", mn_ports
1395 # print "\tonos_ports[] = ", onos_ports
Jon Hallb1290e82014-11-18 16:17:48 -05001396 mn_ports_log = mn_ports
1397 onos_ports_log = onos_ports
Jon Hall7eb38402015-01-08 17:19:54 -08001398 mn_ports = [ x for x in mn_ports ]
1399 onos_ports = [ x for x in onos_ports ]
Jon Hall38481722014-11-04 16:50:05 -05001400
Jon Hall7eb38402015-01-08 17:19:54 -08001401 # TODO: handle other reserved port numbers besides LOCAL
1402 # NOTE: Reserved ports
1403 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1404 # long( uint64( -2 ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001405 for mn_port in mn_ports_log:
1406 if mn_port in onos_ports:
Jon Hall7eb38402015-01-08 17:19:54 -08001407 # don't set results to true here as this is just one of
1408 # many checks and it might override a failure
1409 mn_ports.remove( mn_port )
1410 onos_ports.remove( mn_port )
1411 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001412 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001413 # TODO: Come up with a better way of handling these
Jon Hallb1290e82014-11-18 16:17:48 -05001414 if 65534 in mn_ports:
Jon Hall7eb38402015-01-08 17:19:54 -08001415 mn_ports.remove( 65534 )
1416 if long( uint64( -2 ) ) in onos_ports:
1417 onos_ports.remove( long( uint64( -2 ) ) )
1418 if len( mn_ports ): # the ports of this switch don't match
Jon Hallb1290e82014-11-18 16:17:48 -05001419 switch_result = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001420 main.log.warn( "Ports in MN but not ONOS: " + str( mn_ports ) )
1421 if len( onos_ports ): # the ports of this switch don't match
Jon Hallb1290e82014-11-18 16:17:48 -05001422 switch_result = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001423 main.log.warn(
1424 "Ports in ONOS but not MN: " +
1425 str( onos_ports ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001426 if switch_result == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001427 main.log.report(
1428 "The list of ports for switch %s(%s) does not match:" %
1429 ( mn_switch[ 'name' ], mn_switch[ 'dpid' ] ) )
1430 main.log.warn( "mn_ports[] = " + str( mn_ports_log ) )
1431 main.log.warn( "onos_ports[] = " + str( onos_ports_log ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001432 ports_results = ports_results and switch_result
1433 return ports_results
Jon Hall72cf1dc2014-10-20 21:04:50 -04001434
Jon Hall7eb38402015-01-08 17:19:54 -08001435 def compare_links( self, topo, links_json ):
1436 """
1437 Compare mn and onos links
1438 topo: sts TestONTopology object
1439 links_json: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001440
Jon Hall7eb38402015-01-08 17:19:54 -08001441 This uses the sts TestONTopology object"""
1442 # FIXME: this does not look for extra links in ONOS, only checks that
1443 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001444 link_results = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001445 output = { "switches": [] }
Jon Hall72cf1dc2014-10-20 21:04:50 -04001446 onos = links_json
Jon Hall7eb38402015-01-08 17:19:54 -08001447 # iterate through the MN topology and pull out switches and and port
1448 # info
1449 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001450 # print "Iterating though switches as seen by Mininet"
1451 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001452 ports = []
1453 for port in switch.ports.values():
Jon Hall7eb38402015-01-08 17:19:54 -08001454 # print port.hw_addr.toStr( separator='' )
1455 ports.append( { 'of_port': port.port_no,
1456 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabedcff052015-01-16 12:53:55 -08001457 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001458 'name': port.name } )
1459 output[ 'switches' ].append( {
1460 "name": switch.name,
1461 "dpid": str( switch.dpid ).zfill( 16 ),
1462 "ports": ports } )
1463 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001464
Jon Hall7eb38402015-01-08 17:19:54 -08001465 mn_links = [
1466 link for link in topo.patch_panel.network_links if (
1467 link.port1.enabled and link.port2.enabled ) ]
1468 if 2 * len( mn_links ) == len( onos ):
Jon Hall72cf1dc2014-10-20 21:04:50 -04001469 link_results = main.TRUE
1470 else:
1471 link_results = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001472 main.log.report(
1473 "Mininet has %i bidirectional links and " +
1474 "ONOS has %i unidirectional links" %
1475 ( len( mn_links ), len( onos ) ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001476
Jon Hall7eb38402015-01-08 17:19:54 -08001477 # iterate through MN links and check if an ONOS link exists in
1478 # both directions
1479 # NOTE: Will currently only show mn links as down if they are
1480 # cut through STS. We can either do everything through STS or
1481 # wait for up_network_links and down_network_links to be
1482 # fully implemented.
Jon Hallfbc828e2015-01-06 17:30:19 -08001483 for link in mn_links:
Jon Hall7eb38402015-01-08 17:19:54 -08001484 # print "Link: %s" % link
1485 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001486 node1 = None
1487 port1 = None
1488 node2 = None
1489 port2 = None
1490 first_dir = main.FALSE
1491 second_dir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001492 for switch in output[ 'switches' ]:
1493 # print "Switch: %s" % switch[ 'name' ]
1494 if switch[ 'name' ] == link.node1.name:
1495 node1 = switch[ 'dpid' ]
1496 for port in switch[ 'ports' ]:
1497 if str( port[ 'name' ] ) == str( link.port1 ):
1498 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001499 if node1 is not None and node2 is not None:
1500 break
Jon Hall7eb38402015-01-08 17:19:54 -08001501 if switch[ 'name' ] == link.node2.name:
1502 node2 = switch[ 'dpid' ]
1503 for port in switch[ 'ports' ]:
1504 if str( port[ 'name' ] ) == str( link.port2 ):
1505 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001506 if node1 is not None and node2 is not None:
1507 break
1508
Jon Hall72cf1dc2014-10-20 21:04:50 -04001509 for onos_link in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001510 onos_node1 = onos_link[ 'src' ][ 'device' ].replace(
1511 ":",
1512 '' ).replace(
1513 "of",
1514 '' )
1515 onos_node2 = onos_link[ 'dst' ][ 'device' ].replace(
1516 ":",
1517 '' ).replace(
1518 "of",
1519 '' )
1520 onos_port1 = onos_link[ 'src' ][ 'port' ]
1521 onos_port2 = onos_link[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001522
Jon Hall72cf1dc2014-10-20 21:04:50 -04001523 # check onos link from node1 to node2
Jon Hall7eb38402015-01-08 17:19:54 -08001524 if str( onos_node1 ) == str( node1 ) and str(
1525 onos_node2 ) == str( node2 ):
1526 if int( onos_port1 ) == int( port1 ) and int(
1527 onos_port2 ) == int( port2 ):
Jon Hall72cf1dc2014-10-20 21:04:50 -04001528 first_dir = main.TRUE
1529 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001530 main.log.warn(
1531 'The port numbers do not match for ' +
1532 str( link ) +
1533 ' between ONOS and MN. When cheking ONOS for ' +
1534 'link %s/%s -> %s/%s' %
1535 ( node1,
1536 port1,
1537 node2,
1538 port2 ) +
1539 ' ONOS has the values %s/%s -> %s/%s' %
1540 ( onos_node1,
1541 onos_port1,
1542 onos_node2,
1543 onos_port2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001544
1545 # check onos link from node2 to node1
Jon Hall7eb38402015-01-08 17:19:54 -08001546 elif ( str( onos_node1 ) == str( node2 ) and
1547 str( onos_node2 ) == str( node1 ) ):
1548 if ( int( onos_port1 ) == int( port2 )
kelvin-onlabedcff052015-01-16 12:53:55 -08001549 and int( onos_port2 ) == int( port1 ) ):
Jon Hall72cf1dc2014-10-20 21:04:50 -04001550 second_dir = main.TRUE
1551 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001552 main.log.warn(
1553 'The port numbers do not match for ' +
1554 str( link ) +
1555 ' between ONOS and MN. When cheking ONOS for ' +
1556 'link %s/%s -> %s/%s' %
1557 ( node2,
1558 port2,
1559 node1,
1560 port1 ) +
1561 ' ONOS has the values %s/%s -> %s/%s' %
1562 ( onos_node2,
1563 onos_port2,
1564 onos_node1,
1565 onos_port1 ) )
1566 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001567 pass
1568 if not first_dir:
Jon Hall7eb38402015-01-08 17:19:54 -08001569 main.log.report(
1570 'ONOS does not have the link %s/%s -> %s/%s' %
1571 ( node1, port1, node2, port2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001572 if not second_dir:
Jon Hall7eb38402015-01-08 17:19:54 -08001573 main.log.report(
1574 'ONOS does not have the link %s/%s -> %s/%s' %
1575 ( node2, port2, node1, port1 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001576 link_results = link_results and first_dir and second_dir
Jon Hall62df9242014-10-22 12:20:17 -04001577 return link_results
Jon Hall72cf1dc2014-10-20 21:04:50 -04001578
Jon Hall7eb38402015-01-08 17:19:54 -08001579 def get_hosts( self ):
1580 """
1581 Returns a list of all hosts
1582 Don't ask questions just use it"""
1583 self.handle.sendline( "" )
1584 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001585
Jon Hall7eb38402015-01-08 17:19:54 -08001586 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1587 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001588
andrewonlab3f0a4af2014-10-17 12:25:14 -04001589 handle_py = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001590 handle_py = handle_py.split( "]\r\n", 1 )[ 1 ]
andrewonlab3f0a4af2014-10-17 12:25:14 -04001591 handle_py = handle_py.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001592
Jon Hall7eb38402015-01-08 17:19:54 -08001593 self.handle.sendline( "" )
1594 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001595
Jon Hall7eb38402015-01-08 17:19:54 -08001596 host_str = handle_py.replace( "]", "" )
1597 host_str = host_str.replace( "'", "" )
1598 host_str = host_str.replace( "[", "" )
1599 host_list = host_str.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001600
Jon Hallfbc828e2015-01-06 17:30:19 -08001601 return host_list
adminbae64d82013-08-01 10:50:15 -07001602
Jon Hall7eb38402015-01-08 17:19:54 -08001603 def update( self ):
1604 """
1605 updates the port address and status information for
1606 each port in mn"""
1607 # TODO: Add error checking. currently the mininet command has no output
1608 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001609 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001610 self.handle.sendline( "" )
1611 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001612
Jon Hall7eb38402015-01-08 17:19:54 -08001613 self.handle.sendline( "update" )
1614 self.handle.expect( "update" )
1615 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001616
Jon Hall7eb38402015-01-08 17:19:54 -08001617 self.handle.sendline( "" )
1618 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001619
Jon Hallb1290e82014-11-18 16:17:48 -05001620 return main.TRUE
1621 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001622 main.log.error( self.name + ": EOF exception found" )
1623 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001624 main.cleanup()
1625 main.exit()
1626
adminbae64d82013-08-01 10:50:15 -07001627if __name__ != "__main__":
1628 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001629 sys.modules[ __name__ ] = MininetCliDriver()