blob: cd64fd000886a911d54ef488943480b9ac3bbe2f [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
Jon Hallbe6dfc42015-01-12 17:37:25 -080022MininetCliDriver is the basic driver which will handle the Mininet functions
23
Jon Hall272a4db2015-01-12 17:43:48 -080024Some functions rely on STS module. To install this,
25 git clone https://github.com/jhall11/sts.git
26
Jon Hallbe6dfc42015-01-12 17:37:25 -080027Some functions rely on a modified version of Mininet. These functions
28should all be noted in the comments. To get this MN version run these commands
29from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080030 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080032 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080033 git pull
34
Jon Hall272a4db2015-01-12 17:43:48 -080035
36 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080037changed when switching branches."""
admin2a9548d2014-06-17 14:08:07 -070038import traceback
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
47class MininetCliDriver( Emulator ):
48
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 Hall7eb38402015-01-08 17:19:54 -080055 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070056 self.flag = 0
57
Jon Hall7eb38402015-01-08 17:19:54 -080058 def connect( self, **connectargs ):
59 """
60 Here the main is the TestON instance after creating
61 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080062 try:
63 for key in connectargs:
64 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080065
kelvin-onlaba1484582015-02-02 15:46:20 -080066 self.name = self.options[ 'name' ]
67 self.handle = super(
68 MininetCliDriver,
69 self ).connect(
70 user_name=self.user_name,
71 ip_address=self.ip_address,
72 port=None,
73 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080074
kelvin-onlaba1484582015-02-02 15:46:20 -080075 if self.handle:
76 main.log.info("Connection successful to the host " +
77 self.user_name +
78 "@" +
79 self.ip_address )
80 return main.TRUE
81 else:
82 main.log.error( "Connection failed to the host " +
83 self.user_name +
84 "@" +
85 self.ip_address )
86 msin.log.error( "Failed to connect to the Mininet CLI" )
87 return main.FALSE
88 except pexpect.EOF:
89 main.log.error( self.name + ": EOF exception found" )
90 main.log.error( self.name + ": " + self.handle.before )
91 main.cleanup()
92 main.exit()
93 except:
94 main.log.info( self.name + ":::::::::::::::::::::::" )
95 main.log.error( traceback.print_exc() )
96 main.log.info( ":::::::::::::::::::::::" )
97 main.cleanup()
98 main.exit()
99
100
101 def startNet( self, topoFile = '', args = '', timeout = 120 ):
Jon Hallfbc828e2015-01-06 17:30:19 -0800102
Jon Hall7eb38402015-01-08 17:19:54 -0800103 if self.handle:
104 main.log.info(
105 self.name +
106 ": Clearing any residual state or processes" )
107 self.handle.sendline( "sudo mn -c" )
108 i = self.handle.expect( [ 'password\sfor\s',
109 'Cleanup\scomplete',
110 pexpect.EOF,
111 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800112 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800113 if i == 0:
114 main.log.info( self.name + ": Sending sudo password" )
115 self.handle.sendline( self.pwd )
116 i = self.handle.expect( [ '%s:' % ( self.user ),
117 '\$',
118 pexpect.EOF,
119 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800120 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800121 if i == 1:
122 main.log.info( self.name + ": Clean" )
123 elif i == 2:
124 main.log.error( self.name + ": Connection terminated" )
125 elif i == 3: # timeout
126 main.log.error(
127 self.name +
128 ": Something while cleaning MN took too long... " )
kelvin-onlaba1484582015-02-02 15:46:20 -0800129 if topoFile == '' and args == '':
130 main.log.info( self.name + ": building fresh mininet" )
131 # for reactive/PARP enabled tests
132 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
133 " " + self.options[ 'arg2' ] +\
134 " --mac --controller " +\
135 self.options[ 'controller' ] + " " +\
136 self.options[ 'arg3' ]
Jon Hallfbc828e2015-01-06 17:30:19 -0800137
kelvin-onlaba1484582015-02-02 15:46:20 -0800138 argList = self.options[ 'arg1' ].split( "," )
139 global topoArgList
140 topoArgList = argList[ 0 ].split( " " )
141 argList = map( int, argList[ 1: ] )
142 topoArgList = topoArgList[ 1: ] + argList
Jon Hallfbc828e2015-01-06 17:30:19 -0800143
kelvin-onlaba1484582015-02-02 15:46:20 -0800144 self.handle.sendline( cmdString )
145 self.handle.expect( [ "sudo mn",
146 pexpect.EOF,
147 pexpect.TIMEOUT ] )
148 while True:
149 i = self.handle.expect( [ 'mininet>',
150 '\*\*\*',
151 'Exception',
152 pexpect.EOF,
153 pexpect.TIMEOUT ],
154 timeout )
155 if i == 0:
156 main.log.info( self.name + ": mininet built" )
157 return main.TRUE
158 if i == 1:
159 self.handle.expect(
160 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
161 main.log.info( self.handle.before )
162 elif i == 2:
163 main.log.error(
164 self.name +
165 ": Launching mininet failed..." )
166 return main.FALSE
167 elif i == 3:
168 main.log.error( self.name + ": Connection timeout" )
169 return main.FALSE
170 elif i == 4: # timeout
171 main.log.error(
172 self.name +
173 ": Something took too long... " )
174 return main.FALSE
175 return main.TRUE
176 else:
177 main.log.info( "Starting topo file " + topoFile )
178 if args == None:
179 args = ''
180 else:
181 main.log.info( "args = " + args)
182 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
183 i = 1
Jon Hall7eb38402015-01-08 17:19:54 -0800184 i = self.handle.expect( [ 'mininet>',
kelvin-onlaba1484582015-02-02 15:46:20 -0800185 pexpect.EOF ,
186 pexpect.TIMEOUT ],
187 timeout)
188 main.log.info(self.name + ": Network started")
189 return main.TRUE
190
Jon Hall7eb38402015-01-08 17:19:54 -0800191 else: # if no handle
192 main.log.error(
193 self.name +
194 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800195 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800196 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800197 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800198 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700199 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800200
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800201 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400202 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800203 # In tree topology, if fanout arg is not given, by default it is 2
204 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400205 fanout = 2
206 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500207 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800208 while( k <= depth - 1 ):
209 count = count + pow( fanout, k )
210 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800211 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800212 while( k <= depth - 2 ):
213 # depth-2 gives you only core links and not considering
214 # edge links as seen by ONOS. If all the links including
215 # edge links are required, do depth-1
216 count = count + pow( fanout, k )
217 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800219 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800221
Jon Hall7eb38402015-01-08 17:19:54 -0800222 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800224 # by default it is 1
225 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400226 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 numSwitches = depth
228 numHostsPerSw = fanout
229 totalNumHosts = numSwitches * numHostsPerSw
230 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800231 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400233 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800234 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800235 "num_switches": int( numSwitches ),
236 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400237 return topoDict
238
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 def calculateSwAndLinks( self ):
240 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400241 return topoDict
242
Jon Hall7eb38402015-01-08 17:19:54 -0800243 def pingall( self, timeout=300 ):
244 """
245 Verifies the reachability of the hosts using pingall command.
246 Optional parameter timeout allows you to specify how long to
247 wait for pingall to complete
248 Returns:
249 main.TRUE if pingall completes with no pings dropped
250 otherwise main.FALSE"""
251 if self.handle:
252 main.log.info(
253 self.name +
254 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700255 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800256 response = self.execute(
257 cmd="pingall",
258 prompt="mininet>",
259 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500260 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800261 main.log.error( self.name + ": EOF exception found" )
262 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500263 main.cleanup()
264 main.exit()
265 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800266 # We may not want to kill the test if pexpect times out
267 main.log.error( self.name + ": TIMEOUT exception found" )
268 main.log.error( self.name +
269 ": " +
270 str( self.handle.before ) )
271 # NOTE: mininet's pingall rounds, so we will check the number of
272 # passed and number of failed
273 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800275 if re.search( pattern, response ):
276 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700277 return main.TRUE
278 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800279 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800280 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800281 # NOTE: Send ctrl-c to make sure pingall is done
282 self.handle.send( "\x03" )
283 self.handle.expect( "Interrupt" )
284 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700285 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800286 else:
287 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500288 main.cleanup()
289 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700290
Jon Hall7eb38402015-01-08 17:19:54 -0800291 def fpingHost( self, **pingParams ):
292 """
293 Uses the fping package for faster pinging...
294 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800295 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800296 command = args[ "SRC" ] + \
297 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
298 self.handle.sendline( command )
299 self.handle.expect(
300 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
301 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
302 response = self.handle.before
303 if re.search( ":\s-", response ):
304 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700305 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800306 elif re.search( ":\s\d{1,2}\.\d\d", response ):
307 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700308 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800309 main.log.info( self.name + ": Install fping on mininet machine... " )
310 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700311 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800312
Jon Hall7eb38402015-01-08 17:19:54 -0800313 def pingHost( self, **pingParams ):
314 """
315 Ping from one mininet host to another
316 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800317 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800318 command = args[ "SRC" ] + " ping " + \
319 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700320 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800321 main.log.warn( "Sending: " + command )
322 self.handle.sendline( command )
323 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700324 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800325 main.log.error(
326 self.name +
327 ": timeout when waiting for response from mininet" )
328 main.log.error( "response: " + str( self.handle.before ) )
329 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700330 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800331 main.log.error(
332 self.name +
333 ": timeout when waiting for response from mininet" )
334 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700335 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800336 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800337 main.log.error( self.name + ": EOF exception found" )
338 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700339 main.cleanup()
340 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800341 main.log.info( self.name + ": Ping Response: " + response )
342 if re.search( ',\s0\%\spacket\sloss', response ):
343 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800344 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700345 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800346 else:
347 main.log.error(
348 self.name +
349 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800350 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700351 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800352
Jon Hall7eb38402015-01-08 17:19:54 -0800353 def checkIP( self, host ):
354 """
355 Verifies the host's ip configured or not."""
356 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700357 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800358 response = self.execute(
359 cmd=host +
360 " ifconfig",
361 prompt="mininet>",
362 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800363 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800364 main.log.error( self.name + ": EOF exception found" )
365 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700366 main.cleanup()
367 main.exit()
adminbae64d82013-08-01 10:50:15 -0700368
Jon Hall7eb38402015-01-08 17:19:54 -0800369 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800370 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
371 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
372 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
373 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
374 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800375 # pattern = "inet addr:10.0.0.6"
376 if re.search( pattern, response ):
377 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700378 return main.TRUE
379 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800380 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700381 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800382 else:
383 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800384
Jon Hall7eb38402015-01-08 17:19:54 -0800385 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700386 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800387 response = self.execute(
388 cmd="h1 /usr/sbin/sshd -D&",
389 prompt="mininet>",
390 timeout=10 )
391 response = self.execute(
392 cmd="h4 /usr/sbin/sshd -D&",
393 prompt="mininet>",
394 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700395 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800396 vars( self )[ key ] = connectargs[ key ]
397 response = self.execute(
398 cmd="xterm h1 h4 ",
399 prompt="mininet>",
400 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800401 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800402 main.log.error( self.name + ": EOF exception found" )
403 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700404 main.cleanup()
405 main.exit()
adminbae64d82013-08-01 10:50:15 -0700406 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800407 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700408 if self.flag == 0:
409 self.flag = 1
410 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800411 else:
adminbae64d82013-08-01 10:50:15 -0700412 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800413
kelvin-onlaba1484582015-02-02 15:46:20 -0800414 def moveHost( self, host, oldSw, newSw, ):
415 """
416 Moves a host from one switch to another on the fly
417 Note: The intf between host and oldSw when detached
418 using detach(), will still show up in the 'net'
419 cmd, because switch.detach() doesn't affect switch.intfs[]
420 (which is correct behavior since the interfaces
421 haven't moved).
422 """
423 if self.handle:
424 try:
425 # Bring link between oldSw-host down
426 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
427 "'down')"
428 print "cmd1= ", cmd
429 response = self.execute(
430 cmd=cmd,
431 prompt="mininet>",
432 timeout=10 )
433
434 # Determine hostintf and Oldswitchintf
435 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
436 ")[0]"
437 print "cmd2= ", cmd
438 self.handle.sendline( cmd )
439 self.handle.expect( "mininet>" )
440
441 # Determine ipaddress of the host-oldSw interface
442 cmd = "px ipaddr = hintf.IP()"
443 print "cmd3= ", cmd
444 self.handle.sendline( cmd )
445 self.handle.expect( "mininet>" )
446
447 # Detach interface between oldSw-host
448 cmd = "px " + oldSw + ".detach( sintf )"
449 print "cmd4= ", cmd
450 self.handle.sendline( cmd )
451 self.handle.expect( "mininet>" )
452
453 # Add link between host-newSw
454 cmd = "py net.addLink(" + host + "," + newSw + ")"
455 print "cmd5= ", cmd
456 self.handle.sendline( cmd )
457 self.handle.expect( "mininet>" )
458
459 # Determine hostintf and Newswitchintf
460 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
461 ")[0]"
462 print "cmd6= ", cmd
463 self.handle.sendline( cmd )
464 self.handle.expect( "mininet>" )
465
466 # Attach interface between newSw-host
467 cmd = "px " + newSw + ".attach( sintf )"
468 print "cmd3= ", cmd
469 self.handle.sendline( cmd )
470 self.handle.expect( "mininet>" )
471
472 # Set ipaddress of the host-newSw interface
473 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
474 print "cmd7 = ", cmd
475 self.handle.sendline( cmd )
476 self.handle.expect( "mininet>" )
477
478 cmd = "net"
479 print "cmd8 = ", cmd
480 self.handle.sendline( cmd )
481 self.handle.expect( "mininet>" )
482 print "output = ", self.handle.before
483
484 # Determine ipaddress of the host-newSw interface
485 cmd = "h1 ifconfig"
486 print "cmd9= ", cmd
487 self.handle.sendline( cmd )
488 self.handle.expect( "mininet>" )
489 print "ifconfig o/p = ", self.handle.before
490
491 return main.TRUE
492 except pexpect.EOF:
493 main.log.error( self.name + ": EOF exception found" )
494 main.log.error( self.name + ": " + self.handle.before )
495 return main.FALSE
496
Jon Hall7eb38402015-01-08 17:19:54 -0800497 def changeIP( self, host, intf, newIP, newNetmask ):
498 """
499 Changes the ip address of a host on the fly
500 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800501 if self.handle:
502 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800503 cmd = host + " ifconfig " + intf + " " + \
504 newIP + " " + 'netmask' + " " + newNetmask
505 self.handle.sendline( cmd )
506 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800507 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800508 main.log.info( "response = " + response )
509 main.log.info(
510 "Ip of host " +
511 host +
512 " changed to new IP " +
513 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800514 return main.TRUE
515 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800516 main.log.error( self.name + ": EOF exception found" )
517 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800518 return main.FALSE
519
Jon Hall7eb38402015-01-08 17:19:54 -0800520 def changeDefaultGateway( self, host, newGW ):
521 """
522 Changes the default gateway of a host
523 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800524 if self.handle:
525 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800526 cmd = host + " route add default gw " + newGW
527 self.handle.sendline( cmd )
528 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800529 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800530 main.log.info( "response = " + response )
531 main.log.info(
532 "Default gateway of host " +
533 host +
534 " changed to " +
535 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800536 return main.TRUE
537 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800538 main.log.error( self.name + ": EOF exception found" )
539 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800540 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800541
Jon Hall7eb38402015-01-08 17:19:54 -0800542 def addStaticMACAddress( self, host, GW, macaddr ):
543 """
544 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800545 if self.handle:
546 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800547 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
548 cmd = host + " arp -s " + GW + " " + macaddr
549 self.handle.sendline( cmd )
550 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800551 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800552 main.log.info( "response = " + response )
553 main.log.info(
554 "Mac adrress of gateway " +
555 GW +
556 " changed to " +
557 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800558 return main.TRUE
559 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800562 return main.FALSE
563
Jon Hall7eb38402015-01-08 17:19:54 -0800564 def verifyStaticGWandMAC( self, host ):
565 """
566 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800567 if self.handle:
568 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800569 # h1 arp -an
570 cmd = host + " arp -an "
571 self.handle.sendline( cmd )
572 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800573 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800574 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800575 return main.TRUE
576 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800577 main.log.error( self.name + ": EOF exception found" )
578 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800579 return main.FALSE
580
Jon Hall7eb38402015-01-08 17:19:54 -0800581 def getMacAddress( self, host ):
582 """
583 Verifies the host's ip configured or not."""
584 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700585 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800586 response = self.execute(
587 cmd=host +
588 " ifconfig",
589 prompt="mininet>",
590 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800591 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700594 main.cleanup()
595 main.exit()
adminbae64d82013-08-01 10:50:15 -0700596
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700597 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 macAddressSearch = re.search( pattern, response, re.I )
599 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800600 main.log.info(
601 self.name +
602 ": Mac-Address of Host " +
603 host +
604 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 macAddress )
606 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700607 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800608 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700609
Jon Hall7eb38402015-01-08 17:19:54 -0800610 def getInterfaceMACAddress( self, host, interface ):
611 """
612 Return the IP address of the interface on the given host"""
613 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700614 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800615 response = self.execute( cmd=host + " ifconfig " + interface,
616 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800617 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800618 main.log.error( self.name + ": EOF exception found" )
619 main.log.error( self.name + ": " + self.handle.before )
620 main.cleanup()
621 main.exit()
622
623 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 macAddressSearch = re.search( pattern, response, re.I )
625 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800626 main.log.info( "No mac address found in %s" % response )
627 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800629 main.log.info(
630 "Mac-Address of " +
631 host +
632 ":" +
633 interface +
634 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 macAddress )
636 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800637 else:
638 main.log.error( "Connection failed to the host" )
639
640 def getIPAddress( self, host ):
641 """
642 Verifies the host's ip configured or not."""
643 if self.handle:
644 try:
645 response = self.execute(
646 cmd=host +
647 " ifconfig",
648 prompt="mininet>",
649 timeout=10 )
650 except pexpect.EOF:
651 main.log.error( self.name + ": EOF exception found" )
652 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700653 main.cleanup()
654 main.exit()
adminbae64d82013-08-01 10:50:15 -0700655
656 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800657 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800658 main.log.info(
659 self.name +
660 ": IP-Address of Host " +
661 host +
662 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800663 ipAddressSearch.group( 1 ) )
664 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800665 else:
666 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800667
Jon Hall7eb38402015-01-08 17:19:54 -0800668 def getSwitchDPID( self, switch ):
669 """
670 return the datapath ID of the switch"""
671 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700672 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700673 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800674 response = self.execute(
675 cmd=cmd,
676 prompt="mininet>",
677 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800678 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800679 main.log.error( self.name + ": EOF exception found" )
680 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700681 main.cleanup()
682 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800683 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800684 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700685 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800686 main.log.info(
687 "Couldn't find DPID for switch %s, found: %s" %
688 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700689 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800690 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700691 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800692 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700693
Jon Hall7eb38402015-01-08 17:19:54 -0800694 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700695 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800696 self.handle.sendline( "" )
697 self.expect( "mininet>" )
698 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700699 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800700 response = self.execute(
701 cmd=cmd,
702 prompt="mininet>",
703 timeout=10 )
704 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700705 response = self.handle.before
706 return response
707 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800708 main.log.error( self.name + ": EOF exception found" )
709 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700710 main.cleanup()
711 main.exit()
712
Jon Hall7eb38402015-01-08 17:19:54 -0800713 def getInterfaces( self, node ):
714 """
715 return information dict about interfaces connected to the node"""
716 if self.handle:
717 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800718 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700719 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700720 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800721 response = self.execute(
722 cmd=cmd,
723 prompt="mininet>",
724 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800725 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800726 main.log.error( self.name + ": EOF exception found" )
727 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700728 main.cleanup()
729 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700730 return response
731 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700733
Jon Hall7eb38402015-01-08 17:19:54 -0800734 def dump( self ):
735 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700736 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800737 response = self.execute(
738 cmd='dump',
739 prompt='mininet>',
740 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800741 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800742 main.log.error( self.name + ": EOF exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700744 main.cleanup()
745 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700746 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800747
Jon Hall7eb38402015-01-08 17:19:54 -0800748 def intfs( self ):
749 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700750 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800751 response = self.execute(
752 cmd='intfs',
753 prompt='mininet>',
754 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800755 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800756 main.log.error( self.name + ": EOF exception found" )
757 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700758 main.cleanup()
759 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700760 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800761
Jon Hall7eb38402015-01-08 17:19:54 -0800762 def net( self ):
763 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700764 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800765 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800766 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800767 main.log.error( self.name + ": EOF exception found" )
768 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700769 main.cleanup()
770 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700771 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800772
773 def iperf( self, host1, host2 ):
774 main.log.info(
775 self.name +
776 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700777 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800778 cmd1 = 'iperf ' + host1 + " " + host2
779 self.handle.sendline( cmd1 )
780 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800781 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800782 if re.search( 'Results:', response ):
783 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800784 return main.TRUE
785 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800786 main.log.error( self.name + ": iperf test failed" )
787 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800788 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800791 main.cleanup()
792 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800793
Jon Hall7eb38402015-01-08 17:19:54 -0800794 def iperfudp( self ):
795 main.log.info(
796 self.name +
797 ": Simple iperf TCP test between two " +
798 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700799 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 response = self.execute(
801 cmd='iperfudp',
802 prompt='mininet>',
803 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800804 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700807 main.cleanup()
808 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700809 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800810
Jon Hall7eb38402015-01-08 17:19:54 -0800811 def nodes( self ):
812 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700813 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 response = self.execute(
815 cmd='nodes',
816 prompt='mininet>',
817 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800818 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700821 main.cleanup()
822 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700823 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800824
Jon Hall7eb38402015-01-08 17:19:54 -0800825 def pingpair( self ):
826 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700827 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800828 response = self.execute(
829 cmd='pingpair',
830 prompt='mininet>',
831 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800832 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 main.log.error( self.name + ": EOF exception found" )
834 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700835 main.cleanup()
836 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800837
Jon Hall7eb38402015-01-08 17:19:54 -0800838 if re.search( ',\s0\%\spacket\sloss', response ):
839 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800840 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700841 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800842 else:
843 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800844 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700845 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800846
Jon Hall7eb38402015-01-08 17:19:54 -0800847 def link( self, **linkargs ):
848 """
849 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800850 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800851 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
852 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
853 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
854 main.log.info(
855 "Bring link between '" +
856 end1 +
857 "' and '" +
858 end2 +
859 "' '" +
860 option +
861 "'" )
862 command = "link " + \
863 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700864 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800865 self.handle.sendline( command )
866 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800867 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700870 main.cleanup()
871 main.exit()
adminbae64d82013-08-01 10:50:15 -0700872 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800873
Jon Hall7eb38402015-01-08 17:19:54 -0800874 def yank( self, **yankargs ):
875 """
876 yank a mininet switch interface to a host"""
877 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800878 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800879 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
880 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
881 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700882 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800883 response = self.execute(
884 cmd=command,
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()
adminaeedddd2013-08-02 15:14:15 -0700892 return main.TRUE
893
Jon Hall7eb38402015-01-08 17:19:54 -0800894 def plug( self, **plugargs ):
895 """
896 plug the yanked mininet switch interface to a switch"""
897 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800898 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800899 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
900 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
901 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700902 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800903 response = self.execute(
904 cmd=command,
905 prompt="mininet>",
906 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800907 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700910 main.cleanup()
911 main.exit()
adminbae64d82013-08-01 10:50:15 -0700912 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800913
Jon Hall7eb38402015-01-08 17:19:54 -0800914 def dpctl( self, **dpctlargs ):
915 """
916 Run dpctl command on all switches."""
917 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800918 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800919 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
920 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
921 command = "dpctl " + cmd + " " + str( cmdargs )
922 try:
923 response = self.execute(
924 cmd=command,
925 prompt="mininet>",
926 timeout=10 )
927 except pexpect.EOF:
928 main.log.error( self.name + ": EOF exception found" )
929 main.log.error( self.name + ": " + self.handle.before )
930 main.cleanup()
931 main.exit()
932 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800933
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 def getVersion( self ):
935 fileInput = path + '/lib/Mininet/INSTALL'
936 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700937 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800938 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800939 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700940 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800941 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500942 return version
adminbae64d82013-08-01 10:50:15 -0700943
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800945 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500946 Parameters:
947 sw: The name of an OVS switch. Example "s1"
948 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800949 The output of the command from the mininet cli
950 or main.FALSE on timeout"""
951 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700952 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800953 response = self.execute(
954 cmd=command,
955 prompt="mininet>",
956 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700957 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500958 return response
admin2a9548d2014-06-17 14:08:07 -0700959 else:
960 return main.FALSE
961 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700964 main.cleanup()
965 main.exit()
adminbae64d82013-08-01 10:50:15 -0700966
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800968 """
969 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800970 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800971 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700972
973 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800974 for j in range( count ):
975 argstring = argstring + ",IP" + \
976 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800977 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700978
Jon Hall7eb38402015-01-08 17:19:54 -0800979 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
980 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800981 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800982 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800983
Jon Hall7eb38402015-01-08 17:19:54 -0800984 command = "sh ovs-vsctl set-controller s" + \
985 str( sw ) + " " + ptcpB + " "
986 for j in range( count ):
987 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800988 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -0800989 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
990 ip = args[
991 "IP" +
992 str( i ) ] if args[
993 "IP" +
994 str( i ) ] is not None else ""
995 port = args[
996 "PORT" +
997 str( i ) ] if args[
998 "PORT" +
999 str( i ) ] is not None else ""
1000 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -08001001 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -07001002 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -07001003 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001004 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -07001005 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001008 main.cleanup()
1009 main.exit()
1010 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001011 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001012 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001013 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -07001014 main.cleanup()
1015 main.exit()
adminbae64d82013-08-01 10:50:15 -07001016
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001018 """
1019 Removes the controller target from sw"""
1020 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001021 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001022 response = self.execute(
1023 cmd=command,
1024 prompt="mininet>",
1025 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001026 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001029 main.cleanup()
1030 main.exit()
1031 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001032 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001033
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001035 """
Jon Hallb1290e82014-11-18 16:17:48 -05001036 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001037 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001038 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001039 NOTE: cannot currently specify what type of switch
1040 required params:
1041 switchname = name of the new switch as a string
1042 optional keyvalues:
1043 dpid = "dpid"
1044 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001045 """
1046 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001047 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001048 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001049 response = self.execute(
1050 cmd=command,
1051 prompt="mininet>",
1052 timeout=10 )
1053 if re.search( "already exists!", response ):
1054 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001055 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001056 elif re.search( "Error", response ):
1057 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001058 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001059 elif re.search( "usage:", response ):
1060 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001061 return main.FALSE
1062 else:
1063 return main.TRUE
1064 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001065 main.log.error( self.name + ": EOF exception found" )
1066 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001067 main.cleanup()
1068 main.exit()
1069
kelvin-onlabd3b64892015-01-20 13:26:24 -08001070 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001071 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001072 delete a switch from the mininet topology
1073 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001074 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001075 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001076 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001077 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001078 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001079 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001080 response = self.execute(
1081 cmd=command,
1082 prompt="mininet>",
1083 timeout=10 )
1084 if re.search( "no switch named", response ):
1085 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001086 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001087 elif re.search( "Error", response ):
1088 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001089 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001090 elif re.search( "usage:", response ):
1091 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001092 return main.FALSE
1093 else:
1094 return main.TRUE
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 )
Jon Hallb1290e82014-11-18 16:17:48 -05001098 main.cleanup()
1099 main.exit()
1100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001102 """
1103 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001104 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001105 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001106 NOTE: cannot currently specify what type of link
1107 required params:
1108 node1 = the string node name of the first endpoint of the link
1109 node2 = the string node name of the second endpoint of the link
1110 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001111 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001112 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001113 response = self.execute(
1114 cmd=command,
1115 prompt="mininet>",
1116 timeout=10 )
1117 if re.search( "doesnt exist!", response ):
1118 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001119 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001120 elif re.search( "Error", response ):
1121 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001122 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001123 elif re.search( "usage:", response ):
1124 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001125 return main.FALSE
1126 else:
1127 return main.TRUE
1128 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001129 main.log.error( self.name + ": EOF exception found" )
1130 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001131 main.cleanup()
1132 main.exit()
1133
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001135 """
1136 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001137 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001138 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001139 required params:
1140 node1 = the string node name of the first endpoint of the link
1141 node2 = the string node name of the second endpoint of the link
1142 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001143 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001144 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001145 response = self.execute(
1146 cmd=command,
1147 prompt="mininet>",
1148 timeout=10 )
1149 if re.search( "no node named", response ):
1150 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001151 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001152 elif re.search( "Error", response ):
1153 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001154 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001155 elif re.search( "usage:", response ):
1156 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001157 return main.FALSE
1158 else:
1159 return main.TRUE
1160 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001161 main.log.error( self.name + ": EOF exception found" )
1162 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001163 main.cleanup()
1164 main.exit()
1165
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001167 """
Jon Hallb1290e82014-11-18 16:17:48 -05001168 Add a host 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 host
1172 required params:
1173 hostname = the string hostname
1174 optional key-value params
1175 switch = "switch name"
1176 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001177 """
1178 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001179 command = "addhost " + str( hostname ) + " " + str( switch )
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( "doesnt exists!", 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( "Error", response ):
1192 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001193 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001194 elif re.search( "usage:", response ):
1195 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001196 return main.FALSE
1197 else:
1198 return main.TRUE
1199 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001200 main.log.error( self.name + ": EOF exception found" )
1201 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001202 main.cleanup()
1203 main.exit()
1204
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001206 """
1207 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001208 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001209 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001210 NOTE: this uses a custom mn function
1211 required params:
1212 hostname = the string hostname
1213 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001214 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001215 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 response = self.execute(
1217 cmd=command,
1218 prompt="mininet>",
1219 timeout=10 )
1220 if re.search( "no host named", response ):
1221 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001222 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001223 elif re.search( "Error", response ):
1224 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001225 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001226 elif re.search( "usage:", response ):
1227 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001228 return main.FALSE
1229 else:
1230 return main.TRUE
1231 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001232 main.log.error( self.name + ": EOF exception found" )
1233 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001234 main.cleanup()
1235 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001236
Jon Hall7eb38402015-01-08 17:19:54 -08001237 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001238 """
1239 Called at the end of the test to disconnect the handle.
1240 """
1241 self.handle.sendline('')
1242 i = 1
1243 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1244 if i == 0:
1245 self.stopNet()
1246 response = ''
1247 # print "Disconnecting Mininet"
1248 if self.handle:
1249 self.handle.sendline( "exit" )
1250 self.handle.expect( "exit" )
1251 self.handle.expect( "(.*)" )
1252 main.log.info( "Mininet CLI is successfully disconnected" )
1253 response = self.handle.before
1254 else:
1255 main.log.error( "Connection failed to the host" )
1256 response = main.FALSE
1257
1258 return response
1259
1260 def stopNet( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001261 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001262 response = ''
1263 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001264 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001265 response = self.execute(
1266 cmd="exit",
1267 prompt="(.*)",
1268 timeout=120 )
kelvin-onlaba1484582015-02-02 15:46:20 -08001269 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001270 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001271 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001272 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001273 main.log.error( self.name + ": EOF exception found" )
1274 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001275 main.cleanup()
1276 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001277 else:
1278 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001279 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001280 return response
1281
kelvin-onlaba1484582015-02-02 15:46:20 -08001282
1283
Jon Hall7eb38402015-01-08 17:19:54 -08001284 def arping( self, src, dest, destmac ):
1285 self.handle.sendline( '' )
1286 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001287
Jon Hall7eb38402015-01-08 17:19:54 -08001288 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001289 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001290 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1291 main.log.info( self.name + ": ARP successful" )
1292 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001293 return main.TRUE
1294 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001295 main.log.warn( self.name + ": ARP FAILURE" )
1296 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001297 return main.FALSE
1298
Jon Hall7eb38402015-01-08 17:19:54 -08001299 def decToHex( self, num ):
1300 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001301
Jon Hall7eb38402015-01-08 17:19:54 -08001302 def getSwitchFlowCount( self, switch ):
1303 """
1304 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001305 if self.handle:
1306 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1307 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001308 response = self.execute(
1309 cmd=cmd,
1310 prompt="mininet>",
1311 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001312 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001313 main.log.error( self.name + ": EOF exception found" )
1314 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001315 main.cleanup()
1316 main.exit()
1317 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001318 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001319 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001320 main.log.info(
1321 "Couldn't find flows on switch %s, found: %s" %
1322 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001323 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001324 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001325 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001326 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001327
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 def checkFlows( self, sw, dumpFormat=None ):
1329 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001330 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001331 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001332 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001333 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001334 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001335 response = self.execute(
1336 cmd=command,
1337 prompt="mininet>",
1338 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001339 return response
1340 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001341 main.log.error( self.name + ": EOF exception found" )
1342 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001343 main.cleanup()
1344 main.exit()
1345 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001346 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001347
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001349 """
1350 Runs tpdump on an intferface and saves the file
1351 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001352 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001353 self.handle.sendline( "" )
1354 self.handle.expect( "mininet>" )
1355 self.handle.sendline(
1356 "sh sudo tcpdump -n -i " +
1357 intf +
1358 " " +
1359 port +
1360 " -w " +
1361 filename.strip() +
1362 " &" )
1363 self.handle.sendline( "" )
1364 i = self.handle.expect( [ 'No\ssuch\device',
1365 'listening\son',
1366 pexpect.TIMEOUT,
1367 "mininet>" ],
1368 timeout=10 )
1369 main.log.warn( self.handle.before + self.handle.after )
1370 self.handle.sendline( "" )
1371 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001372 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001373 main.log.error(
1374 self.name +
1375 ": tcpdump - No such device exists. " +
1376 "tcpdump attempted on: " +
1377 intf )
admin2a9548d2014-06-17 14:08:07 -07001378 return main.FALSE
1379 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001380 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001381 return main.TRUE
1382 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001383 main.log.error(
1384 self.name +
1385 ": tcpdump command timed out! Check interface name," +
1386 " given interface was: " +
1387 intf )
admin2a9548d2014-06-17 14:08:07 -07001388 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001389 elif i == 3:
1390 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001391 return main.TRUE
1392 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001393 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001394 return main.FALSE
1395 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001396 main.log.error( self.name + ": EOF exception found" )
1397 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001398 main.cleanup()
1399 main.exit()
1400 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001401 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001402 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001403 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001404 main.cleanup()
1405 main.exit()
1406
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001408 "pkills tcpdump"
1409 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001410 self.handle.sendline( "sh sudo pkill tcpdump" )
1411 self.handle.expect( "mininet>" )
1412 self.handle.sendline( "" )
1413 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001414 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001415 main.log.error( self.name + ": EOF exception found" )
1416 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001417 main.cleanup()
1418 main.exit()
1419 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001420 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001421 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001422 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001423 main.cleanup()
1424 main.exit()
1425
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001427 """
1428 Compare mn and onos switches
1429 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001431
Jon Hall7eb38402015-01-08 17:19:54 -08001432 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001434 output = { "switches": [] }
1435 # iterate through the MN topology and pull out switches and and port
1436 # info
1437 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001438 ports = []
1439 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001440 ports.append( { 'of_port': port.port_no,
1441 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001443 'name': port.name } )
1444 output[ 'switches' ].append( {
1445 "name": switch.name,
1446 "dpid": str( switch.dpid ).zfill( 16 ),
1447 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001448
Jon Hall7eb38402015-01-08 17:19:54 -08001449 # print "mn"
1450 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001452 # indent=4,
1453 # separators=( ',', ': ' ) )
1454 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 # print json.dumps( switchesJson,
1456 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001457 # indent=4,
1458 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001459
1460 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001461 mnDPIDs = []
1462 for switch in output[ 'switches' ]:
1463 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001464 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001465 # print "List of Mininet switch DPID's"
1466 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001467 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001468 main.log.error(
1469 self.name +
1470 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001471 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001473 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001474 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001475 if switch[ 'available' ]:
1476 onosDPIDs.append(
1477 switch[ 'id' ].replace(
1478 ":",
1479 '' ).replace(
1480 "of",
1481 '' ).lower() )
1482 # else:
1483 # print "Switch is unavailable:"
1484 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001485 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001486 # print "List of ONOS switch DPID's"
1487 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001488
Jon Hall7eb38402015-01-08 17:19:54 -08001489 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001491 main.log.report( "Switches in MN but not in ONOS:" )
1492 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1493 main.log.report( str( list1 ) )
1494 main.log.report( "Switches in ONOS but not in MN:" )
1495 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001496 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001497 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 switchResults = main.TRUE
1499 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001500
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001502 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001503 Compare mn and onos ports
1504 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001506
Jon Hallfbc828e2015-01-06 17:30:19 -08001507 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001508 1. This uses the sts TestONTopology object
1509 2. numpy - "sudo pip install numpy"
1510
Jon Hall7eb38402015-01-08 17:19:54 -08001511 """
1512 # FIXME: this does not look for extra ports in ONOS, only checks that
1513 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001514 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001516 output = { "switches": [] }
1517 # iterate through the MN topology and pull out switches and and port
1518 # info
1519 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001520 ports = []
1521 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001522 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001524 tmpPort[ 'of_port' ] = port.port_no
1525 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 tmpPort[ 'name' ] = port.name
1527 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001528
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 ports.append( tmpPort )
1530 tmpSwitch = {}
1531 tmpSwitch[ 'name' ] = switch.name
1532 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1533 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001534
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001536
Jon Hall7eb38402015-01-08 17:19:54 -08001537 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 for mnSwitch in output[ 'switches' ]:
1539 mnPorts = []
1540 onosPorts = []
1541 switchResult = main.TRUE
1542 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001543 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 mnPorts.append( port[ 'of_port' ] )
1545 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001546 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001547 # print onosSwitch
1548 if onosSwitch[ 'device' ][ 'available' ]:
1549 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001550 ':',
1551 '' ).replace(
1552 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001553 '' ) == mnSwitch[ 'dpid' ]:
1554 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001555 if port[ 'isEnabled' ]:
1556 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 # onosPorts.append( 'local' )
1558 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001559 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001560 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001561 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001562 mnPorts.sort( key=float )
1563 onosPorts.sort( key=float )
1564 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1565 # print "\tmn_ports[] = ", mnPorts
1566 # print "\tonos_ports[] = ", onosPorts
1567 mnPortsLog = mnPorts
1568 onosPortsLog = onosPorts
1569 mnPorts = [ x for x in mnPorts ]
1570 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001571
Jon Hall7eb38402015-01-08 17:19:54 -08001572 # TODO: handle other reserved port numbers besides LOCAL
1573 # NOTE: Reserved ports
1574 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1575 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 for mnPort in mnPortsLog:
1577 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001578 # don't set results to true here as this is just one of
1579 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 mnPorts.remove( mnPort )
1581 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001582 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001583 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001584 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 if 65534 in mnPorts:
1586 mnPorts.remove( 65534 )
1587 if long( uint64( -2 ) ) in onosPorts:
1588 onosPorts.remove( long( uint64( -2 ) ) )
1589 if len( mnPorts ): # the ports of this switch don't match
1590 switchResult = main.FALSE
1591 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1592 if len( onosPorts ): # the ports of this switch don't match
1593 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001594 main.log.warn(
1595 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 str( onosPorts ) )
1597 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001598 main.log.report(
1599 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1601 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1602 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1603 portsResults = portsResults and switchResult
1604 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001605
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001607 """
1608 Compare mn and onos links
1609 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001611
Jon Hall7eb38402015-01-08 17:19:54 -08001612 This uses the sts TestONTopology object"""
1613 # FIXME: this does not look for extra links in ONOS, only checks that
1614 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001616 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001618 # iterate through the MN topology and pull out switches and and port
1619 # info
1620 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001621 # print "Iterating though switches as seen by Mininet"
1622 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001623 ports = []
1624 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001625 # print port.hw_addr.toStr( separator='' )
1626 ports.append( { 'of_port': port.port_no,
1627 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001628 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001629 'name': port.name } )
1630 output[ 'switches' ].append( {
1631 "name": switch.name,
1632 "dpid": str( switch.dpid ).zfill( 16 ),
1633 "ports": ports } )
1634 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001635
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001637 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001638 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001639 if 2 * len( mnLinks ) == len( onos ):
1640 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001641 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001643 main.log.report(
Jon Hall328ddca2015-01-28 15:57:15 -08001644 "Mininet has " + str( len( mnLinks ) ) +
1645 " bidirectional links and ONOS has " +
1646 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001647
Jon Hall7eb38402015-01-08 17:19:54 -08001648 # iterate through MN links and check if an ONOS link exists in
1649 # both directions
1650 # NOTE: Will currently only show mn links as down if they are
1651 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001653 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001654 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001655 # print "Link: %s" % link
1656 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001657 node1 = None
1658 port1 = None
1659 node2 = None
1660 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 firstDir = main.FALSE
1662 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001663 for switch in output[ 'switches' ]:
1664 # print "Switch: %s" % switch[ 'name' ]
1665 if switch[ 'name' ] == link.node1.name:
1666 node1 = switch[ 'dpid' ]
1667 for port in switch[ 'ports' ]:
1668 if str( port[ 'name' ] ) == str( link.port1 ):
1669 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001670 if node1 is not None and node2 is not None:
1671 break
Jon Hall7eb38402015-01-08 17:19:54 -08001672 if switch[ 'name' ] == link.node2.name:
1673 node2 = switch[ 'dpid' ]
1674 for port in switch[ 'ports' ]:
1675 if str( port[ 'name' ] ) == str( link.port2 ):
1676 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001677 if node1 is not None and node2 is not None:
1678 break
1679
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 for onosLink in onos:
1681 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001682 ":",
1683 '' ).replace(
1684 "of",
1685 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001686 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001687 ":",
1688 '' ).replace(
1689 "of",
1690 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001691 onosPort1 = onosLink[ 'src' ][ 'port' ]
1692 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001693
Jon Hall72cf1dc2014-10-20 21:04:50 -04001694 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001695 if str( onosNode1 ) == str( node1 ) and str(
1696 onosNode2 ) == str( node2 ):
1697 if int( onosPort1 ) == int( port1 ) and int(
1698 onosPort2 ) == int( port2 ):
1699 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001700 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001701 main.log.warn(
1702 'The port numbers do not match for ' +
1703 str( link ) +
1704 ' between ONOS and MN. When cheking ONOS for ' +
1705 'link %s/%s -> %s/%s' %
1706 ( node1,
1707 port1,
1708 node2,
1709 port2 ) +
1710 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 ( onosNode1,
1712 onosPort1,
1713 onosNode2,
1714 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001715
1716 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001717 elif ( str( onosNode1 ) == str( node2 ) and
1718 str( onosNode2 ) == str( node1 ) ):
1719 if ( int( onosPort1 ) == int( port2 )
1720 and int( onosPort2 ) == int( port1 ) ):
1721 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001722 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001723 main.log.warn(
1724 'The port numbers do not match for ' +
1725 str( link ) +
1726 ' between ONOS and MN. When cheking ONOS for ' +
1727 'link %s/%s -> %s/%s' %
1728 ( node2,
1729 port2,
1730 node1,
1731 port1 ) +
1732 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 ( onosNode2,
1734 onosPort2,
1735 onosNode1,
1736 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001737 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001738 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001739 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001740 main.log.report(
1741 'ONOS does not have the link %s/%s -> %s/%s' %
1742 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001743 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001744 main.log.report(
1745 'ONOS does not have the link %s/%s -> %s/%s' %
1746 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 linkResults = linkResults and firstDir and secondDir
1748 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001749
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001751 """
1752 Returns a list of all hosts
1753 Don't ask questions just use it"""
1754 self.handle.sendline( "" )
1755 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001756
Jon Hall7eb38402015-01-08 17:19:54 -08001757 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1758 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001759
kelvin-onlabd3b64892015-01-20 13:26:24 -08001760 handlePy = self.handle.before
1761 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1762 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001763
Jon Hall7eb38402015-01-08 17:19:54 -08001764 self.handle.sendline( "" )
1765 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001766
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 hostStr = handlePy.replace( "]", "" )
1768 hostStr = hostStr.replace( "'", "" )
1769 hostStr = hostStr.replace( "[", "" )
1770 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001771
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 return hostList
adminbae64d82013-08-01 10:50:15 -07001773
Jon Hall7eb38402015-01-08 17:19:54 -08001774 def update( self ):
1775 """
1776 updates the port address and status information for
1777 each port in mn"""
1778 # TODO: Add error checking. currently the mininet command has no output
1779 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001780 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001781 self.handle.sendline( "" )
1782 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001783
Jon Hall7eb38402015-01-08 17:19:54 -08001784 self.handle.sendline( "update" )
1785 self.handle.expect( "update" )
1786 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001787
Jon Hall7eb38402015-01-08 17:19:54 -08001788 self.handle.sendline( "" )
1789 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001790
Jon Hallb1290e82014-11-18 16:17:48 -05001791 return main.TRUE
1792 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001793 main.log.error( self.name + ": EOF exception found" )
1794 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001795 main.cleanup()
1796 main.exit()
1797
adminbae64d82013-08-01 10:50:15 -07001798if __name__ != "__main__":
1799 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001800 sys.modules[ __name__ ] = MininetCliDriver()