blob: d3ca4dd4de8a5fd8609d7f26ccbab84df9f55443 [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
Jon Hall7eb38402015-01-08 17:19:54 -080042sys.path.append( "../" )
Jon Hall1ccf82c2014-10-15 14:55:16 -040043from math import pow
adminbae64d82013-08-01 10:50:15 -070044from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
kelvin-onlab50907142015-04-01 13:37:45 -070047class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080048
49 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
53 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080056 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070057 self.flag = 0
58
Jon Hall7eb38402015-01-08 17:19:54 -080059 def connect( self, **connectargs ):
60 """
61 Here the main is the TestON instance after creating
62 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080063 try:
64 for key in connectargs:
65 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080066
kelvin-onlaba1484582015-02-02 15:46:20 -080067 self.name = self.options[ 'name' ]
68 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070069 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080070 self ).connect(
71 user_name=self.user_name,
72 ip_address=self.ip_address,
73 port=None,
74 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080075
kelvin-onlaba1484582015-02-02 15:46:20 -080076 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080077 main.log.info( "Connection successful to the host " +
78 self.user_name +
79 "@" +
80 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080081 return main.TRUE
82 else:
83 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080084 self.user_name +
85 "@" +
86 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080087 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -080088 return main.FALSE
89 except pexpect.EOF:
90 main.log.error( self.name + ": EOF exception found" )
91 main.log.error( self.name + ": " + self.handle.before )
92 main.cleanup()
93 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080094 except Exception:
95 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -080096 main.cleanup()
97 main.exit()
98
kelvin-onlab10e8d392015-06-03 13:53:45 -070099 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800100 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700101 Description:
102 Starts Mininet accepts a topology(.py) file and/or an optional
103 argument, to start the mininet, as a parameter.
104 Can also send regular mininet command to load up desired topology.
105 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
106 Options:
107 topoFile = file path for topology file (.py)
108 args = extra option added when starting the topology from the file
109 mnCmd = Mininet command use to start topology
110 Returns:
111 main.TRUE if the mininet starts successfully, main.FALSE
112 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800113 """
Jon Hall7eb38402015-01-08 17:19:54 -0800114 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700115 # make sure old networks are cleaned up
116 main.log.info( self.name +
117 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800118 self.handle.sendline( "sudo mn -c" )
119 i = self.handle.expect( [ 'password\sfor\s',
120 'Cleanup\scomplete',
121 pexpect.EOF,
122 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800123 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800124 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700125 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800126 main.log.info( self.name + ": Sending sudo password" )
127 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800128 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800129 '\$',
130 pexpect.EOF,
131 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800132 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800133 if i == 1:
134 main.log.info( self.name + ": Clean" )
135 elif i == 2:
136 main.log.error( self.name + ": Connection terminated" )
137 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700138 main.log.error( self.name + ": Something while cleaning " +
139 "Mininet took too long... " )
140 # Craft the string to start mininet
141 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700142 if not mnCmd:
143 if topoFile is None or topoFile == '': # If no file is given
144 main.log.info( self.name + ": building fresh Mininet" )
145 cmdString += "mn "
146 if args is None or args == '':
147 # If no args given, use args from .topo file
148 args = self.options[ 'arg1' ] +\
149 " " + self.options[ 'arg2' ] +\
150 " --mac --controller " +\
151 self.options[ 'controller' ] + " " +\
152 self.options[ 'arg3' ]
153 else: # else only use given args
154 pass
155 # TODO: allow use of topo args and method args?
156 else: # Use given topology file
157 main.log.info( "Starting Mininet from topo file " + topoFile )
158 cmdString += topoFile + " "
159 if args is None:
160 args = ''
161 # TODO: allow use of args from .topo file?
162 cmdString += args
163 else:
164 main.log.info( "Starting Mininet topology using '" + mnCmd +
165 "' command" )
166 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700167 # Send the command and check if network started
168 self.handle.sendline( "" )
169 self.handle.expect( '\$' )
170 main.log.info( "Sending '" + cmdString + "' to " + self.name )
171 self.handle.sendline( cmdString )
172 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800173 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700174 'Exception',
175 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800176 pexpect.EOF,
177 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700178 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800179 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700180 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800181 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800182 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700183 response = str( self.handle.before +
184 self.handle.after )
185 self.handle.expect( '\$' )
186 response += str( self.handle.before +
187 self.handle.after )
188 main.log.error(
189 self.name +
190 ": Launching Mininet failed: " + response )
191 return main.FALSE
192 elif i == 2:
193 self.handle.expect( [ "\n",
194 pexpect.EOF,
195 pexpect.TIMEOUT ],
196 timeout )
197 main.log.info( self.handle.before )
198 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800199 main.log.error( self.name + ": Connection timeout" )
200 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700201 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800202 main.log.error(
203 self.name +
204 ": Something took too long... " )
205 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700206 # Why did we hit this part?
207 main.log.error( "startNet did not return correctly" )
208 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800209 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700210 main.log.error( self.name + ": Connection failed to the host " +
211 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800212 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700213 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800214
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800215 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400216 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800217 # In tree topology, if fanout arg is not given, by default it is 2
218 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400219 fanout = 2
220 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500221 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800222 while( k <= depth - 1 ):
223 count = count + pow( fanout, k )
224 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800225 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800226 while( k <= depth - 2 ):
227 # depth-2 gives you only core links and not considering
228 # edge links as seen by ONOS. If all the links including
229 # edge links are required, do depth-1
230 count = count + pow( fanout, k )
231 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800233 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800235
Jon Hall7eb38402015-01-08 17:19:54 -0800236 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800238 # by default it is 1
239 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400240 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 numSwitches = depth
242 numHostsPerSw = fanout
243 totalNumHosts = numSwitches * numHostsPerSw
244 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800245 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800247 topoDict = { "num_switches": int( numSwitches ),
248 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400249 return topoDict
250
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700252 """
253 Calculate the number of switches and links in a topo."""
254 # TODO: combine this function and numSwitchesNlinks
255 argList = self.options[ 'arg1' ].split( "," )
256 topoArgList = argList[ 0 ].split( " " )
257 argList = map( int, argList[ 1: ] )
258 topoArgList = topoArgList[ 1: ] + argList
259
260 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400261 return topoDict
262
kelvin-onlabc44f0192015-04-02 22:08:41 -0700263 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0):
Jon Hall7eb38402015-01-08 17:19:54 -0800264 """
265 Verifies the reachability of the hosts using pingall command.
266 Optional parameter timeout allows you to specify how long to
267 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700268 Optional:
Jon Hall390696c2015-05-05 17:13:41 -0700269 timeout(seconds) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700270 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700271 ping
272 acceptableFailed - Set the number of acceptable failed pings for the
273 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800274 Returns:
275 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700276 otherwise main.FALSE
277 """
278 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700279 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700280 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700281 if self.handle:
282 main.log.info(
283 self.name +
284 ": Checking reachabilty to the hosts using pingall" )
285 response = ""
286 failedPings = 0
287 returnValue = main.TRUE
288 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700289 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700290 while True:
291 i = self.handle.expect( [ "mininet>","X",
292 pexpect.EOF,
293 pexpect.TIMEOUT ],
294 timeout )
295 if i == 0:
296 main.log.info( self.name + ": pingall finished")
297 response += self.handle.before
298 break
299 elif i == 1:
300 response += self.handle.before + self.handle.after
301 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700302 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700303 returnValue = main.FALSE
304 if shortCircuit:
305 main.log.error( self.name +
306 ": Aborting pingall - "
307 + str( failedPings ) +
308 " pings failed" )
309 break
Jon Hall390696c2015-05-05 17:13:41 -0700310 if ( time.time() - startTime ) > timeout:
311 returnValue = main.FALSE
312 main.log.error( self.name +
313 ": Aborting pingall - " +
314 "Function took too long " )
315 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700316 elif i == 2:
317 main.log.error( self.name +
318 ": EOF exception found" )
319 main.log.error( self.name + ": " +
320 self.handle.before )
321 main.cleanup()
322 main.exit()
323 elif i == 3:
324 response += self.handle.before
325 main.log.error( self.name +
326 ": TIMEOUT exception found" )
327 main.log.error( self.name +
328 ": " +
329 str( response ) )
330 # NOTE: Send ctrl-c to make sure pingall is done
331 self.handle.sendline( "\x03" )
332 self.handle.expect( "Interrupt" )
333 self.handle.expect( "mininet>" )
334 break
335 pattern = "Results\:"
336 main.log.info( "Pingall output: " + str( response ) )
337 if re.search( pattern, response ):
338 main.log.info( self.name + ": Pingall finished with "
339 + str( failedPings ) + " failed pings" )
340 return returnValue
341 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700342 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700343 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700344 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700345 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700346 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700347 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700348 main.log.error( self.name + ": Connection failed to the host" )
349 main.cleanup()
350 main.exit()
351 except pexpect.TIMEOUT:
352 if response:
353 main.log.info( "Pingall output: " + str( response ) )
354 main.log.error( self.name + ": pexpect.TIMEOUT found" )
355 return main.FALSE
356 except pexpect.EOF:
357 main.log.error( self.name + ": EOF exception found" )
358 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500359 main.cleanup()
360 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700361
Jon Hall7eb38402015-01-08 17:19:54 -0800362 def fpingHost( self, **pingParams ):
363 """
364 Uses the fping package for faster pinging...
365 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800366 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800367 command = args[ "SRC" ] + \
368 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
369 self.handle.sendline( command )
370 self.handle.expect(
371 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
372 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
373 response = self.handle.before
374 if re.search( ":\s-", response ):
375 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700376 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800377 elif re.search( ":\s\d{1,2}\.\d\d", response ):
378 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700379 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800380 main.log.info( self.name + ": Install fping on mininet machine... " )
381 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700382 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800383
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400384 def pingallHosts( self, hostList, pingType='ipv4' ):
385 """
kelvin-onlab2ff57022015-05-29 10:48:51 -0700386 Ping all specified hosts with a specific ping type
387
388 Acceptable pingTypes:
389 - 'ipv4'
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400390 - 'ipv6'
kelvin-onlab2ff57022015-05-29 10:48:51 -0700391
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400392 Acceptable hostList:
393 - ['h1','h2','h3','h4']
kelvin-onlab2ff57022015-05-29 10:48:51 -0700394
395 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400396 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700397
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400398 Returns main.FALSE if one or more of hosts specified
399 cannot reach each other"""
kelvin-onlab2ff57022015-05-29 10:48:51 -0700400
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400401 if pingType == "ipv4":
kelvin-onlab2ff57022015-05-29 10:48:51 -0700402 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400403 elif pingType == "ipv6":
404 cmd = " ping6 -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400405 else:
406 main.log.warn( "Invalid pingType specified" )
407 return
408
409 try:
410 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700411
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400412 isReachable = main.TRUE
413
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400414 for host in hostList:
415 listIndex = hostList.index(host)
416 # List of hosts to ping other than itself
417 pingList = hostList[:listIndex] + hostList[(listIndex+1):]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700418
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400419 for temp in pingList:
420 # Current host pings all other hosts specified
kelvin-onlab2ff57022015-05-29 10:48:51 -0700421 pingCmd = str(host) + cmd + str(temp)
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400422 self.handle.sendline( pingCmd )
423 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
424 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
425 response = self.handle.before
426 if re.search( ',\s0\%\spacket\sloss', response ):
427 main.log.info( str(host) + " -> " + str(temp) )
428 else:
429 main.log.info( str(host) + " -> X ("+str(temp)+") "
kelvin-onlab2ff57022015-05-29 10:48:51 -0700430 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400431 # One of the host to host pair is unreachable
432 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400433
kelvin-onlab2ff57022015-05-29 10:48:51 -0700434 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400435
436 except pexpect.EOF:
437 main.log.error( self.name + ": EOF exception found" )
438 main.log.error( self.name + ": " + self.handle.before )
439 main.cleanup()
440 main.exit()
441
Jon Hall7eb38402015-01-08 17:19:54 -0800442 def pingHost( self, **pingParams ):
443 """
444 Ping from one mininet host to another
445 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800446 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800447 command = args[ "SRC" ] + " ping " + \
448 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700449 try:
Jon Hall61282e32015-03-19 11:34:11 -0700450 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800451 self.handle.sendline( command )
452 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700453 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800454 main.log.error(
455 self.name +
456 ": timeout when waiting for response from mininet" )
457 main.log.error( "response: " + str( self.handle.before ) )
458 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700459 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800460 main.log.error(
461 self.name +
462 ": timeout when waiting for response from mininet" )
463 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700464 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800465 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800466 main.log.error( self.name + ": EOF exception found" )
467 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700468 main.cleanup()
469 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800470 main.log.info( self.name + ": Ping Response: " + response )
471 if re.search( ',\s0\%\spacket\sloss', response ):
472 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800473 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700474 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800475 else:
476 main.log.error(
477 self.name +
478 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800479 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700480 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800481
Jon Hall7eb38402015-01-08 17:19:54 -0800482 def checkIP( self, host ):
483 """
484 Verifies the host's ip configured or not."""
485 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700486 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800487 response = self.execute(
488 cmd=host +
489 " ifconfig",
490 prompt="mininet>",
491 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800492 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800493 main.log.error( self.name + ": EOF exception found" )
494 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700495 main.cleanup()
496 main.exit()
adminbae64d82013-08-01 10:50:15 -0700497
Jon Hall7eb38402015-01-08 17:19:54 -0800498 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800499 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
500 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
501 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
502 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
503 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800504 # pattern = "inet addr:10.0.0.6"
505 if re.search( pattern, response ):
506 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700507 return main.TRUE
508 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800509 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700510 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800511 else:
512 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800513
Jon Hall7eb38402015-01-08 17:19:54 -0800514 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800515 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700516 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800517 response = self.execute(
518 cmd="h1 /usr/sbin/sshd -D&",
519 prompt="mininet>",
520 timeout=10 )
521 response = self.execute(
522 cmd="h4 /usr/sbin/sshd -D&",
523 prompt="mininet>",
524 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700525 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800526 vars( self )[ key ] = connectargs[ key ]
527 response = self.execute(
528 cmd="xterm h1 h4 ",
529 prompt="mininet>",
530 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800531 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800532 main.log.error( self.name + ": EOF exception found" )
533 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700534 main.cleanup()
535 main.exit()
adminbae64d82013-08-01 10:50:15 -0700536 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800537 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700538 if self.flag == 0:
539 self.flag = 1
540 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800541 else:
adminbae64d82013-08-01 10:50:15 -0700542 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800543
kelvin-onlaba1484582015-02-02 15:46:20 -0800544 def moveHost( self, host, oldSw, newSw, ):
545 """
546 Moves a host from one switch to another on the fly
547 Note: The intf between host and oldSw when detached
548 using detach(), will still show up in the 'net'
549 cmd, because switch.detach() doesn't affect switch.intfs[]
550 (which is correct behavior since the interfaces
551 haven't moved).
552 """
553 if self.handle:
554 try:
555 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800556 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
557 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800558 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800559 response = self.execute( cmd=cmd,
560 prompt="mininet>",
561 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800562
563 # Determine hostintf and Oldswitchintf
564 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800565 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800566 print "cmd2= ", cmd
567 self.handle.sendline( cmd )
568 self.handle.expect( "mininet>" )
569
shahshreya73537862015-02-11 15:15:24 -0800570 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800571 cmd = "px ipaddr = hintf.IP()"
572 print "cmd3= ", cmd
573 self.handle.sendline( cmd )
574 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800575
576 cmd = "px macaddr = hintf.MAC()"
577 print "cmd3= ", cmd
578 self.handle.sendline( cmd )
579 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800580
581 # Detach interface between oldSw-host
582 cmd = "px " + oldSw + ".detach( sintf )"
583 print "cmd4= ", cmd
584 self.handle.sendline( cmd )
585 self.handle.expect( "mininet>" )
586
587 # Add link between host-newSw
588 cmd = "py net.addLink(" + host + "," + newSw + ")"
589 print "cmd5= ", cmd
590 self.handle.sendline( cmd )
591 self.handle.expect( "mininet>" )
592
593 # Determine hostintf and Newswitchintf
594 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800595 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800596 print "cmd6= ", cmd
597 self.handle.sendline( cmd )
598 self.handle.expect( "mininet>" )
599
600 # Attach interface between newSw-host
601 cmd = "px " + newSw + ".attach( sintf )"
602 print "cmd3= ", cmd
603 self.handle.sendline( cmd )
604 self.handle.expect( "mininet>" )
605
606 # Set ipaddress of the host-newSw interface
607 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
608 print "cmd7 = ", cmd
609 self.handle.sendline( cmd )
610 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800611
612 # Set macaddress of the host-newSw interface
613 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
614 print "cmd8 = ", cmd
615 self.handle.sendline( cmd )
616 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800617
618 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800619 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800620 self.handle.sendline( cmd )
621 self.handle.expect( "mininet>" )
622 print "output = ", self.handle.before
623
624 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800625 cmd = host + " ifconfig"
626 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800627 self.handle.sendline( cmd )
628 self.handle.expect( "mininet>" )
629 print "ifconfig o/p = ", self.handle.before
630
631 return main.TRUE
632 except pexpect.EOF:
633 main.log.error( self.name + ": EOF exception found" )
634 main.log.error( self.name + ": " + self.handle.before )
635 return main.FALSE
636
Jon Hall7eb38402015-01-08 17:19:54 -0800637 def changeIP( self, host, intf, newIP, newNetmask ):
638 """
639 Changes the ip address of a host on the fly
640 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800641 if self.handle:
642 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800643 cmd = host + " ifconfig " + intf + " " + \
644 newIP + " " + 'netmask' + " " + newNetmask
645 self.handle.sendline( cmd )
646 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800647 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800648 main.log.info( "response = " + response )
649 main.log.info(
650 "Ip of host " +
651 host +
652 " changed to new IP " +
653 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800654 return main.TRUE
655 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800656 main.log.error( self.name + ": EOF exception found" )
657 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800658 return main.FALSE
659
Jon Hall7eb38402015-01-08 17:19:54 -0800660 def changeDefaultGateway( self, host, newGW ):
661 """
662 Changes the default gateway of a host
663 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800664 if self.handle:
665 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800666 cmd = host + " route add default gw " + newGW
667 self.handle.sendline( cmd )
668 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800669 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800670 main.log.info( "response = " + response )
671 main.log.info(
672 "Default gateway of host " +
673 host +
674 " changed to " +
675 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800676 return main.TRUE
677 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800678 main.log.error( self.name + ": EOF exception found" )
679 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800680 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800681
Jon Hall7eb38402015-01-08 17:19:54 -0800682 def addStaticMACAddress( self, host, GW, macaddr ):
683 """
Jon Hallefbd9792015-03-05 16:11:36 -0800684 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800685 if self.handle:
686 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800687 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
688 cmd = host + " arp -s " + GW + " " + macaddr
689 self.handle.sendline( cmd )
690 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800691 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800692 main.log.info( "response = " + response )
693 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800694 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800695 GW +
696 " changed to " +
697 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800698 return main.TRUE
699 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800700 main.log.error( self.name + ": EOF exception found" )
701 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800702 return main.FALSE
703
Jon Hall7eb38402015-01-08 17:19:54 -0800704 def verifyStaticGWandMAC( self, host ):
705 """
706 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800707 if self.handle:
708 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800709 # h1 arp -an
710 cmd = host + " arp -an "
711 self.handle.sendline( cmd )
712 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800713 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800714 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800715 return main.TRUE
716 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800717 main.log.error( self.name + ": EOF exception found" )
718 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800719 return main.FALSE
720
Jon Hall7eb38402015-01-08 17:19:54 -0800721 def getMacAddress( self, host ):
722 """
723 Verifies the host's ip configured or not."""
724 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700725 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800726 response = self.execute(
727 cmd=host +
728 " ifconfig",
729 prompt="mininet>",
730 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800731 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700734 main.cleanup()
735 main.exit()
adminbae64d82013-08-01 10:50:15 -0700736
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700737 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 macAddressSearch = re.search( pattern, response, re.I )
739 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.info(
741 self.name +
742 ": Mac-Address of Host " +
743 host +
744 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 macAddress )
746 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700747 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700749
Jon Hall7eb38402015-01-08 17:19:54 -0800750 def getInterfaceMACAddress( self, host, interface ):
751 """
752 Return the IP address of the interface on the given host"""
753 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700754 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800755 response = self.execute( cmd=host + " ifconfig " + interface,
756 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800757 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800758 main.log.error( self.name + ": EOF exception found" )
759 main.log.error( self.name + ": " + self.handle.before )
760 main.cleanup()
761 main.exit()
762
763 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 macAddressSearch = re.search( pattern, response, re.I )
765 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800766 main.log.info( "No mac address found in %s" % response )
767 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800769 main.log.info(
770 "Mac-Address of " +
771 host +
772 ":" +
773 interface +
774 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 macAddress )
776 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800777 else:
778 main.log.error( "Connection failed to the host" )
779
780 def getIPAddress( self, host ):
781 """
782 Verifies the host's ip configured or not."""
783 if self.handle:
784 try:
785 response = self.execute(
786 cmd=host +
787 " ifconfig",
788 prompt="mininet>",
789 timeout=10 )
790 except pexpect.EOF:
791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700793 main.cleanup()
794 main.exit()
adminbae64d82013-08-01 10:50:15 -0700795
796 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800797 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800798 main.log.info(
799 self.name +
800 ": IP-Address of Host " +
801 host +
802 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 ipAddressSearch.group( 1 ) )
804 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800805 else:
806 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800807
Jon Hall7eb38402015-01-08 17:19:54 -0800808 def getSwitchDPID( self, switch ):
809 """
810 return the datapath ID of the switch"""
811 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700812 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700813 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 response = self.execute(
815 cmd=cmd,
816 prompt="mininet>",
817 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800818 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700821 main.cleanup()
822 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800823 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800824 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700825 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800826 main.log.info(
827 "Couldn't find DPID for switch %s, found: %s" %
828 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700829 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800830 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700831 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800832 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700833
Jon Hall7eb38402015-01-08 17:19:54 -0800834 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700835 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800836 self.handle.sendline( "" )
837 self.expect( "mininet>" )
838 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700839 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800840 response = self.execute(
841 cmd=cmd,
842 prompt="mininet>",
843 timeout=10 )
844 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700845 response = self.handle.before
846 return response
847 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800848 main.log.error( self.name + ": EOF exception found" )
849 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700850 main.cleanup()
851 main.exit()
852
Jon Hall7eb38402015-01-08 17:19:54 -0800853 def getInterfaces( self, node ):
854 """
855 return information dict about interfaces connected to the node"""
856 if self.handle:
857 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800858 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700859 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700860 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800861 response = self.execute(
862 cmd=cmd,
863 prompt="mininet>",
864 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800865 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700868 main.cleanup()
869 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700870 return response
871 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800872 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700873
Jon Hall7eb38402015-01-08 17:19:54 -0800874 def dump( self ):
875 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700876 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800877 response = self.execute(
878 cmd='dump',
879 prompt='mininet>',
880 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800881 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800882 main.log.error( self.name + ": EOF exception found" )
883 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700884 main.cleanup()
885 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700886 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800887
Jon Hall7eb38402015-01-08 17:19:54 -0800888 def intfs( self ):
889 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700890 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800891 response = self.execute(
892 cmd='intfs',
893 prompt='mininet>',
894 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800895 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800896 main.log.error( self.name + ": EOF exception found" )
897 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700898 main.cleanup()
899 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700900 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800901
Jon Hall7eb38402015-01-08 17:19:54 -0800902 def net( self ):
903 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700904 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800905 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800906 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700909 main.cleanup()
910 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700911 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800912
913 def iperf( self, host1, host2 ):
914 main.log.info(
915 self.name +
916 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700917 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800918 cmd1 = 'iperf ' + host1 + " " + host2
919 self.handle.sendline( cmd1 )
920 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800921 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800922 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800923 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800924 return main.TRUE
925 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800926 main.log.error( self.name + ": iperf test failed" )
927 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800928 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800929 main.log.error( self.name + ": EOF exception found" )
930 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800931 main.cleanup()
932 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800933
Jon Hall7eb38402015-01-08 17:19:54 -0800934 def iperfudp( self ):
935 main.log.info(
936 self.name +
937 ": Simple iperf TCP test between two " +
938 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700939 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800940 response = self.execute(
941 cmd='iperfudp',
942 prompt='mininet>',
943 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800944 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800945 main.log.error( self.name + ": EOF exception found" )
946 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700947 main.cleanup()
948 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700949 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800950
Jon Hall7eb38402015-01-08 17:19:54 -0800951 def nodes( self ):
952 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700953 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800954 response = self.execute(
955 cmd='nodes',
956 prompt='mininet>',
957 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800958 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700961 main.cleanup()
962 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700963 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800964
Jon Hall7eb38402015-01-08 17:19:54 -0800965 def pingpair( self ):
966 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700967 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800968 response = self.execute(
969 cmd='pingpair',
970 prompt='mininet>',
971 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800972 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800973 main.log.error( self.name + ": EOF exception found" )
974 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700975 main.cleanup()
976 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800977
Jon Hall7eb38402015-01-08 17:19:54 -0800978 if re.search( ',\s0\%\spacket\sloss', response ):
979 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800980 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700981 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800982 else:
983 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700985 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800986
Jon Hall7eb38402015-01-08 17:19:54 -0800987 def link( self, **linkargs ):
988 """
989 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800990 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800991 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
992 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
993 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
994 main.log.info(
995 "Bring link between '" +
996 end1 +
997 "' and '" +
998 end2 +
999 "' '" +
1000 option +
1001 "'" )
1002 command = "link " + \
1003 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001004 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001005 self.handle.sendline( command )
1006 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001007 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001010 main.cleanup()
1011 main.exit()
adminbae64d82013-08-01 10:50:15 -07001012 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001013
Jon Hall7eb38402015-01-08 17:19:54 -08001014 def yank( self, **yankargs ):
1015 """
1016 yank a mininet switch interface to a host"""
1017 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001018 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001019 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1020 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1021 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001022 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001023 response = self.execute(
1024 cmd=command,
1025 prompt="mininet>",
1026 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001027 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001028 main.log.error( self.name + ": EOF exception found" )
1029 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001030 main.cleanup()
1031 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001032 return main.TRUE
1033
Jon Hall7eb38402015-01-08 17:19:54 -08001034 def plug( self, **plugargs ):
1035 """
1036 plug the yanked mininet switch interface to a switch"""
1037 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001038 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001039 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1040 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1041 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001042 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001043 response = self.execute(
1044 cmd=command,
1045 prompt="mininet>",
1046 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001047 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001048 main.log.error( self.name + ": EOF exception found" )
1049 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001050 main.cleanup()
1051 main.exit()
adminbae64d82013-08-01 10:50:15 -07001052 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001053
Jon Hall7eb38402015-01-08 17:19:54 -08001054 def dpctl( self, **dpctlargs ):
1055 """
1056 Run dpctl command on all switches."""
1057 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001058 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001059 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1060 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1061 command = "dpctl " + cmd + " " + str( cmdargs )
1062 try:
1063 response = self.execute(
1064 cmd=command,
1065 prompt="mininet>",
1066 timeout=10 )
1067 except pexpect.EOF:
1068 main.log.error( self.name + ": EOF exception found" )
1069 main.log.error( self.name + ": " + self.handle.before )
1070 main.cleanup()
1071 main.exit()
1072 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001073
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -08001075 #FIXME: What uses this? This should be refactored to get
1076 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 fileInput = path + '/lib/Mininet/INSTALL'
1078 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001079 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001081 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001082 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001083 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001084 return version
adminbae64d82013-08-01 10:50:15 -07001085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001087 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001088 Parameters:
1089 sw: The name of an OVS switch. Example "s1"
1090 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001091 The output of the command from the mininet cli
1092 or main.FALSE on timeout"""
1093 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001094 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001095 response = self.execute(
1096 cmd=command,
1097 prompt="mininet>",
1098 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001099 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001100 return response
admin2a9548d2014-06-17 14:08:07 -07001101 else:
1102 return main.FALSE
1103 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001106 main.cleanup()
1107 main.exit()
adminbae64d82013-08-01 10:50:15 -07001108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001110 """
1111 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001112 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001113 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001114
1115 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001116 for j in range( count ):
1117 argstring = argstring + ",IP" + \
1118 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001119 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001120
Jon Hall7eb38402015-01-08 17:19:54 -08001121 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1122 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001123 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001124 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001125
Jon Hall7eb38402015-01-08 17:19:54 -08001126 command = "sh ovs-vsctl set-controller s" + \
1127 str( sw ) + " " + ptcpB + " "
1128 for j in range( count ):
1129 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001130 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001131 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1132 ip = args[
1133 "IP" +
1134 str( i ) ] if args[
1135 "IP" +
1136 str( i ) ] is not None else ""
1137 port = args[
1138 "PORT" +
1139 str( i ) ] if args[
1140 "PORT" +
1141 str( i ) ] is not None else ""
1142 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001143 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001144 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001145 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001146 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001147 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001148 main.log.error( self.name + ": EOF exception found" )
1149 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001150 main.cleanup()
1151 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001152 except Exception:
1153 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001154 main.cleanup()
1155 main.exit()
adminbae64d82013-08-01 10:50:15 -07001156
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001158 """
1159 Removes the controller target from sw"""
1160 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001161 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001162 response = self.execute(
1163 cmd=command,
1164 prompt="mininet>",
1165 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001166 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001167 main.log.error( self.name + ": EOF exception found" )
1168 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001169 main.cleanup()
1170 main.exit()
1171 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001172 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001173
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001175 """
Jon Hallb1290e82014-11-18 16:17:48 -05001176 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001177 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001178 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001179 NOTE: cannot currently specify what type of switch
1180 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001181 sw = name of the new switch as a string
1182 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001183 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001184 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001185 """
1186 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001187 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001188 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001189 response = self.execute(
1190 cmd=command,
1191 prompt="mininet>",
1192 timeout=10 )
1193 if re.search( "already exists!", response ):
1194 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001195 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001196 elif re.search( "Error", response ):
1197 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001198 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001199 elif re.search( "usage:", response ):
1200 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001201 return main.FALSE
1202 else:
1203 return main.TRUE
1204 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001205 main.log.error( self.name + ": EOF exception found" )
kaouthera3f13ca22015-05-05 15:01:41 -07001206 main.log.error(self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001207 main.cleanup()
1208 main.exit()
1209
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001211 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001212 delete a switch from the mininet topology
1213 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001214 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001215 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001216 sw = name of the switch as a string
1217 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001218 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001219 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001220 response = self.execute(
1221 cmd=command,
1222 prompt="mininet>",
1223 timeout=10 )
1224 if re.search( "no switch named", response ):
1225 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001226 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001227 elif re.search( "Error", response ):
1228 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001229 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001230 elif re.search( "usage:", response ):
1231 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001232 return main.FALSE
1233 else:
1234 return main.TRUE
1235 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 main.log.error( self.name + ": EOF exception found" )
1237 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001238 main.cleanup()
1239 main.exit()
1240
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001242 """
1243 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001244 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001245 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001246 NOTE: cannot currently specify what type of link
1247 required params:
1248 node1 = the string node name of the first endpoint of the link
1249 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001250 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001251 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001252 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001253 response = self.execute(
1254 cmd=command,
1255 prompt="mininet>",
1256 timeout=10 )
1257 if re.search( "doesnt exist!", response ):
1258 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001259 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001260 elif re.search( "Error", response ):
1261 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001262 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001263 elif re.search( "usage:", response ):
1264 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001265 return main.FALSE
1266 else:
1267 return main.TRUE
1268 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001269 main.log.error( self.name + ": EOF exception found" )
1270 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001271 main.cleanup()
1272 main.exit()
1273
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001275 """
1276 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001277 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001278 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001279 required params:
1280 node1 = the string node name of the first endpoint of the link
1281 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001282 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001283 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001284 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001285 response = self.execute(
1286 cmd=command,
1287 prompt="mininet>",
1288 timeout=10 )
1289 if re.search( "no node named", response ):
1290 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001291 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001292 elif re.search( "Error", response ):
1293 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001294 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001295 elif re.search( "usage:", response ):
1296 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001297 return main.FALSE
1298 else:
1299 return main.TRUE
1300 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001301 main.log.error( self.name + ": EOF exception found" )
1302 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001303 main.cleanup()
1304 main.exit()
1305
kelvin-onlabd3b64892015-01-20 13:26:24 -08001306 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001307 """
Jon Hallb1290e82014-11-18 16:17:48 -05001308 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001309 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001310 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001311 NOTE: cannot currently specify what type of host
1312 required params:
1313 hostname = the string hostname
1314 optional key-value params
1315 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001316 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001317 """
1318 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001319 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001320 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001321 response = self.execute(
1322 cmd=command,
1323 prompt="mininet>",
1324 timeout=10 )
1325 if re.search( "already exists!", response ):
1326 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001327 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001328 elif re.search( "doesnt exists!", response ):
1329 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001330 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001331 elif re.search( "Error", response ):
1332 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001333 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001334 elif re.search( "usage:", response ):
1335 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001336 return main.FALSE
1337 else:
1338 return main.TRUE
1339 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001340 main.log.error( self.name + ": EOF exception found" )
1341 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001342 main.cleanup()
1343 main.exit()
1344
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001346 """
1347 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001348 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001349 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001350 NOTE: this uses a custom mn function
1351 required params:
1352 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001353 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001354 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001355 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001356 response = self.execute(
1357 cmd=command,
1358 prompt="mininet>",
1359 timeout=10 )
1360 if re.search( "no host named", response ):
1361 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001362 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001363 elif re.search( "Error", response ):
1364 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001365 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001366 elif re.search( "usage:", response ):
1367 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001368 return main.FALSE
1369 else:
1370 return main.TRUE
1371 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001372 main.log.error( self.name + ": EOF exception found" )
1373 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001374 main.cleanup()
1375 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001376
Jon Hall7eb38402015-01-08 17:19:54 -08001377 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001378 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001379 Called at the end of the test to stop the mininet and
1380 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001381 """
1382 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001383 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001384 timeout=2)
Jon Hall390696c2015-05-05 17:13:41 -07001385 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001386 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001387 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001388 elif i == 1:
1389 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001390 # print "Disconnecting Mininet"
1391 if self.handle:
1392 self.handle.sendline( "exit" )
1393 self.handle.expect( "exit" )
1394 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001395 else:
1396 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001397 return response
1398
Hari Krishnab35c6d02015-03-18 11:13:51 -07001399 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001400 """
Jon Hall21270ac2015-02-16 17:59:55 -08001401 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001402 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001403 main.FALSE if the pexpect handle does not exist.
1404
Jon Halld61331b2015-02-17 16:35:47 -08001405 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001406 """
Jon Hall21270ac2015-02-16 17:59:55 -08001407
Jon Halld61331b2015-02-17 16:35:47 -08001408 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001409 response = ''
1410 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001411 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001412 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001413 i = self.handle.expect( [ 'mininet>',
1414 '\$',
1415 pexpect.EOF,
1416 pexpect.TIMEOUT ],
1417 timeout )
1418 if i == 0:
1419 main.log.info( "Exiting mininet..." )
1420
Jon Hall7eb38402015-01-08 17:19:54 -08001421 response = self.execute(
1422 cmd="exit",
1423 prompt="(.*)",
1424 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001425 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001426 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001427 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001428
kelvin-onlab56a3f462015-02-06 14:04:43 -08001429 if i == 1:
1430 main.log.info( " Mininet trying to exit while not " +
1431 "in the mininet prompt" )
1432 elif i == 2:
1433 main.log.error( "Something went wrong exiting mininet" )
1434 elif i == 3: # timeout
1435 main.log.error( "Something went wrong exiting mininet " +
1436 "TIMEOUT" )
1437
Hari Krishnab35c6d02015-03-18 11:13:51 -07001438 if fileName:
1439 self.handle.sendline("")
1440 self.handle.expect('\$')
1441 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001442 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001443 main.log.error( self.name + ": EOF exception found" )
1444 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001445 main.cleanup()
1446 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001447 else:
1448 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001449 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001450 return response
1451
kelvin-onlabf0594d72015-05-19 17:25:12 -07001452 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001453 """
1454 Description:
1455 Sends arp message from mininet host for hosts discovery
1456 Required:
1457 host - hosts name
1458 Optional:
1459 ip - ip address that does not exist in the network so there would
1460 be no reply.
1461 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001462 if ethDevice:
1463 ethDevice = '-I ' + ethDevice + ' '
1464 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001465 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001466 main.log.warn( "Sending: " + cmd )
1467 self.handle.sendline( cmd )
1468 response = self.handle.before
1469 self.handle.sendline( "" )
1470 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001471 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001472
1473 except pexpect.EOF:
1474 main.log.error( self.name + ": EOF exception found" )
1475 main.log.error( self.name + ": " + self.handle.before )
1476 main.cleanup()
1477 main.exit()
admin07529932013-11-22 14:58:28 -08001478
Jon Hall7eb38402015-01-08 17:19:54 -08001479 def decToHex( self, num ):
1480 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001481
Jon Hall7eb38402015-01-08 17:19:54 -08001482 def getSwitchFlowCount( self, switch ):
1483 """
1484 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001485 if self.handle:
1486 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1487 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001488 response = self.execute(
1489 cmd=cmd,
1490 prompt="mininet>",
1491 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001492 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001493 main.log.error( self.name + ": EOF exception found" )
1494 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001495 main.cleanup()
1496 main.exit()
1497 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001498 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001499 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001500 main.log.info(
1501 "Couldn't find flows on switch %s, found: %s" %
1502 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001503 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001504 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001505 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001506 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001507
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 def checkFlows( self, sw, dumpFormat=None ):
1509 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001510 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001512 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001513 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001514 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001515 response = self.execute(
1516 cmd=command,
1517 prompt="mininet>",
1518 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001519 return response
1520 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001521 main.log.error( self.name + ": EOF exception found" )
1522 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001523 main.cleanup()
1524 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001525
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001527 """
Jon Hallefbd9792015-03-05 16:11:36 -08001528 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001529 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001530 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001531 self.handle.sendline( "" )
1532 self.handle.expect( "mininet>" )
1533 self.handle.sendline(
1534 "sh sudo tcpdump -n -i " +
1535 intf +
1536 " " +
1537 port +
1538 " -w " +
1539 filename.strip() +
1540 " &" )
1541 self.handle.sendline( "" )
1542 i = self.handle.expect( [ 'No\ssuch\device',
1543 'listening\son',
1544 pexpect.TIMEOUT,
1545 "mininet>" ],
1546 timeout=10 )
1547 main.log.warn( self.handle.before + self.handle.after )
1548 self.handle.sendline( "" )
1549 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001550 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001551 main.log.error(
1552 self.name +
1553 ": tcpdump - No such device exists. " +
1554 "tcpdump attempted on: " +
1555 intf )
admin2a9548d2014-06-17 14:08:07 -07001556 return main.FALSE
1557 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001558 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001559 return main.TRUE
1560 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001561 main.log.error(
1562 self.name +
1563 ": tcpdump command timed out! Check interface name," +
1564 " given interface was: " +
1565 intf )
admin2a9548d2014-06-17 14:08:07 -07001566 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001567 elif i == 3:
1568 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001569 return main.TRUE
1570 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001571 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001572 return main.FALSE
1573 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001576 main.cleanup()
1577 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001580 main.cleanup()
1581 main.exit()
1582
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001584 """
1585 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001586 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001587 self.handle.sendline( "sh sudo pkill tcpdump" )
1588 self.handle.expect( "mininet>" )
1589 self.handle.sendline( "" )
1590 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001591 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001592 main.log.error( self.name + ": EOF exception found" )
1593 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001594 main.cleanup()
1595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001596 except Exception:
1597 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001598 main.cleanup()
1599 main.exit()
1600
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001602 """
1603 Compare mn and onos switches
1604 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001606
Jon Hall7eb38402015-01-08 17:19:54 -08001607 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001609 output = { "switches": [] }
1610 # iterate through the MN topology and pull out switches and and port
1611 # info
1612 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001613 ports = []
1614 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001615 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001616 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001617 'name': port.name } )
1618 output[ 'switches' ].append( {
1619 "name": switch.name,
1620 "dpid": str( switch.dpid ).zfill( 16 ),
1621 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001622
Jon Hall7eb38402015-01-08 17:19:54 -08001623 # print "mn"
1624 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001625 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001626 # indent=4,
1627 # separators=( ',', ': ' ) )
1628 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001630 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001631 # indent=4,
1632 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001633
1634 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001635 mnDPIDs = []
1636 for switch in output[ 'switches' ]:
1637 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001638 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001639 # print "List of Mininet switch DPID's"
1640 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001641 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001642 main.log.error(
1643 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07001644 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001645 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001647 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001648 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001649 if switch[ 'available' ]:
1650 onosDPIDs.append(
1651 switch[ 'id' ].replace(
1652 ":",
1653 '' ).replace(
1654 "of",
1655 '' ).lower() )
1656 # else:
1657 # print "Switch is unavailable:"
1658 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001659 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001660 # print "List of ONOS switch DPID's"
1661 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001662
Jon Hall7eb38402015-01-08 17:19:54 -08001663 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001665 main.log.report( "Switches in MN but not in ONOS:" )
1666 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1667 main.log.report( str( list1 ) )
1668 main.log.report( "Switches in ONOS but not in MN:" )
1669 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001670 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001671 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 switchResults = main.TRUE
1673 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001674
kelvin-onlabd3b64892015-01-20 13:26:24 -08001675 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001676 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001677 Compare mn and onos ports
1678 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001680
Jon Hallfbc828e2015-01-06 17:30:19 -08001681 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001682 1. This uses the sts TestONTopology object
1683 2. numpy - "sudo pip install numpy"
1684
Jon Hall7eb38402015-01-08 17:19:54 -08001685 """
1686 # FIXME: this does not look for extra ports in ONOS, only checks that
1687 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001688 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001690 output = { "switches": [] }
1691 # iterate through the MN topology and pull out switches and and port
1692 # info
1693 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001694 ports = []
1695 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001696 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001697 tmpPort = { 'of_port': port.port_no,
1698 'mac': str( port.hw_addr ).replace( '\'', '' ),
1699 'name': port.name,
1700 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001701
kelvin-onlabd3b64892015-01-20 13:26:24 -08001702 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001703 tmpSwitch = { 'name': switch.name,
1704 'dpid': str( switch.dpid ).zfill( 16 ),
1705 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001706
kelvin-onlabd3b64892015-01-20 13:26:24 -08001707 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001708
Jon Hall7eb38402015-01-08 17:19:54 -08001709 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001710 for mnSwitch in output[ 'switches' ]:
1711 mnPorts = []
1712 onosPorts = []
1713 switchResult = main.TRUE
1714 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001715 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 mnPorts.append( port[ 'of_port' ] )
1717 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001718 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001719 # print onosSwitch
1720 if onosSwitch[ 'device' ][ 'available' ]:
1721 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001722 ':',
1723 '' ).replace(
1724 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001725 '' ) == mnSwitch[ 'dpid' ]:
1726 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001727 if port[ 'isEnabled' ]:
1728 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001729 # onosPorts.append( 'local' )
1730 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001731 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001732 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001733 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001734 mnPorts.sort( key=float )
1735 onosPorts.sort( key=float )
1736 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1737 # print "\tmn_ports[] = ", mnPorts
1738 # print "\tonos_ports[] = ", onosPorts
1739 mnPortsLog = mnPorts
1740 onosPortsLog = onosPorts
1741 mnPorts = [ x for x in mnPorts ]
1742 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001743
Jon Hall7eb38402015-01-08 17:19:54 -08001744 # TODO: handle other reserved port numbers besides LOCAL
1745 # NOTE: Reserved ports
1746 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1747 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 for mnPort in mnPortsLog:
1749 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001750 # don't set results to true here as this is just one of
1751 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001752 mnPorts.remove( mnPort )
1753 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001754 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001755 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001756 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001757 if 65534 in mnPorts:
1758 mnPorts.remove( 65534 )
1759 if long( uint64( -2 ) ) in onosPorts:
1760 onosPorts.remove( long( uint64( -2 ) ) )
1761 if len( mnPorts ): # the ports of this switch don't match
1762 switchResult = main.FALSE
1763 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1764 if len( onosPorts ): # the ports of this switch don't match
1765 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001766 main.log.warn(
1767 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 str( onosPorts ) )
1769 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001770 main.log.report(
1771 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1773 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1774 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1775 portsResults = portsResults and switchResult
1776 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001777
kelvin-onlabd3b64892015-01-20 13:26:24 -08001778 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001779 """
1780 Compare mn and onos links
1781 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001782 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001783
Jon Hall7eb38402015-01-08 17:19:54 -08001784 This uses the sts TestONTopology object"""
1785 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001786 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001787 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001788 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001789 # iterate through the MN topology and pull out switches and and port
1790 # info
1791 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001792 # print "Iterating though switches as seen by Mininet"
1793 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001794 ports = []
1795 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001796 # print port.hw_addr.toStr( separator='' )
1797 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001798 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001799 'name': port.name } )
1800 output[ 'switches' ].append( {
1801 "name": switch.name,
1802 "dpid": str( switch.dpid ).zfill( 16 ),
1803 "ports": ports } )
1804 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001805
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001807 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001808 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001809 if 2 * len( mnLinks ) == len( onos ):
1810 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001811 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001812 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001813 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001814 "Mininet has " + str( len( mnLinks ) ) +
1815 " bidirectional links and ONOS has " +
1816 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001817
Jon Hall7eb38402015-01-08 17:19:54 -08001818 # iterate through MN links and check if an ONOS link exists in
1819 # both directions
1820 # NOTE: Will currently only show mn links as down if they are
1821 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001822 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001823 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001825 # print "Link: %s" % link
1826 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001827 node1 = None
1828 port1 = None
1829 node2 = None
1830 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 firstDir = main.FALSE
1832 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001833 for switch in output[ 'switches' ]:
1834 # print "Switch: %s" % switch[ 'name' ]
1835 if switch[ 'name' ] == link.node1.name:
1836 node1 = switch[ 'dpid' ]
1837 for port in switch[ 'ports' ]:
1838 if str( port[ 'name' ] ) == str( link.port1 ):
1839 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001840 if node1 is not None and node2 is not None:
1841 break
Jon Hall7eb38402015-01-08 17:19:54 -08001842 if switch[ 'name' ] == link.node2.name:
1843 node2 = switch[ 'dpid' ]
1844 for port in switch[ 'ports' ]:
1845 if str( port[ 'name' ] ) == str( link.port2 ):
1846 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001847 if node1 is not None and node2 is not None:
1848 break
1849
kelvin-onlabd3b64892015-01-20 13:26:24 -08001850 for onosLink in onos:
1851 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001852 ":",
1853 '' ).replace(
1854 "of",
1855 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001857 ":",
1858 '' ).replace(
1859 "of",
1860 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 onosPort1 = onosLink[ 'src' ][ 'port' ]
1862 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001863
Jon Hall72cf1dc2014-10-20 21:04:50 -04001864 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 if str( onosNode1 ) == str( node1 ) and str(
1866 onosNode2 ) == str( node2 ):
1867 if int( onosPort1 ) == int( port1 ) and int(
1868 onosPort2 ) == int( port2 ):
1869 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001870 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001871 main.log.warn(
1872 'The port numbers do not match for ' +
1873 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001874 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001875 'link %s/%s -> %s/%s' %
1876 ( node1,
1877 port1,
1878 node2,
1879 port2 ) +
1880 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001881 ( onosNode1,
1882 onosPort1,
1883 onosNode2,
1884 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001885
1886 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001887 elif ( str( onosNode1 ) == str( node2 ) and
1888 str( onosNode2 ) == str( node1 ) ):
1889 if ( int( onosPort1 ) == int( port2 )
1890 and int( onosPort2 ) == int( port1 ) ):
1891 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001892 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001893 main.log.warn(
1894 'The port numbers do not match for ' +
1895 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001896 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001897 'link %s/%s -> %s/%s' %
1898 ( node2,
1899 port2,
1900 node1,
1901 port1 ) +
1902 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001903 ( onosNode2,
1904 onosPort2,
1905 onosNode1,
1906 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001907 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001908 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001909 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001910 main.log.report(
1911 'ONOS does not have the link %s/%s -> %s/%s' %
1912 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001913 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001914 main.log.report(
1915 'ONOS does not have the link %s/%s -> %s/%s' %
1916 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001917 linkResults = linkResults and firstDir and secondDir
1918 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001919
Jon Hallff6b4b22015-02-23 09:25:15 -08001920 def compareHosts( self, topo, hostsJson ):
1921 """
1922 Compare mn and onos Hosts.
1923 Since Mininet hosts are quiet, ONOS will only know of them when they
1924 speak. For this reason, we will only check that the hosts in ONOS
1925 stores are in Mininet, and not vice versa.
1926 topo: sts TestONTopology object
1927 hostsJson: parsed json object from the onos hosts api
1928
1929 This uses the sts TestONTopology object"""
1930 import json
1931 hostResults = main.TRUE
1932 hosts = []
1933 # iterate through the MN topology and pull out hosts
1934 for mnHost in topo.graph.hosts:
1935 interfaces = []
1936 for intf in mnHost.interfaces:
1937 interfaces.append( {
1938 "name": intf.name, # str
1939 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1940 # hw_addr is of type EthAddr, Not JSON serializable
1941 "hw_addr": str( intf.hw_addr ) } )
1942 hosts.append( {
1943 "name": mnHost.name, # str
1944 "interfaces": interfaces } ) # list
1945 for onosHost in hostsJson:
1946 onosMAC = onosHost[ 'mac' ].lower()
1947 match = False
1948 for mnHost in hosts:
1949 for mnIntf in mnHost[ 'interfaces' ]:
1950 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1951 match = True
1952 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001953 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08001954 pass # all is well
1955 else:
1956 # misssing ip
1957 main.log.error( "ONOS host " + onosHost[ 'id' ]
1958 + " has a different IP than " +
1959 "the Mininet host." )
1960 output = json.dumps(
1961 onosHost,
1962 sort_keys=True,
1963 indent=4,
1964 separators=( ',', ': ' ) )
1965 main.log.info( output )
1966 hostResults = main.FALSE
1967 if not match:
1968 hostResults = main.FALSE
1969 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1970 "corresponding Mininet host." )
1971 output = json.dumps( onosHost,
1972 sort_keys=True,
1973 indent=4,
1974 separators=( ',', ': ' ) )
1975 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001976 return hostResults
1977
kelvin-onlabd3b64892015-01-20 13:26:24 -08001978 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001979 """
1980 Returns a list of all hosts
1981 Don't ask questions just use it"""
1982 self.handle.sendline( "" )
1983 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001984
Jon Hall7eb38402015-01-08 17:19:54 -08001985 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1986 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001987
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 handlePy = self.handle.before
1989 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1990 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001991
Jon Hall7eb38402015-01-08 17:19:54 -08001992 self.handle.sendline( "" )
1993 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001994
kelvin-onlabd3b64892015-01-20 13:26:24 -08001995 hostStr = handlePy.replace( "]", "" )
1996 hostStr = hostStr.replace( "'", "" )
1997 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07001998 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001999 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002000
kelvin-onlabd3b64892015-01-20 13:26:24 -08002001 return hostList
adminbae64d82013-08-01 10:50:15 -07002002
Jon Hall7eb38402015-01-08 17:19:54 -08002003 def update( self ):
2004 """
2005 updates the port address and status information for
2006 each port in mn"""
2007 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002008 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002009 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002010 self.handle.sendline( "" )
2011 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002012
Jon Hall7eb38402015-01-08 17:19:54 -08002013 self.handle.sendline( "update" )
2014 self.handle.expect( "update" )
2015 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002016
Jon Hall7eb38402015-01-08 17:19:54 -08002017 self.handle.sendline( "" )
2018 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002019
Jon Hallb1290e82014-11-18 16:17:48 -05002020 return main.TRUE
2021 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002022 main.log.error( self.name + ": EOF exception found" )
2023 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002024 main.cleanup()
2025 main.exit()
2026
kaouthera3f13ca22015-05-05 15:01:41 -07002027 def assignVLAN( self, host, intf, vlan):
2028 """
2029 Add vlan tag to a host.
2030 Dependencies:
2031 This class depends on the "vlan" package
2032 $ sudo apt-get install vlan
2033 Configuration:
2034 Load the 8021q module into the kernel
2035 $sudo modprobe 8021q
2036
2037 To make this setup permanent:
2038 $ sudo su -c 'echo "8021q" >> /etc/modules'
2039 """
2040 if self.handle:
2041 try:
2042 # get the ip address of the host
2043 main.log.info("Get the ip address of the host")
2044 ipaddr = self.getIPAddress(host)
2045 print repr(ipaddr)
2046
2047 # remove IP from interface intf
2048 # Ex: h1 ifconfig h1-eth0 inet 0
2049 main.log.info("Remove IP from interface ")
2050 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2051 self.handle.sendline( cmd2 )
2052 self.handle.expect( "mininet>" )
2053 response = self.handle.before
2054 main.log.info ( "====> %s ", response)
2055
2056
2057 # create VLAN interface
2058 # Ex: h1 vconfig add h1-eth0 100
2059 main.log.info("Create Vlan")
2060 cmd3 = host + " vconfig add " + intf + " " + vlan
2061 self.handle.sendline( cmd3 )
2062 self.handle.expect( "mininet>" )
2063 response = self.handle.before
2064 main.log.info( "====> %s ", response )
2065
2066 # assign the host's IP to the VLAN interface
2067 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2068 main.log.info("Assign the host IP to the vlan interface")
2069 vintf = intf + "." + vlan
2070 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2071 self.handle.sendline( cmd4 )
2072 self.handle.expect( "mininet>" )
2073 response = self.handle.before
2074 main.log.info ( "====> %s ", response)
2075
2076
2077 return main.TRUE
2078 except pexpect.EOF:
2079 main.log.error( self.name + ": EOF exception found" )
2080 main.log.error( self.name + ": " + self.handle.before )
2081 return main.FALSE
2082
adminbae64d82013-08-01 10:50:15 -07002083if __name__ != "__main__":
2084 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002085 sys.modules[ __name__ ] = MininetCliDriver()
kaouthera3f13ca22015-05-05 15:01:41 -07002086
2087