blob: b7e96a1766616217d9491abe7c969679006d54f8 [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 """
101 Starts Mininet accepts a topology(.py) file and/or an optional
Jon Hallefbd9792015-03-05 16:11:36 -0800102 argument ,to start the mininet, as a parameter.
Jon Hall21270ac2015-02-16 17:59:55 -0800103 Returns main.TRUE if the mininet starts successfully and
104 main.FALSE otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800105 """
Jon Hall7eb38402015-01-08 17:19:54 -0800106 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700107 # make sure old networks are cleaned up
108 main.log.info( self.name +
109 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800110 self.handle.sendline( "sudo mn -c" )
111 i = self.handle.expect( [ 'password\sfor\s',
112 'Cleanup\scomplete',
113 pexpect.EOF,
114 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800115 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800116 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700117 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800118 main.log.info( self.name + ": Sending sudo password" )
119 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800120 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800121 '\$',
122 pexpect.EOF,
123 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800124 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800125 if i == 1:
126 main.log.info( self.name + ": Clean" )
127 elif i == 2:
128 main.log.error( self.name + ": Connection terminated" )
129 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700130 main.log.error( self.name + ": Something while cleaning " +
131 "Mininet took too long... " )
132 # Craft the string to start mininet
133 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700134 if not mnCmd:
135 if topoFile is None or topoFile == '': # If no file is given
136 main.log.info( self.name + ": building fresh Mininet" )
137 cmdString += "mn "
138 if args is None or args == '':
139 # If no args given, use args from .topo file
140 args = self.options[ 'arg1' ] +\
141 " " + self.options[ 'arg2' ] +\
142 " --mac --controller " +\
143 self.options[ 'controller' ] + " " +\
144 self.options[ 'arg3' ]
145 else: # else only use given args
146 pass
147 # TODO: allow use of topo args and method args?
148 else: # Use given topology file
149 main.log.info( "Starting Mininet from topo file " + topoFile )
150 cmdString += topoFile + " "
151 if args is None:
152 args = ''
153 # TODO: allow use of args from .topo file?
154 cmdString += args
155 else:
156 main.log.info( "Starting Mininet topology using '" + mnCmd +
157 "' command" )
158 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700159 # Send the command and check if network started
160 self.handle.sendline( "" )
161 self.handle.expect( '\$' )
162 main.log.info( "Sending '" + cmdString + "' to " + self.name )
163 self.handle.sendline( cmdString )
164 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800165 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700166 'Exception',
167 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800168 pexpect.EOF,
169 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700170 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800171 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700172 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800173 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800174 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700175 response = str( self.handle.before +
176 self.handle.after )
177 self.handle.expect( '\$' )
178 response += str( self.handle.before +
179 self.handle.after )
180 main.log.error(
181 self.name +
182 ": Launching Mininet failed: " + response )
183 return main.FALSE
184 elif i == 2:
185 self.handle.expect( [ "\n",
186 pexpect.EOF,
187 pexpect.TIMEOUT ],
188 timeout )
189 main.log.info( self.handle.before )
190 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800191 main.log.error( self.name + ": Connection timeout" )
192 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700193 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800194 main.log.error(
195 self.name +
196 ": Something took too long... " )
197 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700198 # Why did we hit this part?
199 main.log.error( "startNet did not return correctly" )
200 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800201 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700202 main.log.error( self.name + ": Connection failed to the host " +
203 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800204 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700205 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800206
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800207 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400208 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800209 # In tree topology, if fanout arg is not given, by default it is 2
210 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400211 fanout = 2
212 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500213 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800214 while( k <= depth - 1 ):
215 count = count + pow( fanout, k )
216 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800218 while( k <= depth - 2 ):
219 # depth-2 gives you only core links and not considering
220 # edge links as seen by ONOS. If all the links including
221 # edge links are required, do depth-1
222 count = count + pow( fanout, k )
223 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800225 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800226 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800227
Jon Hall7eb38402015-01-08 17:19:54 -0800228 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800230 # by default it is 1
231 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400232 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 numSwitches = depth
234 numHostsPerSw = fanout
235 totalNumHosts = numSwitches * numHostsPerSw
236 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800237 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800239 topoDict = { "num_switches": int( numSwitches ),
240 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400241 return topoDict
242
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700244 """
245 Calculate the number of switches and links in a topo."""
246 # TODO: combine this function and numSwitchesNlinks
247 argList = self.options[ 'arg1' ].split( "," )
248 topoArgList = argList[ 0 ].split( " " )
249 argList = map( int, argList[ 1: ] )
250 topoArgList = topoArgList[ 1: ] + argList
251
252 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400253 return topoDict
254
kelvin-onlabc44f0192015-04-02 22:08:41 -0700255 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0):
Jon Hall7eb38402015-01-08 17:19:54 -0800256 """
257 Verifies the reachability of the hosts using pingall command.
258 Optional parameter timeout allows you to specify how long to
259 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700260 Optional:
Jon Hall390696c2015-05-05 17:13:41 -0700261 timeout(seconds) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700262 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700263 ping
264 acceptableFailed - Set the number of acceptable failed pings for the
265 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800266 Returns:
267 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700268 otherwise main.FALSE
269 """
270 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700271 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700272 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700273 if self.handle:
274 main.log.info(
275 self.name +
276 ": Checking reachabilty to the hosts using pingall" )
277 response = ""
278 failedPings = 0
279 returnValue = main.TRUE
280 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700281 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700282 while True:
283 i = self.handle.expect( [ "mininet>","X",
284 pexpect.EOF,
285 pexpect.TIMEOUT ],
286 timeout )
287 if i == 0:
288 main.log.info( self.name + ": pingall finished")
289 response += self.handle.before
290 break
291 elif i == 1:
292 response += self.handle.before + self.handle.after
293 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700294 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700295 returnValue = main.FALSE
296 if shortCircuit:
297 main.log.error( self.name +
298 ": Aborting pingall - "
299 + str( failedPings ) +
300 " pings failed" )
301 break
Jon Hall390696c2015-05-05 17:13:41 -0700302 if ( time.time() - startTime ) > timeout:
303 returnValue = main.FALSE
304 main.log.error( self.name +
305 ": Aborting pingall - " +
306 "Function took too long " )
307 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700308 elif i == 2:
309 main.log.error( self.name +
310 ": EOF exception found" )
311 main.log.error( self.name + ": " +
312 self.handle.before )
313 main.cleanup()
314 main.exit()
315 elif i == 3:
316 response += self.handle.before
317 main.log.error( self.name +
318 ": TIMEOUT exception found" )
319 main.log.error( self.name +
320 ": " +
321 str( response ) )
322 # NOTE: Send ctrl-c to make sure pingall is done
323 self.handle.sendline( "\x03" )
324 self.handle.expect( "Interrupt" )
325 self.handle.expect( "mininet>" )
326 break
327 pattern = "Results\:"
328 main.log.info( "Pingall output: " + str( response ) )
329 if re.search( pattern, response ):
330 main.log.info( self.name + ": Pingall finished with "
331 + str( failedPings ) + " failed pings" )
332 return returnValue
333 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700334 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700335 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700336 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700337 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700338 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700339 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700340 main.log.error( self.name + ": Connection failed to the host" )
341 main.cleanup()
342 main.exit()
343 except pexpect.TIMEOUT:
344 if response:
345 main.log.info( "Pingall output: " + str( response ) )
346 main.log.error( self.name + ": pexpect.TIMEOUT found" )
347 return main.FALSE
348 except pexpect.EOF:
349 main.log.error( self.name + ": EOF exception found" )
350 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500351 main.cleanup()
352 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700353
Jon Hall7eb38402015-01-08 17:19:54 -0800354 def fpingHost( self, **pingParams ):
355 """
356 Uses the fping package for faster pinging...
357 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800358 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800359 command = args[ "SRC" ] + \
360 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
361 self.handle.sendline( command )
362 self.handle.expect(
363 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
364 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
365 response = self.handle.before
366 if re.search( ":\s-", response ):
367 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700368 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800369 elif re.search( ":\s\d{1,2}\.\d\d", response ):
370 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700371 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800372 main.log.info( self.name + ": Install fping on mininet machine... " )
373 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700374 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800375
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400376 def pingallHosts( self, hostList, pingType='ipv4' ):
377 """
kelvin-onlab2ff57022015-05-29 10:48:51 -0700378 Ping all specified hosts with a specific ping type
379
380 Acceptable pingTypes:
381 - 'ipv4'
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400382 - 'ipv6'
kelvin-onlab2ff57022015-05-29 10:48:51 -0700383
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400384 Acceptable hostList:
385 - ['h1','h2','h3','h4']
kelvin-onlab2ff57022015-05-29 10:48:51 -0700386
387 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400388 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700389
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400390 Returns main.FALSE if one or more of hosts specified
391 cannot reach each other"""
kelvin-onlab2ff57022015-05-29 10:48:51 -0700392
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400393 if pingType == "ipv4":
kelvin-onlab2ff57022015-05-29 10:48:51 -0700394 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400395 elif pingType == "ipv6":
396 cmd = " ping6 -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400397 else:
398 main.log.warn( "Invalid pingType specified" )
399 return
400
401 try:
402 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700403
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400404 isReachable = main.TRUE
405
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 for host in hostList:
407 listIndex = hostList.index(host)
408 # List of hosts to ping other than itself
409 pingList = hostList[:listIndex] + hostList[(listIndex+1):]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700410
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400411 for temp in pingList:
412 # Current host pings all other hosts specified
kelvin-onlab2ff57022015-05-29 10:48:51 -0700413 pingCmd = str(host) + cmd + str(temp)
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400414 self.handle.sendline( pingCmd )
415 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
416 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
417 response = self.handle.before
418 if re.search( ',\s0\%\spacket\sloss', response ):
419 main.log.info( str(host) + " -> " + str(temp) )
420 else:
421 main.log.info( str(host) + " -> X ("+str(temp)+") "
kelvin-onlab2ff57022015-05-29 10:48:51 -0700422 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400423 # One of the host to host pair is unreachable
424 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400425
kelvin-onlab2ff57022015-05-29 10:48:51 -0700426 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400427
428 except pexpect.EOF:
429 main.log.error( self.name + ": EOF exception found" )
430 main.log.error( self.name + ": " + self.handle.before )
431 main.cleanup()
432 main.exit()
433
Jon Hall7eb38402015-01-08 17:19:54 -0800434 def pingHost( self, **pingParams ):
435 """
436 Ping from one mininet host to another
437 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800438 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800439 command = args[ "SRC" ] + " ping " + \
440 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700441 try:
Jon Hall61282e32015-03-19 11:34:11 -0700442 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800443 self.handle.sendline( command )
444 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700445 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800446 main.log.error(
447 self.name +
448 ": timeout when waiting for response from mininet" )
449 main.log.error( "response: " + str( self.handle.before ) )
450 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700451 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800452 main.log.error(
453 self.name +
454 ": timeout when waiting for response from mininet" )
455 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700456 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800457 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800458 main.log.error( self.name + ": EOF exception found" )
459 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700460 main.cleanup()
461 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800462 main.log.info( self.name + ": Ping Response: " + response )
463 if re.search( ',\s0\%\spacket\sloss', response ):
464 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800465 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700466 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800467 else:
468 main.log.error(
469 self.name +
470 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800471 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700472 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800473
Jon Hall7eb38402015-01-08 17:19:54 -0800474 def checkIP( self, host ):
475 """
476 Verifies the host's ip configured or not."""
477 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700478 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800479 response = self.execute(
480 cmd=host +
481 " ifconfig",
482 prompt="mininet>",
483 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800484 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800485 main.log.error( self.name + ": EOF exception found" )
486 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700487 main.cleanup()
488 main.exit()
adminbae64d82013-08-01 10:50:15 -0700489
Jon Hall7eb38402015-01-08 17:19:54 -0800490 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800491 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
492 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
493 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
494 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
495 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800496 # pattern = "inet addr:10.0.0.6"
497 if re.search( pattern, response ):
498 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700499 return main.TRUE
500 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800501 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700502 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800503 else:
504 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800505
Jon Hall7eb38402015-01-08 17:19:54 -0800506 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800507 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700508 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800509 response = self.execute(
510 cmd="h1 /usr/sbin/sshd -D&",
511 prompt="mininet>",
512 timeout=10 )
513 response = self.execute(
514 cmd="h4 /usr/sbin/sshd -D&",
515 prompt="mininet>",
516 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700517 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800518 vars( self )[ key ] = connectargs[ key ]
519 response = self.execute(
520 cmd="xterm h1 h4 ",
521 prompt="mininet>",
522 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800523 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800524 main.log.error( self.name + ": EOF exception found" )
525 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700526 main.cleanup()
527 main.exit()
adminbae64d82013-08-01 10:50:15 -0700528 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800529 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700530 if self.flag == 0:
531 self.flag = 1
532 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800533 else:
adminbae64d82013-08-01 10:50:15 -0700534 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800535
kelvin-onlaba1484582015-02-02 15:46:20 -0800536 def moveHost( self, host, oldSw, newSw, ):
537 """
538 Moves a host from one switch to another on the fly
539 Note: The intf between host and oldSw when detached
540 using detach(), will still show up in the 'net'
541 cmd, because switch.detach() doesn't affect switch.intfs[]
542 (which is correct behavior since the interfaces
543 haven't moved).
544 """
545 if self.handle:
546 try:
547 # Bring link between oldSw-host down
Jon Hallefbd9792015-03-05 16:11:36 -0800548 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
549 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800550 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800551 response = self.execute( cmd=cmd,
552 prompt="mininet>",
553 timeout=10 )
kelvin-onlaba1484582015-02-02 15:46:20 -0800554
555 # Determine hostintf and Oldswitchintf
556 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800557 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800558 print "cmd2= ", cmd
559 self.handle.sendline( cmd )
560 self.handle.expect( "mininet>" )
561
shahshreya73537862015-02-11 15:15:24 -0800562 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800563 cmd = "px ipaddr = hintf.IP()"
564 print "cmd3= ", cmd
565 self.handle.sendline( cmd )
566 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800567
568 cmd = "px macaddr = hintf.MAC()"
569 print "cmd3= ", cmd
570 self.handle.sendline( cmd )
571 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800572
573 # Detach interface between oldSw-host
574 cmd = "px " + oldSw + ".detach( sintf )"
575 print "cmd4= ", cmd
576 self.handle.sendline( cmd )
577 self.handle.expect( "mininet>" )
578
579 # Add link between host-newSw
580 cmd = "py net.addLink(" + host + "," + newSw + ")"
581 print "cmd5= ", cmd
582 self.handle.sendline( cmd )
583 self.handle.expect( "mininet>" )
584
585 # Determine hostintf and Newswitchintf
586 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800587 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800588 print "cmd6= ", cmd
589 self.handle.sendline( cmd )
590 self.handle.expect( "mininet>" )
591
592 # Attach interface between newSw-host
593 cmd = "px " + newSw + ".attach( sintf )"
594 print "cmd3= ", cmd
595 self.handle.sendline( cmd )
596 self.handle.expect( "mininet>" )
597
598 # Set ipaddress of the host-newSw interface
599 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
600 print "cmd7 = ", cmd
601 self.handle.sendline( cmd )
602 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800603
604 # Set macaddress of the host-newSw interface
605 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
606 print "cmd8 = ", cmd
607 self.handle.sendline( cmd )
608 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800609
610 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800611 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800612 self.handle.sendline( cmd )
613 self.handle.expect( "mininet>" )
614 print "output = ", self.handle.before
615
616 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800617 cmd = host + " ifconfig"
618 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800619 self.handle.sendline( cmd )
620 self.handle.expect( "mininet>" )
621 print "ifconfig o/p = ", self.handle.before
622
623 return main.TRUE
624 except pexpect.EOF:
625 main.log.error( self.name + ": EOF exception found" )
626 main.log.error( self.name + ": " + self.handle.before )
627 return main.FALSE
628
Jon Hall7eb38402015-01-08 17:19:54 -0800629 def changeIP( self, host, intf, newIP, newNetmask ):
630 """
631 Changes the ip address of a host on the fly
632 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800633 if self.handle:
634 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800635 cmd = host + " ifconfig " + intf + " " + \
636 newIP + " " + 'netmask' + " " + newNetmask
637 self.handle.sendline( cmd )
638 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800639 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800640 main.log.info( "response = " + response )
641 main.log.info(
642 "Ip of host " +
643 host +
644 " changed to new IP " +
645 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800646 return main.TRUE
647 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800648 main.log.error( self.name + ": EOF exception found" )
649 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800650 return main.FALSE
651
Jon Hall7eb38402015-01-08 17:19:54 -0800652 def changeDefaultGateway( self, host, newGW ):
653 """
654 Changes the default gateway of a host
655 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800656 if self.handle:
657 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800658 cmd = host + " route add default gw " + newGW
659 self.handle.sendline( cmd )
660 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800661 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800662 main.log.info( "response = " + response )
663 main.log.info(
664 "Default gateway of host " +
665 host +
666 " changed to " +
667 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800668 return main.TRUE
669 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800670 main.log.error( self.name + ": EOF exception found" )
671 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800672 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800673
Jon Hall7eb38402015-01-08 17:19:54 -0800674 def addStaticMACAddress( self, host, GW, macaddr ):
675 """
Jon Hallefbd9792015-03-05 16:11:36 -0800676 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800677 if self.handle:
678 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800679 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
680 cmd = host + " arp -s " + GW + " " + macaddr
681 self.handle.sendline( cmd )
682 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800683 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800684 main.log.info( "response = " + response )
685 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800686 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800687 GW +
688 " changed to " +
689 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800690 return main.TRUE
691 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800692 main.log.error( self.name + ": EOF exception found" )
693 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800694 return main.FALSE
695
Jon Hall7eb38402015-01-08 17:19:54 -0800696 def verifyStaticGWandMAC( self, host ):
697 """
698 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800699 if self.handle:
700 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800701 # h1 arp -an
702 cmd = host + " arp -an "
703 self.handle.sendline( cmd )
704 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800705 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800706 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800707 return main.TRUE
708 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800709 main.log.error( self.name + ": EOF exception found" )
710 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800711 return main.FALSE
712
Jon Hall7eb38402015-01-08 17:19:54 -0800713 def getMacAddress( self, host ):
714 """
715 Verifies the host's ip configured or not."""
716 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700717 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800718 response = self.execute(
719 cmd=host +
720 " ifconfig",
721 prompt="mininet>",
722 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800723 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800724 main.log.error( self.name + ": EOF exception found" )
725 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700726 main.cleanup()
727 main.exit()
adminbae64d82013-08-01 10:50:15 -0700728
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700729 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 macAddressSearch = re.search( pattern, response, re.I )
731 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.info(
733 self.name +
734 ": Mac-Address of Host " +
735 host +
736 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 macAddress )
738 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700739 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700741
Jon Hall7eb38402015-01-08 17:19:54 -0800742 def getInterfaceMACAddress( self, host, interface ):
743 """
744 Return the IP address of the interface on the given host"""
745 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700746 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 response = self.execute( cmd=host + " ifconfig " + interface,
748 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800749 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800750 main.log.error( self.name + ": EOF exception found" )
751 main.log.error( self.name + ": " + self.handle.before )
752 main.cleanup()
753 main.exit()
754
755 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 macAddressSearch = re.search( pattern, response, re.I )
757 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800758 main.log.info( "No mac address found in %s" % response )
759 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800761 main.log.info(
762 "Mac-Address of " +
763 host +
764 ":" +
765 interface +
766 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 macAddress )
768 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800769 else:
770 main.log.error( "Connection failed to the host" )
771
772 def getIPAddress( self, host ):
773 """
774 Verifies the host's ip configured or not."""
775 if self.handle:
776 try:
777 response = self.execute(
778 cmd=host +
779 " ifconfig",
780 prompt="mininet>",
781 timeout=10 )
782 except pexpect.EOF:
783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700785 main.cleanup()
786 main.exit()
adminbae64d82013-08-01 10:50:15 -0700787
788 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800790 main.log.info(
791 self.name +
792 ": IP-Address of Host " +
793 host +
794 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 ipAddressSearch.group( 1 ) )
796 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800797 else:
798 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800799
Jon Hall7eb38402015-01-08 17:19:54 -0800800 def getSwitchDPID( self, switch ):
801 """
802 return the datapath ID of the switch"""
803 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700804 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700805 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800806 response = self.execute(
807 cmd=cmd,
808 prompt="mininet>",
809 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800810 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800811 main.log.error( self.name + ": EOF exception found" )
812 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700813 main.cleanup()
814 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800815 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800816 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700817 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800818 main.log.info(
819 "Couldn't find DPID for switch %s, found: %s" %
820 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700821 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800822 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700823 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800824 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700825
Jon Hall7eb38402015-01-08 17:19:54 -0800826 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700827 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800828 self.handle.sendline( "" )
829 self.expect( "mininet>" )
830 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700831 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800832 response = self.execute(
833 cmd=cmd,
834 prompt="mininet>",
835 timeout=10 )
836 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700837 response = self.handle.before
838 return response
839 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800840 main.log.error( self.name + ": EOF exception found" )
841 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700842 main.cleanup()
843 main.exit()
844
Jon Hall7eb38402015-01-08 17:19:54 -0800845 def getInterfaces( self, node ):
846 """
847 return information dict about interfaces connected to the node"""
848 if self.handle:
849 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800850 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700851 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700852 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800853 response = self.execute(
854 cmd=cmd,
855 prompt="mininet>",
856 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800857 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800858 main.log.error( self.name + ": EOF exception found" )
859 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700860 main.cleanup()
861 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700862 return response
863 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800864 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700865
Jon Hall7eb38402015-01-08 17:19:54 -0800866 def dump( self ):
867 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700868 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800869 response = self.execute(
870 cmd='dump',
871 prompt='mininet>',
872 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800873 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800874 main.log.error( self.name + ": EOF exception found" )
875 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700876 main.cleanup()
877 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700878 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800879
Jon Hall7eb38402015-01-08 17:19:54 -0800880 def intfs( self ):
881 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700882 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800883 response = self.execute(
884 cmd='intfs',
885 prompt='mininet>',
886 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800887 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800888 main.log.error( self.name + ": EOF exception found" )
889 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700890 main.cleanup()
891 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700892 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800893
Jon Hall7eb38402015-01-08 17:19:54 -0800894 def net( self ):
895 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700896 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800897 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800898 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800899 main.log.error( self.name + ": EOF exception found" )
900 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700901 main.cleanup()
902 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700903 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800904
905 def iperf( self, host1, host2 ):
906 main.log.info(
907 self.name +
908 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700909 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800910 cmd1 = 'iperf ' + host1 + " " + host2
911 self.handle.sendline( cmd1 )
912 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800913 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800914 if re.search( 'Results:', response ):
Jon Hallefbd9792015-03-05 16:11:36 -0800915 main.log.info( self.name + ": iperf test successful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800916 return main.TRUE
917 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800918 main.log.error( self.name + ": iperf test failed" )
919 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800920 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800921 main.log.error( self.name + ": EOF exception found" )
922 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800923 main.cleanup()
924 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800925
Jon Hall7eb38402015-01-08 17:19:54 -0800926 def iperfudp( self ):
927 main.log.info(
928 self.name +
929 ": Simple iperf TCP test between two " +
930 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700931 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800932 response = self.execute(
933 cmd='iperfudp',
934 prompt='mininet>',
935 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800936 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700939 main.cleanup()
940 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700941 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800942
Jon Hall7eb38402015-01-08 17:19:54 -0800943 def nodes( self ):
944 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700945 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800946 response = self.execute(
947 cmd='nodes',
948 prompt='mininet>',
949 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800950 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800951 main.log.error( self.name + ": EOF exception found" )
952 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700953 main.cleanup()
954 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700955 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800956
Jon Hall7eb38402015-01-08 17:19:54 -0800957 def pingpair( self ):
958 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700959 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800960 response = self.execute(
961 cmd='pingpair',
962 prompt='mininet>',
963 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800964 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800965 main.log.error( self.name + ": EOF exception found" )
966 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700967 main.cleanup()
968 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800969
Jon Hall7eb38402015-01-08 17:19:54 -0800970 if re.search( ',\s0\%\spacket\sloss', response ):
971 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700973 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800974 else:
975 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700977 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800978
Jon Hall7eb38402015-01-08 17:19:54 -0800979 def link( self, **linkargs ):
980 """
981 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800982 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800983 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
984 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
985 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
986 main.log.info(
987 "Bring link between '" +
988 end1 +
989 "' and '" +
990 end2 +
991 "' '" +
992 option +
993 "'" )
994 command = "link " + \
995 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700996 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800997 self.handle.sendline( command )
998 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800999 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001000 main.log.error( self.name + ": EOF exception found" )
1001 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001002 main.cleanup()
1003 main.exit()
adminbae64d82013-08-01 10:50:15 -07001004 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001005
Jon Hall7eb38402015-01-08 17:19:54 -08001006 def yank( self, **yankargs ):
1007 """
1008 yank a mininet switch interface to a host"""
1009 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001010 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001011 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1012 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1013 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001014 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001015 response = self.execute(
1016 cmd=command,
1017 prompt="mininet>",
1018 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001019 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001022 main.cleanup()
1023 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001024 return main.TRUE
1025
Jon Hall7eb38402015-01-08 17:19:54 -08001026 def plug( self, **plugargs ):
1027 """
1028 plug the yanked mininet switch interface to a switch"""
1029 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001030 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001031 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1032 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1033 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001034 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001035 response = self.execute(
1036 cmd=command,
1037 prompt="mininet>",
1038 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001039 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001040 main.log.error( self.name + ": EOF exception found" )
1041 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001042 main.cleanup()
1043 main.exit()
adminbae64d82013-08-01 10:50:15 -07001044 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001045
Jon Hall7eb38402015-01-08 17:19:54 -08001046 def dpctl( self, **dpctlargs ):
1047 """
1048 Run dpctl command on all switches."""
1049 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001050 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001051 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1052 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1053 command = "dpctl " + cmd + " " + str( cmdargs )
1054 try:
1055 response = self.execute(
1056 cmd=command,
1057 prompt="mininet>",
1058 timeout=10 )
1059 except pexpect.EOF:
1060 main.log.error( self.name + ": EOF exception found" )
1061 main.log.error( self.name + ": " + self.handle.before )
1062 main.cleanup()
1063 main.exit()
1064 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001065
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 def getVersion( self ):
Jon Hallff6b4b22015-02-23 09:25:15 -08001067 #FIXME: What uses this? This should be refactored to get
1068 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 fileInput = path + '/lib/Mininet/INSTALL'
1070 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001071 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001073 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001074 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001075 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001076 return version
adminbae64d82013-08-01 10:50:15 -07001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001079 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001080 Parameters:
1081 sw: The name of an OVS switch. Example "s1"
1082 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001083 The output of the command from the mininet cli
1084 or main.FALSE on timeout"""
1085 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001086 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001087 response = self.execute(
1088 cmd=command,
1089 prompt="mininet>",
1090 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001091 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001092 return response
admin2a9548d2014-06-17 14:08:07 -07001093 else:
1094 return main.FALSE
1095 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001096 main.log.error( self.name + ": EOF exception found" )
1097 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001098 main.cleanup()
1099 main.exit()
adminbae64d82013-08-01 10:50:15 -07001100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001102 """
1103 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001104 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001105 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -07001106
1107 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -08001108 for j in range( count ):
1109 argstring = argstring + ",IP" + \
1110 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001111 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -07001112
Jon Hall7eb38402015-01-08 17:19:54 -08001113 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1114 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001115 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -08001116 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -08001117
Jon Hall7eb38402015-01-08 17:19:54 -08001118 command = "sh ovs-vsctl set-controller s" + \
1119 str( sw ) + " " + ptcpB + " "
1120 for j in range( count ):
1121 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001122 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -08001123 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
1124 ip = args[
1125 "IP" +
1126 str( i ) ] if args[
1127 "IP" +
1128 str( i ) ] is not None else ""
1129 port = args[
1130 "PORT" +
1131 str( i ) ] if args[
1132 "PORT" +
1133 str( i ) ] is not None else ""
1134 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001135 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001136 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001137 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001138 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001139 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001140 main.log.error( self.name + ": EOF exception found" )
1141 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001142 main.cleanup()
1143 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001144 except Exception:
1145 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall6094a362014-04-11 14:46:56 -07001146 main.cleanup()
1147 main.exit()
adminbae64d82013-08-01 10:50:15 -07001148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001150 """
1151 Removes the controller target from sw"""
1152 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001153 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001154 response = self.execute(
1155 cmd=command,
1156 prompt="mininet>",
1157 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001158 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001159 main.log.error( self.name + ": EOF exception found" )
1160 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001161 main.cleanup()
1162 main.exit()
1163 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001164 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001165
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001167 """
Jon Hallb1290e82014-11-18 16:17:48 -05001168 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001169 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001170 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001171 NOTE: cannot currently specify what type of switch
1172 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001173 sw = name of the new switch as a string
1174 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001175 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001176 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001177 """
1178 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001179 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001180 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 response = self.execute(
1182 cmd=command,
1183 prompt="mininet>",
1184 timeout=10 )
1185 if re.search( "already exists!", response ):
1186 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001187 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001188 elif re.search( "Error", response ):
1189 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001190 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001191 elif re.search( "usage:", response ):
1192 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001193 return main.FALSE
1194 else:
1195 return main.TRUE
1196 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001197 main.log.error( self.name + ": EOF exception found" )
kaouthera3f13ca22015-05-05 15:01:41 -07001198 main.log.error(self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001199 main.cleanup()
1200 main.exit()
1201
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001203 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001204 delete a switch from the mininet topology
1205 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001206 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001207 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001208 sw = name of the switch as a string
1209 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001210 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001211 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001212 response = self.execute(
1213 cmd=command,
1214 prompt="mininet>",
1215 timeout=10 )
1216 if re.search( "no switch named", response ):
1217 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001218 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001219 elif re.search( "Error", response ):
1220 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001221 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001222 elif re.search( "usage:", response ):
1223 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001224 return main.FALSE
1225 else:
1226 return main.TRUE
1227 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001228 main.log.error( self.name + ": EOF exception found" )
1229 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001230 main.cleanup()
1231 main.exit()
1232
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001234 """
1235 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001236 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001237 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001238 NOTE: cannot currently specify what type of link
1239 required params:
1240 node1 = the string node name of the first endpoint of the link
1241 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001242 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001243 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001244 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001245 response = self.execute(
1246 cmd=command,
1247 prompt="mininet>",
1248 timeout=10 )
1249 if re.search( "doesnt exist!", response ):
1250 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001251 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001252 elif re.search( "Error", response ):
1253 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001254 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001255 elif re.search( "usage:", response ):
1256 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001257 return main.FALSE
1258 else:
1259 return main.TRUE
1260 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001261 main.log.error( self.name + ": EOF exception found" )
1262 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001263 main.cleanup()
1264 main.exit()
1265
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001267 """
1268 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001269 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001270 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001271 required params:
1272 node1 = the string node name of the first endpoint of the link
1273 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001274 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001275 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001276 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001277 response = self.execute(
1278 cmd=command,
1279 prompt="mininet>",
1280 timeout=10 )
1281 if re.search( "no node named", response ):
1282 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001283 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001284 elif re.search( "Error", response ):
1285 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001286 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001287 elif re.search( "usage:", response ):
1288 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001289 return main.FALSE
1290 else:
1291 return main.TRUE
1292 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001293 main.log.error( self.name + ": EOF exception found" )
1294 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001295 main.cleanup()
1296 main.exit()
1297
kelvin-onlabd3b64892015-01-20 13:26:24 -08001298 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001299 """
Jon Hallb1290e82014-11-18 16:17:48 -05001300 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001301 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001302 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001303 NOTE: cannot currently specify what type of host
1304 required params:
1305 hostname = the string hostname
1306 optional key-value params
1307 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001308 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001309 """
1310 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001311 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001312 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001313 response = self.execute(
1314 cmd=command,
1315 prompt="mininet>",
1316 timeout=10 )
1317 if re.search( "already exists!", response ):
1318 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001319 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001320 elif re.search( "doesnt exists!", response ):
1321 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001322 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001323 elif re.search( "Error", response ):
1324 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001325 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001326 elif re.search( "usage:", response ):
1327 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001328 return main.FALSE
1329 else:
1330 return main.TRUE
1331 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001332 main.log.error( self.name + ": EOF exception found" )
1333 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001334 main.cleanup()
1335 main.exit()
1336
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001338 """
1339 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001340 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001341 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001342 NOTE: this uses a custom mn function
1343 required params:
1344 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001345 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001346 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001347 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001348 response = self.execute(
1349 cmd=command,
1350 prompt="mininet>",
1351 timeout=10 )
1352 if re.search( "no host named", response ):
1353 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001354 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001355 elif re.search( "Error", response ):
1356 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001357 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001358 elif re.search( "usage:", response ):
1359 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001360 return main.FALSE
1361 else:
1362 return main.TRUE
1363 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001364 main.log.error( self.name + ": EOF exception found" )
1365 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001366 main.cleanup()
1367 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001368
Jon Hall7eb38402015-01-08 17:19:54 -08001369 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001370 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001371 Called at the end of the test to stop the mininet and
1372 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001373 """
1374 self.handle.sendline('')
Jon Halld61331b2015-02-17 16:35:47 -08001375 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -08001376 timeout=2)
Jon Hall390696c2015-05-05 17:13:41 -07001377 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001378 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001379 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001380 elif i == 1:
1381 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001382 # print "Disconnecting Mininet"
1383 if self.handle:
1384 self.handle.sendline( "exit" )
1385 self.handle.expect( "exit" )
1386 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001387 else:
1388 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001389 return response
1390
Hari Krishnab35c6d02015-03-18 11:13:51 -07001391 def stopNet( self, fileName = "", timeout=5):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001392 """
Jon Hall21270ac2015-02-16 17:59:55 -08001393 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001394 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001395 main.FALSE if the pexpect handle does not exist.
1396
Jon Halld61331b2015-02-17 16:35:47 -08001397 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001398 """
Jon Hall21270ac2015-02-16 17:59:55 -08001399
Jon Halld61331b2015-02-17 16:35:47 -08001400 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001401 response = ''
1402 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001403 try:
kelvin-onlab26bc17f2015-02-06 14:08:59 -08001404 self.handle.sendline("")
kelvin-onlab56a3f462015-02-06 14:04:43 -08001405 i = self.handle.expect( [ 'mininet>',
1406 '\$',
1407 pexpect.EOF,
1408 pexpect.TIMEOUT ],
1409 timeout )
1410 if i == 0:
1411 main.log.info( "Exiting mininet..." )
1412
Jon Hall7eb38402015-01-08 17:19:54 -08001413 response = self.execute(
1414 cmd="exit",
1415 prompt="(.*)",
1416 timeout=120 )
Jon Halld61331b2015-02-17 16:35:47 -08001417 main.log.info( self.name + ": Stopped")
Jon Hall7eb38402015-01-08 17:19:54 -08001418 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001419 response = main.TRUE
Hari Krishnab35c6d02015-03-18 11:13:51 -07001420
kelvin-onlab56a3f462015-02-06 14:04:43 -08001421 if i == 1:
1422 main.log.info( " Mininet trying to exit while not " +
1423 "in the mininet prompt" )
1424 elif i == 2:
1425 main.log.error( "Something went wrong exiting mininet" )
1426 elif i == 3: # timeout
1427 main.log.error( "Something went wrong exiting mininet " +
1428 "TIMEOUT" )
1429
Hari Krishnab35c6d02015-03-18 11:13:51 -07001430 if fileName:
1431 self.handle.sendline("")
1432 self.handle.expect('\$')
1433 self.handle.sendline("sudo kill -9 \`ps -ef | grep \""+ fileName +"\" | grep -v grep | awk '{print $2}'\`")
Jon Hallfbc828e2015-01-06 17:30:19 -08001434 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001437 main.cleanup()
1438 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001439 else:
1440 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001441 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001442 return response
1443
kelvin-onlabf0594d72015-05-19 17:25:12 -07001444 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001445 """
1446 Description:
1447 Sends arp message from mininet host for hosts discovery
1448 Required:
1449 host - hosts name
1450 Optional:
1451 ip - ip address that does not exist in the network so there would
1452 be no reply.
1453 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001454 if ethDevice:
1455 ethDevice = '-I ' + ethDevice + ' '
1456 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001457 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001458 main.log.warn( "Sending: " + cmd )
1459 self.handle.sendline( cmd )
1460 response = self.handle.before
1461 self.handle.sendline( "" )
1462 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001463 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001464
1465 except pexpect.EOF:
1466 main.log.error( self.name + ": EOF exception found" )
1467 main.log.error( self.name + ": " + self.handle.before )
1468 main.cleanup()
1469 main.exit()
admin07529932013-11-22 14:58:28 -08001470
Jon Hall7eb38402015-01-08 17:19:54 -08001471 def decToHex( self, num ):
1472 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001473
Jon Hall7eb38402015-01-08 17:19:54 -08001474 def getSwitchFlowCount( self, switch ):
1475 """
1476 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001477 if self.handle:
1478 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1479 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001480 response = self.execute(
1481 cmd=cmd,
1482 prompt="mininet>",
1483 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001484 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001485 main.log.error( self.name + ": EOF exception found" )
1486 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001487 main.cleanup()
1488 main.exit()
1489 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001490 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001491 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001492 main.log.info(
1493 "Couldn't find flows on switch %s, found: %s" %
1494 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001495 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001496 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001497 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001498 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001499
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 def checkFlows( self, sw, dumpFormat=None ):
1501 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001502 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001504 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001505 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001506 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001507 response = self.execute(
1508 cmd=command,
1509 prompt="mininet>",
1510 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001511 return response
1512 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001513 main.log.error( self.name + ": EOF exception found" )
1514 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001515 main.cleanup()
1516 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001517
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001519 """
Jon Hallefbd9792015-03-05 16:11:36 -08001520 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001521 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001522 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001523 self.handle.sendline( "" )
1524 self.handle.expect( "mininet>" )
1525 self.handle.sendline(
1526 "sh sudo tcpdump -n -i " +
1527 intf +
1528 " " +
1529 port +
1530 " -w " +
1531 filename.strip() +
1532 " &" )
1533 self.handle.sendline( "" )
1534 i = self.handle.expect( [ 'No\ssuch\device',
1535 'listening\son',
1536 pexpect.TIMEOUT,
1537 "mininet>" ],
1538 timeout=10 )
1539 main.log.warn( self.handle.before + self.handle.after )
1540 self.handle.sendline( "" )
1541 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001542 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001543 main.log.error(
1544 self.name +
1545 ": tcpdump - No such device exists. " +
1546 "tcpdump attempted on: " +
1547 intf )
admin2a9548d2014-06-17 14:08:07 -07001548 return main.FALSE
1549 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001550 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001551 return main.TRUE
1552 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001553 main.log.error(
1554 self.name +
1555 ": tcpdump command timed out! Check interface name," +
1556 " given interface was: " +
1557 intf )
admin2a9548d2014-06-17 14:08:07 -07001558 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001559 elif i == 3:
1560 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001561 return main.TRUE
1562 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001563 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001564 return main.FALSE
1565 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001566 main.log.error( self.name + ": EOF exception found" )
1567 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001568 main.cleanup()
1569 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001570 except Exception:
1571 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001572 main.cleanup()
1573 main.exit()
1574
kelvin-onlabd3b64892015-01-20 13:26:24 -08001575 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001576 """
1577 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001578 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001579 self.handle.sendline( "sh sudo pkill tcpdump" )
1580 self.handle.expect( "mininet>" )
1581 self.handle.sendline( "" )
1582 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001583 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001584 main.log.error( self.name + ": EOF exception found" )
1585 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001586 main.cleanup()
1587 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001588 except Exception:
1589 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001590 main.cleanup()
1591 main.exit()
1592
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001594 """
1595 Compare mn and onos switches
1596 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001598
Jon Hall7eb38402015-01-08 17:19:54 -08001599 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001601 output = { "switches": [] }
1602 # iterate through the MN topology and pull out switches and and port
1603 # info
1604 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001605 ports = []
1606 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001607 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001608 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001609 'name': port.name } )
1610 output[ 'switches' ].append( {
1611 "name": switch.name,
1612 "dpid": str( switch.dpid ).zfill( 16 ),
1613 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001614
Jon Hall7eb38402015-01-08 17:19:54 -08001615 # print "mn"
1616 # print json.dumps( output,
Jon Hallff6b4b22015-02-23 09:25:15 -08001617 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001618 # indent=4,
1619 # separators=( ',', ': ' ) )
1620 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 # print json.dumps( switchesJson,
Jon Hallff6b4b22015-02-23 09:25:15 -08001622 # sort_keys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001623 # indent=4,
1624 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001625
1626 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001627 mnDPIDs = []
1628 for switch in output[ 'switches' ]:
1629 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001630 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001631 # print "List of Mininet switch DPID's"
1632 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001633 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001634 main.log.error(
1635 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07001636 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001637 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001639 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001640 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001641 if switch[ 'available' ]:
1642 onosDPIDs.append(
1643 switch[ 'id' ].replace(
1644 ":",
1645 '' ).replace(
1646 "of",
1647 '' ).lower() )
1648 # else:
1649 # print "Switch is unavailable:"
1650 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001651 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001652 # print "List of ONOS switch DPID's"
1653 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001654
Jon Hall7eb38402015-01-08 17:19:54 -08001655 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001657 main.log.report( "Switches in MN but not in ONOS:" )
1658 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1659 main.log.report( str( list1 ) )
1660 main.log.report( "Switches in ONOS but not in MN:" )
1661 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001662 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001663 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 switchResults = main.TRUE
1665 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001666
kelvin-onlabd3b64892015-01-20 13:26:24 -08001667 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001668 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001669 Compare mn and onos ports
1670 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001672
Jon Hallfbc828e2015-01-06 17:30:19 -08001673 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001674 1. This uses the sts TestONTopology object
1675 2. numpy - "sudo pip install numpy"
1676
Jon Hall7eb38402015-01-08 17:19:54 -08001677 """
1678 # FIXME: this does not look for extra ports in ONOS, only checks that
1679 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001680 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001682 output = { "switches": [] }
1683 # iterate through the MN topology and pull out switches and and port
1684 # info
1685 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001686 ports = []
1687 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001688 # print port.hw_addr.toStr( separator='' )
Jon Hallefbd9792015-03-05 16:11:36 -08001689 tmpPort = { 'of_port': port.port_no,
1690 'mac': str( port.hw_addr ).replace( '\'', '' ),
1691 'name': port.name,
1692 'enabled': port.enabled }
Jon Hall39f29df2014-11-04 19:30:21 -05001693
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 ports.append( tmpPort )
Jon Hallefbd9792015-03-05 16:11:36 -08001695 tmpSwitch = { 'name': switch.name,
1696 'dpid': str( switch.dpid ).zfill( 16 ),
1697 'ports': ports }
Jon Hall39f29df2014-11-04 19:30:21 -05001698
kelvin-onlabd3b64892015-01-20 13:26:24 -08001699 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001700
Jon Hall7eb38402015-01-08 17:19:54 -08001701 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001702 for mnSwitch in output[ 'switches' ]:
1703 mnPorts = []
1704 onosPorts = []
1705 switchResult = main.TRUE
1706 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001707 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001708 mnPorts.append( port[ 'of_port' ] )
1709 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001710 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 # print onosSwitch
1712 if onosSwitch[ 'device' ][ 'available' ]:
1713 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001714 ':',
1715 '' ).replace(
1716 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001717 '' ) == mnSwitch[ 'dpid' ]:
1718 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001719 if port[ 'isEnabled' ]:
1720 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001721 # onosPorts.append( 'local' )
1722 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001723 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001724 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001725 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 mnPorts.sort( key=float )
1727 onosPorts.sort( key=float )
1728 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1729 # print "\tmn_ports[] = ", mnPorts
1730 # print "\tonos_ports[] = ", onosPorts
1731 mnPortsLog = mnPorts
1732 onosPortsLog = onosPorts
1733 mnPorts = [ x for x in mnPorts ]
1734 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001735
Jon Hall7eb38402015-01-08 17:19:54 -08001736 # TODO: handle other reserved port numbers besides LOCAL
1737 # NOTE: Reserved ports
1738 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1739 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 for mnPort in mnPortsLog:
1741 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001742 # don't set results to true here as this is just one of
1743 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 mnPorts.remove( mnPort )
1745 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001746 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001747 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001748 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 if 65534 in mnPorts:
1750 mnPorts.remove( 65534 )
1751 if long( uint64( -2 ) ) in onosPorts:
1752 onosPorts.remove( long( uint64( -2 ) ) )
1753 if len( mnPorts ): # the ports of this switch don't match
1754 switchResult = main.FALSE
1755 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1756 if len( onosPorts ): # the ports of this switch don't match
1757 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001758 main.log.warn(
1759 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001760 str( onosPorts ) )
1761 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001762 main.log.report(
1763 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1765 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1766 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1767 portsResults = portsResults and switchResult
1768 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001769
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001771 """
1772 Compare mn and onos links
1773 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001775
Jon Hall7eb38402015-01-08 17:19:54 -08001776 This uses the sts TestONTopology object"""
1777 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08001778 # ONOS has what is in MN
Jon Hall7eb38402015-01-08 17:19:54 -08001779 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001780 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001781 # iterate through the MN topology and pull out switches and and port
1782 # info
1783 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001784 # print "Iterating though switches as seen by Mininet"
1785 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001786 ports = []
1787 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001788 # print port.hw_addr.toStr( separator='' )
1789 ports.append( { 'of_port': port.port_no,
Jon Hallefbd9792015-03-05 16:11:36 -08001790 'mac': str( port.hw_addr ).replace( '\'', '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001791 'name': port.name } )
1792 output[ 'switches' ].append( {
1793 "name": switch.name,
1794 "dpid": str( switch.dpid ).zfill( 16 ),
1795 "ports": ports } )
1796 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001797
kelvin-onlabd3b64892015-01-20 13:26:24 -08001798 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001799 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001800 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 if 2 * len( mnLinks ) == len( onos ):
1802 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001803 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001804 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001805 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001806 "Mininet has " + str( len( mnLinks ) ) +
1807 " bidirectional links and ONOS has " +
1808 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001809
Jon Hall7eb38402015-01-08 17:19:54 -08001810 # iterate through MN links and check if an ONOS link exists in
1811 # both directions
1812 # NOTE: Will currently only show mn links as down if they are
1813 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001815 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001817 # print "Link: %s" % link
1818 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001819 node1 = None
1820 port1 = None
1821 node2 = None
1822 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001823 firstDir = main.FALSE
1824 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001825 for switch in output[ 'switches' ]:
1826 # print "Switch: %s" % switch[ 'name' ]
1827 if switch[ 'name' ] == link.node1.name:
1828 node1 = switch[ 'dpid' ]
1829 for port in switch[ 'ports' ]:
1830 if str( port[ 'name' ] ) == str( link.port1 ):
1831 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001832 if node1 is not None and node2 is not None:
1833 break
Jon Hall7eb38402015-01-08 17:19:54 -08001834 if switch[ 'name' ] == link.node2.name:
1835 node2 = switch[ 'dpid' ]
1836 for port in switch[ 'ports' ]:
1837 if str( port[ 'name' ] ) == str( link.port2 ):
1838 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001839 if node1 is not None and node2 is not None:
1840 break
1841
kelvin-onlabd3b64892015-01-20 13:26:24 -08001842 for onosLink in onos:
1843 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001844 ":",
1845 '' ).replace(
1846 "of",
1847 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001848 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001849 ":",
1850 '' ).replace(
1851 "of",
1852 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 onosPort1 = onosLink[ 'src' ][ 'port' ]
1854 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001855
Jon Hall72cf1dc2014-10-20 21:04:50 -04001856 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001857 if str( onosNode1 ) == str( node1 ) and str(
1858 onosNode2 ) == str( node2 ):
1859 if int( onosPort1 ) == int( port1 ) and int(
1860 onosPort2 ) == int( port2 ):
1861 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001862 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001863 main.log.warn(
1864 'The port numbers do not match for ' +
1865 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001866 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001867 'link %s/%s -> %s/%s' %
1868 ( node1,
1869 port1,
1870 node2,
1871 port2 ) +
1872 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001873 ( onosNode1,
1874 onosPort1,
1875 onosNode2,
1876 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001877
1878 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 elif ( str( onosNode1 ) == str( node2 ) and
1880 str( onosNode2 ) == str( node1 ) ):
1881 if ( int( onosPort1 ) == int( port2 )
1882 and int( onosPort2 ) == int( port1 ) ):
1883 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001884 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001885 main.log.warn(
1886 'The port numbers do not match for ' +
1887 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08001888 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08001889 'link %s/%s -> %s/%s' %
1890 ( node2,
1891 port2,
1892 node1,
1893 port1 ) +
1894 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001895 ( onosNode2,
1896 onosPort2,
1897 onosNode1,
1898 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001899 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001900 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001901 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001902 main.log.report(
1903 'ONOS does not have the link %s/%s -> %s/%s' %
1904 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001905 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001906 main.log.report(
1907 'ONOS does not have the link %s/%s -> %s/%s' %
1908 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001909 linkResults = linkResults and firstDir and secondDir
1910 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001911
Jon Hallff6b4b22015-02-23 09:25:15 -08001912 def compareHosts( self, topo, hostsJson ):
1913 """
1914 Compare mn and onos Hosts.
1915 Since Mininet hosts are quiet, ONOS will only know of them when they
1916 speak. For this reason, we will only check that the hosts in ONOS
1917 stores are in Mininet, and not vice versa.
1918 topo: sts TestONTopology object
1919 hostsJson: parsed json object from the onos hosts api
1920
1921 This uses the sts TestONTopology object"""
1922 import json
1923 hostResults = main.TRUE
1924 hosts = []
1925 # iterate through the MN topology and pull out hosts
1926 for mnHost in topo.graph.hosts:
1927 interfaces = []
1928 for intf in mnHost.interfaces:
1929 interfaces.append( {
1930 "name": intf.name, # str
1931 "ips": [ str( ip ) for ip in intf.ips ], # list of IPAddrs
1932 # hw_addr is of type EthAddr, Not JSON serializable
1933 "hw_addr": str( intf.hw_addr ) } )
1934 hosts.append( {
1935 "name": mnHost.name, # str
1936 "interfaces": interfaces } ) # list
1937 for onosHost in hostsJson:
1938 onosMAC = onosHost[ 'mac' ].lower()
1939 match = False
1940 for mnHost in hosts:
1941 for mnIntf in mnHost[ 'interfaces' ]:
1942 if onosMAC == mnIntf[ 'hw_addr' ].lower() :
1943 match = True
1944 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001945 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08001946 pass # all is well
1947 else:
1948 # misssing ip
1949 main.log.error( "ONOS host " + onosHost[ 'id' ]
1950 + " has a different IP than " +
1951 "the Mininet host." )
1952 output = json.dumps(
1953 onosHost,
1954 sort_keys=True,
1955 indent=4,
1956 separators=( ',', ': ' ) )
1957 main.log.info( output )
1958 hostResults = main.FALSE
1959 if not match:
1960 hostResults = main.FALSE
1961 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
1962 "corresponding Mininet host." )
1963 output = json.dumps( onosHost,
1964 sort_keys=True,
1965 indent=4,
1966 separators=( ',', ': ' ) )
1967 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08001968 return hostResults
1969
kelvin-onlabd3b64892015-01-20 13:26:24 -08001970 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001971 """
1972 Returns a list of all hosts
1973 Don't ask questions just use it"""
1974 self.handle.sendline( "" )
1975 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001976
Jon Hall7eb38402015-01-08 17:19:54 -08001977 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1978 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001979
kelvin-onlabd3b64892015-01-20 13:26:24 -08001980 handlePy = self.handle.before
1981 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1982 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001983
Jon Hall7eb38402015-01-08 17:19:54 -08001984 self.handle.sendline( "" )
1985 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001986
kelvin-onlabd3b64892015-01-20 13:26:24 -08001987 hostStr = handlePy.replace( "]", "" )
1988 hostStr = hostStr.replace( "'", "" )
1989 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07001990 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001991 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001992
kelvin-onlabd3b64892015-01-20 13:26:24 -08001993 return hostList
adminbae64d82013-08-01 10:50:15 -07001994
Jon Hall7eb38402015-01-08 17:19:54 -08001995 def update( self ):
1996 """
1997 updates the port address and status information for
1998 each port in mn"""
1999 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002000 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002001 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002002 self.handle.sendline( "" )
2003 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002004
Jon Hall7eb38402015-01-08 17:19:54 -08002005 self.handle.sendline( "update" )
2006 self.handle.expect( "update" )
2007 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002008
Jon Hall7eb38402015-01-08 17:19:54 -08002009 self.handle.sendline( "" )
2010 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002011
Jon Hallb1290e82014-11-18 16:17:48 -05002012 return main.TRUE
2013 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002014 main.log.error( self.name + ": EOF exception found" )
2015 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002016 main.cleanup()
2017 main.exit()
2018
kaouthera3f13ca22015-05-05 15:01:41 -07002019 def assignVLAN( self, host, intf, vlan):
2020 """
2021 Add vlan tag to a host.
2022 Dependencies:
2023 This class depends on the "vlan" package
2024 $ sudo apt-get install vlan
2025 Configuration:
2026 Load the 8021q module into the kernel
2027 $sudo modprobe 8021q
2028
2029 To make this setup permanent:
2030 $ sudo su -c 'echo "8021q" >> /etc/modules'
2031 """
2032 if self.handle:
2033 try:
2034 # get the ip address of the host
2035 main.log.info("Get the ip address of the host")
2036 ipaddr = self.getIPAddress(host)
2037 print repr(ipaddr)
2038
2039 # remove IP from interface intf
2040 # Ex: h1 ifconfig h1-eth0 inet 0
2041 main.log.info("Remove IP from interface ")
2042 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2043 self.handle.sendline( cmd2 )
2044 self.handle.expect( "mininet>" )
2045 response = self.handle.before
2046 main.log.info ( "====> %s ", response)
2047
2048
2049 # create VLAN interface
2050 # Ex: h1 vconfig add h1-eth0 100
2051 main.log.info("Create Vlan")
2052 cmd3 = host + " vconfig add " + intf + " " + vlan
2053 self.handle.sendline( cmd3 )
2054 self.handle.expect( "mininet>" )
2055 response = self.handle.before
2056 main.log.info( "====> %s ", response )
2057
2058 # assign the host's IP to the VLAN interface
2059 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2060 main.log.info("Assign the host IP to the vlan interface")
2061 vintf = intf + "." + vlan
2062 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2063 self.handle.sendline( cmd4 )
2064 self.handle.expect( "mininet>" )
2065 response = self.handle.before
2066 main.log.info ( "====> %s ", response)
2067
2068
2069 return main.TRUE
2070 except pexpect.EOF:
2071 main.log.error( self.name + ": EOF exception found" )
2072 main.log.error( self.name + ": " + self.handle.before )
2073 return main.FALSE
2074
adminbae64d82013-08-01 10:50:15 -07002075if __name__ != "__main__":
2076 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002077 sys.modules[ __name__ ] = MininetCliDriver()
kaouthera3f13ca22015-05-05 15:01:41 -07002078
2079