blob: aa36725c8a39673baf4b4260f54a66ddd657e13c [file] [log] [blame]
kaouthera3f13ca22015-05-05 15:01:41 -07001
adminbae64d82013-08-01 10:50:15 -07002#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08003"""
adminbae64d82013-08-01 10:50:15 -07004Created on 26-Oct-2012
5
Jon Hallbe6dfc42015-01-12 17:37:25 -08006author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07007
8
Jon Hall7eb38402015-01-08 17:19:54 -08009TestON is free software: you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation, either version 2 of the License, or
12( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070013
Jon Hall7eb38402015-01-08 17:19:54 -080014TestON is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070018
Jon Hall7eb38402015-01-08 17:19:54 -080019You should have received a copy of the GNU General Public License
20along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070021
22
Jon Hallbe6dfc42015-01-12 17:37:25 -080023MininetCliDriver is the basic driver which will handle the Mininet functions
24
Jon Hall272a4db2015-01-12 17:43:48 -080025Some functions rely on STS module. To install this,
26 git clone https://github.com/jhall11/sts.git
27
Jon Hallbe6dfc42015-01-12 17:37:25 -080028Some functions rely on a modified version of Mininet. These functions
29should all be noted in the comments. To get this MN version run these commands
30from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080031 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080032 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080033 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080034 git pull
35
Jon Hall272a4db2015-01-12 17:43:48 -080036
37 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080038changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070039import pexpect
adminbae64d82013-08-01 10:50:15 -070040import re
41import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070042import types
Jon Hall7eb38402015-01-08 17:19:54 -080043sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040044from math import pow
adminbae64d82013-08-01 10:50:15 -070045from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070046
Jon Hall7eb38402015-01-08 17:19:54 -080047
kelvin-onlab50907142015-04-01 13:37:45 -070048class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080049
50 """
51 MininetCliDriver is the basic driver which will handle
52 the Mininet functions"""
53 def __init__( self ):
54 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070055 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080057 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070058 self.flag = 0
59
Jon Hall7eb38402015-01-08 17:19:54 -080060 def connect( self, **connectargs ):
61 """
62 Here the main is the TestON instance after creating
63 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080064 try:
65 for key in connectargs:
66 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080067
kelvin-onlaba1484582015-02-02 15:46:20 -080068 self.name = self.options[ 'name' ]
69 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070070 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080071 self ).connect(
72 user_name=self.user_name,
73 ip_address=self.ip_address,
74 port=None,
75 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080076
kelvin-onlaba1484582015-02-02 15:46:20 -080077 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080078 main.log.info( "Connection successful to the host " +
79 self.user_name +
80 "@" +
81 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080082 return main.TRUE
83 else:
84 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080085 self.user_name +
86 "@" +
87 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080088 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -080089 return main.FALSE
90 except pexpect.EOF:
91 main.log.error( self.name + ": EOF exception found" )
92 main.log.error( self.name + ": " + self.handle.before )
93 main.cleanup()
94 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080095 except Exception:
96 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -080097 main.cleanup()
98 main.exit()
99
kelvin-onlab10e8d392015-06-03 13:53:45 -0700100 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800101 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700102 Description:
103 Starts Mininet accepts a topology(.py) file and/or an optional
104 argument, to start the mininet, as a parameter.
105 Can also send regular mininet command to load up desired topology.
106 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
107 Options:
108 topoFile = file path for topology file (.py)
109 args = extra option added when starting the topology from the file
110 mnCmd = Mininet command use to start topology
111 Returns:
112 main.TRUE if the mininet starts successfully, main.FALSE
113 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800114 """
Jon Hall7eb38402015-01-08 17:19:54 -0800115 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700116 # make sure old networks are cleaned up
117 main.log.info( self.name +
118 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800119 self.handle.sendline( "sudo mn -c" )
120 i = self.handle.expect( [ 'password\sfor\s',
121 'Cleanup\scomplete',
122 pexpect.EOF,
123 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800124 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800125 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700126 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800127 main.log.info( self.name + ": Sending sudo password" )
128 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800129 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800130 '\$',
131 pexpect.EOF,
132 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800133 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800134 if i == 1:
135 main.log.info( self.name + ": Clean" )
136 elif i == 2:
137 main.log.error( self.name + ": Connection terminated" )
138 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700139 main.log.error( self.name + ": Something while cleaning " +
140 "Mininet took too long... " )
141 # Craft the string to start mininet
142 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700143 if not mnCmd:
144 if topoFile is None or topoFile == '': # If no file is given
145 main.log.info( self.name + ": building fresh Mininet" )
146 cmdString += "mn "
147 if args is None or args == '':
148 # If no args given, use args from .topo file
149 args = self.options[ 'arg1' ] +\
150 " " + self.options[ 'arg2' ] +\
151 " --mac --controller " +\
152 self.options[ 'controller' ] + " " +\
153 self.options[ 'arg3' ]
154 else: # else only use given args
155 pass
156 # TODO: allow use of topo args and method args?
157 else: # Use given topology file
158 main.log.info( "Starting Mininet from topo file " + topoFile )
159 cmdString += topoFile + " "
160 if args is None:
161 args = ''
162 # TODO: allow use of args from .topo file?
163 cmdString += args
164 else:
165 main.log.info( "Starting Mininet topology using '" + mnCmd +
166 "' command" )
167 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700168 # Send the command and check if network started
169 self.handle.sendline( "" )
170 self.handle.expect( '\$' )
171 main.log.info( "Sending '" + cmdString + "' to " + self.name )
172 self.handle.sendline( cmdString )
173 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800174 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700175 'Exception',
176 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800177 pexpect.EOF,
178 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700179 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800180 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700181 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800182 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800183 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700184 response = str( self.handle.before +
185 self.handle.after )
186 self.handle.expect( '\$' )
187 response += str( self.handle.before +
188 self.handle.after )
189 main.log.error(
190 self.name +
191 ": Launching Mininet failed: " + response )
192 return main.FALSE
193 elif i == 2:
194 self.handle.expect( [ "\n",
195 pexpect.EOF,
196 pexpect.TIMEOUT ],
197 timeout )
198 main.log.info( self.handle.before )
199 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800200 main.log.error( self.name + ": Connection timeout" )
201 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700202 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800203 main.log.error(
204 self.name +
205 ": Something took too long... " )
206 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700207 # Why did we hit this part?
208 main.log.error( "startNet did not return correctly" )
209 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800210 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700211 main.log.error( self.name + ": Connection failed to the host " +
212 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800213 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700214 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800215
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800216 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400217 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800218 # In tree topology, if fanout arg is not given, by default it is 2
219 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400220 fanout = 2
221 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500222 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800223 while( k <= depth - 1 ):
224 count = count + pow( fanout, k )
225 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800226 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800227 while( k <= depth - 2 ):
228 # depth-2 gives you only core links and not considering
229 # edge links as seen by ONOS. If all the links including
230 # edge links are required, do depth-1
231 count = count + pow( fanout, k )
232 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800234 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800235 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800236
Jon Hall7eb38402015-01-08 17:19:54 -0800237 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800239 # by default it is 1
240 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400241 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 numSwitches = depth
243 numHostsPerSw = fanout
244 totalNumHosts = numSwitches * numHostsPerSw
245 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800246 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800248 topoDict = { "num_switches": int( numSwitches ),
249 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400250 return topoDict
251
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700253 """
254 Calculate the number of switches and links in a topo."""
255 # TODO: combine this function and numSwitchesNlinks
256 argList = self.options[ 'arg1' ].split( "," )
257 topoArgList = argList[ 0 ].split( " " )
258 argList = map( int, argList[ 1: ] )
259 topoArgList = topoArgList[ 1: ] + argList
260
261 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400262 return topoDict
263
kelvin-onlabc44f0192015-04-02 22:08:41 -0700264 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0):
Jon Hall7eb38402015-01-08 17:19:54 -0800265 """
266 Verifies the reachability of the hosts using pingall command.
267 Optional parameter timeout allows you to specify how long to
268 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700269 Optional:
Jon Hall390696c2015-05-05 17:13:41 -0700270 timeout(seconds) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700271 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700272 ping
273 acceptableFailed - Set the number of acceptable failed pings for the
274 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800275 Returns:
276 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700277 otherwise main.FALSE
278 """
279 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700280 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700281 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700282 if self.handle:
283 main.log.info(
284 self.name +
285 ": Checking reachabilty to the hosts using pingall" )
286 response = ""
287 failedPings = 0
288 returnValue = main.TRUE
289 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700290 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700291 while True:
292 i = self.handle.expect( [ "mininet>","X",
293 pexpect.EOF,
294 pexpect.TIMEOUT ],
295 timeout )
296 if i == 0:
297 main.log.info( self.name + ": pingall finished")
298 response += self.handle.before
299 break
300 elif i == 1:
301 response += self.handle.before + self.handle.after
302 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700303 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700304 returnValue = main.FALSE
305 if shortCircuit:
306 main.log.error( self.name +
307 ": Aborting pingall - "
308 + str( failedPings ) +
309 " pings failed" )
310 break
Jon Hall390696c2015-05-05 17:13:41 -0700311 if ( time.time() - startTime ) > timeout:
312 returnValue = main.FALSE
313 main.log.error( self.name +
314 ": Aborting pingall - " +
315 "Function took too long " )
316 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700317 elif i == 2:
318 main.log.error( self.name +
319 ": EOF exception found" )
320 main.log.error( self.name + ": " +
321 self.handle.before )
322 main.cleanup()
323 main.exit()
324 elif i == 3:
325 response += self.handle.before
326 main.log.error( self.name +
327 ": TIMEOUT exception found" )
328 main.log.error( self.name +
329 ": " +
330 str( response ) )
331 # NOTE: Send ctrl-c to make sure pingall is done
332 self.handle.sendline( "\x03" )
333 self.handle.expect( "Interrupt" )
334 self.handle.expect( "mininet>" )
335 break
336 pattern = "Results\:"
337 main.log.info( "Pingall output: " + str( response ) )
338 if re.search( pattern, response ):
339 main.log.info( self.name + ": Pingall finished with "
340 + str( failedPings ) + " failed pings" )
341 return returnValue
342 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700343 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700344 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700345 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700346 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700347 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700348 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700349 main.log.error( self.name + ": Connection failed to the host" )
350 main.cleanup()
351 main.exit()
352 except pexpect.TIMEOUT:
353 if response:
354 main.log.info( "Pingall output: " + str( response ) )
355 main.log.error( self.name + ": pexpect.TIMEOUT found" )
356 return main.FALSE
357 except pexpect.EOF:
358 main.log.error( self.name + ": EOF exception found" )
359 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500360 main.cleanup()
361 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700362
Jon Hall7eb38402015-01-08 17:19:54 -0800363 def fpingHost( self, **pingParams ):
364 """
365 Uses the fping package for faster pinging...
366 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800367 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800368 command = args[ "SRC" ] + \
369 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
370 self.handle.sendline( command )
371 self.handle.expect(
372 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
373 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
374 response = self.handle.before
375 if re.search( ":\s-", response ):
376 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700377 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800378 elif re.search( ":\s\d{1,2}\.\d\d", response ):
379 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700380 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800381 main.log.info( self.name + ": Install fping on mininet machine... " )
382 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700383 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800384
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400385 def pingallHosts( self, hostList, pingType='ipv4' ):
386 """
kelvin-onlab2ff57022015-05-29 10:48:51 -0700387 Ping all specified hosts with a specific ping type
388
389 Acceptable pingTypes:
390 - 'ipv4'
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400391 - 'ipv6'
kelvin-onlab2ff57022015-05-29 10:48:51 -0700392
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400393 Acceptable hostList:
394 - ['h1','h2','h3','h4']
kelvin-onlab2ff57022015-05-29 10:48:51 -0700395
396 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400397 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700398
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400399 Returns main.FALSE if one or more of hosts specified
400 cannot reach each other"""
kelvin-onlab2ff57022015-05-29 10:48:51 -0700401
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400402 if pingType == "ipv4":
kelvin-onlab2ff57022015-05-29 10:48:51 -0700403 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400404 elif pingType == "ipv6":
405 cmd = " ping6 -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 else:
407 main.log.warn( "Invalid pingType specified" )
408 return
409
410 try:
411 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700412
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400413 isReachable = main.TRUE
414
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400415 for host in hostList:
416 listIndex = hostList.index(host)
417 # List of hosts to ping other than itself
418 pingList = hostList[:listIndex] + hostList[(listIndex+1):]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700419
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400420 for temp in pingList:
421 # Current host pings all other hosts specified
kelvin-onlab2ff57022015-05-29 10:48:51 -0700422 pingCmd = str(host) + cmd + str(temp)
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400423 self.handle.sendline( pingCmd )
424 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
425 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
426 response = self.handle.before
427 if re.search( ',\s0\%\spacket\sloss', response ):
428 main.log.info( str(host) + " -> " + str(temp) )
429 else:
430 main.log.info( str(host) + " -> X ("+str(temp)+") "
kelvin-onlab2ff57022015-05-29 10:48:51 -0700431 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400432 # One of the host to host pair is unreachable
433 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400434
kelvin-onlab2ff57022015-05-29 10:48:51 -0700435 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400436
437 except pexpect.EOF:
438 main.log.error( self.name + ": EOF exception found" )
439 main.log.error( self.name + ": " + self.handle.before )
440 main.cleanup()
441 main.exit()
442
Jon Hall7eb38402015-01-08 17:19:54 -0800443 def pingHost( self, **pingParams ):
444 """
445 Ping from one mininet host to another
446 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800447 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800448 command = args[ "SRC" ] + " ping " + \
449 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700450 try:
Jon Hall61282e32015-03-19 11:34:11 -0700451 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800452 self.handle.sendline( command )
453 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700454 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800455 main.log.error(
456 self.name +
457 ": timeout when waiting for response from mininet" )
458 main.log.error( "response: " + str( self.handle.before ) )
459 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700460 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800461 main.log.error(
462 self.name +
463 ": timeout when waiting for response from mininet" )
464 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700465 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800466 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800467 main.log.error( self.name + ": EOF exception found" )
468 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700469 main.cleanup()
470 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800471 main.log.info( self.name + ": Ping Response: " + response )
472 if re.search( ',\s0\%\spacket\sloss', response ):
473 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700475 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800476 else:
477 main.log.error(
478 self.name +
479 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700481 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800482
Jon Hall7eb38402015-01-08 17:19:54 -0800483 def checkIP( self, host ):
484 """
485 Verifies the host's ip configured or not."""
486 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700487 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800488 response = self.execute(
489 cmd=host +
490 " ifconfig",
491 prompt="mininet>",
492 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800493 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800494 main.log.error( self.name + ": EOF exception found" )
495 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700496 main.cleanup()
497 main.exit()
adminbae64d82013-08-01 10:50:15 -0700498
Jon Hall7eb38402015-01-08 17:19:54 -0800499 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800500 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
501 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
502 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
503 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
504 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800505 # pattern = "inet addr:10.0.0.6"
506 if re.search( pattern, response ):
507 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700508 return main.TRUE
509 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800510 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700511 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800512 else:
513 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800514
Jon Hall7eb38402015-01-08 17:19:54 -0800515 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800516 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700517 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800518 response = self.execute(
519 cmd="h1 /usr/sbin/sshd -D&",
520 prompt="mininet>",
521 timeout=10 )
522 response = self.execute(
523 cmd="h4 /usr/sbin/sshd -D&",
524 prompt="mininet>",
525 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700526 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800527 vars( self )[ key ] = connectargs[ key ]
528 response = self.execute(
529 cmd="xterm h1 h4 ",
530 prompt="mininet>",
531 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800532 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800533 main.log.error( self.name + ": EOF exception found" )
534 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700535 main.cleanup()
536 main.exit()
adminbae64d82013-08-01 10:50:15 -0700537 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800538 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700539 if self.flag == 0:
540 self.flag = 1
541 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800542 else:
adminbae64d82013-08-01 10:50:15 -0700543 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800544
kelvin-onlaba1484582015-02-02 15:46:20 -0800545 def moveHost( self, host, oldSw, newSw, ):
546 """
547 Moves a host from one switch to another on the fly
548 Note: The intf between host and oldSw when detached
549 using detach(), will still show up in the 'net'
550 cmd, because switch.detach() doesn't affect switch.intfs[]
551 (which is correct behavior since the interfaces
552 haven't moved).
553 """
554 if self.handle:
555 try:
556 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800557 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
558 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800559 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800560 response = self.execute( cmd=cmd,
561 prompt="mininet>",
562 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800563
564 # Determine hostintf and Oldswitchintf
565 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800566 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800567 print "cmd2= ", cmd
568 self.handle.sendline( cmd )
569 self.handle.expect( "mininet>" )
570
shahshreya73537862015-02-11 15:15:24 -0800571 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800572 cmd = "px ipaddr = hintf.IP()"
573 print "cmd3= ", cmd
574 self.handle.sendline( cmd )
575 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800576
577 cmd = "px macaddr = hintf.MAC()"
578 print "cmd3= ", cmd
579 self.handle.sendline( cmd )
580 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800581
582 # Detach interface between oldSw-host
583 cmd = "px " + oldSw + ".detach( sintf )"
584 print "cmd4= ", cmd
585 self.handle.sendline( cmd )
586 self.handle.expect( "mininet>" )
587
588 # Add link between host-newSw
589 cmd = "py net.addLink(" + host + "," + newSw + ")"
590 print "cmd5= ", cmd
591 self.handle.sendline( cmd )
592 self.handle.expect( "mininet>" )
593
594 # Determine hostintf and Newswitchintf
595 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800596 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800597 print "cmd6= ", cmd
598 self.handle.sendline( cmd )
599 self.handle.expect( "mininet>" )
600
601 # Attach interface between newSw-host
602 cmd = "px " + newSw + ".attach( sintf )"
603 print "cmd3= ", cmd
604 self.handle.sendline( cmd )
605 self.handle.expect( "mininet>" )
606
607 # Set ipaddress of the host-newSw interface
608 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
609 print "cmd7 = ", cmd
610 self.handle.sendline( cmd )
611 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800612
613 # Set macaddress of the host-newSw interface
614 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
615 print "cmd8 = ", cmd
616 self.handle.sendline( cmd )
617 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800618
619 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800620 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800621 self.handle.sendline( cmd )
622 self.handle.expect( "mininet>" )
623 print "output = ", self.handle.before
624
625 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800626 cmd = host + " ifconfig"
627 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800628 self.handle.sendline( cmd )
629 self.handle.expect( "mininet>" )
630 print "ifconfig o/p = ", self.handle.before
631
632 return main.TRUE
633 except pexpect.EOF:
634 main.log.error( self.name + ": EOF exception found" )
635 main.log.error( self.name + ": " + self.handle.before )
636 return main.FALSE
637
Jon Hall7eb38402015-01-08 17:19:54 -0800638 def changeIP( self, host, intf, newIP, newNetmask ):
639 """
640 Changes the ip address of a host on the fly
641 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800642 if self.handle:
643 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800644 cmd = host + " ifconfig " + intf + " " + \
645 newIP + " " + 'netmask' + " " + newNetmask
646 self.handle.sendline( cmd )
647 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800648 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800649 main.log.info( "response = " + response )
650 main.log.info(
651 "Ip of host " +
652 host +
653 " changed to new IP " +
654 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800655 return main.TRUE
656 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800657 main.log.error( self.name + ": EOF exception found" )
658 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800659 return main.FALSE
660
Jon Hall7eb38402015-01-08 17:19:54 -0800661 def changeDefaultGateway( self, host, newGW ):
662 """
663 Changes the default gateway of a host
664 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800665 if self.handle:
666 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800667 cmd = host + " route add default gw " + newGW
668 self.handle.sendline( cmd )
669 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800670 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800671 main.log.info( "response = " + response )
672 main.log.info(
673 "Default gateway of host " +
674 host +
675 " changed to " +
676 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800677 return main.TRUE
678 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800679 main.log.error( self.name + ": EOF exception found" )
680 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800681 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800682
Jon Hall7eb38402015-01-08 17:19:54 -0800683 def addStaticMACAddress( self, host, GW, macaddr ):
684 """
Jon Hallefbd9792015-03-05 16:11:36 -0800685 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800686 if self.handle:
687 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800688 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
689 cmd = host + " arp -s " + GW + " " + macaddr
690 self.handle.sendline( cmd )
691 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800692 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800693 main.log.info( "response = " + response )
694 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800695 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800696 GW +
697 " changed to " +
698 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800699 return main.TRUE
700 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800703 return main.FALSE
704
Jon Hall7eb38402015-01-08 17:19:54 -0800705 def verifyStaticGWandMAC( self, host ):
706 """
707 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800708 if self.handle:
709 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800710 # h1 arp -an
711 cmd = host + " arp -an "
712 self.handle.sendline( cmd )
713 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800714 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800715 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800716 return main.TRUE
717 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800718 main.log.error( self.name + ": EOF exception found" )
719 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800720 return main.FALSE
721
Jon Hall7eb38402015-01-08 17:19:54 -0800722 def getMacAddress( self, host ):
723 """
724 Verifies the host's ip configured or not."""
725 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700726 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800727 response = self.execute(
728 cmd=host +
729 " ifconfig",
730 prompt="mininet>",
731 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800732 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700735 main.cleanup()
736 main.exit()
adminbae64d82013-08-01 10:50:15 -0700737
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700738 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 macAddressSearch = re.search( pattern, response, re.I )
740 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800741 main.log.info(
742 self.name +
743 ": Mac-Address of Host " +
744 host +
745 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 macAddress )
747 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700748 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800749 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700750
Jon Hall7eb38402015-01-08 17:19:54 -0800751 def getInterfaceMACAddress( self, host, interface ):
752 """
753 Return the IP address of the interface on the given host"""
754 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700755 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800756 response = self.execute( cmd=host + " ifconfig " + interface,
757 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800758 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
761 main.cleanup()
762 main.exit()
763
764 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 macAddressSearch = re.search( pattern, response, re.I )
766 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800767 main.log.info( "No mac address found in %s" % response )
768 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800770 main.log.info(
771 "Mac-Address of " +
772 host +
773 ":" +
774 interface +
775 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800776 macAddress )
777 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800778 else:
779 main.log.error( "Connection failed to the host" )
780
781 def getIPAddress( self, host ):
782 """
783 Verifies the host's ip configured or not."""
784 if self.handle:
785 try:
786 response = self.execute(
787 cmd=host +
788 " ifconfig",
789 prompt="mininet>",
790 timeout=10 )
791 except pexpect.EOF:
792 main.log.error( self.name + ": EOF exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700794 main.cleanup()
795 main.exit()
adminbae64d82013-08-01 10:50:15 -0700796
797 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800799 main.log.info(
800 self.name +
801 ": IP-Address of Host " +
802 host +
803 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800804 ipAddressSearch.group( 1 ) )
805 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800806 else:
807 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800808
Jon Hall7eb38402015-01-08 17:19:54 -0800809 def getSwitchDPID( self, switch ):
810 """
811 return the datapath ID of the switch"""
812 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700813 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700814 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800815 response = self.execute(
816 cmd=cmd,
817 prompt="mininet>",
818 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800819 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800820 main.log.error( self.name + ": EOF exception found" )
821 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700822 main.cleanup()
823 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800824 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800825 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700826 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800827 main.log.info(
828 "Couldn't find DPID for switch %s, found: %s" %
829 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700830 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800831 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700832 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700834
Jon Hall7eb38402015-01-08 17:19:54 -0800835 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700836 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800837 self.handle.sendline( "" )
838 self.expect( "mininet>" )
839 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700840 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800841 response = self.execute(
842 cmd=cmd,
843 prompt="mininet>",
844 timeout=10 )
845 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700846 response = self.handle.before
847 return response
848 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700851 main.cleanup()
852 main.exit()
853
Jon Hall7eb38402015-01-08 17:19:54 -0800854 def getInterfaces( self, node ):
855 """
856 return information dict about interfaces connected to the node"""
857 if self.handle:
858 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800859 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700860 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700861 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800862 response = self.execute(
863 cmd=cmd,
864 prompt="mininet>",
865 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800866 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800867 main.log.error( self.name + ": EOF exception found" )
868 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700869 main.cleanup()
870 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700871 return response
872 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800873 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700874
Jon Hall7eb38402015-01-08 17:19:54 -0800875 def dump( self ):
876 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700877 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800878 response = self.execute(
879 cmd='dump',
880 prompt='mininet>',
881 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800882 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800883 main.log.error( self.name + ": EOF exception found" )
884 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700885 main.cleanup()
886 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700887 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800888
Jon Hall7eb38402015-01-08 17:19:54 -0800889 def intfs( self ):
890 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700891 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800892 response = self.execute(
893 cmd='intfs',
894 prompt='mininet>',
895 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800896 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700899 main.cleanup()
900 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700901 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800902
Jon Hall7eb38402015-01-08 17:19:54 -0800903 def net( self ):
904 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700905 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800906 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800907 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700910 main.cleanup()
911 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700912 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800913
914 def iperf( self, host1, host2 ):
915 main.log.info(
916 self.name +
917 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700918 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800919 cmd1 = 'iperf ' + host1 + " " + host2
920 self.handle.sendline( cmd1 )
921 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800922 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800923 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800924 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800925 return main.TRUE
926 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800927 main.log.error( self.name + ": iperf test failed" )
928 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800929 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800932 main.cleanup()
933 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800934
Jon Hall7eb38402015-01-08 17:19:54 -0800935 def iperfudp( self ):
936 main.log.info(
937 self.name +
938 ": Simple iperf TCP test between two " +
939 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700940 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800941 response = self.execute(
942 cmd='iperfudp',
943 prompt='mininet>',
944 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800945 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700948 main.cleanup()
949 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700950 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800951
Jon Hall7eb38402015-01-08 17:19:54 -0800952 def nodes( self ):
953 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700954 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800955 response = self.execute(
956 cmd='nodes',
957 prompt='mininet>',
958 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800959 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800960 main.log.error( self.name + ": EOF exception found" )
961 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700962 main.cleanup()
963 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700964 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800965
Jon Hall7eb38402015-01-08 17:19:54 -0800966 def pingpair( self ):
967 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700968 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800969 response = self.execute(
970 cmd='pingpair',
971 prompt='mininet>',
972 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800973 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800974 main.log.error( self.name + ": EOF exception found" )
975 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700976 main.cleanup()
977 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800978
Jon Hall7eb38402015-01-08 17:19:54 -0800979 if re.search( ',\s0\%\spacket\sloss', response ):
980 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800981 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700982 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800983 else:
984 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700986 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800987
Jon Hall7eb38402015-01-08 17:19:54 -0800988 def link( self, **linkargs ):
989 """
990 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800991 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800992 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
993 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
994 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
995 main.log.info(
996 "Bring link between '" +
997 end1 +
998 "' and '" +
999 end2 +
1000 "' '" +
1001 option +
1002 "'" )
1003 command = "link " + \
1004 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001005 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001006 self.handle.sendline( command )
1007 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001008 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001009 main.log.error( self.name + ": EOF exception found" )
1010 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001011 main.cleanup()
1012 main.exit()
adminbae64d82013-08-01 10:50:15 -07001013 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001014
Jon Hall7eb38402015-01-08 17:19:54 -08001015 def yank( self, **yankargs ):
1016 """
1017 yank a mininet switch interface to a host"""
1018 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001019 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001020 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1021 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1022 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001023 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001024 response = self.execute(
1025 cmd=command,
1026 prompt="mininet>",
1027 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001028 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001029 main.log.error( self.name + ": EOF exception found" )
1030 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001031 main.cleanup()
1032 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001033 return main.TRUE
1034
Jon Hall7eb38402015-01-08 17:19:54 -08001035 def plug( self, **plugargs ):
1036 """
1037 plug the yanked mininet switch interface to a switch"""
1038 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001039 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001040 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1041 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1042 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001043 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001044 response = self.execute(
1045 cmd=command,
1046 prompt="mininet>",
1047 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001048 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001049 main.log.error( self.name + ": EOF exception found" )
1050 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001051 main.cleanup()
1052 main.exit()
adminbae64d82013-08-01 10:50:15 -07001053 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001054
Jon Hall7eb38402015-01-08 17:19:54 -08001055 def dpctl( self, **dpctlargs ):
1056 """
1057 Run dpctl command on all switches."""
1058 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001059 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001060 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1061 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1062 command = "dpctl " + cmd + " " + str( cmdargs )
1063 try:
1064 response = self.execute(
1065 cmd=command,
1066 prompt="mininet>",
1067 timeout=10 )
1068 except pexpect.EOF:
1069 main.log.error( self.name + ": EOF exception found" )
1070 main.log.error( self.name + ": " + self.handle.before )
1071 main.cleanup()
1072 main.exit()
1073 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001074
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -08001076 #FIXME: What uses this? This should be refactored to get
1077 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 fileInput = path + '/lib/Mininet/INSTALL'
1079 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001080 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001081 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001082 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001083 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001084 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001085 return version
adminbae64d82013-08-01 10:50:15 -07001086
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001088 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001089 Parameters:
1090 sw: The name of an OVS switch. Example "s1"
1091 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001092 The output of the command from the mininet cli
1093 or main.FALSE on timeout"""
1094 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001095 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001096 response = self.execute(
1097 cmd=command,
1098 prompt="mininet>",
1099 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001100 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001101 return response
admin2a9548d2014-06-17 14:08:07 -07001102 else:
1103 return main.FALSE
1104 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001105 main.log.error( self.name + ": EOF exception found" )
1106 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001107 main.cleanup()
1108 main.exit()
adminbae64d82013-08-01 10:50:15 -07001109
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001110 def assignSwController( self, sw, ip, port="6633", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001111 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001112 Description:
1113 Assign switches to the controllers ( for ovs use only )
1114 Required:
1115 sw - Name of the switch. This can be a list or a string.
1116 ip - Ip addresses of controllers. This can be a list or a string.
1117 Optional:
1118 port - ONOS use port 6633, if no list of ports is passed, then
1119 the all the controller will use 6633 as their port number
1120 ptcp - ptcp number, This can be a string or a list that has
1121 the same length as switch. This is optional and not required
1122 when using ovs switches.
1123 NOTE: If switches and ptcp are given in a list type they should have the
1124 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1125 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001126
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001127 Return:
1128 Returns main.TRUE if mininet correctly assigned switches to
1129 controllers, otherwise it will return main.FALSE or an appropriate
1130 exception(s)
1131 """
1132 assignResult = main.TRUE
1133 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001134 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001135 command = "sh ovs-vsctl set-controller "
1136 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001137 try:
1138 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001139 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001140 if isinstance( port, types.StringType ) or \
1141 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001142 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001143 elif isinstance( port, types.ListType ):
1144 main.log.error( self.name + ": Only one controller " +
1145 "assigned and a list of ports has" +
1146 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001147 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001148 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001149 main.log.error( self.name + ": Invalid controller port " +
1150 "number. Please specify correct " +
1151 "controller port" )
1152 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001153
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001154 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001155 if isinstance( port, types.StringType ) or \
1156 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001157 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001158 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1159 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001160 elif isinstance( port, types.ListType ):
1161 if ( len( ip ) != len( port ) ):
1162 main.log.error( self.name + ": Port list = " +
1163 str( len( port ) ) +
1164 "should be the same as controller" +
1165 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001166 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001167 else:
1168 onosIp = ""
1169 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001170 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1171 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001172 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001173 main.log.error( self.name + ": Invalid controller port " +
1174 "number. Please specify correct " +
1175 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001176 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001177 else:
1178 main.log.error( self.name + ": Invalid ip address" )
1179 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001180
1181 if isinstance( sw, types.StringType ):
1182 command += sw + " "
1183 if ptcp:
1184 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001185 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001186 elif isinstance( ptcp, types.ListType ):
1187 main.log.error( self.name + ": Only one switch is " +
1188 "being set and multiple PTCP is " +
1189 "being passed " )
1190 else:
1191 main.log.error( self.name + ": Invalid PTCP" )
1192 ptcp = ""
1193 command += onosIp
1194 commandList.append( command )
1195
1196 elif isinstance( sw, types.ListType ):
1197 if ptcp:
1198 if isinstance( ptcp, types.ListType ):
1199 if len( ptcp ) != len( sw ):
1200 main.log.error( self.name + ": PTCP length = " +
1201 str( len( ptcp ) ) +
1202 " is not the same as switch" +
1203 " length = " +
1204 str( len( sw ) ) )
1205 return main.FALSE
1206 else:
1207 for switch, ptcpNum in zip( sw, ptcp ):
1208 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001209 tempCmd += switch + " ptcp:" + \
1210 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001211 tempCmd += onosIp
1212 commandList.append( tempCmd )
1213 else:
1214 main.log.error( self.name + ": Invalid PTCP" )
1215 return main.FALSE
1216 else:
1217 for switch in sw:
1218 tempCmd = "sh ovs-vsctl set-controller "
1219 tempCmd += switch + " " + onosIp
1220 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001221 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001222 main.log.error( self.name + ": Invalid switch type " )
1223 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001224
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001225 for cmd in commandList:
1226 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001227 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001228 except pexpect.TIMEOUT:
1229 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1230 return main.FALSE
1231 except pexpect.EOF:
1232 main.log.error( self.name + ": EOF exception found" )
1233 main.log.error( self.name + ": " + self.handle.before )
1234 main.cleanup()
1235 main.exit()
1236 return main.TRUE
1237 except Exception:
1238 main.log.exception( self.name + ": Uncaught exception!" )
1239 main.cleanup()
1240 main.exit()
adminbae64d82013-08-01 10:50:15 -07001241
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001243 """
1244 Removes the controller target from sw"""
1245 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001246 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001247 response = self.execute(
1248 cmd=command,
1249 prompt="mininet>",
1250 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001251 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001252 main.log.error( self.name + ": EOF exception found" )
1253 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001254 main.cleanup()
1255 main.exit()
1256 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001257 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001258
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001260 """
Jon Hallb1290e82014-11-18 16:17:48 -05001261 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001262 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001263 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001264 NOTE: cannot currently specify what type of switch
1265 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001266 sw = name of the new switch as a string
1267 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001268 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001269 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001270 """
1271 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001272 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001273 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001274 response = self.execute(
1275 cmd=command,
1276 prompt="mininet>",
1277 timeout=10 )
1278 if re.search( "already exists!", response ):
1279 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001280 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001281 elif re.search( "Error", response ):
1282 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001283 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001284 elif re.search( "usage:", response ):
1285 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001286 return main.FALSE
1287 else:
1288 return main.TRUE
1289 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001290 main.log.error( self.name + ": EOF exception found" )
kaouthera3f13ca22015-05-05 15:01:41 -07001291 main.log.error(self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001292 main.cleanup()
1293 main.exit()
1294
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001296 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001297 delete a switch from the mininet topology
1298 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001299 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001300 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001301 sw = name of the switch as a string
1302 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001303 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001304 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001305 response = self.execute(
1306 cmd=command,
1307 prompt="mininet>",
1308 timeout=10 )
1309 if re.search( "no switch named", response ):
1310 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001311 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001312 elif re.search( "Error", response ):
1313 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001314 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001315 elif re.search( "usage:", response ):
1316 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001317 return main.FALSE
1318 else:
1319 return main.TRUE
1320 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001321 main.log.error( self.name + ": EOF exception found" )
1322 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001323 main.cleanup()
1324 main.exit()
1325
kelvin-onlabd3b64892015-01-20 13:26:24 -08001326 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001327 """
1328 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001329 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001330 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001331 NOTE: cannot currently specify what type of link
1332 required params:
1333 node1 = the string node name of the first endpoint of the link
1334 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001335 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001336 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001337 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001338 response = self.execute(
1339 cmd=command,
1340 prompt="mininet>",
1341 timeout=10 )
1342 if re.search( "doesnt exist!", response ):
1343 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001344 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001345 elif re.search( "Error", response ):
1346 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001347 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001348 elif re.search( "usage:", response ):
1349 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001350 return main.FALSE
1351 else:
1352 return main.TRUE
1353 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001354 main.log.error( self.name + ": EOF exception found" )
1355 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001356 main.cleanup()
1357 main.exit()
1358
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001360 """
1361 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001362 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001363 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001364 required params:
1365 node1 = the string node name of the first endpoint of the link
1366 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001367 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001368 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001369 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001370 response = self.execute(
1371 cmd=command,
1372 prompt="mininet>",
1373 timeout=10 )
1374 if re.search( "no node named", response ):
1375 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001376 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001377 elif re.search( "Error", response ):
1378 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001379 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001380 elif re.search( "usage:", response ):
1381 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001382 return main.FALSE
1383 else:
1384 return main.TRUE
1385 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001386 main.log.error( self.name + ": EOF exception found" )
1387 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001388 main.cleanup()
1389 main.exit()
1390
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001392 """
Jon Hallb1290e82014-11-18 16:17:48 -05001393 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001394 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001395 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001396 NOTE: cannot currently specify what type of host
1397 required params:
1398 hostname = the string hostname
1399 optional key-value params
1400 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001401 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001402 """
1403 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001404 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001405 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001406 response = self.execute(
1407 cmd=command,
1408 prompt="mininet>",
1409 timeout=10 )
1410 if re.search( "already exists!", response ):
1411 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001412 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001413 elif re.search( "doesnt exists!", response ):
1414 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001415 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001416 elif re.search( "Error", response ):
1417 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001418 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001419 elif re.search( "usage:", response ):
1420 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001421 return main.FALSE
1422 else:
1423 return main.TRUE
1424 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001425 main.log.error( self.name + ": EOF exception found" )
1426 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001427 main.cleanup()
1428 main.exit()
1429
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001431 """
1432 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001433 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001434 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001435 NOTE: this uses a custom mn function
1436 required params:
1437 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001438 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001439 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001440 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001441 response = self.execute(
1442 cmd=command,
1443 prompt="mininet>",
1444 timeout=10 )
1445 if re.search( "no host named", response ):
1446 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001447 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001448 elif re.search( "Error", response ):
1449 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001450 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001451 elif re.search( "usage:", response ):
1452 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001453 return main.FALSE
1454 else:
1455 return main.TRUE
1456 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001457 main.log.error( self.name + ": EOF exception found" )
1458 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001459 main.cleanup()
1460 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001461
Jon Hall7eb38402015-01-08 17:19:54 -08001462 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001463 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001464 Called at the end of the test to stop the mininet and
1465 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001466 """
1467 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001468 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001469 timeout=2)
Jon Hall390696c2015-05-05 17:13:41 -07001470 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001471 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001472 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001473 elif i == 1:
1474 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001475 # print "Disconnecting Mininet"
1476 if self.handle:
1477 self.handle.sendline( "exit" )
1478 self.handle.expect( "exit" )
1479 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001480 else:
1481 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001482 return response
1483
Hari Krishnab35c6d02015-03-18 11:13:51 -07001484 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001485 """
Jon Hall21270ac2015-02-16 17:59:55 -08001486 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001487 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001488 main.FALSE if the pexpect handle does not exist.
1489
Jon Halld61331b2015-02-17 16:35:47 -08001490 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001491 """
Jon Hall21270ac2015-02-16 17:59:55 -08001492
Jon Halld61331b2015-02-17 16:35:47 -08001493 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001494 response = ''
1495 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001496 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001497 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001498 i = self.handle.expect( [ 'mininet>',
1499 '\$',
1500 pexpect.EOF,
1501 pexpect.TIMEOUT ],
1502 timeout )
1503 if i == 0:
1504 main.log.info( "Exiting mininet..." )
1505
Jon Hall7eb38402015-01-08 17:19:54 -08001506 response = self.execute(
1507 cmd="exit",
1508 prompt="(.*)",
1509 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001510 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001511 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001512 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001513
kelvin-onlab56a3f462015-02-06 14:04:43 -08001514 if i == 1:
1515 main.log.info( " Mininet trying to exit while not " +
1516 "in the mininet prompt" )
1517 elif i == 2:
1518 main.log.error( "Something went wrong exiting mininet" )
1519 elif i == 3: # timeout
1520 main.log.error( "Something went wrong exiting mininet " +
1521 "TIMEOUT" )
1522
Hari Krishnab35c6d02015-03-18 11:13:51 -07001523 if fileName:
1524 self.handle.sendline("")
1525 self.handle.expect('\$')
1526 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001527 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001528 main.log.error( self.name + ": EOF exception found" )
1529 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001530 main.cleanup()
1531 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001532 else:
1533 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001534 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001535 return response
1536
kelvin-onlabf0594d72015-05-19 17:25:12 -07001537 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001538 """
1539 Description:
1540 Sends arp message from mininet host for hosts discovery
1541 Required:
1542 host - hosts name
1543 Optional:
1544 ip - ip address that does not exist in the network so there would
1545 be no reply.
1546 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001547 if ethDevice:
1548 ethDevice = '-I ' + ethDevice + ' '
1549 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001550 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001551 main.log.warn( "Sending: " + cmd )
1552 self.handle.sendline( cmd )
1553 response = self.handle.before
1554 self.handle.sendline( "" )
1555 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001556 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001557
1558 except pexpect.EOF:
1559 main.log.error( self.name + ": EOF exception found" )
1560 main.log.error( self.name + ": " + self.handle.before )
1561 main.cleanup()
1562 main.exit()
admin07529932013-11-22 14:58:28 -08001563
Jon Hall7eb38402015-01-08 17:19:54 -08001564 def decToHex( self, num ):
1565 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001566
Jon Hall7eb38402015-01-08 17:19:54 -08001567 def getSwitchFlowCount( self, switch ):
1568 """
1569 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001570 if self.handle:
1571 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1572 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001573 response = self.execute(
1574 cmd=cmd,
1575 prompt="mininet>",
1576 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001577 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001578 main.log.error( self.name + ": EOF exception found" )
1579 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001580 main.cleanup()
1581 main.exit()
1582 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001583 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001584 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001585 main.log.info(
1586 "Couldn't find flows on switch %s, found: %s" %
1587 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001588 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001589 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001590 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001591 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001592
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 def checkFlows( self, sw, dumpFormat=None ):
1594 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001595 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001597 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001598 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001599 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001600 response = self.execute(
1601 cmd=command,
1602 prompt="mininet>",
1603 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001604 return response
1605 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001606 main.log.error( self.name + ": EOF exception found" )
1607 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001608 main.cleanup()
1609 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001610
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001612 """
Jon Hallefbd9792015-03-05 16:11:36 -08001613 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001614 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001615 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001616 self.handle.sendline( "" )
1617 self.handle.expect( "mininet>" )
1618 self.handle.sendline(
1619 "sh sudo tcpdump -n -i " +
1620 intf +
1621 " " +
1622 port +
1623 " -w " +
1624 filename.strip() +
1625 " &" )
1626 self.handle.sendline( "" )
1627 i = self.handle.expect( [ 'No\ssuch\device',
1628 'listening\son',
1629 pexpect.TIMEOUT,
1630 "mininet>" ],
1631 timeout=10 )
1632 main.log.warn( self.handle.before + self.handle.after )
1633 self.handle.sendline( "" )
1634 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001635 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001636 main.log.error(
1637 self.name +
1638 ": tcpdump - No such device exists. " +
1639 "tcpdump attempted on: " +
1640 intf )
admin2a9548d2014-06-17 14:08:07 -07001641 return main.FALSE
1642 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001643 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001644 return main.TRUE
1645 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001646 main.log.error(
1647 self.name +
1648 ": tcpdump command timed out! Check interface name," +
1649 " given interface was: " +
1650 intf )
admin2a9548d2014-06-17 14:08:07 -07001651 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001652 elif i == 3:
1653 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001654 return main.TRUE
1655 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001656 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001657 return main.FALSE
1658 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001659 main.log.error( self.name + ": EOF exception found" )
1660 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001661 main.cleanup()
1662 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001663 except Exception:
1664 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001665 main.cleanup()
1666 main.exit()
1667
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001669 """
1670 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001671 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001672 self.handle.sendline( "sh sudo pkill tcpdump" )
1673 self.handle.expect( "mininet>" )
1674 self.handle.sendline( "" )
1675 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001676 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001677 main.log.error( self.name + ": EOF exception found" )
1678 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001679 main.cleanup()
1680 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001681 except Exception:
1682 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001683 main.cleanup()
1684 main.exit()
1685
kelvin-onlabd3b64892015-01-20 13:26:24 -08001686 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001687 """
1688 Compare mn and onos switches
1689 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001690 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001691
Jon Hall7eb38402015-01-08 17:19:54 -08001692 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001693 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001694 output = { "switches": [] }
1695 # iterate through the MN topology and pull out switches and and port
1696 # info
1697 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001698 ports = []
1699 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001700 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001701 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001702 'name': port.name } )
1703 output[ 'switches' ].append( {
1704 "name": switch.name,
1705 "dpid": str( switch.dpid ).zfill( 16 ),
1706 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001707
Jon Hall7eb38402015-01-08 17:19:54 -08001708 # print "mn"
1709 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001710 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001711 # indent=4,
1712 # separators=( ',', ': ' ) )
1713 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001714 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001715 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001716 # indent=4,
1717 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001718
1719 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001720 mnDPIDs = []
1721 for switch in output[ 'switches' ]:
1722 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001723 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001724 # print "List of Mininet switch DPID's"
1725 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001727 main.log.error(
1728 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07001729 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001730 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001732 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001733 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001734 if switch[ 'available' ]:
1735 onosDPIDs.append(
1736 switch[ 'id' ].replace(
1737 ":",
1738 '' ).replace(
1739 "of",
1740 '' ).lower() )
1741 # else:
1742 # print "Switch is unavailable:"
1743 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001744 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001745 # print "List of ONOS switch DPID's"
1746 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001747
Jon Hall7eb38402015-01-08 17:19:54 -08001748 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001750 main.log.report( "Switches in MN but not in ONOS:" )
1751 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1752 main.log.report( str( list1 ) )
1753 main.log.report( "Switches in ONOS but not in MN:" )
1754 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001755 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001756 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001757 switchResults = main.TRUE
1758 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001759
kelvin-onlabd3b64892015-01-20 13:26:24 -08001760 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001761 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001762 Compare mn and onos ports
1763 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001765
Jon Hallfbc828e2015-01-06 17:30:19 -08001766 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001767 1. This uses the sts TestONTopology object
1768 2. numpy - "sudo pip install numpy"
1769
Jon Hall7eb38402015-01-08 17:19:54 -08001770 """
1771 # FIXME: this does not look for extra ports in ONOS, only checks that
1772 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001773 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001775 output = { "switches": [] }
1776 # iterate through the MN topology and pull out switches and and port
1777 # info
1778 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001779 ports = []
1780 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001781 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001782 tmpPort = { 'of_port': port.port_no,
1783 'mac': str( port.hw_addr ).replace( '\'', '' ),
1784 'name': port.name,
1785 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001786
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001788 tmpSwitch = { 'name': switch.name,
1789 'dpid': str( switch.dpid ).zfill( 16 ),
1790 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001791
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001793
Jon Hall7eb38402015-01-08 17:19:54 -08001794 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 for mnSwitch in output[ 'switches' ]:
1796 mnPorts = []
1797 onosPorts = []
1798 switchResult = main.TRUE
1799 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001800 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 mnPorts.append( port[ 'of_port' ] )
1802 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001803 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001804 # print onosSwitch
1805 if onosSwitch[ 'device' ][ 'available' ]:
1806 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001807 ':',
1808 '' ).replace(
1809 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001810 '' ) == mnSwitch[ 'dpid' ]:
1811 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001812 if port[ 'isEnabled' ]:
1813 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 # onosPorts.append( 'local' )
1815 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001816 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001818 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001819 mnPorts.sort( key=float )
1820 onosPorts.sort( key=float )
1821 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1822 # print "\tmn_ports[] = ", mnPorts
1823 # print "\tonos_ports[] = ", onosPorts
1824 mnPortsLog = mnPorts
1825 onosPortsLog = onosPorts
1826 mnPorts = [ x for x in mnPorts ]
1827 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001828
Jon Hall7eb38402015-01-08 17:19:54 -08001829 # TODO: handle other reserved port numbers besides LOCAL
1830 # NOTE: Reserved ports
1831 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1832 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 for mnPort in mnPortsLog:
1834 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001835 # don't set results to true here as this is just one of
1836 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001837 mnPorts.remove( mnPort )
1838 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001839 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001840 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001841 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001842 if 65534 in mnPorts:
1843 mnPorts.remove( 65534 )
1844 if long( uint64( -2 ) ) in onosPorts:
1845 onosPorts.remove( long( uint64( -2 ) ) )
1846 if len( mnPorts ): # the ports of this switch don't match
1847 switchResult = main.FALSE
1848 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1849 if len( onosPorts ): # the ports of this switch don't match
1850 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001851 main.log.warn(
1852 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 str( onosPorts ) )
1854 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001855 main.log.report(
1856 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001857 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1858 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1859 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1860 portsResults = portsResults and switchResult
1861 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001862
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001864 """
1865 Compare mn and onos links
1866 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001868
Jon Hall7eb38402015-01-08 17:19:54 -08001869 This uses the sts TestONTopology object"""
1870 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001871 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001872 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001873 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001874 # iterate through the MN topology and pull out switches and and port
1875 # info
1876 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001877 # print "Iterating though switches as seen by Mininet"
1878 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001879 ports = []
1880 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001881 # print port.hw_addr.toStr( separator='' )
1882 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001883 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001884 'name': port.name } )
1885 output[ 'switches' ].append( {
1886 "name": switch.name,
1887 "dpid": str( switch.dpid ).zfill( 16 ),
1888 "ports": ports } )
1889 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001890
kelvin-onlabd3b64892015-01-20 13:26:24 -08001891 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001892 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001893 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001894 if 2 * len( mnLinks ) == len( onos ):
1895 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001896 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001897 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001898 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001899 "Mininet has " + str( len( mnLinks ) ) +
1900 " bidirectional links and ONOS has " +
1901 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001902
Jon Hall7eb38402015-01-08 17:19:54 -08001903 # iterate through MN links and check if an ONOS link exists in
1904 # both directions
1905 # NOTE: Will currently only show mn links as down if they are
1906 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001907 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001908 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001909 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001910 # print "Link: %s" % link
1911 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001912 node1 = None
1913 port1 = None
1914 node2 = None
1915 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 firstDir = main.FALSE
1917 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001918 for switch in output[ 'switches' ]:
1919 # print "Switch: %s" % switch[ 'name' ]
1920 if switch[ 'name' ] == link.node1.name:
1921 node1 = switch[ 'dpid' ]
1922 for port in switch[ 'ports' ]:
1923 if str( port[ 'name' ] ) == str( link.port1 ):
1924 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001925 if node1 is not None and node2 is not None:
1926 break
Jon Hall7eb38402015-01-08 17:19:54 -08001927 if switch[ 'name' ] == link.node2.name:
1928 node2 = switch[ 'dpid' ]
1929 for port in switch[ 'ports' ]:
1930 if str( port[ 'name' ] ) == str( link.port2 ):
1931 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001932 if node1 is not None and node2 is not None:
1933 break
1934
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 for onosLink in onos:
1936 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001937 ":",
1938 '' ).replace(
1939 "of",
1940 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001941 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001942 ":",
1943 '' ).replace(
1944 "of",
1945 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001946 onosPort1 = onosLink[ 'src' ][ 'port' ]
1947 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001948
Jon Hall72cf1dc2014-10-20 21:04:50 -04001949 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001950 if str( onosNode1 ) == str( node1 ) and str(
1951 onosNode2 ) == str( node2 ):
1952 if int( onosPort1 ) == int( port1 ) and int(
1953 onosPort2 ) == int( port2 ):
1954 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001955 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001956 main.log.warn(
1957 'The port numbers do not match for ' +
1958 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001959 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001960 'link %s/%s -> %s/%s' %
1961 ( node1,
1962 port1,
1963 node2,
1964 port2 ) +
1965 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001966 ( onosNode1,
1967 onosPort1,
1968 onosNode2,
1969 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001970
1971 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001972 elif ( str( onosNode1 ) == str( node2 ) and
1973 str( onosNode2 ) == str( node1 ) ):
1974 if ( int( onosPort1 ) == int( port2 )
1975 and int( onosPort2 ) == int( port1 ) ):
1976 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001977 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001978 main.log.warn(
1979 'The port numbers do not match for ' +
1980 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001981 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001982 'link %s/%s -> %s/%s' %
1983 ( node2,
1984 port2,
1985 node1,
1986 port1 ) +
1987 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 ( onosNode2,
1989 onosPort2,
1990 onosNode1,
1991 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001992 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001993 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001994 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001995 main.log.report(
1996 'ONOS does not have the link %s/%s -> %s/%s' %
1997 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001998 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001999 main.log.report(
2000 'ONOS does not have the link %s/%s -> %s/%s' %
2001 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002002 linkResults = linkResults and firstDir and secondDir
2003 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002004
Jon Hallff6b4b22015-02-23 09:25:15 -08002005 def compareHosts( self, topo, hostsJson ):
2006 """
2007 Compare mn and onos Hosts.
2008 Since Mininet hosts are quiet, ONOS will only know of them when they
2009 speak. For this reason, we will only check that the hosts in ONOS
2010 stores are in Mininet, and not vice versa.
2011 topo: sts TestONTopology object
2012 hostsJson: parsed json object from the onos hosts api
2013
2014 This uses the sts TestONTopology object"""
2015 import json
2016 hostResults = main.TRUE
2017 hosts = []
2018 # iterate through the MN topology and pull out hosts
2019 for mnHost in topo.graph.hosts:
2020 interfaces = []
2021 for intf in mnHost.interfaces:
2022 interfaces.append( {
2023 "name": intf.name, # str
2024 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
2025 # hw_addr is of type EthAddr, Not JSON serializable
2026 "hw_addr": str( intf.hw_addr ) } )
2027 hosts.append( {
2028 "name": mnHost.name, # str
2029 "interfaces": interfaces } ) # list
2030 for onosHost in hostsJson:
2031 onosMAC = onosHost[ 'mac' ].lower()
2032 match = False
2033 for mnHost in hosts:
2034 for mnIntf in mnHost[ 'interfaces' ]:
2035 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
2036 match = True
2037 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002038 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002039 pass # all is well
2040 else:
2041 # misssing ip
2042 main.log.error( "ONOS host " + onosHost[ 'id' ]
2043 + " has a different IP than " +
2044 "the Mininet host." )
2045 output = json.dumps(
2046 onosHost,
2047 sort_keys=True,
2048 indent=4,
2049 separators=( ',', ': ' ) )
2050 main.log.info( output )
2051 hostResults = main.FALSE
2052 if not match:
2053 hostResults = main.FALSE
2054 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2055 "corresponding Mininet host." )
2056 output = json.dumps( onosHost,
2057 sort_keys=True,
2058 indent=4,
2059 separators=( ',', ': ' ) )
2060 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002061 return hostResults
2062
kelvin-onlabd3b64892015-01-20 13:26:24 -08002063 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002064 """
2065 Returns a list of all hosts
2066 Don't ask questions just use it"""
2067 self.handle.sendline( "" )
2068 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002069
Jon Hall7eb38402015-01-08 17:19:54 -08002070 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2071 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002072
kelvin-onlabd3b64892015-01-20 13:26:24 -08002073 handlePy = self.handle.before
2074 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2075 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002076
Jon Hall7eb38402015-01-08 17:19:54 -08002077 self.handle.sendline( "" )
2078 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002079
kelvin-onlabd3b64892015-01-20 13:26:24 -08002080 hostStr = handlePy.replace( "]", "" )
2081 hostStr = hostStr.replace( "'", "" )
2082 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002083 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002084 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002085
kelvin-onlabd3b64892015-01-20 13:26:24 -08002086 return hostList
adminbae64d82013-08-01 10:50:15 -07002087
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002088 def getHosts( self ):
2089 """
2090 Returns a list of all hosts
2091 Don't ask questions just use it"""
2092 self.handle.sendline( "" )
2093 self.handle.expect( "mininet>" )
2094
2095 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2096 self.handle.expect( "mininet>" )
2097
2098 handlePy = self.handle.before
2099 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2100 handlePy = handlePy.rstrip()
2101
2102 self.handle.sendline( "" )
2103 self.handle.expect( "mininet>" )
2104
2105 hostStr = handlePy.replace( "]", "" )
2106 hostStr = hostStr.replace( "'", "" )
2107 hostStr = hostStr.replace( "[", "" )
2108 hostStr = hostStr.replace( " ", "" )
2109 hostList = hostStr.split( "," )
2110
2111 return hostList
2112
2113 def getSwitch( self ):
2114 """
2115 Returns a list of all switches
2116 Again, don't ask question just use it...
2117 """
2118 # get host list...
2119 hostList = self.getHosts()
2120 # Make host set
2121 hostSet = set( hostList )
2122
2123 # Getting all the nodes in mininet
2124 self.handle.sendline( "" )
2125 self.handle.expect( "mininet>" )
2126
2127 self.handle.sendline( "py [ node.name for node in net.values() ]" )
2128 self.handle.expect( "mininet>" )
2129
2130 handlePy = self.handle.before
2131 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2132 handlePy = handlePy.rstrip()
2133
2134 self.handle.sendline( "" )
2135 self.handle.expect( "mininet>" )
2136
2137 nodesStr = handlePy.replace( "]", "" )
2138 nodesStr = nodesStr.replace( "'", "" )
2139 nodesStr = nodesStr.replace( "[", "" )
2140 nodesStr = nodesStr.replace( " ", "" )
2141 nodesList = nodesStr.split( "," )
2142
2143 nodesSet = set( nodesList )
2144 # discarding default controller(s) node
2145 nodesSet.discard( 'c0' )
2146 nodesSet.discard( 'c1' )
2147 nodesSet.discard( 'c2' )
2148
2149 switchSet = nodesSet - hostSet
2150 switchList = list( switchSet )
2151
2152 return switchList
2153
Jon Hall7eb38402015-01-08 17:19:54 -08002154 def update( self ):
2155 """
2156 updates the port address and status information for
2157 each port in mn"""
2158 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002159 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002160 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002161 self.handle.sendline( "" )
2162 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002163
Jon Hall7eb38402015-01-08 17:19:54 -08002164 self.handle.sendline( "update" )
2165 self.handle.expect( "update" )
2166 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002167
Jon Hall7eb38402015-01-08 17:19:54 -08002168 self.handle.sendline( "" )
2169 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002170
Jon Hallb1290e82014-11-18 16:17:48 -05002171 return main.TRUE
2172 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002173 main.log.error( self.name + ": EOF exception found" )
2174 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002175 main.cleanup()
2176 main.exit()
2177
kaouthera3f13ca22015-05-05 15:01:41 -07002178 def assignVLAN( self, host, intf, vlan):
2179 """
2180 Add vlan tag to a host.
2181 Dependencies:
2182 This class depends on the "vlan" package
2183 $ sudo apt-get install vlan
2184 Configuration:
2185 Load the 8021q module into the kernel
2186 $sudo modprobe 8021q
2187
2188 To make this setup permanent:
2189 $ sudo su -c 'echo "8021q" >> /etc/modules'
2190 """
2191 if self.handle:
2192 try:
2193 # get the ip address of the host
2194 main.log.info("Get the ip address of the host")
2195 ipaddr = self.getIPAddress(host)
2196 print repr(ipaddr)
2197
2198 # remove IP from interface intf
2199 # Ex: h1 ifconfig h1-eth0 inet 0
2200 main.log.info("Remove IP from interface ")
2201 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2202 self.handle.sendline( cmd2 )
2203 self.handle.expect( "mininet>" )
2204 response = self.handle.before
2205 main.log.info ( "====> %s ", response)
2206
2207
2208 # create VLAN interface
2209 # Ex: h1 vconfig add h1-eth0 100
2210 main.log.info("Create Vlan")
2211 cmd3 = host + " vconfig add " + intf + " " + vlan
2212 self.handle.sendline( cmd3 )
2213 self.handle.expect( "mininet>" )
2214 response = self.handle.before
2215 main.log.info( "====> %s ", response )
2216
2217 # assign the host's IP to the VLAN interface
2218 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2219 main.log.info("Assign the host IP to the vlan interface")
2220 vintf = intf + "." + vlan
2221 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2222 self.handle.sendline( cmd4 )
2223 self.handle.expect( "mininet>" )
2224 response = self.handle.before
2225 main.log.info ( "====> %s ", response)
2226
2227
2228 return main.TRUE
2229 except pexpect.EOF:
2230 main.log.error( self.name + ": EOF exception found" )
2231 main.log.error( self.name + ": " + self.handle.before )
2232 return main.FALSE
2233
adminbae64d82013-08-01 10:50:15 -07002234if __name__ != "__main__":
2235 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002236 sys.modules[ __name__ ] = MininetCliDriver()
kaouthera3f13ca22015-05-05 15:01:41 -07002237
2238