blob: c9b39ea2d0ebe18814e5efb7b8b9abb296d32be3 [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-onlaba0ce3222015-01-27 17:25:15 -080062 try:
63 for key in connectargs:
64 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080065
kelvin-onlaba0ce3222015-01-27 17:25:15 -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-onlaba0ce3222015-01-27 17:25:15 -080075 self.sshHandle = self.handle
Jon Hallfbc828e2015-01-06 17:30:19 -080076
kelvin-onlaba0ce3222015-01-27 17:25:15 -080077 if self.handle:
78 main.log.info("Connection successful to the host " +
79 self.user_name +
80 "@" +
81 self.ip_address )
82 return main.TRUE
83 else:
84 main.log.error( "Connection failed to the host " +
85 self.user_name +
86 "@" +
87 self.ip_address )
88 msin.log.error( "Failed to connect to the Mininet CLI" )
89 return main.FALSE
90 except pexpect.EOF:
91 main.log.error( self.name + ": EOF exception found" )
92 main.log.error( self.name + ": " + self.handle.before )
93 main.cleanup()
94 main.exit()
95 except:
96 main.log.info( self.name + ":::::::::::::::::::::::" )
97 main.log.error( traceback.print_exc() )
98 main.log.info( ":::::::::::::::::::::::" )
99 main.cleanup()
100 main.exit()
101
102
103 """
Jon Hall7eb38402015-01-08 17:19:54 -0800104 if self.handle:
105 main.log.info(
106 self.name +
107 ": Clearing any residual state or processes" )
108 self.handle.sendline( "sudo mn -c" )
109 i = self.handle.expect( [ 'password\sfor\s',
110 'Cleanup\scomplete',
111 pexpect.EOF,
112 pexpect.TIMEOUT ],
113 120 )
114 if i == 0:
115 main.log.info( self.name + ": Sending sudo password" )
116 self.handle.sendline( self.pwd )
117 i = self.handle.expect( [ '%s:' % ( self.user ),
118 '\$',
119 pexpect.EOF,
120 pexpect.TIMEOUT ],
121 120 )
122 if i == 1:
123 main.log.info( self.name + ": Clean" )
124 elif i == 2:
125 main.log.error( self.name + ": Connection terminated" )
126 elif i == 3: # timeout
127 main.log.error(
128 self.name +
129 ": Something while cleaning MN took too long... " )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800130 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800131
kelvin-onlab97d64e72015-01-28 11:14:55 -0800132 def startNet( self, topoFile = '', args = '', timeout = 120 ):
Jon Hallfbc828e2015-01-06 17:30:19 -0800133
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800134 self.name = self.options[ 'name' ]
135 if self.handle:
136 main.log.info(
137 self.name +
138 ": Clearing any residual state or processes" )
139 self.handle.sendline( "sudo mn -c" )
140 i = self.handle.expect( [ 'password\sfor\s',
141 'Cleanup\scomplete',
142 pexpect.EOF,
143 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800144 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800145 if i == 0:
146 main.log.info( self.name + ": Sending sudo password" )
147 self.handle.sendline( self.pwd )
148 i = self.handle.expect( [ '%s:' % ( self.user ),
149 '\$',
Jon Hall7eb38402015-01-08 17:19:54 -0800150 pexpect.EOF,
151 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800152 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800153 if i == 1:
154 main.log.info( self.name + ": Clean" )
155 elif i == 2:
156 main.log.error( self.name + ": Connection terminated" )
157 elif i == 3: # timeout
158 main.log.error(
159 self.name +
160 ": Something while cleaning MN took too long... " )
kelvin-onlab97d64e72015-01-28 11:14:55 -0800161 if topoFile == '' and args == '':
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800162 main.log.info( self.name + ": building fresh mininet" )
163 # for reactive/PARP enabled tests
164 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
165 " " + self.options[ 'arg2' ] +\
166 " --mac --controller " +\
167 self.options[ 'controller' ] + " " +\
168 self.options[ 'arg3' ]
169
170 argList = self.options[ 'arg1' ].split( "," )
171 global topoArgList
172 topoArgList = argList[ 0 ].split( " " )
173 argList = map( int, argList[ 1: ] )
174 topoArgList = topoArgList[ 1: ] + argList
175
176 self.handle.sendline( cmdString )
177 self.handle.expect( [ "sudo mn",
178 pexpect.EOF,
179 pexpect.TIMEOUT ] )
180 while True:
181 i = self.handle.expect( [ 'mininet>',
182 '\*\*\*',
183 'Exception',
184 pexpect.EOF,
185 pexpect.TIMEOUT ],
kelvin-onlab97d64e72015-01-28 11:14:55 -0800186 timeout )
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800187 if i == 0:
188 main.log.info( self.name + ": mininet built" )
189 return main.TRUE
190 if i == 1:
191 self.handle.expect(
192 [ "\n", pexpect.EOF, pexpect.TIMEOUT ] )
193 main.log.info( self.handle.before )
194 elif i == 2:
195 main.log.error(
196 self.name +
197 ": Launching mininet failed..." )
198 return main.FALSE
199 elif i == 3:
200 main.log.error( self.name + ": Connection timeout" )
201 return main.FALSE
202 elif i == 4: # timeout
203 main.log.error(
204 self.name +
205 ": Something took too long... " )
206 return main.FALSE
207 return main.TRUE
208 else:
kelvin-onlab97d64e72015-01-28 11:14:55 -0800209 main.log.info( "Starting topo file " + topoFile )
210 if args == None:
211 args = ''
212 else:
213 main.log.info( "args = " + args)
214 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800215 i = 1
216 i = self.handle.expect( [ 'mininet>',
217 pexpect.EOF ,
kelvin-onlab97d64e72015-01-28 11:14:55 -0800218 pexpect.TIMEOUT ],
219 timeout)
kelvin-onlaba0ce3222015-01-27 17:25:15 -0800220 main.log.info(self.name + ": Network started")
221 return main.TRUE
222
Jon Hall7eb38402015-01-08 17:19:54 -0800223 else: # if no handle
224 main.log.error(
225 self.name +
226 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800227 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800228 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800229 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800230 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700231 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800232
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800233 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400234 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800235 # In tree topology, if fanout arg is not given, by default it is 2
236 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400237 fanout = 2
238 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500239 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800240 while( k <= depth - 1 ):
241 count = count + pow( fanout, k )
242 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800244 while( k <= depth - 2 ):
245 # depth-2 gives you only core links and not considering
246 # edge links as seen by ONOS. If all the links including
247 # edge links are required, do depth-1
248 count = count + pow( fanout, k )
249 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800251 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800253
Jon Hall7eb38402015-01-08 17:19:54 -0800254 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800256 # by default it is 1
257 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400258 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 numSwitches = depth
260 numHostsPerSw = fanout
261 totalNumHosts = numSwitches * numHostsPerSw
262 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800263 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400265 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800266 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 "num_switches": int( numSwitches ),
268 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400269 return topoDict
270
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 def calculateSwAndLinks( self ):
272 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400273 return topoDict
274
Jon Hall7eb38402015-01-08 17:19:54 -0800275 def pingall( self, timeout=300 ):
276 """
277 Verifies the reachability of the hosts using pingall command.
278 Optional parameter timeout allows you to specify how long to
279 wait for pingall to complete
280 Returns:
281 main.TRUE if pingall completes with no pings dropped
282 otherwise main.FALSE"""
283 if self.handle:
284 main.log.info(
285 self.name +
286 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700287 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800288 response = self.execute(
289 cmd="pingall",
290 prompt="mininet>",
291 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500292 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800293 main.log.error( self.name + ": EOF exception found" )
294 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500295 main.cleanup()
296 main.exit()
297 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800298 # We may not want to kill the test if pexpect times out
299 main.log.error( self.name + ": TIMEOUT exception found" )
300 main.log.error( self.name +
301 ": " +
302 str( self.handle.before ) )
303 # NOTE: mininet's pingall rounds, so we will check the number of
304 # passed and number of failed
305 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800306 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800307 if re.search( pattern, response ):
308 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700309 return main.TRUE
310 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800311 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800312 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800313 # NOTE: Send ctrl-c to make sure pingall is done
314 self.handle.send( "\x03" )
315 self.handle.expect( "Interrupt" )
316 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700317 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800318 else:
319 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500320 main.cleanup()
321 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700322
Jon Hall7eb38402015-01-08 17:19:54 -0800323 def fpingHost( self, **pingParams ):
324 """
325 Uses the fping package for faster pinging...
326 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800327 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800328 command = args[ "SRC" ] + \
329 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
330 self.handle.sendline( command )
331 self.handle.expect(
332 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
333 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
334 response = self.handle.before
335 if re.search( ":\s-", response ):
336 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700337 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800338 elif re.search( ":\s\d{1,2}\.\d\d", response ):
339 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700340 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800341 main.log.info( self.name + ": Install fping on mininet machine... " )
342 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700343 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800344
Jon Hall7eb38402015-01-08 17:19:54 -0800345 def pingHost( self, **pingParams ):
346 """
347 Ping from one mininet host to another
348 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800349 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800350 command = args[ "SRC" ] + " ping " + \
351 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700352 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800353 main.log.warn( "Sending: " + command )
354 self.handle.sendline( command )
355 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700356 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800357 main.log.error(
358 self.name +
359 ": timeout when waiting for response from mininet" )
360 main.log.error( "response: " + str( self.handle.before ) )
361 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700362 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800363 main.log.error(
364 self.name +
365 ": timeout when waiting for response from mininet" )
366 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700367 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800368 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800369 main.log.error( self.name + ": EOF exception found" )
370 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700371 main.cleanup()
372 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800373 main.log.info( self.name + ": Ping Response: " + response )
374 if re.search( ',\s0\%\spacket\sloss', response ):
375 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800376 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700377 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800378 else:
379 main.log.error(
380 self.name +
381 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800382 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700383 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800384
Jon Hall7eb38402015-01-08 17:19:54 -0800385 def checkIP( self, host ):
386 """
387 Verifies the host's ip configured or not."""
388 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700389 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800390 response = self.execute(
391 cmd=host +
392 " ifconfig",
393 prompt="mininet>",
394 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800395 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800396 main.log.error( self.name + ": EOF exception found" )
397 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700398 main.cleanup()
399 main.exit()
adminbae64d82013-08-01 10:50:15 -0700400
Jon Hall7eb38402015-01-08 17:19:54 -0800401 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800402 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
403 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
404 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
405 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
406 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800407 # pattern = "inet addr:10.0.0.6"
408 if re.search( pattern, response ):
409 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700410 return main.TRUE
411 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800412 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700413 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800414 else:
415 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800416
Jon Hall7eb38402015-01-08 17:19:54 -0800417 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700418 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800419 response = self.execute(
420 cmd="h1 /usr/sbin/sshd -D&",
421 prompt="mininet>",
422 timeout=10 )
423 response = self.execute(
424 cmd="h4 /usr/sbin/sshd -D&",
425 prompt="mininet>",
426 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700427 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800428 vars( self )[ key ] = connectargs[ key ]
429 response = self.execute(
430 cmd="xterm h1 h4 ",
431 prompt="mininet>",
432 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800433 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800434 main.log.error( self.name + ": EOF exception found" )
435 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700436 main.cleanup()
437 main.exit()
adminbae64d82013-08-01 10:50:15 -0700438 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800439 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700440 if self.flag == 0:
441 self.flag = 1
442 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800443 else:
adminbae64d82013-08-01 10:50:15 -0700444 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800445
Jon Hall7eb38402015-01-08 17:19:54 -0800446 def changeIP( self, host, intf, newIP, newNetmask ):
447 """
448 Changes the ip address of a host on the fly
449 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800450 if self.handle:
451 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800452 cmd = host + " ifconfig " + intf + " " + \
453 newIP + " " + 'netmask' + " " + newNetmask
454 self.handle.sendline( cmd )
455 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800456 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800457 main.log.info( "response = " + response )
458 main.log.info(
459 "Ip of host " +
460 host +
461 " changed to new IP " +
462 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800463 return main.TRUE
464 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800465 main.log.error( self.name + ": EOF exception found" )
466 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800467 return main.FALSE
468
Jon Hall7eb38402015-01-08 17:19:54 -0800469 def changeDefaultGateway( self, host, newGW ):
470 """
471 Changes the default gateway of a host
472 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800473 if self.handle:
474 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800475 cmd = host + " route add default gw " + newGW
476 self.handle.sendline( cmd )
477 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800478 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800479 main.log.info( "response = " + response )
480 main.log.info(
481 "Default gateway of host " +
482 host +
483 " changed to " +
484 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800485 return main.TRUE
486 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800487 main.log.error( self.name + ": EOF exception found" )
488 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800489 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800490
Jon Hall7eb38402015-01-08 17:19:54 -0800491 def addStaticMACAddress( self, host, GW, macaddr ):
492 """
493 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800494 if self.handle:
495 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800496 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
497 cmd = host + " arp -s " + GW + " " + macaddr
498 self.handle.sendline( cmd )
499 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800500 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800501 main.log.info( "response = " + response )
502 main.log.info(
503 "Mac adrress of gateway " +
504 GW +
505 " changed to " +
506 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800507 return main.TRUE
508 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800509 main.log.error( self.name + ": EOF exception found" )
510 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800511 return main.FALSE
512
Jon Hall7eb38402015-01-08 17:19:54 -0800513 def verifyStaticGWandMAC( self, host ):
514 """
515 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800516 if self.handle:
517 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800518 # h1 arp -an
519 cmd = host + " arp -an "
520 self.handle.sendline( cmd )
521 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800522 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800523 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800524 return main.TRUE
525 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800526 main.log.error( self.name + ": EOF exception found" )
527 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800528 return main.FALSE
529
Jon Hall7eb38402015-01-08 17:19:54 -0800530 def getMacAddress( self, host ):
531 """
532 Verifies the host's ip configured or not."""
533 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700534 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800535 response = self.execute(
536 cmd=host +
537 " ifconfig",
538 prompt="mininet>",
539 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800540 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800541 main.log.error( self.name + ": EOF exception found" )
542 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700543 main.cleanup()
544 main.exit()
adminbae64d82013-08-01 10:50:15 -0700545
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700546 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 macAddressSearch = re.search( pattern, response, re.I )
548 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800549 main.log.info(
550 self.name +
551 ": Mac-Address of Host " +
552 host +
553 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800554 macAddress )
555 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700556 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800557 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700558
Jon Hall7eb38402015-01-08 17:19:54 -0800559 def getInterfaceMACAddress( self, host, interface ):
560 """
561 Return the IP address of the interface on the given host"""
562 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700563 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800564 response = self.execute( cmd=host + " ifconfig " + interface,
565 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800566 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800567 main.log.error( self.name + ": EOF exception found" )
568 main.log.error( self.name + ": " + self.handle.before )
569 main.cleanup()
570 main.exit()
571
572 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 macAddressSearch = re.search( pattern, response, re.I )
574 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800575 main.log.info( "No mac address found in %s" % response )
576 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800578 main.log.info(
579 "Mac-Address of " +
580 host +
581 ":" +
582 interface +
583 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 macAddress )
585 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800586 else:
587 main.log.error( "Connection failed to the host" )
588
589 def getIPAddress( self, host ):
590 """
591 Verifies the host's ip configured or not."""
592 if self.handle:
593 try:
594 response = self.execute(
595 cmd=host +
596 " ifconfig",
597 prompt="mininet>",
598 timeout=10 )
599 except pexpect.EOF:
600 main.log.error( self.name + ": EOF exception found" )
601 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700602 main.cleanup()
603 main.exit()
adminbae64d82013-08-01 10:50:15 -0700604
605 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800607 main.log.info(
608 self.name +
609 ": IP-Address of Host " +
610 host +
611 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 ipAddressSearch.group( 1 ) )
613 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800614 else:
615 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800616
Jon Hall7eb38402015-01-08 17:19:54 -0800617 def getSwitchDPID( self, switch ):
618 """
619 return the datapath ID of the switch"""
620 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700621 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700622 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800623 response = self.execute(
624 cmd=cmd,
625 prompt="mininet>",
626 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800627 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800628 main.log.error( self.name + ": EOF exception found" )
629 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700630 main.cleanup()
631 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800632 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800633 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700634 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800635 main.log.info(
636 "Couldn't find DPID for switch %s, found: %s" %
637 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700638 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800639 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700640 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800641 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700642
Jon Hall7eb38402015-01-08 17:19:54 -0800643 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700644 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800645 self.handle.sendline( "" )
646 self.expect( "mininet>" )
647 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700648 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800649 response = self.execute(
650 cmd=cmd,
651 prompt="mininet>",
652 timeout=10 )
653 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700654 response = self.handle.before
655 return response
656 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800657 main.log.error( self.name + ": EOF exception found" )
658 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700659 main.cleanup()
660 main.exit()
661
Jon Hall7eb38402015-01-08 17:19:54 -0800662 def getInterfaces( self, node ):
663 """
664 return information dict about interfaces connected to the node"""
665 if self.handle:
666 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800667 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700668 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700669 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800670 response = self.execute(
671 cmd=cmd,
672 prompt="mininet>",
673 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800674 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700677 main.cleanup()
678 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700679 return response
680 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800681 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700682
Jon Hall7eb38402015-01-08 17:19:54 -0800683 def dump( self ):
684 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700685 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800686 response = self.execute(
687 cmd='dump',
688 prompt='mininet>',
689 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800690 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800691 main.log.error( self.name + ": EOF exception found" )
692 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700693 main.cleanup()
694 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700695 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800696
Jon Hall7eb38402015-01-08 17:19:54 -0800697 def intfs( self ):
698 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700699 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800700 response = self.execute(
701 cmd='intfs',
702 prompt='mininet>',
703 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800704 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800705 main.log.error( self.name + ": EOF exception found" )
706 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700707 main.cleanup()
708 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700709 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800710
Jon Hall7eb38402015-01-08 17:19:54 -0800711 def net( self ):
712 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700713 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800714 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800715 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800716 main.log.error( self.name + ": EOF exception found" )
717 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700718 main.cleanup()
719 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700720 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800721
722 def iperf( self, host1, host2 ):
723 main.log.info(
724 self.name +
725 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700726 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800727 cmd1 = 'iperf ' + host1 + " " + host2
728 self.handle.sendline( cmd1 )
729 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800730 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800731 if re.search( 'Results:', response ):
732 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800733 return main.TRUE
734 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800735 main.log.error( self.name + ": iperf test failed" )
736 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800737 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800740 main.cleanup()
741 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800742
Jon Hall7eb38402015-01-08 17:19:54 -0800743 def iperfudp( self ):
744 main.log.info(
745 self.name +
746 ": Simple iperf TCP test between two " +
747 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700748 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800749 response = self.execute(
750 cmd='iperfudp',
751 prompt='mininet>',
752 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800753 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800754 main.log.error( self.name + ": EOF exception found" )
755 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700756 main.cleanup()
757 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700758 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800759
Jon Hall7eb38402015-01-08 17:19:54 -0800760 def nodes( self ):
761 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700762 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800763 response = self.execute(
764 cmd='nodes',
765 prompt='mininet>',
766 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800767 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800768 main.log.error( self.name + ": EOF exception found" )
769 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700770 main.cleanup()
771 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700772 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800773
Jon Hall7eb38402015-01-08 17:19:54 -0800774 def pingpair( self ):
775 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700776 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800777 response = self.execute(
778 cmd='pingpair',
779 prompt='mininet>',
780 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800781 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700784 main.cleanup()
785 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800786
Jon Hall7eb38402015-01-08 17:19:54 -0800787 if re.search( ',\s0\%\spacket\sloss', response ):
788 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700790 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800791 else:
792 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800793 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700794 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800795
Jon Hall7eb38402015-01-08 17:19:54 -0800796 def link( self, **linkargs ):
797 """
798 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800799 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800800 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
801 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
802 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
803 main.log.info(
804 "Bring link between '" +
805 end1 +
806 "' and '" +
807 end2 +
808 "' '" +
809 option +
810 "'" )
811 command = "link " + \
812 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700813 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 self.handle.sendline( command )
815 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800816 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800817 main.log.error( self.name + ": EOF exception found" )
818 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700819 main.cleanup()
820 main.exit()
adminbae64d82013-08-01 10:50:15 -0700821 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800822
Jon Hall7eb38402015-01-08 17:19:54 -0800823 def yank( self, **yankargs ):
824 """
825 yank a mininet switch interface to a host"""
826 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800827 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800828 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
829 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
830 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700831 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800832 response = self.execute(
833 cmd=command,
834 prompt="mininet>",
835 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800836 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800837 main.log.error( self.name + ": EOF exception found" )
838 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700839 main.cleanup()
840 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700841 return main.TRUE
842
Jon Hall7eb38402015-01-08 17:19:54 -0800843 def plug( self, **plugargs ):
844 """
845 plug the yanked mininet switch interface to a switch"""
846 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800847 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800848 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
849 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
850 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700851 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800852 response = self.execute(
853 cmd=command,
854 prompt="mininet>",
855 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800856 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800857 main.log.error( self.name + ": EOF exception found" )
858 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700859 main.cleanup()
860 main.exit()
adminbae64d82013-08-01 10:50:15 -0700861 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800862
Jon Hall7eb38402015-01-08 17:19:54 -0800863 def dpctl( self, **dpctlargs ):
864 """
865 Run dpctl command on all switches."""
866 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800867 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800868 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
869 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
870 command = "dpctl " + cmd + " " + str( cmdargs )
871 try:
872 response = self.execute(
873 cmd=command,
874 prompt="mininet>",
875 timeout=10 )
876 except pexpect.EOF:
877 main.log.error( self.name + ": EOF exception found" )
878 main.log.error( self.name + ": " + self.handle.before )
879 main.cleanup()
880 main.exit()
881 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800882
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 def getVersion( self ):
884 fileInput = path + '/lib/Mininet/INSTALL'
885 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700886 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800888 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700889 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800890 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500891 return version
adminbae64d82013-08-01 10:50:15 -0700892
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800894 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500895 Parameters:
896 sw: The name of an OVS switch. Example "s1"
897 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800898 The output of the command from the mininet cli
899 or main.FALSE on timeout"""
900 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700901 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800902 response = self.execute(
903 cmd=command,
904 prompt="mininet>",
905 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700906 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500907 return response
admin2a9548d2014-06-17 14:08:07 -0700908 else:
909 return main.FALSE
910 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700913 main.cleanup()
914 main.exit()
adminbae64d82013-08-01 10:50:15 -0700915
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800917 """
918 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800919 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800920 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700921
922 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800923 for j in range( count ):
924 argstring = argstring + ",IP" + \
925 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800926 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700927
Jon Hall7eb38402015-01-08 17:19:54 -0800928 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
929 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800930 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800931 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800932
Jon Hall7eb38402015-01-08 17:19:54 -0800933 command = "sh ovs-vsctl set-controller s" + \
934 str( sw ) + " " + ptcpB + " "
935 for j in range( count ):
936 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800937 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -0800938 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
939 ip = args[
940 "IP" +
941 str( i ) ] if args[
942 "IP" +
943 str( i ) ] is not None else ""
944 port = args[
945 "PORT" +
946 str( i ) ] if args[
947 "PORT" +
948 str( i ) ] is not None else ""
949 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800950 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -0700951 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -0700952 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800953 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -0700954 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800955 main.log.error( self.name + ": EOF exception found" )
956 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700957 main.cleanup()
958 main.exit()
959 except:
Jon Hall7eb38402015-01-08 17:19:54 -0800960 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -0800961 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -0800962 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -0700963 main.cleanup()
964 main.exit()
adminbae64d82013-08-01 10:50:15 -0700965
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800967 """
968 Removes the controller target from sw"""
969 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -0700970 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800971 response = self.execute(
972 cmd=command,
973 prompt="mininet>",
974 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800975 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800976 main.log.error( self.name + ": EOF exception found" )
977 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -0700978 main.cleanup()
979 main.exit()
980 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800981 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -0700982
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800984 """
Jon Hallb1290e82014-11-18 16:17:48 -0500985 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -0800986 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -0800987 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -0500988 NOTE: cannot currently specify what type of switch
989 required params:
990 switchname = name of the new switch as a string
991 optional keyvalues:
992 dpid = "dpid"
993 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800994 """
995 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -0800996 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -0500997 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800998 response = self.execute(
999 cmd=command,
1000 prompt="mininet>",
1001 timeout=10 )
1002 if re.search( "already exists!", response ):
1003 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001004 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001005 elif re.search( "Error", response ):
1006 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001007 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001008 elif re.search( "usage:", response ):
1009 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001010 return main.FALSE
1011 else:
1012 return main.TRUE
1013 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001014 main.log.error( self.name + ": EOF exception found" )
1015 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001016 main.cleanup()
1017 main.exit()
1018
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001020 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001021 delete a switch from the mininet topology
1022 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001023 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001024 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001025 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001026 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001027 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001028 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001029 response = self.execute(
1030 cmd=command,
1031 prompt="mininet>",
1032 timeout=10 )
1033 if re.search( "no switch named", response ):
1034 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001035 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001036 elif re.search( "Error", response ):
1037 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001038 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001039 elif re.search( "usage:", response ):
1040 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001041 return main.FALSE
1042 else:
1043 return main.TRUE
1044 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001047 main.cleanup()
1048 main.exit()
1049
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001051 """
1052 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001053 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001054 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001055 NOTE: cannot currently specify what type of link
1056 required params:
1057 node1 = the string node name of the first endpoint of the link
1058 node2 = the string node name of the second endpoint of the link
1059 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001060 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001061 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001062 response = self.execute(
1063 cmd=command,
1064 prompt="mininet>",
1065 timeout=10 )
1066 if re.search( "doesnt exist!", response ):
1067 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001068 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001069 elif re.search( "Error", response ):
1070 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001071 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001072 elif re.search( "usage:", response ):
1073 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001074 return main.FALSE
1075 else:
1076 return main.TRUE
1077 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001078 main.log.error( self.name + ": EOF exception found" )
1079 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001080 main.cleanup()
1081 main.exit()
1082
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001084 """
1085 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001086 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001087 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001088 required params:
1089 node1 = the string node name of the first endpoint of the link
1090 node2 = the string node name of the second endpoint of the link
1091 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001092 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001093 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001094 response = self.execute(
1095 cmd=command,
1096 prompt="mininet>",
1097 timeout=10 )
1098 if re.search( "no node named", response ):
1099 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001100 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001101 elif re.search( "Error", response ):
1102 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001103 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001104 elif re.search( "usage:", response ):
1105 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001106 return main.FALSE
1107 else:
1108 return main.TRUE
1109 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001110 main.log.error( self.name + ": EOF exception found" )
1111 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001112 main.cleanup()
1113 main.exit()
1114
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001116 """
Jon Hallb1290e82014-11-18 16:17:48 -05001117 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001118 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001119 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001120 NOTE: cannot currently specify what type of host
1121 required params:
1122 hostname = the string hostname
1123 optional key-value params
1124 switch = "switch name"
1125 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001126 """
1127 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001128 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001129 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001130 response = self.execute(
1131 cmd=command,
1132 prompt="mininet>",
1133 timeout=10 )
1134 if re.search( "already exists!", response ):
1135 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001136 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001137 elif re.search( "doesnt exists!", response ):
1138 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001139 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001140 elif re.search( "Error", response ):
1141 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001142 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001143 elif re.search( "usage:", response ):
1144 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001145 return main.FALSE
1146 else:
1147 return main.TRUE
1148 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001149 main.log.error( self.name + ": EOF exception found" )
1150 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001151 main.cleanup()
1152 main.exit()
1153
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001155 """
1156 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001157 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001158 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001159 NOTE: this uses a custom mn function
1160 required params:
1161 hostname = the string hostname
1162 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001163 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001164 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001165 response = self.execute(
1166 cmd=command,
1167 prompt="mininet>",
1168 timeout=10 )
1169 if re.search( "no host named", response ):
1170 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001171 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001172 elif re.search( "Error", response ):
1173 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001174 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001175 elif re.search( "usage:", response ):
1176 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001177 return main.FALSE
1178 else:
1179 return main.TRUE
1180 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 main.log.error( self.name + ": EOF exception found" )
1182 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001183 main.cleanup()
1184 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001185
Jon Hall7eb38402015-01-08 17:19:54 -08001186 def disconnect( self ):
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001187 """
1188 Called at the end of the test to disconnect the handle.
1189 """
1190 self.handle.sendline('')
1191 i = 1
1192 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1193 if i == 0:
1194 self.stopNet()
1195 response = ''
1196 # print "Disconnecting Mininet"
1197 if self.handle:
1198 self.handle.sendline( "exit" )
1199 self.handle.expect( "exit" )
1200 self.handle.expect( "(.*)" )
1201 main.log.info( "Mininet CLI is successfully disconnected" )
1202 response = self.handle.before
1203 else:
1204 main.log.error( "Connection failed to the host" )
1205 response = main.FALSE
1206
1207 return response
1208
1209 def stopNet( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001210 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001211 response = ''
1212 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001213 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001214 response = self.execute(
1215 cmd="exit",
1216 prompt="(.*)",
1217 timeout=120 )
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001218 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001219 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001220 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001221 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001222 main.log.error( self.name + ": EOF exception found" )
1223 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001224 main.cleanup()
1225 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001226 else:
1227 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001228 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001229 return response
1230
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001231
1232
Jon Hall7eb38402015-01-08 17:19:54 -08001233 def arping( self, src, dest, destmac ):
1234 self.handle.sendline( '' )
1235 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001236
Jon Hall7eb38402015-01-08 17:19:54 -08001237 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001238 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001239 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1240 main.log.info( self.name + ": ARP successful" )
1241 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001242 return main.TRUE
1243 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001244 main.log.warn( self.name + ": ARP FAILURE" )
1245 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001246 return main.FALSE
1247
Jon Hall7eb38402015-01-08 17:19:54 -08001248 def decToHex( self, num ):
1249 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001250
Jon Hall7eb38402015-01-08 17:19:54 -08001251 def getSwitchFlowCount( self, switch ):
1252 """
1253 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001254 if self.handle:
1255 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1256 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001257 response = self.execute(
1258 cmd=cmd,
1259 prompt="mininet>",
1260 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001261 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001262 main.log.error( self.name + ": EOF exception found" )
1263 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001264 main.cleanup()
1265 main.exit()
1266 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001267 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001268 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001269 main.log.info(
1270 "Couldn't find flows on switch %s, found: %s" %
1271 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001272 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001273 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001274 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001275 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001276
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 def checkFlows( self, sw, dumpFormat=None ):
1278 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001279 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001281 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001282 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001283 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001284 response = self.execute(
1285 cmd=command,
1286 prompt="mininet>",
1287 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001288 return response
1289 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001290 main.log.error( self.name + ": EOF exception found" )
1291 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001292 main.cleanup()
1293 main.exit()
1294 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001295 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001296
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001298 """
1299 Runs tpdump on an intferface and saves the file
1300 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001301 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001302 self.handle.sendline( "" )
1303 self.handle.expect( "mininet>" )
1304 self.handle.sendline(
1305 "sh sudo tcpdump -n -i " +
1306 intf +
1307 " " +
1308 port +
1309 " -w " +
1310 filename.strip() +
1311 " &" )
1312 self.handle.sendline( "" )
1313 i = self.handle.expect( [ 'No\ssuch\device',
1314 'listening\son',
1315 pexpect.TIMEOUT,
1316 "mininet>" ],
1317 timeout=10 )
1318 main.log.warn( self.handle.before + self.handle.after )
1319 self.handle.sendline( "" )
1320 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001321 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001322 main.log.error(
1323 self.name +
1324 ": tcpdump - No such device exists. " +
1325 "tcpdump attempted on: " +
1326 intf )
admin2a9548d2014-06-17 14:08:07 -07001327 return main.FALSE
1328 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001329 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001330 return main.TRUE
1331 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001332 main.log.error(
1333 self.name +
1334 ": tcpdump command timed out! Check interface name," +
1335 " given interface was: " +
1336 intf )
admin2a9548d2014-06-17 14:08:07 -07001337 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001338 elif i == 3:
1339 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001340 return main.TRUE
1341 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001342 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001343 return main.FALSE
1344 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001345 main.log.error( self.name + ": EOF exception found" )
1346 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001347 main.cleanup()
1348 main.exit()
1349 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001351 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001352 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001353 main.cleanup()
1354 main.exit()
1355
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001357 "pkills tcpdump"
1358 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001359 self.handle.sendline( "sh sudo pkill tcpdump" )
1360 self.handle.expect( "mininet>" )
1361 self.handle.sendline( "" )
1362 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001363 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 )
admin2a9548d2014-06-17 14:08:07 -07001366 main.cleanup()
1367 main.exit()
1368 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001369 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001370 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001371 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001372 main.cleanup()
1373 main.exit()
1374
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001376 """
1377 Compare mn and onos switches
1378 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001380
Jon Hall7eb38402015-01-08 17:19:54 -08001381 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001383 output = { "switches": [] }
1384 # iterate through the MN topology and pull out switches and and port
1385 # info
1386 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001387 ports = []
1388 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001389 ports.append( { 'of_port': port.port_no,
1390 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001392 'name': port.name } )
1393 output[ 'switches' ].append( {
1394 "name": switch.name,
1395 "dpid": str( switch.dpid ).zfill( 16 ),
1396 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001397
Jon Hall7eb38402015-01-08 17:19:54 -08001398 # print "mn"
1399 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001401 # indent=4,
1402 # separators=( ',', ': ' ) )
1403 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 # print json.dumps( switchesJson,
1405 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001406 # indent=4,
1407 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001408
1409 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001410 mnDPIDs = []
1411 for switch in output[ 'switches' ]:
1412 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001413 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001414 # print "List of Mininet switch DPID's"
1415 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001417 main.log.error(
1418 self.name +
1419 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001420 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001422 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001423 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 if switch[ 'available' ]:
1425 onosDPIDs.append(
1426 switch[ 'id' ].replace(
1427 ":",
1428 '' ).replace(
1429 "of",
1430 '' ).lower() )
1431 # else:
1432 # print "Switch is unavailable:"
1433 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001434 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001435 # print "List of ONOS switch DPID's"
1436 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001437
Jon Hall7eb38402015-01-08 17:19:54 -08001438 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001439 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001440 main.log.report( "Switches in MN but not in ONOS:" )
1441 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1442 main.log.report( str( list1 ) )
1443 main.log.report( "Switches in ONOS but not in MN:" )
1444 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001445 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001446 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 switchResults = main.TRUE
1448 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001449
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001451 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001452 Compare mn and onos ports
1453 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001455
Jon Hallfbc828e2015-01-06 17:30:19 -08001456 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001457 1. This uses the sts TestONTopology object
1458 2. numpy - "sudo pip install numpy"
1459
Jon Hall7eb38402015-01-08 17:19:54 -08001460 """
1461 # FIXME: this does not look for extra ports in ONOS, only checks that
1462 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001463 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001465 output = { "switches": [] }
1466 # iterate through the MN topology and pull out switches and and port
1467 # info
1468 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001469 ports = []
1470 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001471 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001473 tmpPort[ 'of_port' ] = port.port_no
1474 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 tmpPort[ 'name' ] = port.name
1476 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001477
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 ports.append( tmpPort )
1479 tmpSwitch = {}
1480 tmpSwitch[ 'name' ] = switch.name
1481 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1482 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001483
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001485
Jon Hall7eb38402015-01-08 17:19:54 -08001486 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 for mnSwitch in output[ 'switches' ]:
1488 mnPorts = []
1489 onosPorts = []
1490 switchResult = main.TRUE
1491 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001492 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 mnPorts.append( port[ 'of_port' ] )
1494 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001495 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 # print onosSwitch
1497 if onosSwitch[ 'device' ][ 'available' ]:
1498 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001499 ':',
1500 '' ).replace(
1501 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 '' ) == mnSwitch[ 'dpid' ]:
1503 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001504 if port[ 'isEnabled' ]:
1505 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 # onosPorts.append( 'local' )
1507 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001508 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001510 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 mnPorts.sort( key=float )
1512 onosPorts.sort( key=float )
1513 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1514 # print "\tmn_ports[] = ", mnPorts
1515 # print "\tonos_ports[] = ", onosPorts
1516 mnPortsLog = mnPorts
1517 onosPortsLog = onosPorts
1518 mnPorts = [ x for x in mnPorts ]
1519 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001520
Jon Hall7eb38402015-01-08 17:19:54 -08001521 # TODO: handle other reserved port numbers besides LOCAL
1522 # NOTE: Reserved ports
1523 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1524 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 for mnPort in mnPortsLog:
1526 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001527 # don't set results to true here as this is just one of
1528 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 mnPorts.remove( mnPort )
1530 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001531 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001532 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001533 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001534 if 65534 in mnPorts:
1535 mnPorts.remove( 65534 )
1536 if long( uint64( -2 ) ) in onosPorts:
1537 onosPorts.remove( long( uint64( -2 ) ) )
1538 if len( mnPorts ): # the ports of this switch don't match
1539 switchResult = main.FALSE
1540 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1541 if len( onosPorts ): # the ports of this switch don't match
1542 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001543 main.log.warn(
1544 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 str( onosPorts ) )
1546 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001547 main.log.report(
1548 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1550 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1551 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1552 portsResults = portsResults and switchResult
1553 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001554
kelvin-onlabd3b64892015-01-20 13:26:24 -08001555 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001556 """
1557 Compare mn and onos links
1558 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001559 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001560
Jon Hall7eb38402015-01-08 17:19:54 -08001561 This uses the sts TestONTopology object"""
1562 # FIXME: this does not look for extra links in ONOS, only checks that
1563 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001565 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001567 # iterate through the MN topology and pull out switches and and port
1568 # info
1569 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001570 # print "Iterating though switches as seen by Mininet"
1571 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001572 ports = []
1573 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001574 # print port.hw_addr.toStr( separator='' )
1575 ports.append( { 'of_port': port.port_no,
1576 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001578 'name': port.name } )
1579 output[ 'switches' ].append( {
1580 "name": switch.name,
1581 "dpid": str( switch.dpid ).zfill( 16 ),
1582 "ports": ports } )
1583 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001584
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001586 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001587 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001588 if 2 * len( mnLinks ) == len( onos ):
1589 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001590 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001592 main.log.report(
1593 "Mininet has %i bidirectional links and " +
1594 "ONOS has %i unidirectional links" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 ( len( mnLinks ), len( onos ) ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001596
Jon Hall7eb38402015-01-08 17:19:54 -08001597 # iterate through MN links and check if an ONOS link exists in
1598 # both directions
1599 # NOTE: Will currently only show mn links as down if they are
1600 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001602 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001604 # print "Link: %s" % link
1605 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001606 node1 = None
1607 port1 = None
1608 node2 = None
1609 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 firstDir = main.FALSE
1611 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001612 for switch in output[ 'switches' ]:
1613 # print "Switch: %s" % switch[ 'name' ]
1614 if switch[ 'name' ] == link.node1.name:
1615 node1 = switch[ 'dpid' ]
1616 for port in switch[ 'ports' ]:
1617 if str( port[ 'name' ] ) == str( link.port1 ):
1618 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001619 if node1 is not None and node2 is not None:
1620 break
Jon Hall7eb38402015-01-08 17:19:54 -08001621 if switch[ 'name' ] == link.node2.name:
1622 node2 = switch[ 'dpid' ]
1623 for port in switch[ 'ports' ]:
1624 if str( port[ 'name' ] ) == str( link.port2 ):
1625 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001626 if node1 is not None and node2 is not None:
1627 break
1628
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 for onosLink in onos:
1630 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001631 ":",
1632 '' ).replace(
1633 "of",
1634 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001636 ":",
1637 '' ).replace(
1638 "of",
1639 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 onosPort1 = onosLink[ 'src' ][ 'port' ]
1641 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001642
Jon Hall72cf1dc2014-10-20 21:04:50 -04001643 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 if str( onosNode1 ) == str( node1 ) and str(
1645 onosNode2 ) == str( node2 ):
1646 if int( onosPort1 ) == int( port1 ) and int(
1647 onosPort2 ) == int( port2 ):
1648 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001649 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001650 main.log.warn(
1651 'The port numbers do not match for ' +
1652 str( link ) +
1653 ' between ONOS and MN. When cheking ONOS for ' +
1654 'link %s/%s -> %s/%s' %
1655 ( node1,
1656 port1,
1657 node2,
1658 port2 ) +
1659 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 ( onosNode1,
1661 onosPort1,
1662 onosNode2,
1663 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001664
1665 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001666 elif ( str( onosNode1 ) == str( node2 ) and
1667 str( onosNode2 ) == str( node1 ) ):
1668 if ( int( onosPort1 ) == int( port2 )
1669 and int( onosPort2 ) == int( port1 ) ):
1670 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001671 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001672 main.log.warn(
1673 'The port numbers do not match for ' +
1674 str( link ) +
1675 ' between ONOS and MN. When cheking ONOS for ' +
1676 'link %s/%s -> %s/%s' %
1677 ( node2,
1678 port2,
1679 node1,
1680 port1 ) +
1681 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 ( onosNode2,
1683 onosPort2,
1684 onosNode1,
1685 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001686 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001687 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001688 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001689 main.log.report(
1690 'ONOS does not have the link %s/%s -> %s/%s' %
1691 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001693 main.log.report(
1694 'ONOS does not have the link %s/%s -> %s/%s' %
1695 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001696 linkResults = linkResults and firstDir and secondDir
1697 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001698
kelvin-onlabd3b64892015-01-20 13:26:24 -08001699 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001700 """
1701 Returns a list of all hosts
1702 Don't ask questions just use it"""
1703 self.handle.sendline( "" )
1704 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001705
Jon Hall7eb38402015-01-08 17:19:54 -08001706 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1707 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001708
kelvin-onlabd3b64892015-01-20 13:26:24 -08001709 handlePy = self.handle.before
1710 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1711 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001712
Jon Hall7eb38402015-01-08 17:19:54 -08001713 self.handle.sendline( "" )
1714 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001715
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 hostStr = handlePy.replace( "]", "" )
1717 hostStr = hostStr.replace( "'", "" )
1718 hostStr = hostStr.replace( "[", "" )
1719 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001720
kelvin-onlabd3b64892015-01-20 13:26:24 -08001721 return hostList
adminbae64d82013-08-01 10:50:15 -07001722
Jon Hall7eb38402015-01-08 17:19:54 -08001723 def update( self ):
1724 """
1725 updates the port address and status information for
1726 each port in mn"""
1727 # TODO: Add error checking. currently the mininet command has no output
1728 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001729 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001730 self.handle.sendline( "" )
1731 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001732
Jon Hall7eb38402015-01-08 17:19:54 -08001733 self.handle.sendline( "update" )
1734 self.handle.expect( "update" )
1735 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001736
Jon Hall7eb38402015-01-08 17:19:54 -08001737 self.handle.sendline( "" )
1738 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001739
Jon Hallb1290e82014-11-18 16:17:48 -05001740 return main.TRUE
1741 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001742 main.log.error( self.name + ": EOF exception found" )
1743 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001744 main.cleanup()
1745 main.exit()
1746
adminbae64d82013-08-01 10:50:15 -07001747if __name__ != "__main__":
1748 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001749 sys.modules[ __name__ ] = MininetCliDriver()