blob: ae1213932941056fd460386f1e2355a0b2b622cf [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
Jon Hallbe6dfc42015-01-12 17:37:25 -080021MininetCliDriver is the basic driver which will handle the Mininet functions
22
23Some functions rely on a modified version of Mininet. These functions
24should all be noted in the comments. To get this MN version run these commands
25from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080026 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080027 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080028 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git pull
30
Jon Hall272a4db2015-01-12 17:43:48 -080031
32 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080033changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070034import pexpect
adminbae64d82013-08-01 10:50:15 -070035import re
36import sys
Jon Hall7eb38402015-01-08 17:19:54 -080037sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040038from math import pow
adminbae64d82013-08-01 10:50:15 -070039from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070040
Jon Hall7eb38402015-01-08 17:19:54 -080041
kelvin-onlab50907142015-04-01 13:37:45 -070042class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080043
44 """
45 MininetCliDriver is the basic driver which will handle
46 the Mininet functions"""
47 def __init__( self ):
48 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070049 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080050 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080051 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070052 self.flag = 0
53
Jon Hall7eb38402015-01-08 17:19:54 -080054 def connect( self, **connectargs ):
55 """
56 Here the main is the TestON instance after creating
57 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080058 try:
59 for key in connectargs:
60 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080061
kelvin-onlaba1484582015-02-02 15:46:20 -080062 self.name = self.options[ 'name' ]
63 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070064 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080065 self ).connect(
66 user_name=self.user_name,
67 ip_address=self.ip_address,
68 port=None,
69 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080070
kelvin-onlaba1484582015-02-02 15:46:20 -080071 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080072 main.log.info( "Connection successful to the host " +
73 self.user_name +
74 "@" +
75 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080076 return main.TRUE
77 else:
78 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080079 self.user_name +
80 "@" +
81 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080082 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -080083 return main.FALSE
84 except pexpect.EOF:
85 main.log.error( self.name + ": EOF exception found" )
86 main.log.error( self.name + ": " + self.handle.before )
87 main.cleanup()
88 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080089 except Exception:
90 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -080091 main.cleanup()
92 main.exit()
93
Jon Hallefbd9792015-03-05 16:11:36 -080094 def startNet( self, topoFile='', args='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -080095 """
96 Starts Mininet accepts a topology(.py) file and/or an optional
Jon Hallefbd9792015-03-05 16:11:36 -080097 argument ,to start the mininet, as a parameter.
Jon Hall21270ac2015-02-16 17:59:55 -080098 Returns main.TRUE if the mininet starts successfully and
99 main.FALSE otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800100 """
Jon Hall7eb38402015-01-08 17:19:54 -0800101 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700102 # make sure old networks are cleaned up
103 main.log.info( self.name +
104 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800105 self.handle.sendline( "sudo mn -c" )
106 i = self.handle.expect( [ 'password\sfor\s',
107 'Cleanup\scomplete',
108 pexpect.EOF,
109 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800110 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800111 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700112 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800113 main.log.info( self.name + ": Sending sudo password" )
114 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800115 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800116 '\$',
117 pexpect.EOF,
118 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800119 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800120 if i == 1:
121 main.log.info( self.name + ": Clean" )
122 elif i == 2:
123 main.log.error( self.name + ": Connection terminated" )
124 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700125 main.log.error( self.name + ": Something while cleaning " +
126 "Mininet took too long... " )
127 # Craft the string to start mininet
128 cmdString = "sudo "
129 if topoFile is None or topoFile == '': # If no file is given
130 main.log.info( self.name + ": building fresh Mininet" )
131 cmdString += "mn "
132 if args is None or args == '':
133 # If no args given, use args from .topo file
134 args = self.options[ 'arg1' ] +\
135 " " + self.options[ 'arg2' ] +\
136 " --mac --controller " +\
137 self.options[ 'controller' ] + " " +\
138 self.options[ 'arg3' ]
139 else: # else only use given args
140 pass
141 # TODO: allow use of topo args and method args?
142 else: # Use given topology file
143 main.log.info( "Starting Mininet from topo file " + topoFile )
144 cmdString += topoFile + " "
Jon Hallefbd9792015-03-05 16:11:36 -0800145 if args is None:
kelvin-onlaba1484582015-02-02 15:46:20 -0800146 args = ''
Jon Hall689d8e42015-04-03 13:59:24 -0700147 # TODO: allow use of args from .topo file?
148 cmdString += args
149 # Send the command and check if network started
150 self.handle.sendline( "" )
151 self.handle.expect( '\$' )
152 main.log.info( "Sending '" + cmdString + "' to " + self.name )
153 self.handle.sendline( cmdString )
154 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800155 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700156 'Exception',
157 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800158 pexpect.EOF,
159 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700160 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800161 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700162 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800163 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800164 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700165 response = str( self.handle.before +
166 self.handle.after )
167 self.handle.expect( '\$' )
168 response += str( self.handle.before +
169 self.handle.after )
170 main.log.error(
171 self.name +
172 ": Launching Mininet failed: " + response )
173 return main.FALSE
174 elif i == 2:
175 self.handle.expect( [ "\n",
176 pexpect.EOF,
177 pexpect.TIMEOUT ],
178 timeout )
179 main.log.info( self.handle.before )
180 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800181 main.log.error( self.name + ": Connection timeout" )
182 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700183 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800184 main.log.error(
185 self.name +
186 ": Something took too long... " )
187 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700188 # Why did we hit this part?
189 main.log.error( "startNet did not return correctly" )
190 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800191 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700192 main.log.error( self.name + ": Connection failed to the host " +
193 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800194 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700195 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800196
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800197 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400198 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800199 # In tree topology, if fanout arg is not given, by default it is 2
200 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400201 fanout = 2
202 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500203 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800204 while( k <= depth - 1 ):
205 count = count + pow( fanout, k )
206 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800207 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800208 while( k <= depth - 2 ):
209 # depth-2 gives you only core links and not considering
210 # edge links as seen by ONOS. If all the links including
211 # edge links are required, do depth-1
212 count = count + pow( fanout, k )
213 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800214 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800215 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800217
Jon Hall7eb38402015-01-08 17:19:54 -0800218 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800219 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800220 # by default it is 1
221 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400222 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 numSwitches = depth
224 numHostsPerSw = fanout
225 totalNumHosts = numSwitches * numHostsPerSw
226 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800227 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800229 topoDict = { "num_switches": int( numSwitches ),
230 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400231 return topoDict
232
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700234 """
235 Calculate the number of switches and links in a topo."""
236 # TODO: combine this function and numSwitchesNlinks
237 argList = self.options[ 'arg1' ].split( "," )
238 topoArgList = argList[ 0 ].split( " " )
239 argList = map( int, argList[ 1: ] )
240 topoArgList = topoArgList[ 1: ] + argList
241
242 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400243 return topoDict
244
kelvin-onlabc44f0192015-04-02 22:08:41 -0700245 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0):
Jon Hall7eb38402015-01-08 17:19:54 -0800246 """
247 Verifies the reachability of the hosts using pingall command.
248 Optional parameter timeout allows you to specify how long to
249 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700250 Optional:
Jon Hall390696c2015-05-05 17:13:41 -0700251 timeout(seconds) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700252 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700253 ping
254 acceptableFailed - Set the number of acceptable failed pings for the
255 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800256 Returns:
257 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700258 otherwise main.FALSE
259 """
260 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700261 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700262 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700263 if self.handle:
264 main.log.info(
265 self.name +
266 ": Checking reachabilty to the hosts using pingall" )
267 response = ""
268 failedPings = 0
269 returnValue = main.TRUE
270 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700271 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700272 while True:
273 i = self.handle.expect( [ "mininet>","X",
274 pexpect.EOF,
275 pexpect.TIMEOUT ],
276 timeout )
277 if i == 0:
278 main.log.info( self.name + ": pingall finished")
279 response += self.handle.before
280 break
281 elif i == 1:
282 response += self.handle.before + self.handle.after
283 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700284 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700285 returnValue = main.FALSE
286 if shortCircuit:
287 main.log.error( self.name +
288 ": Aborting pingall - "
289 + str( failedPings ) +
290 " pings failed" )
291 break
Jon Hall390696c2015-05-05 17:13:41 -0700292 if ( time.time() - startTime ) > timeout:
293 returnValue = main.FALSE
294 main.log.error( self.name +
295 ": Aborting pingall - " +
296 "Function took too long " )
297 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700298 elif i == 2:
299 main.log.error( self.name +
300 ": EOF exception found" )
301 main.log.error( self.name + ": " +
302 self.handle.before )
303 main.cleanup()
304 main.exit()
305 elif i == 3:
306 response += self.handle.before
307 main.log.error( self.name +
308 ": TIMEOUT exception found" )
309 main.log.error( self.name +
310 ": " +
311 str( response ) )
312 # NOTE: Send ctrl-c to make sure pingall is done
313 self.handle.sendline( "\x03" )
314 self.handle.expect( "Interrupt" )
315 self.handle.expect( "mininet>" )
316 break
317 pattern = "Results\:"
318 main.log.info( "Pingall output: " + str( response ) )
319 if re.search( pattern, response ):
320 main.log.info( self.name + ": Pingall finished with "
321 + str( failedPings ) + " failed pings" )
322 return returnValue
323 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700324 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700325 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700326 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700327 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700328 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700329 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700330 main.log.error( self.name + ": Connection failed to the host" )
331 main.cleanup()
332 main.exit()
333 except pexpect.TIMEOUT:
334 if response:
335 main.log.info( "Pingall output: " + str( response ) )
336 main.log.error( self.name + ": pexpect.TIMEOUT found" )
337 return main.FALSE
338 except pexpect.EOF:
339 main.log.error( self.name + ": EOF exception found" )
340 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500341 main.cleanup()
342 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700343
Jon Hall7eb38402015-01-08 17:19:54 -0800344 def fpingHost( self, **pingParams ):
345 """
346 Uses the fping package for faster pinging...
347 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800348 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800349 command = args[ "SRC" ] + \
350 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
351 self.handle.sendline( command )
352 self.handle.expect(
353 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
354 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
355 response = self.handle.before
356 if re.search( ":\s-", response ):
357 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700358 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800359 elif re.search( ":\s\d{1,2}\.\d\d", response ):
360 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700361 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800362 main.log.info( self.name + ": Install fping on mininet machine... " )
363 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700364 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800365
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400366 def pingallHosts( self, hostList, pingType='ipv4' ):
367 """
Jon Hallb6a54872015-06-12 14:02:42 -0700368 Ping all specified hosts with a specific ping type
369
370 Acceptable pingTypes:
371 - 'ipv4'
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400372 - 'ipv6'
Jon Hallb6a54872015-06-12 14:02:42 -0700373
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400374 Acceptable hostList:
375 - ['h1','h2','h3','h4']
Jon Hallb6a54872015-06-12 14:02:42 -0700376
377 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400378 each other
Jon Hallb6a54872015-06-12 14:02:42 -0700379
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400380 Returns main.FALSE if one or more of hosts specified
381 cannot reach each other"""
Jon Hallb6a54872015-06-12 14:02:42 -0700382
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400383 if pingType == "ipv4":
Jon Hallb6a54872015-06-12 14:02:42 -0700384 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400385 elif pingType == "ipv6":
386 cmd = " ping6 -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400387 else:
388 main.log.warn( "Invalid pingType specified" )
389 return
390
391 try:
392 main.log.info( "Testing reachability between specified hosts" )
Jon Hallb6a54872015-06-12 14:02:42 -0700393
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400394 isReachable = main.TRUE
395
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400396 for host in hostList:
397 listIndex = hostList.index(host)
398 # List of hosts to ping other than itself
399 pingList = hostList[:listIndex] + hostList[(listIndex+1):]
Jon Hallb6a54872015-06-12 14:02:42 -0700400
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400401 for temp in pingList:
402 # Current host pings all other hosts specified
Jon Hallb6a54872015-06-12 14:02:42 -0700403 pingCmd = str(host) + cmd + str(temp)
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400404 self.handle.sendline( pingCmd )
405 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
406 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
407 response = self.handle.before
408 if re.search( ',\s0\%\spacket\sloss', response ):
409 main.log.info( str(host) + " -> " + str(temp) )
410 else:
411 main.log.info( str(host) + " -> X ("+str(temp)+") "
Jon Hallb6a54872015-06-12 14:02:42 -0700412 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400413 # One of the host to host pair is unreachable
414 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400415
Jon Hallb6a54872015-06-12 14:02:42 -0700416 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400417
418 except pexpect.EOF:
419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
421 main.cleanup()
422 main.exit()
423
Jon Hall7eb38402015-01-08 17:19:54 -0800424 def pingHost( self, **pingParams ):
425 """
426 Ping from one mininet host to another
427 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800428 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800429 command = args[ "SRC" ] + " ping " + \
430 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700431 try:
Jon Hall61282e32015-03-19 11:34:11 -0700432 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800433 self.handle.sendline( command )
434 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700435 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800436 main.log.error(
437 self.name +
438 ": timeout when waiting for response from mininet" )
439 main.log.error( "response: " + str( self.handle.before ) )
440 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700441 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800442 main.log.error(
443 self.name +
444 ": timeout when waiting for response from mininet" )
445 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700446 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800447 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800448 main.log.error( self.name + ": EOF exception found" )
449 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700450 main.cleanup()
451 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800452 main.log.info( self.name + ": Ping Response: " + response )
453 if re.search( ',\s0\%\spacket\sloss', response ):
454 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800455 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700456 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800457 else:
458 main.log.error(
459 self.name +
460 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800461 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700462 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800463
Jon Hall7eb38402015-01-08 17:19:54 -0800464 def checkIP( self, host ):
465 """
466 Verifies the host's ip configured or not."""
467 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700468 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800469 response = self.execute(
470 cmd=host +
471 " ifconfig",
472 prompt="mininet>",
473 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800474 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800475 main.log.error( self.name + ": EOF exception found" )
476 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700477 main.cleanup()
478 main.exit()
adminbae64d82013-08-01 10:50:15 -0700479
Jon Hall7eb38402015-01-08 17:19:54 -0800480 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800481 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
482 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
483 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
484 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
485 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800486 # pattern = "inet addr:10.0.0.6"
487 if re.search( pattern, response ):
488 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700489 return main.TRUE
490 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800491 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700492 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800493 else:
494 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800495
Jon Hall7eb38402015-01-08 17:19:54 -0800496 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800497 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700498 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800499 response = self.execute(
500 cmd="h1 /usr/sbin/sshd -D&",
501 prompt="mininet>",
502 timeout=10 )
503 response = self.execute(
504 cmd="h4 /usr/sbin/sshd -D&",
505 prompt="mininet>",
506 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700507 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800508 vars( self )[ key ] = connectargs[ key ]
509 response = self.execute(
510 cmd="xterm h1 h4 ",
511 prompt="mininet>",
512 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800513 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800514 main.log.error( self.name + ": EOF exception found" )
515 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700516 main.cleanup()
517 main.exit()
adminbae64d82013-08-01 10:50:15 -0700518 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800519 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700520 if self.flag == 0:
521 self.flag = 1
522 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800523 else:
adminbae64d82013-08-01 10:50:15 -0700524 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800525
kelvin-onlaba1484582015-02-02 15:46:20 -0800526 def moveHost( self, host, oldSw, newSw, ):
527 """
528 Moves a host from one switch to another on the fly
529 Note: The intf between host and oldSw when detached
530 using detach(), will still show up in the 'net'
531 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Hallb6a54872015-06-12 14:02:42 -0700532 (which is correct behavior since the interfaces
kelvin-onlaba1484582015-02-02 15:46:20 -0800533 haven't moved).
534 """
535 if self.handle:
536 try:
537 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800538 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
539 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800540 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800541 response = self.execute( cmd=cmd,
542 prompt="mininet>",
543 timeout=10 )
Jon Hallb6a54872015-06-12 14:02:42 -0700544
kelvin-onlaba1484582015-02-02 15:46:20 -0800545 # Determine hostintf and Oldswitchintf
546 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800547 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800548 print "cmd2= ", cmd
549 self.handle.sendline( cmd )
550 self.handle.expect( "mininet>" )
551
shahshreya73537862015-02-11 15:15:24 -0800552 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800553 cmd = "px ipaddr = hintf.IP()"
554 print "cmd3= ", cmd
555 self.handle.sendline( cmd )
556 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800557
558 cmd = "px macaddr = hintf.MAC()"
559 print "cmd3= ", cmd
560 self.handle.sendline( cmd )
561 self.handle.expect( "mininet>" )
Jon Hallb6a54872015-06-12 14:02:42 -0700562
kelvin-onlaba1484582015-02-02 15:46:20 -0800563 # Detach interface between oldSw-host
564 cmd = "px " + oldSw + ".detach( sintf )"
565 print "cmd4= ", cmd
566 self.handle.sendline( cmd )
567 self.handle.expect( "mininet>" )
568
569 # Add link between host-newSw
570 cmd = "py net.addLink(" + host + "," + newSw + ")"
571 print "cmd5= ", cmd
572 self.handle.sendline( cmd )
573 self.handle.expect( "mininet>" )
Jon Hallb6a54872015-06-12 14:02:42 -0700574
kelvin-onlaba1484582015-02-02 15:46:20 -0800575 # Determine hostintf and Newswitchintf
576 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800577 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800578 print "cmd6= ", cmd
579 self.handle.sendline( cmd )
Jon Hallb6a54872015-06-12 14:02:42 -0700580 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800581
582 # Attach interface between newSw-host
583 cmd = "px " + newSw + ".attach( sintf )"
584 print "cmd3= ", cmd
585 self.handle.sendline( cmd )
586 self.handle.expect( "mininet>" )
Jon Hallb6a54872015-06-12 14:02:42 -0700587
kelvin-onlaba1484582015-02-02 15:46:20 -0800588 # Set ipaddress of the host-newSw interface
589 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
590 print "cmd7 = ", cmd
591 self.handle.sendline( cmd )
592 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800593
594 # Set macaddress of the host-newSw interface
595 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
596 print "cmd8 = ", cmd
597 self.handle.sendline( cmd )
598 self.handle.expect( "mininet>" )
Jon Hallb6a54872015-06-12 14:02:42 -0700599
kelvin-onlaba1484582015-02-02 15:46:20 -0800600 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800601 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800602 self.handle.sendline( cmd )
603 self.handle.expect( "mininet>" )
604 print "output = ", self.handle.before
605
606 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800607 cmd = host + " ifconfig"
608 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800609 self.handle.sendline( cmd )
610 self.handle.expect( "mininet>" )
611 print "ifconfig o/p = ", self.handle.before
Jon Hallb6a54872015-06-12 14:02:42 -0700612
kelvin-onlaba1484582015-02-02 15:46:20 -0800613 return main.TRUE
614 except pexpect.EOF:
615 main.log.error( self.name + ": EOF exception found" )
616 main.log.error( self.name + ": " + self.handle.before )
617 return main.FALSE
618
Jon Hall7eb38402015-01-08 17:19:54 -0800619 def changeIP( self, host, intf, newIP, newNetmask ):
620 """
621 Changes the ip address of a host on the fly
622 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800623 if self.handle:
624 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800625 cmd = host + " ifconfig " + intf + " " + \
626 newIP + " " + 'netmask' + " " + newNetmask
627 self.handle.sendline( cmd )
628 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800629 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800630 main.log.info( "response = " + response )
631 main.log.info(
632 "Ip of host " +
633 host +
634 " changed to new IP " +
635 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800636 return main.TRUE
637 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800638 main.log.error( self.name + ": EOF exception found" )
639 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800640 return main.FALSE
641
Jon Hall7eb38402015-01-08 17:19:54 -0800642 def changeDefaultGateway( self, host, newGW ):
643 """
644 Changes the default gateway of a host
645 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800646 if self.handle:
647 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800648 cmd = host + " route add default gw " + newGW
649 self.handle.sendline( cmd )
650 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800651 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800652 main.log.info( "response = " + response )
653 main.log.info(
654 "Default gateway of host " +
655 host +
656 " changed to " +
657 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800658 return main.TRUE
659 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800660 main.log.error( self.name + ": EOF exception found" )
661 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800662 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800663
Jon Hall7eb38402015-01-08 17:19:54 -0800664 def addStaticMACAddress( self, host, GW, macaddr ):
665 """
Jon Hallefbd9792015-03-05 16:11:36 -0800666 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800667 if self.handle:
668 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800669 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
670 cmd = host + " arp -s " + GW + " " + macaddr
671 self.handle.sendline( cmd )
672 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800673 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800674 main.log.info( "response = " + response )
675 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800676 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800677 GW +
678 " changed to " +
679 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800680 return main.TRUE
681 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800684 return main.FALSE
685
Jon Hall7eb38402015-01-08 17:19:54 -0800686 def verifyStaticGWandMAC( self, host ):
687 """
688 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800689 if self.handle:
690 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800691 # h1 arp -an
692 cmd = host + " arp -an "
693 self.handle.sendline( cmd )
694 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800695 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800696 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800697 return main.TRUE
698 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800701 return main.FALSE
702
Jon Hall7eb38402015-01-08 17:19:54 -0800703 def getMacAddress( self, host ):
704 """
705 Verifies the host's ip configured or not."""
706 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700707 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800708 response = self.execute(
709 cmd=host +
710 " ifconfig",
711 prompt="mininet>",
712 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800713 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700716 main.cleanup()
717 main.exit()
adminbae64d82013-08-01 10:50:15 -0700718
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700719 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 macAddressSearch = re.search( pattern, response, re.I )
721 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800722 main.log.info(
723 self.name +
724 ": Mac-Address of Host " +
725 host +
726 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 macAddress )
728 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700729 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800730 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700731
Jon Hall7eb38402015-01-08 17:19:54 -0800732 def getInterfaceMACAddress( self, host, interface ):
733 """
734 Return the IP address of the interface on the given host"""
735 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700736 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800737 response = self.execute( cmd=host + " ifconfig " + interface,
738 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800739 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.error( self.name + ": EOF exception found" )
741 main.log.error( self.name + ": " + self.handle.before )
742 main.cleanup()
743 main.exit()
744
745 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 macAddressSearch = re.search( pattern, response, re.I )
747 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.info( "No mac address found in %s" % response )
749 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800751 main.log.info(
752 "Mac-Address of " +
753 host +
754 ":" +
755 interface +
756 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800757 macAddress )
758 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800759 else:
760 main.log.error( "Connection failed to the host" )
761
762 def getIPAddress( self, host ):
763 """
764 Verifies the host's ip configured or not."""
765 if self.handle:
766 try:
767 response = self.execute(
768 cmd=host +
769 " ifconfig",
770 prompt="mininet>",
771 timeout=10 )
772 except pexpect.EOF:
773 main.log.error( self.name + ": EOF exception found" )
774 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700775 main.cleanup()
776 main.exit()
adminbae64d82013-08-01 10:50:15 -0700777
778 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800779 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800780 main.log.info(
781 self.name +
782 ": IP-Address of Host " +
783 host +
784 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 ipAddressSearch.group( 1 ) )
786 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800787 else:
788 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800789
Jon Hall7eb38402015-01-08 17:19:54 -0800790 def getSwitchDPID( self, switch ):
791 """
792 return the datapath ID of the switch"""
793 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700794 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700795 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800796 response = self.execute(
797 cmd=cmd,
798 prompt="mininet>",
799 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800800 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700803 main.cleanup()
804 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800805 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800806 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700807 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800808 main.log.info(
809 "Couldn't find DPID for switch %s, found: %s" %
810 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700811 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800812 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700813 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700815
Jon Hall7eb38402015-01-08 17:19:54 -0800816 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700817 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800818 self.handle.sendline( "" )
819 self.expect( "mininet>" )
820 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700821 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800822 response = self.execute(
823 cmd=cmd,
824 prompt="mininet>",
825 timeout=10 )
826 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700827 response = self.handle.before
828 return response
829 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800830 main.log.error( self.name + ": EOF exception found" )
831 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700832 main.cleanup()
833 main.exit()
834
Jon Hall7eb38402015-01-08 17:19:54 -0800835 def getInterfaces( self, node ):
836 """
837 return information dict about interfaces connected to the node"""
838 if self.handle:
839 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800840 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700841 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700842 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800843 response = self.execute(
844 cmd=cmd,
845 prompt="mininet>",
846 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800847 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800848 main.log.error( self.name + ": EOF exception found" )
849 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700850 main.cleanup()
851 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700852 return response
853 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800854 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700855
Jon Hall7eb38402015-01-08 17:19:54 -0800856 def dump( self ):
857 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700858 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800859 response = self.execute(
860 cmd='dump',
861 prompt='mininet>',
862 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800863 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()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700868 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800869
Jon Hall7eb38402015-01-08 17:19:54 -0800870 def intfs( self ):
871 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700872 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800873 response = self.execute(
874 cmd='intfs',
875 prompt='mininet>',
876 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800877 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800878 main.log.error( self.name + ": EOF exception found" )
879 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700880 main.cleanup()
881 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700882 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800883
Jon Hall7eb38402015-01-08 17:19:54 -0800884 def net( self ):
885 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700886 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800888 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800889 main.log.error( self.name + ": EOF exception found" )
890 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700891 main.cleanup()
892 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700893 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800894
Jon Hallb6a54872015-06-12 14:02:42 -0700895 def links( self ):
896 main.log.info( self.name + ": List network links" )
897 try:
898 response = self.execute( cmd='links', prompt='mininet>',
899 timeout=10 )
900 except pexpect.EOF:
901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
903 main.cleanup()
904 main.exit()
905 return response
906
Jon Hall7eb38402015-01-08 17:19:54 -0800907 def iperf( self, host1, host2 ):
908 main.log.info(
909 self.name +
910 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700911 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800912 cmd1 = 'iperf ' + host1 + " " + host2
913 self.handle.sendline( cmd1 )
914 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800915 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800916 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800917 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800918 return main.TRUE
919 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800920 main.log.error( self.name + ": iperf test failed" )
921 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800922 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800925 main.cleanup()
926 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800927
Jon Hall7eb38402015-01-08 17:19:54 -0800928 def iperfudp( self ):
929 main.log.info(
930 self.name +
931 ": Simple iperf TCP test between two " +
932 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700933 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800934 response = self.execute(
935 cmd='iperfudp',
936 prompt='mininet>',
937 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800938 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800939 main.log.error( self.name + ": EOF exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700941 main.cleanup()
942 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700943 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800944
Jon Hall7eb38402015-01-08 17:19:54 -0800945 def nodes( self ):
946 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700947 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800948 response = self.execute(
949 cmd='nodes',
950 prompt='mininet>',
951 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800952 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800953 main.log.error( self.name + ": EOF exception found" )
954 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700955 main.cleanup()
956 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700957 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800958
Jon Hall7eb38402015-01-08 17:19:54 -0800959 def pingpair( self ):
960 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700961 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800962 response = self.execute(
963 cmd='pingpair',
964 prompt='mininet>',
965 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800966 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800967 main.log.error( self.name + ": EOF exception found" )
968 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700969 main.cleanup()
970 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800971
Jon Hall7eb38402015-01-08 17:19:54 -0800972 if re.search( ',\s0\%\spacket\sloss', response ):
973 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700975 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800976 else:
977 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700979 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800980
Jon Hall7eb38402015-01-08 17:19:54 -0800981 def link( self, **linkargs ):
982 """
983 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800984 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800985 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
986 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
987 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
988 main.log.info(
989 "Bring link between '" +
990 end1 +
991 "' and '" +
992 end2 +
993 "' '" +
994 option +
995 "'" )
996 command = "link " + \
997 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700998 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800999 self.handle.sendline( command )
1000 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001001 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001002 main.log.error( self.name + ": EOF exception found" )
1003 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001004 main.cleanup()
1005 main.exit()
adminbae64d82013-08-01 10:50:15 -07001006 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001007
Jon Hall7eb38402015-01-08 17:19:54 -08001008 def yank( self, **yankargs ):
1009 """
1010 yank a mininet switch interface to a host"""
1011 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001012 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001013 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1014 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1015 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001016 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001017 response = self.execute(
1018 cmd=command,
1019 prompt="mininet>",
1020 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001021 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001022 main.log.error( self.name + ": EOF exception found" )
1023 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001024 main.cleanup()
1025 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001026 return main.TRUE
1027
Jon Hall7eb38402015-01-08 17:19:54 -08001028 def plug( self, **plugargs ):
1029 """
1030 plug the yanked mininet switch interface to a switch"""
1031 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001032 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001033 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1034 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1035 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001036 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001037 response = self.execute(
1038 cmd=command,
1039 prompt="mininet>",
1040 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001041 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001042 main.log.error( self.name + ": EOF exception found" )
1043 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001044 main.cleanup()
1045 main.exit()
adminbae64d82013-08-01 10:50:15 -07001046 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001047
Jon Hall7eb38402015-01-08 17:19:54 -08001048 def dpctl( self, **dpctlargs ):
1049 """
1050 Run dpctl command on all switches."""
1051 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001052 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001053 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1054 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1055 command = "dpctl " + cmd + " " + str( cmdargs )
1056 try:
1057 response = self.execute(
1058 cmd=command,
1059 prompt="mininet>",
1060 timeout=10 )
1061 except pexpect.EOF:
1062 main.log.error( self.name + ": EOF exception found" )
1063 main.log.error( self.name + ": " + self.handle.before )
1064 main.cleanup()
1065 main.exit()
1066 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001067
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -08001069 #FIXME: What uses this? This should be refactored to get
1070 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 fileInput = path + '/lib/Mininet/INSTALL'
1072 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001073 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001075 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001076 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001077 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001078 return version
adminbae64d82013-08-01 10:50:15 -07001079
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001081 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001082 Parameters:
1083 sw: The name of an OVS switch. Example "s1"
1084 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001085 The output of the command from the mininet cli
1086 or main.FALSE on timeout"""
1087 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001088 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001089 response = self.execute(
1090 cmd=command,
1091 prompt="mininet>",
1092 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001093 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001094 return response
admin2a9548d2014-06-17 14:08:07 -07001095 else:
1096 return main.FALSE
1097 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001098 main.log.error( self.name + ": EOF exception found" )
1099 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001100 main.cleanup()
1101 main.exit()
adminbae64d82013-08-01 10:50:15 -07001102
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001104 """
1105 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001106 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001107 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001108
1109 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001110 for j in range( count ):
1111 argstring = argstring + ",IP" + \
1112 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001113 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001114
Jon Hall7eb38402015-01-08 17:19:54 -08001115 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1116 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001117 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001118 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001119
Jon Hall7eb38402015-01-08 17:19:54 -08001120 command = "sh ovs-vsctl set-controller s" + \
1121 str( sw ) + " " + ptcpB + " "
1122 for j in range( count ):
1123 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001124 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001125 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1126 ip = args[
1127 "IP" +
1128 str( i ) ] if args[
1129 "IP" +
1130 str( i ) ] is not None else ""
1131 port = args[
1132 "PORT" +
1133 str( i ) ] if args[
1134 "PORT" +
1135 str( i ) ] is not None else ""
1136 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001137 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001138 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001139 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001140 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -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 )
Jon Hall6094a362014-04-11 14:46:56 -07001144 main.cleanup()
1145 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001146 except Exception:
1147 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001148 main.cleanup()
1149 main.exit()
adminbae64d82013-08-01 10:50:15 -07001150
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001152 """
1153 Removes the controller target from sw"""
1154 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001155 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001156 response = self.execute(
1157 cmd=command,
1158 prompt="mininet>",
1159 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001160 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001161 main.log.error( self.name + ": EOF exception found" )
1162 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001163 main.cleanup()
1164 main.exit()
1165 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001166 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001167
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001169 """
Jon Hallb1290e82014-11-18 16:17:48 -05001170 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001171 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001172 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001173 NOTE: cannot currently specify what type of switch
1174 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001175 sw = name of the new switch as a string
1176 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001177 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001178 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001179 """
1180 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001181 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001182 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001183 response = self.execute(
1184 cmd=command,
1185 prompt="mininet>",
1186 timeout=10 )
1187 if re.search( "already exists!", response ):
1188 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001189 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001190 elif re.search( "Error", response ):
1191 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001192 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001193 elif re.search( "usage:", response ):
1194 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001195 return main.FALSE
1196 else:
1197 return main.TRUE
1198 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001199 main.log.error( self.name + ": EOF exception found" )
1200 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001201 main.cleanup()
1202 main.exit()
1203
kelvin-onlabd3b64892015-01-20 13:26:24 -08001204 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001205 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001206 delete a switch from the mininet topology
1207 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001208 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001209 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001210 sw = name of the switch as a string
1211 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001212 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001213 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001214 response = self.execute(
1215 cmd=command,
1216 prompt="mininet>",
1217 timeout=10 )
1218 if re.search( "no switch named", response ):
1219 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001220 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001221 elif re.search( "Error", response ):
1222 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001223 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001224 elif re.search( "usage:", response ):
1225 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001226 return main.FALSE
1227 else:
1228 return main.TRUE
1229 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001230 main.log.error( self.name + ": EOF exception found" )
1231 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001232 main.cleanup()
1233 main.exit()
1234
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001236 """
1237 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001238 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001239 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001240 NOTE: cannot currently specify what type of link
1241 required params:
1242 node1 = the string node name of the first endpoint of the link
1243 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001244 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001245 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001246 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001247 response = self.execute(
1248 cmd=command,
1249 prompt="mininet>",
1250 timeout=10 )
1251 if re.search( "doesnt exist!", response ):
1252 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001253 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001254 elif re.search( "Error", response ):
1255 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001256 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001257 elif re.search( "usage:", response ):
1258 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001259 return main.FALSE
1260 else:
1261 return main.TRUE
1262 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001263 main.log.error( self.name + ": EOF exception found" )
1264 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001265 main.cleanup()
1266 main.exit()
1267
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001269 """
1270 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001271 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001272 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001273 required params:
1274 node1 = the string node name of the first endpoint of the link
1275 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001276 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001277 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001278 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001279 response = self.execute(
1280 cmd=command,
1281 prompt="mininet>",
1282 timeout=10 )
1283 if re.search( "no node named", response ):
1284 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001285 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001286 elif re.search( "Error", response ):
1287 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001288 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001289 elif re.search( "usage:", response ):
1290 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001291 return main.FALSE
1292 else:
1293 return main.TRUE
1294 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001295 main.log.error( self.name + ": EOF exception found" )
1296 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001297 main.cleanup()
1298 main.exit()
1299
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001301 """
Jon Hallb1290e82014-11-18 16:17:48 -05001302 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001303 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001304 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001305 NOTE: cannot currently specify what type of host
1306 required params:
1307 hostname = the string hostname
1308 optional key-value params
1309 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001310 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001311 """
1312 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001313 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001314 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001315 response = self.execute(
1316 cmd=command,
1317 prompt="mininet>",
1318 timeout=10 )
1319 if re.search( "already exists!", response ):
1320 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001321 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001322 elif re.search( "doesnt exists!", response ):
1323 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001324 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001325 elif re.search( "Error", response ):
1326 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001327 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001328 elif re.search( "usage:", response ):
1329 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001330 return main.FALSE
1331 else:
1332 return main.TRUE
1333 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001334 main.log.error( self.name + ": EOF exception found" )
1335 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001336 main.cleanup()
1337 main.exit()
1338
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001340 """
1341 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001342 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001343 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001344 NOTE: this uses a custom mn function
1345 required params:
1346 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001347 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001348 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001349 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 response = self.execute(
1351 cmd=command,
1352 prompt="mininet>",
1353 timeout=10 )
1354 if re.search( "no host named", response ):
1355 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001356 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001357 elif re.search( "Error", response ):
1358 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001359 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001360 elif re.search( "usage:", response ):
1361 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001362 return main.FALSE
1363 else:
1364 return main.TRUE
1365 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.error( self.name + ": EOF exception found" )
1367 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001368 main.cleanup()
1369 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001370
Jon Hall7eb38402015-01-08 17:19:54 -08001371 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001372 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001373 Called at the end of the test to stop the mininet and
1374 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001375 """
1376 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001377 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001378 timeout=2)
Jon Hall390696c2015-05-05 17:13:41 -07001379 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001380 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001381 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001382 elif i == 1:
1383 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001384 # print "Disconnecting Mininet"
1385 if self.handle:
1386 self.handle.sendline( "exit" )
1387 self.handle.expect( "exit" )
1388 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001389 else:
1390 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001391 return response
1392
Hari Krishnab35c6d02015-03-18 11:13:51 -07001393 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001394 """
Jon Hall21270ac2015-02-16 17:59:55 -08001395 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001396 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001397 main.FALSE if the pexpect handle does not exist.
1398
Jon Halld61331b2015-02-17 16:35:47 -08001399 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001400 """
Jon Hall21270ac2015-02-16 17:59:55 -08001401
Jon Halld61331b2015-02-17 16:35:47 -08001402 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001403 response = ''
1404 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001405 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001406 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001407 i = self.handle.expect( [ 'mininet>',
1408 '\$',
1409 pexpect.EOF,
1410 pexpect.TIMEOUT ],
1411 timeout )
1412 if i == 0:
1413 main.log.info( "Exiting mininet..." )
Jon Hall7eb38402015-01-08 17:19:54 -08001414 response = self.execute(
1415 cmd="exit",
1416 prompt="(.*)",
1417 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001418 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001419 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001420 response = main.TRUE
Jon Hallb6a54872015-06-12 14:02:42 -07001421
kelvin-onlab56a3f462015-02-06 14:04:43 -08001422 if i == 1:
1423 main.log.info( " Mininet trying to exit while not " +
1424 "in the mininet prompt" )
1425 elif i == 2:
1426 main.log.error( "Something went wrong exiting mininet" )
1427 elif i == 3: # timeout
1428 main.log.error( "Something went wrong exiting mininet " +
1429 "TIMEOUT" )
Jon Hallb6a54872015-06-12 14:02:42 -07001430
Hari Krishnab35c6d02015-03-18 11:13:51 -07001431 if fileName:
1432 self.handle.sendline("")
1433 self.handle.expect('\$')
1434 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001435 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001436 main.log.error( self.name + ": EOF exception found" )
1437 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001438 main.cleanup()
1439 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001440 else:
1441 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001442 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001443 return response
1444
kelvin-onlabf0594d72015-05-19 17:25:12 -07001445 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001446 """
1447 Description:
1448 Sends arp message from mininet host for hosts discovery
1449 Required:
1450 host - hosts name
1451 Optional:
1452 ip - ip address that does not exist in the network so there would
1453 be no reply.
1454 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001455 if ethDevice:
1456 ethDevice = '-I ' + ethDevice + ' '
1457 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001458 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001459 main.log.warn( "Sending: " + cmd )
1460 self.handle.sendline( cmd )
1461 response = self.handle.before
1462 self.handle.sendline( "" )
1463 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001464 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001465
1466 except pexpect.EOF:
1467 main.log.error( self.name + ": EOF exception found" )
1468 main.log.error( self.name + ": " + self.handle.before )
1469 main.cleanup()
1470 main.exit()
admin07529932013-11-22 14:58:28 -08001471
Jon Hall7eb38402015-01-08 17:19:54 -08001472 def decToHex( self, num ):
1473 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001474
Jon Hall7eb38402015-01-08 17:19:54 -08001475 def getSwitchFlowCount( self, switch ):
1476 """
1477 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001478 if self.handle:
1479 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1480 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001481 response = self.execute(
1482 cmd=cmd,
1483 prompt="mininet>",
1484 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001485 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001486 main.log.error( self.name + ": EOF exception found" )
1487 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001488 main.cleanup()
1489 main.exit()
1490 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001491 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001492 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001493 main.log.info(
1494 "Couldn't find flows on switch %s, found: %s" %
1495 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001496 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001497 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001498 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001499 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001500
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 def checkFlows( self, sw, dumpFormat=None ):
1502 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001503 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001504 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001505 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001506 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001507 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001508 response = self.execute(
1509 cmd=command,
1510 prompt="mininet>",
1511 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001512 return response
1513 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001514 main.log.error( self.name + ": EOF exception found" )
1515 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001516 main.cleanup()
1517 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001518
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001520 """
Jon Hallefbd9792015-03-05 16:11:36 -08001521 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001522 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001523 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001524 self.handle.sendline( "" )
1525 self.handle.expect( "mininet>" )
1526 self.handle.sendline(
1527 "sh sudo tcpdump -n -i " +
1528 intf +
1529 " " +
1530 port +
1531 " -w " +
1532 filename.strip() +
1533 " &" )
1534 self.handle.sendline( "" )
1535 i = self.handle.expect( [ 'No\ssuch\device',
1536 'listening\son',
1537 pexpect.TIMEOUT,
1538 "mininet>" ],
1539 timeout=10 )
1540 main.log.warn( self.handle.before + self.handle.after )
1541 self.handle.sendline( "" )
1542 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001543 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001544 main.log.error(
1545 self.name +
1546 ": tcpdump - No such device exists. " +
1547 "tcpdump attempted on: " +
1548 intf )
admin2a9548d2014-06-17 14:08:07 -07001549 return main.FALSE
1550 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001551 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001552 return main.TRUE
1553 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001554 main.log.error(
1555 self.name +
1556 ": tcpdump command timed out! Check interface name," +
1557 " given interface was: " +
1558 intf )
admin2a9548d2014-06-17 14:08:07 -07001559 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001560 elif i == 3:
1561 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001562 return main.TRUE
1563 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001564 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001565 return main.FALSE
1566 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001567 main.log.error( self.name + ": EOF exception found" )
1568 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001569 main.cleanup()
1570 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001571 except Exception:
1572 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001573 main.cleanup()
1574 main.exit()
1575
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001577 """
1578 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001579 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001580 self.handle.sendline( "sh sudo pkill tcpdump" )
1581 self.handle.expect( "mininet>" )
1582 self.handle.sendline( "" )
1583 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001584 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001585 main.log.error( self.name + ": EOF exception found" )
1586 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001587 main.cleanup()
1588 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001589 except Exception:
1590 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001591 main.cleanup()
1592 main.exit()
1593
Jon Hallb6a54872015-06-12 14:02:42 -07001594 def getPorts(self, nodeName, verbose=False ):
1595 """
1596 Read ports from a Mininet switch.
1597
1598 Returns a json structure containing information about the
1599 ports of the given switch.
1600 """
1601 response = self.getInterfaces( nodeName )
1602 # TODO: Sanity check on response. log if no such switch exists
1603 ports = []
1604 for line in response.split( "\n" ):
1605 if not line.startswith( "name=" ):
1606 continue
1607 portVars = {}
1608 for var in line.split( "," ):
1609 key, value = var.split( "=" )
1610 portVars[ key ] = value
1611 isUp = portVars.pop( 'enabled', "True" )
1612 isUp = "True" in isUp
1613 if verbose:
1614 main.log.info( "Reading switch port %s(%s)" %
1615 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
1616 mac = portVars[ 'mac' ]
1617 if mac== 'None':
1618 mac = None
1619 ips = []
1620 ip = portVars[ 'ip' ]
1621 if ip == 'None':
1622 ip = None
1623 ips.append( ip )
1624 name = portVars[ 'name' ]
1625 if name == 'None':
1626 name = None
1627 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
1628 if name == 'lo':
1629 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
1630 else:
1631 portNo = re.search( portRe, name ).group( 'port' )
1632 ports.append( { 'of_port': portNo,
1633 'mac': str( mac ).replace( '\'', '' ),
1634 'name': name,
1635 'ips': ips,
1636 'enabled': isUp } )
1637 return ports
1638
1639 def getSwitches(self, verbose=False ):
1640 """
1641 Read switches from Mininet.
1642
1643 Returns a dictionary whose keys are the switch names and the value is
1644 a dictionary containing information about the switch.
1645 """
1646 # FIXME: This currently only works with OVS Switches
1647
1648 # Regex patterns to parse dump output
1649 # Example Switch:
1650 # <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=5238>
1651 # <OVSSwitch{'protocols': 'OpenFlow10'} s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
1652 swRE = r"<OVSSwitch(\{.*\})?\s(?P<name>[^:]+)\:\s" +\
1653 "(?P<ports>([^,]+,)*[^,\s]+)"
1654 # Update mn port info
1655 self.update()
1656 output = { }
1657 dump = self.dump().split( "\n" )
1658 for line in dump:
1659 if line.startswith( "<OVSSwitch" ):
1660 result = re.search( swRE, line, re.I )
1661 name = result.group( 'name' )
1662 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
1663 if verbose:
1664 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
1665 ports = self.getPorts( name )
1666 output[ name ] = { "dpid": dpid, "ports": ports }
1667 return output
1668
1669 def getHosts(self, verbose=False):
1670 """
1671 Read hosts from Mininet.
1672
1673 Returns a dictionary whose keys are the host names and the value is
1674 a dictionary containing information about the host.
1675 """
1676 # Regex patterns to parse dump output
1677 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
1678 # or <Host h1: pid=12725>
1679 # NOTE: Does not correctly match hosts with multi-links
1680 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
1681 # FIXME: Fix that
1682 hostRE = r"<Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
1683 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
1684 # update mn port info
1685 self.update()
1686 # Get mininet dump
1687 dump = self.dump().split( "\n" )
Jon Hallaef00402015-06-12 17:35:53 -07001688 hosts = {}
Jon Hallb6a54872015-06-12 14:02:42 -07001689 for line in dump:
1690 if line.startswith( "<Host" ):
1691 result = re.search( hostRE, line )
1692 name = result.group( 'name' )
1693 interfaces = []
1694 response = self.getInterfaces( name )
1695 # Populate interface info
1696 for line in response.split( "\n" ):
1697 if line.startswith( "name=" ):
1698 portVars = {}
1699 for var in line.split( "," ):
1700 key, value = var.split( "=" )
1701 portVars[ key ] = value
1702 isUp = portVars.pop( 'enabled', "True" )
1703 isUp = "True" in isUp
1704 if verbose:
1705 main.log.info( "Reading host port %s(%s)" %
1706 ( portVars[ 'name' ],
1707 portVars[ 'mac' ] ) )
1708 mac = portVars[ 'mac' ]
1709 if mac== 'None':
1710 mac = None
1711 ips = []
1712 ip = portVars[ 'ip' ]
1713 if ip == 'None':
1714 ip = None
1715 ips.append( ip )
1716 intfName = portVars[ 'name' ]
1717 if name == 'None':
1718 name = None
1719 interfaces.append( {
1720 "name": intfName,
1721 "ips": ips,
1722 "mac": str( mac ),
1723 "isUp": isUp } )
Jon Hallaef00402015-06-12 17:35:53 -07001724 hosts[ name ] = { "interfaces": interfaces }
Jon Hallb6a54872015-06-12 14:02:42 -07001725 return hosts
1726
1727 def getLinks( self ):
1728 """
1729 Gathers information about current Mininet links. These links may not
1730 be up if one of the ports is down.
1731
1732 Returns a list of dictionaries with link endpoints.
1733
1734 The dictionary structure is:
1735 { 'node1': str(node1 name)
1736 'node2': str(node2 name)
1737 'port1': str(port1 of_port)
1738 'port2': str(port2 of_port) }
1739 Note: The port number returned is the eth#, not necessarily the of_port
1740 number. In Mininet, for OVS switch, these should be the same. For
1741 hosts, this is just the eth#.
1742 """
1743 self.update()
1744 response = self.links().split( '\n' )
1745
1746 # Examples:
1747 # s1-eth3<->s2-eth1 (OK OK)
1748 # s13-eth3<->h27-eth0 (OK OK)
1749 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
1750 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
1751 links = []
1752 for line in response:
1753 match = re.search( linkRE, line )
1754 if match:
1755 node1 = match.group( 'node1' )
1756 node2 = match.group( 'node2' )
1757 port1 = match.group( 'port1' )
1758 port2 = match.group( 'port2' )
1759 links.append( { 'node1': node1,
1760 'node2': node2,
1761 'port1': port1,
1762 'port2': port2 } )
1763 return links
1764
1765 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001766 """
1767 Compare mn and onos switches
Jon Hallb6a54872015-06-12 14:02:42 -07001768 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001769
Jon Hallb6a54872015-06-12 14:02:42 -07001770 Dependencies:
1771 1. numpy - "sudo pip install numpy"
1772 """
1773 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04001774 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001775 mnDPIDs = []
Jon Hallb6a54872015-06-12 14:02:42 -07001776 for swName, switch in switches.iteritems():
Jon Hall7eb38402015-01-08 17:19:54 -08001777 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001778 mnDPIDs.sort()
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001780 main.log.error(
1781 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07001782 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001783 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001785 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001786 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001787 if switch[ 'available' ]:
Jon Hallb6a54872015-06-12 14:02:42 -07001788 onosDPIDs.append( switch[ 'id' ].replace( ":", ''
1789 ).replace( "of", '' ).lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001790 onosDPIDs.sort()
Jon Hall3d87d502014-10-17 18:37:42 -04001791
Jon Hall7eb38402015-01-08 17:19:54 -08001792 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 switchResults = main.FALSE
Jon Hallb6a54872015-06-12 14:02:42 -07001794 main.log.error( "Switches in MN but not in ONOS:" )
Jon Hall7eb38402015-01-08 17:19:54 -08001795 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
Jon Hallb6a54872015-06-12 14:02:42 -07001796 main.log.error( str( list1 ) )
1797 main.log.error( "Switches in ONOS but not in MN:" )
Jon Hall7eb38402015-01-08 17:19:54 -08001798 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
Jon Hallb6a54872015-06-12 14:02:42 -07001799 main.log.error( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001800 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 switchResults = main.TRUE
Jon Hallb6a54872015-06-12 14:02:42 -07001802 finalResults = switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001803
Jon Hall7eb38402015-01-08 17:19:54 -08001804 # FIXME: this does not look for extra ports in ONOS, only checks that
1805 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 portsResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001807
Jon Hall7eb38402015-01-08 17:19:54 -08001808 # PORTS
Jon Hallb6a54872015-06-12 14:02:42 -07001809 for name, mnSwitch in switches.iteritems():
kelvin-onlabd3b64892015-01-20 13:26:24 -08001810 mnPorts = []
1811 onosPorts = []
1812 switchResult = main.TRUE
1813 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001814 if port[ 'enabled' ]:
Jon Hallb6a54872015-06-12 14:02:42 -07001815 mnPorts.append( int( port[ 'of_port' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 for onosSwitch in portsJson:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 if onosSwitch[ 'device' ][ 'available' ]:
Jon Hallb6a54872015-06-12 14:02:42 -07001818 if onosSwitch[ 'device' ][ 'id' ].replace( ':',''
1819 ).replace( "of", '' ) == mnSwitch[ 'dpid' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001820 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001821 if port[ 'isEnabled' ]:
1822 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001823 # onosPorts.append( 'local' )
1824 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001825 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001826 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001827 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001828 mnPorts.sort( key=float )
1829 onosPorts.sort( key=float )
Jon Hallb6a54872015-06-12 14:02:42 -07001830
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 mnPortsLog = mnPorts
1832 onosPortsLog = onosPorts
1833 mnPorts = [ x for x in mnPorts ]
1834 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001835
Jon Hall7eb38402015-01-08 17:19:54 -08001836 # TODO: handle other reserved port numbers besides LOCAL
1837 # NOTE: Reserved ports
1838 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1839 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001840 for mnPort in mnPortsLog:
1841 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001842 # don't set results to true here as this is just one of
1843 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001844 mnPorts.remove( mnPort )
1845 onosPorts.remove( mnPort )
Jon Hallb6a54872015-06-12 14:02:42 -07001846
Jon Hall7eb38402015-01-08 17:19:54 -08001847 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001848 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001849 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001850 if 65534 in mnPorts:
1851 mnPorts.remove( 65534 )
1852 if long( uint64( -2 ) ) in onosPorts:
1853 onosPorts.remove( long( uint64( -2 ) ) )
1854 if len( mnPorts ): # the ports of this switch don't match
1855 switchResult = main.FALSE
1856 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1857 if len( onosPorts ): # the ports of this switch don't match
1858 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001859 main.log.warn(
1860 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 str( onosPorts ) )
1862 if switchResult == main.FALSE:
Jon Hallb6a54872015-06-12 14:02:42 -07001863 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08001864 "The list of ports for switch %s(%s) does not match:" %
Jon Hallb6a54872015-06-12 14:02:42 -07001865 ( name, mnSwitch[ 'dpid' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001866 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1867 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1868 portsResults = portsResults and switchResult
Jon Hallb6a54872015-06-12 14:02:42 -07001869 finalResults = finalResults and portsResults
1870 return finalResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001871
Jon Hallb6a54872015-06-12 14:02:42 -07001872 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001873 """
1874 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001875 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001876
Jon Hallb6a54872015-06-12 14:02:42 -07001877 """
Jon Hall7eb38402015-01-08 17:19:54 -08001878 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001879 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001880 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04001881
Jon Hallb6a54872015-06-12 14:02:42 -07001882 mnLinks = [ ]
1883 for l in links:
1884 try:
1885 node1 = switches[ l[ 'node1' ] ]
1886 node2 = switches[ l[ 'node2' ] ]
1887 enabled = True
1888 for port in node1[ 'ports' ]:
1889 if port[ 'of_port' ] == l[ 'port1' ]:
1890 enabled = enabled and port[ 'enabled' ]
1891 for port in node2[ 'ports' ]:
1892 if port[ 'of_port' ] == l[ 'port2']:
1893 enabled = enabled and port[ 'enabled' ]
1894 if enabled:
1895 mnLinks.append( l )
1896 except KeyError:
1897 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001898 if 2 * len( mnLinks ) == len( onos ):
1899 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001900 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001901 linkResults = main.FALSE
Jon Hallb6a54872015-06-12 14:02:42 -07001902 main.log.error(
Jon Hall328ddca2015-01-28 15:57:15 -08001903 "Mininet has " + str( len( mnLinks ) ) +
1904 " bidirectional links and ONOS has " +
1905 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001906
Jon Hall7eb38402015-01-08 17:19:54 -08001907 # iterate through MN links and check if an ONOS link exists in
1908 # both directions
kelvin-onlabd3b64892015-01-20 13:26:24 -08001909 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001910 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001911 node1 = None
1912 port1 = None
1913 node2 = None
1914 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 firstDir = main.FALSE
1916 secondDir = main.FALSE
Jon Hallb6a54872015-06-12 14:02:42 -07001917 for swName, switch in switches.iteritems():
1918 if swName == link[ 'node1' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001919 node1 = switch[ 'dpid' ]
1920 for port in switch[ 'ports' ]:
Jon Hallb6a54872015-06-12 14:02:42 -07001921 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08001922 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001923 if node1 is not None and node2 is not None:
1924 break
Jon Hallb6a54872015-06-12 14:02:42 -07001925 if swName == link[ 'node2' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001926 node2 = switch[ 'dpid' ]
1927 for port in switch[ 'ports' ]:
Jon Hallb6a54872015-06-12 14:02:42 -07001928 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08001929 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001930 if node1 is not None and node2 is not None:
1931 break
1932
kelvin-onlabd3b64892015-01-20 13:26:24 -08001933 for onosLink in onos:
1934 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hallb6a54872015-06-12 14:02:42 -07001935 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001936 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hallb6a54872015-06-12 14:02:42 -07001937 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001938 onosPort1 = onosLink[ 'src' ][ 'port' ]
1939 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001940
Jon Hall72cf1dc2014-10-20 21:04:50 -04001941 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001942 if str( onosNode1 ) == str( node1 ) and str(
1943 onosNode2 ) == str( node2 ):
1944 if int( onosPort1 ) == int( port1 ) and int(
1945 onosPort2 ) == int( port2 ):
1946 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001947 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001948 main.log.warn(
1949 'The port numbers do not match for ' +
1950 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001951 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001952 'link %s/%s -> %s/%s' %
Jon Hallb6a54872015-06-12 14:02:42 -07001953 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08001954 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallb6a54872015-06-12 14:02:42 -07001955 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001956
1957 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 elif ( str( onosNode1 ) == str( node2 ) and
1959 str( onosNode2 ) == str( node1 ) ):
1960 if ( int( onosPort1 ) == int( port2 )
1961 and int( onosPort2 ) == int( port1 ) ):
1962 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001963 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001964 main.log.warn(
1965 'The port numbers do not match for ' +
1966 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001967 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001968 'link %s/%s -> %s/%s' %
Jon Hallb6a54872015-06-12 14:02:42 -07001969 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08001970 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallb6a54872015-06-12 14:02:42 -07001971 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001972 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001973 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001974 if not firstDir:
Jon Hallb6a54872015-06-12 14:02:42 -07001975 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08001976 'ONOS does not have the link %s/%s -> %s/%s' %
1977 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001978 if not secondDir:
Jon Hallb6a54872015-06-12 14:02:42 -07001979 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08001980 'ONOS does not have the link %s/%s -> %s/%s' %
1981 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 linkResults = linkResults and firstDir and secondDir
1983 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001984
Jon Hallb6a54872015-06-12 14:02:42 -07001985 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08001986 """
Jon Hallb6a54872015-06-12 14:02:42 -07001987 Compare mn and onos Hosts.
1988 Since Mininet hosts are quiet, ONOS will only know of them when they
1989 speak. For this reason, we will only check that the hosts in ONOS
1990 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08001991
Jon Hallb6a54872015-06-12 14:02:42 -07001992 Arguments:
1993 hostsJson: parsed json object from the onos hosts api
1994 Returns:
1995 """
Jon Hallff6b4b22015-02-23 09:25:15 -08001996 import json
1997 hostResults = main.TRUE
Jon Hallff6b4b22015-02-23 09:25:15 -08001998 for onosHost in hostsJson:
1999 onosMAC = onosHost[ 'mac' ].lower()
2000 match = False
2001 for mnHost in hosts:
2002 for mnIntf in mnHost[ 'interfaces' ]:
Jon Hallb6a54872015-06-12 14:02:42 -07002003 if onosMAC == mnIntf[ 'mac' ].lower() :
Jon Hallff6b4b22015-02-23 09:25:15 -08002004 match = True
2005 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002006 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002007 pass # all is well
2008 else:
2009 # misssing ip
2010 main.log.error( "ONOS host " + onosHost[ 'id' ]
Jon Hallb6a54872015-06-12 14:02:42 -07002011 + " has a different IP(" +
2012 str( onosHost[ 'ipAddresses' ] ) +
2013 ") than the Mininet host(" +
2014 str( ip ) + ")." )
Jon Hallff6b4b22015-02-23 09:25:15 -08002015 output = json.dumps(
2016 onosHost,
2017 sort_keys=True,
2018 indent=4,
2019 separators=( ',', ': ' ) )
2020 main.log.info( output )
2021 hostResults = main.FALSE
2022 if not match:
2023 hostResults = main.FALSE
2024 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2025 "corresponding Mininet host." )
2026 output = json.dumps( onosHost,
2027 sort_keys=True,
2028 indent=4,
2029 separators=( ',', ': ' ) )
2030 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002031 return hostResults
2032
Jon Hallb6a54872015-06-12 14:02:42 -07002033 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002034 """
2035 Returns a list of all hosts
2036 Don't ask questions just use it"""
2037 self.handle.sendline( "" )
2038 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002039
Jon Hall7eb38402015-01-08 17:19:54 -08002040 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2041 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002042
kelvin-onlabd3b64892015-01-20 13:26:24 -08002043 handlePy = self.handle.before
2044 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2045 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002046
Jon Hall7eb38402015-01-08 17:19:54 -08002047 self.handle.sendline( "" )
2048 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002049
kelvin-onlabd3b64892015-01-20 13:26:24 -08002050 hostStr = handlePy.replace( "]", "" )
2051 hostStr = hostStr.replace( "'", "" )
2052 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002053 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002054 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002055
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 return hostList
adminbae64d82013-08-01 10:50:15 -07002057
Jon Hall7eb38402015-01-08 17:19:54 -08002058 def update( self ):
2059 """
2060 updates the port address and status information for
2061 each port in mn"""
2062 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002063 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002064 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002065 self.handle.sendline( "" )
2066 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002067
Jon Hall7eb38402015-01-08 17:19:54 -08002068 self.handle.sendline( "update" )
2069 self.handle.expect( "update" )
2070 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002071
Jon Hall7eb38402015-01-08 17:19:54 -08002072 self.handle.sendline( "" )
2073 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002074
Jon Hallb1290e82014-11-18 16:17:48 -05002075 return main.TRUE
2076 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002077 main.log.error( self.name + ": EOF exception found" )
2078 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002079 main.cleanup()
2080 main.exit()
2081
adminbae64d82013-08-01 10:50:15 -07002082if __name__ != "__main__":
2083 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002084 sys.modules[ __name__ ] = MininetCliDriver()