blob: 785aa86ef8026f04f4c66a9f3739c911aa19b5f5 [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-onlaba0ce3222015-01-27 17:25:15 -0800132 def startNet( self, topoFile = None, args = None ):
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 ],
144 120 )
145 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-onlaba0ce3222015-01-27 17:25:15 -0800152 120 )
153 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... " )
161 if topoFile == None and args == None:
162 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 ],
186 300 )
187 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:
209 self.handle.sendline('sudo ' + topoFile + ' ' + args)
210 self.handle.sendline('')
211 i = 1
212 i = self.handle.expect( [ 'mininet>',
213 pexpect.EOF ,
214 pexpect.TIMEOUT ],
215 timeout = 2)
216 self.handle.expect('mininet>')
217 main.log.info(self.name + ": Network started")
218 return main.TRUE
219
Jon Hall7eb38402015-01-08 17:19:54 -0800220 else: # if no handle
221 main.log.error(
222 self.name +
223 ": Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800224 self.user_name +
Jon Hall7eb38402015-01-08 17:19:54 -0800225 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -0800226 self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800227 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700228 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800229
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800230 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400231 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800232 # In tree topology, if fanout arg is not given, by default it is 2
233 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400234 fanout = 2
235 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500236 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800237 while( k <= depth - 1 ):
238 count = count + pow( fanout, k )
239 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800241 while( k <= depth - 2 ):
242 # depth-2 gives you only core links and not considering
243 # edge links as seen by ONOS. If all the links including
244 # edge links are required, do depth-1
245 count = count + pow( fanout, k )
246 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800248 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800250
Jon Hall7eb38402015-01-08 17:19:54 -0800251 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800253 # by default it is 1
254 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400255 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800256 numSwitches = depth
257 numHostsPerSw = fanout
258 totalNumHosts = numSwitches * numHostsPerSw
259 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800260 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400262 topoDict = {}
Jon Hall7eb38402015-01-08 17:19:54 -0800263 topoDict = {
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 "num_switches": int( numSwitches ),
265 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400266 return topoDict
267
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 def calculateSwAndLinks( self ):
269 topoDict = self.numSwitchesN_links( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400270 return topoDict
271
Jon Hall7eb38402015-01-08 17:19:54 -0800272 def pingall( self, timeout=300 ):
273 """
274 Verifies the reachability of the hosts using pingall command.
275 Optional parameter timeout allows you to specify how long to
276 wait for pingall to complete
277 Returns:
278 main.TRUE if pingall completes with no pings dropped
279 otherwise main.FALSE"""
280 if self.handle:
281 main.log.info(
282 self.name +
283 ": Checking reachabilty to the hosts using pingall" )
Jon Hall6094a362014-04-11 14:46:56 -0700284 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800285 response = self.execute(
286 cmd="pingall",
287 prompt="mininet>",
288 timeout=int( timeout ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500289 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800290 main.log.error( self.name + ": EOF exception found" )
291 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500292 main.cleanup()
293 main.exit()
294 except pexpect.TIMEOUT:
Jon Hall7eb38402015-01-08 17:19:54 -0800295 # We may not want to kill the test if pexpect times out
296 main.log.error( self.name + ": TIMEOUT exception found" )
297 main.log.error( self.name +
298 ": " +
299 str( self.handle.before ) )
300 # NOTE: mininet's pingall rounds, so we will check the number of
301 # passed and number of failed
302 pattern = "Results\:\s0\%\sdropped\s\(" +\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800303 "(?P<passed>[\d]+)/(?P=passed)"
Jon Hall7eb38402015-01-08 17:19:54 -0800304 if re.search( pattern, response ):
305 main.log.info( self.name + ": All hosts are reachable" )
adminbae64d82013-08-01 10:50:15 -0700306 return main.TRUE
307 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800308 main.log.error( self.name + ": Unable to reach all the hosts" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800309 main.log.info( "Pingall output: " + str( response ) )
Jon Hall7eb38402015-01-08 17:19:54 -0800310 # NOTE: Send ctrl-c to make sure pingall is done
311 self.handle.send( "\x03" )
312 self.handle.expect( "Interrupt" )
313 self.handle.expect( "mininet>" )
adminbae64d82013-08-01 10:50:15 -0700314 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800315 else:
316 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallb1290e82014-11-18 16:17:48 -0500317 main.cleanup()
318 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700319
Jon Hall7eb38402015-01-08 17:19:54 -0800320 def fpingHost( self, **pingParams ):
321 """
322 Uses the fping package for faster pinging...
323 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800324 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800325 command = args[ "SRC" ] + \
326 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
327 self.handle.sendline( command )
328 self.handle.expect(
329 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
330 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
331 response = self.handle.before
332 if re.search( ":\s-", response ):
333 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700334 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800335 elif re.search( ":\s\d{1,2}\.\d\d", response ):
336 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700337 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800338 main.log.info( self.name + ": Install fping on mininet machine... " )
339 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700340 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800341
Jon Hall7eb38402015-01-08 17:19:54 -0800342 def pingHost( self, **pingParams ):
343 """
344 Ping from one mininet host to another
345 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800346 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800347 command = args[ "SRC" ] + " ping " + \
348 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700349 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800350 main.log.warn( "Sending: " + command )
351 self.handle.sendline( command )
352 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700353 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800354 main.log.error(
355 self.name +
356 ": timeout when waiting for response from mininet" )
357 main.log.error( "response: " + str( self.handle.before ) )
358 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700359 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800360 main.log.error(
361 self.name +
362 ": timeout when waiting for response from mininet" )
363 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700364 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800365 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800366 main.log.error( self.name + ": EOF exception found" )
367 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700368 main.cleanup()
369 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800370 main.log.info( self.name + ": Ping Response: " + response )
371 if re.search( ',\s0\%\spacket\sloss', response ):
372 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800373 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700374 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800375 else:
376 main.log.error(
377 self.name +
378 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800379 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700380 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800381
Jon Hall7eb38402015-01-08 17:19:54 -0800382 def checkIP( self, host ):
383 """
384 Verifies the host's ip configured or not."""
385 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700386 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800387 response = self.execute(
388 cmd=host +
389 " ifconfig",
390 prompt="mininet>",
391 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800392 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800393 main.log.error( self.name + ": EOF exception found" )
394 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700395 main.cleanup()
396 main.exit()
adminbae64d82013-08-01 10:50:15 -0700397
Jon Hall7eb38402015-01-08 17:19:54 -0800398 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800399 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
400 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
401 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
402 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
403 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800404 # pattern = "inet addr:10.0.0.6"
405 if re.search( pattern, response ):
406 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700407 return main.TRUE
408 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800409 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700410 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800411 else:
412 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800413
Jon Hall7eb38402015-01-08 17:19:54 -0800414 def verifySSH( self, **connectargs ):
Jon Hall6094a362014-04-11 14:46:56 -0700415 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800416 response = self.execute(
417 cmd="h1 /usr/sbin/sshd -D&",
418 prompt="mininet>",
419 timeout=10 )
420 response = self.execute(
421 cmd="h4 /usr/sbin/sshd -D&",
422 prompt="mininet>",
423 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700424 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800425 vars( self )[ key ] = connectargs[ key ]
426 response = self.execute(
427 cmd="xterm h1 h4 ",
428 prompt="mininet>",
429 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800430 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800431 main.log.error( self.name + ": EOF exception found" )
432 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700433 main.cleanup()
434 main.exit()
adminbae64d82013-08-01 10:50:15 -0700435 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800436 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700437 if self.flag == 0:
438 self.flag = 1
439 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800440 else:
adminbae64d82013-08-01 10:50:15 -0700441 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800442
Jon Hall7eb38402015-01-08 17:19:54 -0800443 def changeIP( self, host, intf, newIP, newNetmask ):
444 """
445 Changes the ip address of a host on the fly
446 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800447 if self.handle:
448 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800449 cmd = host + " ifconfig " + intf + " " + \
450 newIP + " " + 'netmask' + " " + newNetmask
451 self.handle.sendline( cmd )
452 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800453 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800454 main.log.info( "response = " + response )
455 main.log.info(
456 "Ip of host " +
457 host +
458 " changed to new IP " +
459 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800460 return main.TRUE
461 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800462 main.log.error( self.name + ": EOF exception found" )
463 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800464 return main.FALSE
465
Jon Hall7eb38402015-01-08 17:19:54 -0800466 def changeDefaultGateway( self, host, newGW ):
467 """
468 Changes the default gateway of a host
469 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800470 if self.handle:
471 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800472 cmd = host + " route add default gw " + newGW
473 self.handle.sendline( cmd )
474 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800475 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800476 main.log.info( "response = " + response )
477 main.log.info(
478 "Default gateway of host " +
479 host +
480 " changed to " +
481 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800482 return main.TRUE
483 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800484 main.log.error( self.name + ": EOF exception found" )
485 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800486 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800487
Jon Hall7eb38402015-01-08 17:19:54 -0800488 def addStaticMACAddress( self, host, GW, macaddr ):
489 """
490 Changes the mac address of a geateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800491 if self.handle:
492 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800493 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
494 cmd = host + " arp -s " + GW + " " + macaddr
495 self.handle.sendline( cmd )
496 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800497 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800498 main.log.info( "response = " + response )
499 main.log.info(
500 "Mac adrress of gateway " +
501 GW +
502 " changed to " +
503 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800504 return main.TRUE
505 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800506 main.log.error( self.name + ": EOF exception found" )
507 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800508 return main.FALSE
509
Jon Hall7eb38402015-01-08 17:19:54 -0800510 def verifyStaticGWandMAC( self, host ):
511 """
512 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800513 if self.handle:
514 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800515 # h1 arp -an
516 cmd = host + " arp -an "
517 self.handle.sendline( cmd )
518 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800519 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800520 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800521 return main.TRUE
522 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800523 main.log.error( self.name + ": EOF exception found" )
524 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800525 return main.FALSE
526
Jon Hall7eb38402015-01-08 17:19:54 -0800527 def getMacAddress( self, host ):
528 """
529 Verifies the host's ip configured or not."""
530 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700531 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800532 response = self.execute(
533 cmd=host +
534 " ifconfig",
535 prompt="mininet>",
536 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800537 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 )
Jon Hall6094a362014-04-11 14:46:56 -0700540 main.cleanup()
541 main.exit()
adminbae64d82013-08-01 10:50:15 -0700542
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700543 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800544 macAddressSearch = re.search( pattern, response, re.I )
545 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800546 main.log.info(
547 self.name +
548 ": Mac-Address of Host " +
549 host +
550 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 macAddress )
552 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700553 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800554 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700555
Jon Hall7eb38402015-01-08 17:19:54 -0800556 def getInterfaceMACAddress( self, host, interface ):
557 """
558 Return the IP address of the interface on the given host"""
559 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700560 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800561 response = self.execute( cmd=host + " ifconfig " + interface,
562 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800563 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800564 main.log.error( self.name + ": EOF exception found" )
565 main.log.error( self.name + ": " + self.handle.before )
566 main.cleanup()
567 main.exit()
568
569 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800570 macAddressSearch = re.search( pattern, response, re.I )
571 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800572 main.log.info( "No mac address found in %s" % response )
573 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800575 main.log.info(
576 "Mac-Address of " +
577 host +
578 ":" +
579 interface +
580 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 macAddress )
582 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800583 else:
584 main.log.error( "Connection failed to the host" )
585
586 def getIPAddress( self, host ):
587 """
588 Verifies the host's ip configured or not."""
589 if self.handle:
590 try:
591 response = self.execute(
592 cmd=host +
593 " ifconfig",
594 prompt="mininet>",
595 timeout=10 )
596 except pexpect.EOF:
597 main.log.error( self.name + ": EOF exception found" )
598 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700599 main.cleanup()
600 main.exit()
adminbae64d82013-08-01 10:50:15 -0700601
602 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800603 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800604 main.log.info(
605 self.name +
606 ": IP-Address of Host " +
607 host +
608 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800609 ipAddressSearch.group( 1 ) )
610 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800611 else:
612 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800613
Jon Hall7eb38402015-01-08 17:19:54 -0800614 def getSwitchDPID( self, switch ):
615 """
616 return the datapath ID of the switch"""
617 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700618 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700619 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800620 response = self.execute(
621 cmd=cmd,
622 prompt="mininet>",
623 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800624 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800625 main.log.error( self.name + ": EOF exception found" )
626 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700627 main.cleanup()
628 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800629 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800630 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700631 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800632 main.log.info(
633 "Couldn't find DPID for switch %s, found: %s" %
634 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700635 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800636 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700637 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800638 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700639
Jon Hall7eb38402015-01-08 17:19:54 -0800640 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700641 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800642 self.handle.sendline( "" )
643 self.expect( "mininet>" )
644 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700645 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800646 response = self.execute(
647 cmd=cmd,
648 prompt="mininet>",
649 timeout=10 )
650 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700651 response = self.handle.before
652 return response
653 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800654 main.log.error( self.name + ": EOF exception found" )
655 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700656 main.cleanup()
657 main.exit()
658
Jon Hall7eb38402015-01-08 17:19:54 -0800659 def getInterfaces( self, node ):
660 """
661 return information dict about interfaces connected to the node"""
662 if self.handle:
663 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800664 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700665 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700666 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800667 response = self.execute(
668 cmd=cmd,
669 prompt="mininet>",
670 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800671 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800672 main.log.error( self.name + ": EOF exception found" )
673 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700674 main.cleanup()
675 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700676 return response
677 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800678 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700679
Jon Hall7eb38402015-01-08 17:19:54 -0800680 def dump( self ):
681 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700682 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800683 response = self.execute(
684 cmd='dump',
685 prompt='mininet>',
686 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800687 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800688 main.log.error( self.name + ": EOF exception found" )
689 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700690 main.cleanup()
691 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700692 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800693
Jon Hall7eb38402015-01-08 17:19:54 -0800694 def intfs( self ):
695 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700696 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800697 response = self.execute(
698 cmd='intfs',
699 prompt='mininet>',
700 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800701 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800702 main.log.error( self.name + ": EOF exception found" )
703 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700704 main.cleanup()
705 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700706 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800707
Jon Hall7eb38402015-01-08 17:19:54 -0800708 def net( self ):
709 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700710 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800712 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800713 main.log.error( self.name + ": EOF exception found" )
714 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700715 main.cleanup()
716 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700717 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800718
719 def iperf( self, host1, host2 ):
720 main.log.info(
721 self.name +
722 ": Simple iperf TCP test between two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700723 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800724 cmd1 = 'iperf ' + host1 + " " + host2
725 self.handle.sendline( cmd1 )
726 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800727 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800728 if re.search( 'Results:', response ):
729 main.log.info( self.name + ": iperf test succssful" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800730 return main.TRUE
731 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.error( self.name + ": iperf test failed" )
733 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800734 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800735 main.log.error( self.name + ": EOF exception found" )
736 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800737 main.cleanup()
738 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800739
Jon Hall7eb38402015-01-08 17:19:54 -0800740 def iperfudp( self ):
741 main.log.info(
742 self.name +
743 ": Simple iperf TCP test between two " +
744 "(optionally specified) hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700745 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 response = self.execute(
747 cmd='iperfudp',
748 prompt='mininet>',
749 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800750 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700753 main.cleanup()
754 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700755 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800756
Jon Hall7eb38402015-01-08 17:19:54 -0800757 def nodes( self ):
758 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -0700759 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800760 response = self.execute(
761 cmd='nodes',
762 prompt='mininet>',
763 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800764 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700767 main.cleanup()
768 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700769 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800770
Jon Hall7eb38402015-01-08 17:19:54 -0800771 def pingpair( self ):
772 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -0700773 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800774 response = self.execute(
775 cmd='pingpair',
776 prompt='mininet>',
777 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800778 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800779 main.log.error( self.name + ": EOF exception found" )
780 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700781 main.cleanup()
782 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800783
Jon Hall7eb38402015-01-08 17:19:54 -0800784 if re.search( ',\s0\%\spacket\sloss', response ):
785 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800786 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700787 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800788 else:
789 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700791 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800792
Jon Hall7eb38402015-01-08 17:19:54 -0800793 def link( self, **linkargs ):
794 """
795 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800796 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800797 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
798 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
799 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
800 main.log.info(
801 "Bring link between '" +
802 end1 +
803 "' and '" +
804 end2 +
805 "' '" +
806 option +
807 "'" )
808 command = "link " + \
809 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -0700810 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800811 self.handle.sendline( command )
812 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800813 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 main.log.error( self.name + ": EOF exception found" )
815 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700816 main.cleanup()
817 main.exit()
adminbae64d82013-08-01 10:50:15 -0700818 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800819
Jon Hall7eb38402015-01-08 17:19:54 -0800820 def yank( self, **yankargs ):
821 """
822 yank a mininet switch interface to a host"""
823 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800824 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800825 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
826 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
827 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700828 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800829 response = self.execute(
830 cmd=command,
831 prompt="mininet>",
832 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800833 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700836 main.cleanup()
837 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700838 return main.TRUE
839
Jon Hall7eb38402015-01-08 17:19:54 -0800840 def plug( self, **plugargs ):
841 """
842 plug the yanked mininet switch interface to a switch"""
843 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800844 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800845 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
846 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
847 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700848 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800849 response = self.execute(
850 cmd=command,
851 prompt="mininet>",
852 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800853 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800854 main.log.error( self.name + ": EOF exception found" )
855 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700856 main.cleanup()
857 main.exit()
adminbae64d82013-08-01 10:50:15 -0700858 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800859
Jon Hall7eb38402015-01-08 17:19:54 -0800860 def dpctl( self, **dpctlargs ):
861 """
862 Run dpctl command on all switches."""
863 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800864 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800865 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
866 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
867 command = "dpctl " + cmd + " " + str( cmdargs )
868 try:
869 response = self.execute(
870 cmd=command,
871 prompt="mininet>",
872 timeout=10 )
873 except pexpect.EOF:
874 main.log.error( self.name + ": EOF exception found" )
875 main.log.error( self.name + ": " + self.handle.before )
876 main.cleanup()
877 main.exit()
878 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800879
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 def getVersion( self ):
881 fileInput = path + '/lib/Mininet/INSTALL'
882 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -0700883 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800884 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -0800885 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -0700886 if result:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -0500888 return version
adminbae64d82013-08-01 10:50:15 -0700889
kelvin-onlabd3b64892015-01-20 13:26:24 -0800890 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800891 """
Jon Hallec3c21e2014-11-10 22:22:37 -0500892 Parameters:
893 sw: The name of an OVS switch. Example "s1"
894 Return:
Jon Hall7eb38402015-01-08 17:19:54 -0800895 The output of the command from the mininet cli
896 or main.FALSE on timeout"""
897 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -0700898 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800899 response = self.execute(
900 cmd=command,
901 prompt="mininet>",
902 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -0700903 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500904 return response
admin2a9548d2014-06-17 14:08:07 -0700905 else:
906 return main.FALSE
907 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 )
admin2a9548d2014-06-17 14:08:07 -0700910 main.cleanup()
911 main.exit()
adminbae64d82013-08-01 10:50:15 -0700912
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 def assignSwController( self, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800914 """
915 count is only needed if there is more than 1 controller"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800916 args = utilities.parse_args( [ "COUNT" ], **kwargs )
Jon Hall7eb38402015-01-08 17:19:54 -0800917 count = args[ "COUNT" ] if args != {} else 1
Jon Hallf89c8552014-04-02 13:14:06 -0700918
919 argstring = "SW"
Jon Hall7eb38402015-01-08 17:19:54 -0800920 for j in range( count ):
921 argstring = argstring + ",IP" + \
922 str( j + 1 ) + ",PORT" + str( j + 1 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800923 args = utilities.parse_args( argstring.split( "," ), **kwargs )
Jon Hallf89c8552014-04-02 13:14:06 -0700924
Jon Hall7eb38402015-01-08 17:19:54 -0800925 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
926 ptcpA = int( args[ "PORT1" ] ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800927 int( sw ) if args[ "PORT1" ] is not None else ""
Jon Hall7eb38402015-01-08 17:19:54 -0800928 ptcpB = "ptcp:" + str( ptcpA ) if ptcpA != "" else ""
Jon Hallfbc828e2015-01-06 17:30:19 -0800929
Jon Hall7eb38402015-01-08 17:19:54 -0800930 command = "sh ovs-vsctl set-controller s" + \
931 str( sw ) + " " + ptcpB + " "
932 for j in range( count ):
933 i = j + 1
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800934 args = utilities.parse_args(
Jon Hall7eb38402015-01-08 17:19:54 -0800935 [ "IP" + str( i ), "PORT" + str( i ) ], **kwargs )
936 ip = args[
937 "IP" +
938 str( i ) ] if args[
939 "IP" +
940 str( i ) ] is not None else ""
941 port = args[
942 "PORT" +
943 str( i ) ] if args[
944 "PORT" +
945 str( i ) ] is not None else ""
946 tcp = "tcp:" + str( ip ) + ":" + str( port ) + \
kelvin-onlabedcff052015-01-16 12:53:55 -0800947 " " if ip != "" else ""
Jon Hallf89c8552014-04-02 13:14:06 -0700948 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -0700949 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800950 self.execute( cmd=command, prompt="mininet>", timeout=5 )
Jon Hall6094a362014-04-11 14:46:56 -0700951 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800952 main.log.error( self.name + ": EOF exception found" )
953 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700954 main.cleanup()
955 main.exit()
956 except:
Jon Hall7eb38402015-01-08 17:19:54 -0800957 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -0800958 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -0800959 main.log.info( ":" * 50 )
Jon Hall6094a362014-04-11 14:46:56 -0700960 main.cleanup()
961 main.exit()
adminbae64d82013-08-01 10:50:15 -0700962
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -0800964 """
965 Removes the controller target from sw"""
966 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -0700967 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800968 response = self.execute(
969 cmd=command,
970 prompt="mininet>",
971 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800972 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800973 main.log.error( self.name + ": EOF exception found" )
974 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -0700975 main.cleanup()
976 main.exit()
977 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800978 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -0700979
kelvin-onlabd3b64892015-01-20 13:26:24 -0800980 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -0800981 """
Jon Hallb1290e82014-11-18 16:17:48 -0500982 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -0800983 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -0800984 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -0500985 NOTE: cannot currently specify what type of switch
986 required params:
987 switchname = name of the new switch as a string
988 optional keyvalues:
989 dpid = "dpid"
990 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800991 """
992 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -0800993 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -0500994 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800995 response = self.execute(
996 cmd=command,
997 prompt="mininet>",
998 timeout=10 )
999 if re.search( "already exists!", response ):
1000 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001001 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001002 elif re.search( "Error", 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( "usage:", response ):
1006 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001007 return main.FALSE
1008 else:
1009 return main.TRUE
1010 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001011 main.log.error( self.name + ": EOF exception found" )
1012 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001013 main.cleanup()
1014 main.exit()
1015
kelvin-onlabd3b64892015-01-20 13:26:24 -08001016 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001017 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001018 delete a switch from the mininet topology
1019 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001020 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001021 required params:
Jon Hallb1290e82014-11-18 16:17:48 -05001022 switchname = name of the switch as a string
Jon Hallbe6dfc42015-01-12 17:37:25 -08001023 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001024 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001025 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001026 response = self.execute(
1027 cmd=command,
1028 prompt="mininet>",
1029 timeout=10 )
1030 if re.search( "no switch named", response ):
1031 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001032 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001033 elif re.search( "Error", 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( "usage:", response ):
1037 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001038 return main.FALSE
1039 else:
1040 return main.TRUE
1041 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001042 main.log.error( self.name + ": EOF exception found" )
1043 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001044 main.cleanup()
1045 main.exit()
1046
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001048 """
1049 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001050 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001051 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001052 NOTE: cannot currently specify what type of link
1053 required params:
1054 node1 = the string node name of the first endpoint of the link
1055 node2 = the string node name of the second endpoint of the link
1056 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001057 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001058 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001059 response = self.execute(
1060 cmd=command,
1061 prompt="mininet>",
1062 timeout=10 )
1063 if re.search( "doesnt exist!", response ):
1064 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001065 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001066 elif re.search( "Error", 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( "usage:", response ):
1070 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001071 return main.FALSE
1072 else:
1073 return main.TRUE
1074 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001075 main.log.error( self.name + ": EOF exception found" )
1076 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001077 main.cleanup()
1078 main.exit()
1079
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001081 """
1082 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001083 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001084 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001085 required params:
1086 node1 = the string node name of the first endpoint of the link
1087 node2 = the string node name of the second endpoint of the link
1088 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001089 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001090 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001091 response = self.execute(
1092 cmd=command,
1093 prompt="mininet>",
1094 timeout=10 )
1095 if re.search( "no node named", response ):
1096 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001097 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001098 elif re.search( "Error", 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( "usage:", response ):
1102 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001103 return main.FALSE
1104 else:
1105 return main.TRUE
1106 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001109 main.cleanup()
1110 main.exit()
1111
kelvin-onlabd3b64892015-01-20 13:26:24 -08001112 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001113 """
Jon Hallb1290e82014-11-18 16:17:48 -05001114 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001115 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001116 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001117 NOTE: cannot currently specify what type of host
1118 required params:
1119 hostname = the string hostname
1120 optional key-value params
1121 switch = "switch name"
1122 returns: main.FASLE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001123 """
1124 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001125 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001126 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001127 response = self.execute(
1128 cmd=command,
1129 prompt="mininet>",
1130 timeout=10 )
1131 if re.search( "already exists!", response ):
1132 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001133 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001134 elif re.search( "doesnt 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( "Error", 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( "usage:", response ):
1141 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001142 return main.FALSE
1143 else:
1144 return main.TRUE
1145 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001148 main.cleanup()
1149 main.exit()
1150
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001152 """
1153 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001154 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001155 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001156 NOTE: this uses a custom mn function
1157 required params:
1158 hostname = the string hostname
1159 returns: main.FASLE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001160 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001161 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001162 response = self.execute(
1163 cmd=command,
1164 prompt="mininet>",
1165 timeout=10 )
1166 if re.search( "no host named", response ):
1167 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001168 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001169 elif re.search( "Error", 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( "usage:", response ):
1173 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001174 return main.FALSE
1175 else:
1176 return main.TRUE
1177 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001178 main.log.error( self.name + ": EOF exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001180 main.cleanup()
1181 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001182
Jon Hall7eb38402015-01-08 17:19:54 -08001183 def disconnect( self ):
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001184 """
1185 Called at the end of the test to disconnect the handle.
1186 """
1187 self.handle.sendline('')
1188 i = 1
1189 i = self.handle.expect( ['mininet>',pexpect.EOF,pexpect.TIMEOUT ], timeout = 2)
1190 if i == 0:
1191 self.stopNet()
1192 response = ''
1193 # print "Disconnecting Mininet"
1194 if self.handle:
1195 self.handle.sendline( "exit" )
1196 self.handle.expect( "exit" )
1197 self.handle.expect( "(.*)" )
1198 main.log.info( "Mininet CLI is successfully disconnected" )
1199 response = self.handle.before
1200 else:
1201 main.log.error( "Connection failed to the host" )
1202 response = main.FALSE
1203
1204 return response
1205
1206 def stopNet( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001207 main.log.info( self.name + ": Disconnecting mininet..." )
adminbae64d82013-08-01 10:50:15 -07001208 response = ''
1209 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001210 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001211 response = self.execute(
1212 cmd="exit",
1213 prompt="(.*)",
1214 timeout=120 )
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001215 main.log.info( self.name + ": Disconnected")
Jon Hall7eb38402015-01-08 17:19:54 -08001216 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001217 response = main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001218 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001219 main.log.error( self.name + ": EOF exception found" )
1220 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001221 main.cleanup()
1222 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001223 else:
1224 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001225 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001226 return response
1227
kelvin-onlaba0ce3222015-01-27 17:25:15 -08001228
1229
Jon Hall7eb38402015-01-08 17:19:54 -08001230 def arping( self, src, dest, destmac ):
1231 self.handle.sendline( '' )
1232 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001233
Jon Hall7eb38402015-01-08 17:19:54 -08001234 self.handle.sendline( src + ' arping ' + dest )
admin07529932013-11-22 14:58:28 -08001235 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
1237 main.log.info( self.name + ": ARP successful" )
1238 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001239 return main.TRUE
1240 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 main.log.warn( self.name + ": ARP FAILURE" )
1242 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
admin07529932013-11-22 14:58:28 -08001243 return main.FALSE
1244
Jon Hall7eb38402015-01-08 17:19:54 -08001245 def decToHex( self, num ):
1246 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001247
Jon Hall7eb38402015-01-08 17:19:54 -08001248 def getSwitchFlowCount( self, switch ):
1249 """
1250 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001251 if self.handle:
1252 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1253 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001254 response = self.execute(
1255 cmd=cmd,
1256 prompt="mininet>",
1257 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001258 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001261 main.cleanup()
1262 main.exit()
1263 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001264 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001265 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001266 main.log.info(
1267 "Couldn't find flows on switch %s, found: %s" %
1268 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001269 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001270 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001271 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001272 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001273
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 def checkFlows( self, sw, dumpFormat=None ):
1275 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001276 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001278 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001279 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001280 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001281 response = self.execute(
1282 cmd=command,
1283 prompt="mininet>",
1284 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001285 return response
1286 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001289 main.cleanup()
1290 main.exit()
1291 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001292 main.log.info( response )
admin2a9548d2014-06-17 14:08:07 -07001293
kelvin-onlabd3b64892015-01-20 13:26:24 -08001294 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001295 """
1296 Runs tpdump on an intferface and saves the file
1297 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001298 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001299 self.handle.sendline( "" )
1300 self.handle.expect( "mininet>" )
1301 self.handle.sendline(
1302 "sh sudo tcpdump -n -i " +
1303 intf +
1304 " " +
1305 port +
1306 " -w " +
1307 filename.strip() +
1308 " &" )
1309 self.handle.sendline( "" )
1310 i = self.handle.expect( [ 'No\ssuch\device',
1311 'listening\son',
1312 pexpect.TIMEOUT,
1313 "mininet>" ],
1314 timeout=10 )
1315 main.log.warn( self.handle.before + self.handle.after )
1316 self.handle.sendline( "" )
1317 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001318 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001319 main.log.error(
1320 self.name +
1321 ": tcpdump - No such device exists. " +
1322 "tcpdump attempted on: " +
1323 intf )
admin2a9548d2014-06-17 14:08:07 -07001324 return main.FALSE
1325 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001326 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001327 return main.TRUE
1328 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001329 main.log.error(
1330 self.name +
1331 ": tcpdump command timed out! Check interface name," +
1332 " given interface was: " +
1333 intf )
admin2a9548d2014-06-17 14:08:07 -07001334 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001335 elif i == 3:
1336 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001337 return main.TRUE
1338 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001339 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001340 return main.FALSE
1341 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001342 main.log.error( self.name + ": EOF exception found" )
1343 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001344 main.cleanup()
1345 main.exit()
1346 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001347 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001348 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001349 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001350 main.cleanup()
1351 main.exit()
1352
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 def stopTcpdump( self ):
admin2a9548d2014-06-17 14:08:07 -07001354 "pkills tcpdump"
1355 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001356 self.handle.sendline( "sh sudo pkill tcpdump" )
1357 self.handle.expect( "mininet>" )
1358 self.handle.sendline( "" )
1359 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001360 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001361 main.log.error( self.name + ": EOF exception found" )
1362 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001363 main.cleanup()
1364 main.exit()
1365 except:
Jon Hall7eb38402015-01-08 17:19:54 -08001366 main.log.info( self.name + ":" * 50 )
kelvin-onlab64b33712015-01-21 15:26:15 -08001367 main.log.error( traceback.print_exc() )
kelvin-onlabedcff052015-01-16 12:53:55 -08001368 main.log.info( ":" * 50 )
admin2a9548d2014-06-17 14:08:07 -07001369 main.cleanup()
1370 main.exit()
1371
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 def compareSwitches( self, topo, switchesJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001373 """
1374 Compare mn and onos switches
1375 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04001377
Jon Hall7eb38402015-01-08 17:19:54 -08001378 This uses the sts TestONTopology object"""
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 # main.log.debug( "Switches_json string: ", switchesJson )
Jon Hall7eb38402015-01-08 17:19:54 -08001380 output = { "switches": [] }
1381 # iterate through the MN topology and pull out switches and and port
1382 # info
1383 for switch in topo.graph.switches:
Jon Hall3d87d502014-10-17 18:37:42 -04001384 ports = []
1385 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001386 ports.append( { 'of_port': port.port_no,
1387 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001389 'name': port.name } )
1390 output[ 'switches' ].append( {
1391 "name": switch.name,
1392 "dpid": str( switch.dpid ).zfill( 16 ),
1393 "ports": ports } )
Jon Hall3d87d502014-10-17 18:37:42 -04001394
Jon Hall7eb38402015-01-08 17:19:54 -08001395 # print "mn"
1396 # print json.dumps( output,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001398 # indent=4,
1399 # separators=( ',', ': ' ) )
1400 # print "onos"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 # print json.dumps( switchesJson,
1402 # sortKeys=True,
Jon Hall7eb38402015-01-08 17:19:54 -08001403 # indent=4,
1404 # separators=( ',', ': ' ) )
Jon Hall3d87d502014-10-17 18:37:42 -04001405
1406 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08001407 mnDPIDs = []
1408 for switch in output[ 'switches' ]:
1409 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04001410 mnDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001411 # print "List of Mininet switch DPID's"
1412 # print mnDPIDs
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08001414 main.log.error(
1415 self.name +
1416 ".compare_switches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04001417 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08001419 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04001420 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 if switch[ 'available' ]:
1422 onosDPIDs.append(
1423 switch[ 'id' ].replace(
1424 ":",
1425 '' ).replace(
1426 "of",
1427 '' ).lower() )
1428 # else:
1429 # print "Switch is unavailable:"
1430 # print switch
Jon Hall3d87d502014-10-17 18:37:42 -04001431 onosDPIDs.sort()
Jon Hall7eb38402015-01-08 17:19:54 -08001432 # print "List of ONOS switch DPID's"
1433 # print onosDPIDs
Jon Hall3d87d502014-10-17 18:37:42 -04001434
Jon Hall7eb38402015-01-08 17:19:54 -08001435 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 switchResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001437 main.log.report( "Switches in MN but not in ONOS:" )
1438 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
1439 main.log.report( str( list1 ) )
1440 main.log.report( "Switches in ONOS but not in MN:" )
1441 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
kelvin-onlabedcff052015-01-16 12:53:55 -08001442 main.log.report( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001443 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08001444 switchResults = main.TRUE
1445 return switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04001446
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 def comparePorts( self, topo, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001448 """
Jon Hall72cf1dc2014-10-20 21:04:50 -04001449 Compare mn and onos ports
1450 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 portsJson: parsed json object from the onos ports api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001452
Jon Hallfbc828e2015-01-06 17:30:19 -08001453 Dependencies:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001454 1. This uses the sts TestONTopology object
1455 2. numpy - "sudo pip install numpy"
1456
Jon Hall7eb38402015-01-08 17:19:54 -08001457 """
1458 # FIXME: this does not look for extra ports in ONOS, only checks that
1459 # ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -04001460 from numpy import uint64
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 portsResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001462 output = { "switches": [] }
1463 # iterate through the MN topology and pull out switches and and port
1464 # info
1465 for switch in topo.graph.switches:
Jon Hall72cf1dc2014-10-20 21:04:50 -04001466 ports = []
1467 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001468 # print port.hw_addr.toStr( separator='' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001469 tmpPort = {}
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001470 tmpPort[ 'of_port' ] = port.port_no
1471 tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 tmpPort[ 'name' ] = port.name
1473 tmpPort[ 'enabled' ] = port.enabled
Jon Hall39f29df2014-11-04 19:30:21 -05001474
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 ports.append( tmpPort )
1476 tmpSwitch = {}
1477 tmpSwitch[ 'name' ] = switch.name
1478 tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
1479 tmpSwitch[ 'ports' ] = ports
Jon Hall39f29df2014-11-04 19:30:21 -05001480
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 output[ 'switches' ].append( tmpSwitch )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001482
Jon Hall7eb38402015-01-08 17:19:54 -08001483 # PORTS
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 for mnSwitch in output[ 'switches' ]:
1485 mnPorts = []
1486 onosPorts = []
1487 switchResult = main.TRUE
1488 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001489 if port[ 'enabled' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 mnPorts.append( port[ 'of_port' ] )
1491 for onosSwitch in portsJson:
Jon Hall7eb38402015-01-08 17:19:54 -08001492 # print "Iterating through a new switch as seen by ONOS"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 # print onosSwitch
1494 if onosSwitch[ 'device' ][ 'available' ]:
1495 if onosSwitch[ 'device' ][ 'id' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001496 ':',
1497 '' ).replace(
1498 "of",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001499 '' ) == mnSwitch[ 'dpid' ]:
1500 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08001501 if port[ 'isEnabled' ]:
1502 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 # onosPorts.append( 'local' )
1504 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001505 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05001507 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 mnPorts.sort( key=float )
1509 onosPorts.sort( key=float )
1510 # print "\nPorts for Switch %s:" % ( mnSwitch[ 'name' ] )
1511 # print "\tmn_ports[] = ", mnPorts
1512 # print "\tonos_ports[] = ", onosPorts
1513 mnPortsLog = mnPorts
1514 onosPortsLog = onosPorts
1515 mnPorts = [ x for x in mnPorts ]
1516 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05001517
Jon Hall7eb38402015-01-08 17:19:54 -08001518 # TODO: handle other reserved port numbers besides LOCAL
1519 # NOTE: Reserved ports
1520 # Local port: -2 in Openflow, ONOS shows 'local', we store as
1521 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 for mnPort in mnPortsLog:
1523 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08001524 # don't set results to true here as this is just one of
1525 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 mnPorts.remove( mnPort )
1527 onosPorts.remove( mnPort )
Jon Hall7eb38402015-01-08 17:19:54 -08001528 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05001529 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08001530 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 if 65534 in mnPorts:
1532 mnPorts.remove( 65534 )
1533 if long( uint64( -2 ) ) in onosPorts:
1534 onosPorts.remove( long( uint64( -2 ) ) )
1535 if len( mnPorts ): # the ports of this switch don't match
1536 switchResult = main.FALSE
1537 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
1538 if len( onosPorts ): # the ports of this switch don't match
1539 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001540 main.log.warn(
1541 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001542 str( onosPorts ) )
1543 if switchResult == main.FALSE:
Jon Hall7eb38402015-01-08 17:19:54 -08001544 main.log.report(
1545 "The list of ports for switch %s(%s) does not match:" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 ( mnSwitch[ 'name' ], mnSwitch[ 'dpid' ] ) )
1547 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
1548 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
1549 portsResults = portsResults and switchResult
1550 return portsResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001551
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 def compareLinks( self, topo, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08001553 """
1554 Compare mn and onos links
1555 topo: sts TestONTopology object
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04001557
Jon Hall7eb38402015-01-08 17:19:54 -08001558 This uses the sts TestONTopology object"""
1559 # FIXME: this does not look for extra links in ONOS, only checks that
1560 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 linkResults = main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001562 output = { "switches": [] }
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 onos = linksJson
Jon Hall7eb38402015-01-08 17:19:54 -08001564 # iterate through the MN topology and pull out switches and and port
1565 # info
1566 for switch in topo.graph.switches:
Jon Hall38481722014-11-04 16:50:05 -05001567 # print "Iterating though switches as seen by Mininet"
1568 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -04001569 ports = []
1570 for port in switch.ports.values():
kelvin-onlab652e1dd2015-01-20 17:01:39 -08001571 # print port.hw_addr.toStr( separator='' )
1572 ports.append( { 'of_port': port.port_no,
1573 'mac': str( port.hw_addr ).replace( '\'',
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 '' ),
Jon Hall7eb38402015-01-08 17:19:54 -08001575 'name': port.name } )
1576 output[ 'switches' ].append( {
1577 "name": switch.name,
1578 "dpid": str( switch.dpid ).zfill( 16 ),
1579 "ports": ports } )
1580 # LINKS
Jon Hall72cf1dc2014-10-20 21:04:50 -04001581
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 mnLinks = [
kelvin-onlab9592d132015-01-20 17:18:02 -08001583 link for link in topo.patch_panel.network_links if (
Jon Hall7eb38402015-01-08 17:19:54 -08001584 link.port1.enabled and link.port2.enabled ) ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 if 2 * len( mnLinks ) == len( onos ):
1586 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001587 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001588 linkResults = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001589 main.log.report(
1590 "Mininet has %i bidirectional links and " +
1591 "ONOS has %i unidirectional links" %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 ( len( mnLinks ), len( onos ) ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001593
Jon Hall7eb38402015-01-08 17:19:54 -08001594 # iterate through MN links and check if an ONOS link exists in
1595 # both directions
1596 # NOTE: Will currently only show mn links as down if they are
1597 # cut through STS. We can either do everything through STS or
kelvin-onlabd3b64892015-01-20 13:26:24 -08001598 # wait for upNetworkLinks and downNetworkLinks to be
Jon Hall7eb38402015-01-08 17:19:54 -08001599 # fully implemented.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08001601 # print "Link: %s" % link
1602 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04001603 node1 = None
1604 port1 = None
1605 node2 = None
1606 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 firstDir = main.FALSE
1608 secondDir = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001609 for switch in output[ 'switches' ]:
1610 # print "Switch: %s" % switch[ 'name' ]
1611 if switch[ 'name' ] == link.node1.name:
1612 node1 = switch[ 'dpid' ]
1613 for port in switch[ 'ports' ]:
1614 if str( port[ 'name' ] ) == str( link.port1 ):
1615 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001616 if node1 is not None and node2 is not None:
1617 break
Jon Hall7eb38402015-01-08 17:19:54 -08001618 if switch[ 'name' ] == link.node2.name:
1619 node2 = switch[ 'dpid' ]
1620 for port in switch[ 'ports' ]:
1621 if str( port[ 'name' ] ) == str( link.port2 ):
1622 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001623 if node1 is not None and node2 is not None:
1624 break
1625
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 for onosLink in onos:
1627 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001628 ":",
1629 '' ).replace(
1630 "of",
1631 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hall7eb38402015-01-08 17:19:54 -08001633 ":",
1634 '' ).replace(
1635 "of",
1636 '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001637 onosPort1 = onosLink[ 'src' ][ 'port' ]
1638 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04001639
Jon Hall72cf1dc2014-10-20 21:04:50 -04001640 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08001641 if str( onosNode1 ) == str( node1 ) and str(
1642 onosNode2 ) == str( node2 ):
1643 if int( onosPort1 ) == int( port1 ) and int(
1644 onosPort2 ) == int( port2 ):
1645 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001646 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001647 main.log.warn(
1648 'The port numbers do not match for ' +
1649 str( link ) +
1650 ' between ONOS and MN. When cheking ONOS for ' +
1651 'link %s/%s -> %s/%s' %
1652 ( node1,
1653 port1,
1654 node2,
1655 port2 ) +
1656 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 ( onosNode1,
1658 onosPort1,
1659 onosNode2,
1660 onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001661
1662 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 elif ( str( onosNode1 ) == str( node2 ) and
1664 str( onosNode2 ) == str( node1 ) ):
1665 if ( int( onosPort1 ) == int( port2 )
1666 and int( onosPort2 ) == int( port1 ) ):
1667 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04001668 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001669 main.log.warn(
1670 'The port numbers do not match for ' +
1671 str( link ) +
1672 ' between ONOS and MN. When cheking ONOS for ' +
1673 'link %s/%s -> %s/%s' %
1674 ( node2,
1675 port2,
1676 node1,
1677 port1 ) +
1678 ' ONOS has the values %s/%s -> %s/%s' %
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 ( onosNode2,
1680 onosPort2,
1681 onosNode1,
1682 onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08001683 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04001684 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 if not firstDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001686 main.log.report(
1687 'ONOS does not have the link %s/%s -> %s/%s' %
1688 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 if not secondDir:
Jon Hall7eb38402015-01-08 17:19:54 -08001690 main.log.report(
1691 'ONOS does not have the link %s/%s -> %s/%s' %
1692 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001693 linkResults = linkResults and firstDir and secondDir
1694 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04001695
kelvin-onlabd3b64892015-01-20 13:26:24 -08001696 def getHosts( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08001697 """
1698 Returns a list of all hosts
1699 Don't ask questions just use it"""
1700 self.handle.sendline( "" )
1701 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04001702
Jon Hall7eb38402015-01-08 17:19:54 -08001703 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
1704 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001705
kelvin-onlabd3b64892015-01-20 13:26:24 -08001706 handlePy = self.handle.before
1707 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
1708 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001709
Jon Hall7eb38402015-01-08 17:19:54 -08001710 self.handle.sendline( "" )
1711 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001712
kelvin-onlabd3b64892015-01-20 13:26:24 -08001713 hostStr = handlePy.replace( "]", "" )
1714 hostStr = hostStr.replace( "'", "" )
1715 hostStr = hostStr.replace( "[", "" )
1716 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001717
kelvin-onlabd3b64892015-01-20 13:26:24 -08001718 return hostList
adminbae64d82013-08-01 10:50:15 -07001719
Jon Hall7eb38402015-01-08 17:19:54 -08001720 def update( self ):
1721 """
1722 updates the port address and status information for
1723 each port in mn"""
1724 # TODO: Add error checking. currently the mininet command has no output
1725 main.log.info( "Updateing MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05001726 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001727 self.handle.sendline( "" )
1728 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001729
Jon Hall7eb38402015-01-08 17:19:54 -08001730 self.handle.sendline( "update" )
1731 self.handle.expect( "update" )
1732 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001733
Jon Hall7eb38402015-01-08 17:19:54 -08001734 self.handle.sendline( "" )
1735 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05001736
Jon Hallb1290e82014-11-18 16:17:48 -05001737 return main.TRUE
1738 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001739 main.log.error( self.name + ": EOF exception found" )
1740 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001741 main.cleanup()
1742 main.exit()
1743
adminbae64d82013-08-01 10:50:15 -07001744if __name__ != "__main__":
1745 import sys
Jon Hall7eb38402015-01-08 17:19:54 -08001746 sys.modules[ __name__ ] = MininetCliDriver()