blob: d4900ad35ee58740566a90f2bcb816f08a393bfe [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import sys
andrewonlab95ce8322014-10-13 14:12:04 -040020import pexpect
21import re
pingping-lin763ee042015-05-20 17:45:30 -070022import json
23import types
24import time
kelvin8ec71442015-01-15 16:57:00 -080025sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040026from drivers.common.clidriver import CLI
27
andrewonlab95ce8322014-10-13 14:12:04 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
pingping-lin763ee042015-05-20 17:45:30 -070035 self.name = None
36 self.home = None
37 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080038 super( CLI, self ).__init__()
39
40 def connect( self, **connectargs ):
41 """
andrewonlab95ce8322014-10-13 14:12:04 -040042 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080043 """
andrewonlab95ce8322014-10-13 14:12:04 -040044 try:
45 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080046 vars( self )[ key ] = connectargs[ key ]
pingping-lin763ee042015-05-20 17:45:30 -070047 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040048 for key in self.options:
49 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080050 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040051 break
pingping-lin763ee042015-05-20 17:45:30 -070052 if self.home is None or self.home == "":
53 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054
kelvin8ec71442015-01-15 16:57:00 -080055 self.name = self.options[ 'name' ]
56 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 user_name=self.user_name,
58 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080059 port=self.port,
60 pwd=self.pwd,
61 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040062
kelvin8ec71442015-01-15 16:57:00 -080063 self.handle.sendline( "cd " + self.home )
64 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040065 if self.handle:
66 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080067 else:
68 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040069 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -070070 except TypeError:
71 main.log.exception( self.name + ": Object not as expected" )
72 return None
andrewonlab95ce8322014-10-13 14:12:04 -040073 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080074 main.log.error( self.name + ": EOF exception found" )
75 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040076 main.cleanup()
77 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -070078 except Exception:
79 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040080 main.cleanup()
81 main.exit()
82
kelvin8ec71442015-01-15 16:57:00 -080083 def disconnect( self ):
84 """
andrewonlab95ce8322014-10-13 14:12:04 -040085 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080086 """
pingping-lin763ee042015-05-20 17:45:30 -070087 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040088 try:
pingping-lin763ee042015-05-20 17:45:30 -070089 if self.handle:
90 i = self.logout()
91 if i == main.TRUE:
92 self.handle.sendline( "" )
93 self.handle.expect( "\$" )
94 self.handle.sendline( "exit" )
95 self.handle.expect( "closed" )
96 except TypeError:
97 main.log.exception( self.name + ": Object not as expected" )
98 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800100 main.log.error( self.name + ": EOF exception found" )
101 main.log.error( self.name + ": " + self.handle.before )
pingping-lin763ee042015-05-20 17:45:30 -0700102 except ValueError:
103 main.log.exception( "Exception in disconnect of " + self.name )
104 response = main.TRUE
105 except Exception:
106 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 response = main.FALSE
108 return response
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def logout( self ):
111 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500112 Sends 'logout' command to ONOS cli
pingping-lin763ee042015-05-20 17:45:30 -0700113 Returns main.TRUE if exited CLI and
114 main.FALSE on timeout (not guranteed you are disconnected)
115 None on TypeError
116 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800117 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500118 try:
pingping-lin763ee042015-05-20 17:45:30 -0700119 if self.handle:
120 self.handle.sendline( "" )
121 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
122 timeout=10 )
123 if i == 0: # In ONOS CLI
124 self.handle.sendline( "logout" )
125 self.handle.expect( "\$" )
126 return main.TRUE
127 elif i == 1: # not in CLI
128 return main.TRUE
129 elif i == 3: # Timeout
130 return main.FALSE
131 else:
andrewonlab9627f432014-11-14 12:45:10 -0500132 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700133 except TypeError:
134 main.log.exception( self.name + ": Object not as expected" )
135 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800137 main.log.error( self.name + ": eof exception found" )
pingping-lin763ee042015-05-20 17:45:30 -0700138 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 main.cleanup()
140 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700141 except ValueError:
142 main.log.error( self.name +
143 "ValueError exception in logout method" )
144 except Exception:
145 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500146 main.cleanup()
147 main.exit()
148
kelvin-onlabd3b64892015-01-20 13:26:24 -0800149 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800150 """
andrewonlab95ce8322014-10-13 14:12:04 -0400151 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800152
andrewonlab95ce8322014-10-13 14:12:04 -0400153 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800154 """
andrewonlab95ce8322014-10-13 14:12:04 -0400155 try:
156 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400158 main.cleanup()
159 main.exit()
160 else:
kelvin8ec71442015-01-15 16:57:00 -0800161 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800162 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800163 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400164 # and that this driver will have to change accordingly
pingping-lin763ee042015-05-20 17:45:30 -0700165 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800166 handleBefore = self.handle.before
167 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800168 # Get the rest of the handle
pingping-lin763ee042015-05-20 17:45:30 -0700169 self.handle.sendline("")
170 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800171 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400172
kelvin-onlabd3b64892015-01-20 13:26:24 -0800173 main.log.info( "Cell call returned: " + handleBefore +
174 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400175
176 return main.TRUE
177
pingping-lin763ee042015-05-20 17:45:30 -0700178 except TypeError:
179 main.log.exception( self.name + ": Object not as expected" )
180 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400181 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800182 main.log.error( self.name + ": eof exception found" )
183 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400184 main.cleanup()
185 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700186 except Exception:
187 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400188 main.cleanup()
189 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800190
pingping-lin57a56ce2015-05-20 16:43:48 -0700191 def startOnosCli( self, ONOSIp, karafTimeout="",
192 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800193 """
pingping-lin763ee042015-05-20 17:45:30 -0700194 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 by user would be used to set the current karaf shell idle timeout.
196 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800197 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 Below is an example to start a session with 60 seconds idle timeout
199 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800200
Hari Krishna25d42f72015-01-05 15:08:28 -0800201 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800202 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800203
kelvin-onlabd3b64892015-01-20 13:26:24 -0800204 Note: karafTimeout is left as str so that this could be read
205 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800206 """
andrewonlab95ce8322014-10-13 14:12:04 -0400207 try:
kelvin8ec71442015-01-15 16:57:00 -0800208 self.handle.sendline( "" )
209 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700210 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500211
212 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800213 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500214 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400215
kelvin8ec71442015-01-15 16:57:00 -0800216 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800218 i = self.handle.expect( [
219 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700220 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400221
222 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800224 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800225 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800226 "config:property-set -p org.apache.karaf.shell\
227 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800228 karafTimeout )
229 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800230 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800231 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400232 return main.TRUE
233 else:
kelvin8ec71442015-01-15 16:57:00 -0800234 # If failed, send ctrl+c to process and try again
235 main.log.info( "Starting CLI failed. Retrying..." )
236 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800238 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
239 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400240 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800242 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800243 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800244 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 "config:property-set -p org.apache.karaf.shell\
246 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800247 karafTimeout )
248 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800250 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400251 return main.TRUE
252 else:
kelvin8ec71442015-01-15 16:57:00 -0800253 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400255 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400256
pingping-lin763ee042015-05-20 17:45:30 -0700257 except TypeError:
258 main.log.exception( self.name + ": Object not as expected" )
259 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400260 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800261 main.log.error( self.name + ": EOF exception found" )
262 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400263 main.cleanup()
264 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700265 except Exception:
266 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400267 main.cleanup()
268 main.exit()
269
pingping-lin763ee042015-05-20 17:45:30 -0700270 def log( self, cmdStr, level="" ):
271 """
272 log the commands in the onos CLI.
273 returns main.TRUE on success
274 returns main.FALSE if Error occurred
275 Available level: DEBUG, TRACE, INFO, WARN, ERROR
276 Level defaults to INFO
277 """
278 try:
279 lvlStr = ""
280 if level:
281 lvlStr = "--level=" + level
282
283 self.handle.sendline( "" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700284 i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700285 if i == 1:
Jon Hallc9eabec2015-06-10 14:33:14 -0700286 main.log.error( self.name + ": onos cli session closed." )
287 main.cleanup()
288 main.exit()
289 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700290 self.handle.sendline( "" )
291 self.handle.expect( "onos>" )
pingping-lin763ee042015-05-20 17:45:30 -0700292 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
293 self.handle.expect( "log:log" )
294 self.handle.expect( "onos>" )
295
296 response = self.handle.before
297 if re.search( "Error", response ):
298 return main.FALSE
299 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700300 except pexpect.TIMEOUT:
301 main.log.exception( self.name + ": TIMEOUT exception found" )
302 main.cleanup()
303 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700304 except pexpect.EOF:
305 main.log.error( self.name + ": EOF exception found" )
306 main.log.error( self.name + ": " + self.handle.before )
307 main.cleanup()
308 main.exit()
309 except Exception:
310 main.log.exception( self.name + ": Uncaught exception!" )
311 main.cleanup()
312 main.exit()
313
314 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800315 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800316 Send a completely user specified string to
317 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400318 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800319
andrewonlaba18f6bf2014-10-13 19:31:54 -0400320 Warning: There are no sanity checking to commands
321 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800322 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400323 try:
pingping-lin763ee042015-05-20 17:45:30 -0700324 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
325 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 self.handle.sendline( cmdStr )
pingping-lin763ee042015-05-20 17:45:30 -0700327 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
328 response = self.handle.before
329 if i == 2:
330 self.handle.sendline()
331 self.handle.expect( ["\$", pexpect.TIMEOUT] )
332 response += self.handle.before
333 print response
334 try:
335 print self.handle.after
336 except TypeError:
337 pass
338 # TODO: do something with i
Jon Hallaea67aa2015-01-23 13:30:57 -0800339 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
340 + self.name + "." )
pingping-lin763ee042015-05-20 17:45:30 -0700341 if debug:
342 main.log.debug( self.name + ": Raw output" )
343 main.log.debug( self.name + ": " + repr( response ) )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400344
pingping-lin763ee042015-05-20 17:45:30 -0700345 # Remove ANSI color control strings from output
Jon Hall7bdfc122015-01-23 11:45:32 -0800346 ansiEscape = re.compile( r'\x1b[^m]*m' )
pingping-lin763ee042015-05-20 17:45:30 -0700347 response = ansiEscape.sub( '', response )
348 if debug:
349 main.log.debug( self.name + ": ansiEscape output" )
350 main.log.debug( self.name + ": " + repr( response ) )
kelvin8ec71442015-01-15 16:57:00 -0800351
pingping-lin763ee042015-05-20 17:45:30 -0700352 # Remove extra return chars that get added
353 response = re.sub( r"\s\r", "", response )
354 if debug:
355 main.log.debug( self.name + ": Removed extra returns " +
356 "from output" )
357 main.log.debug( self.name + ": " + repr( response ) )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400358
pingping-lin763ee042015-05-20 17:45:30 -0700359 # Strip excess whitespace
360 response = response.strip()
361 if debug:
362 main.log.debug( self.name + ": parsed and stripped output" )
363 main.log.debug( self.name + ": " + repr( response ) )
364
365 # parse for just the output, remove the cmd from response
366 output = response.split( cmdStr.strip(), 1 )
367 if debug:
368 main.log.debug( self.name + ": split output" )
369 for r in output:
370 main.log.debug( self.name + ": " + repr( r ) )
371 return output[1].strip()
372 except IndexError:
373 main.log.exception( self.name + ": Object not as expected" )
374 return None
375 except TypeError:
376 main.log.exception( self.name + ": Object not as expected" )
377 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400378 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800379 main.log.error( self.name + ": EOF exception found" )
380 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400381 main.cleanup()
382 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700383 except Exception:
384 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400385 main.cleanup()
386 main.exit()
387
kelvin8ec71442015-01-15 16:57:00 -0800388 # IMPORTANT NOTE:
389 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800390 # the cli command changing 'a:b' with 'aB'.
391 # Ex ) onos:topology > onosTopology
392 # onos:links > onosLinks
393 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800394
kelvin-onlabd3b64892015-01-20 13:26:24 -0800395 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800396 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400397 Adds a new cluster node by ID and address information.
398 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800399 * nodeId
400 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400401 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800403 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400404 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800405 cmdStr = "add-node " + str( nodeId ) + " " +\
406 str( ONOSIp ) + " " + str( tcpPort )
407 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800408 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800409 main.log.error( "Error in adding node" )
410 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800411 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400412 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800413 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400414 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700415 except TypeError:
416 main.log.exception( self.name + ": Object not as expected" )
417 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 main.cleanup()
422 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700423 except Exception:
424 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400425 main.cleanup()
426 main.exit()
427
kelvin-onlabd3b64892015-01-20 13:26:24 -0800428 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800429 """
andrewonlab86dc3082014-10-13 18:18:38 -0400430 Removes a cluster by ID
431 Issues command: 'remove-node [<node-id>]'
432 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800434 """
andrewonlab86dc3082014-10-13 18:18:38 -0400435 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400436
kelvin-onlabd3b64892015-01-20 13:26:24 -0800437 cmdStr = "remove-node " + str( nodeId )
pingping-lin763ee042015-05-20 17:45:30 -0700438 handle = self.sendline( cmdStr )
439 if re.search( "Error", handle ):
440 main.log.error( "Error in removing node" )
441 main.log.error( handle )
442 return main.FALSE
443 else:
444 return main.TRUE
445 except TypeError:
446 main.log.exception( self.name + ": Object not as expected" )
447 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800449 main.log.error( self.name + ": EOF exception found" )
450 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400451 main.cleanup()
452 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700453 except Exception:
454 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400455 main.cleanup()
456 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400457
pingping-lin763ee042015-05-20 17:45:30 -0700458 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800459 """
andrewonlab7c211572014-10-15 16:45:20 -0400460 List the nodes currently visible
461 Issues command: 'nodes'
pingping-lin763ee042015-05-20 17:45:30 -0700462 Optional argument:
463 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800464 """
andrewonlab7c211572014-10-15 16:45:20 -0400465 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800466 cmdStr = "nodes"
pingping-lin763ee042015-05-20 17:45:30 -0700467 if jsonFormat:
468 cmdStr += " -j"
469 output = self.sendline( cmdStr )
470 return output
471 except TypeError:
472 main.log.exception( self.name + ": Object not as expected" )
473 return None
andrewonlab7c211572014-10-15 16:45:20 -0400474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800475 main.log.error( self.name + ": EOF exception found" )
476 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400477 main.cleanup()
478 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700479 except Exception:
480 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400481 main.cleanup()
482 main.exit()
483
kelvin8ec71442015-01-15 16:57:00 -0800484 def topology( self ):
485 """
pingping-lin763ee042015-05-20 17:45:30 -0700486 Definition:
487 Returns the output of topology command.
488 Return:
489 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800490 """
andrewonlab95ce8322014-10-13 14:12:04 -0400491 try:
pingping-lin763ee042015-05-20 17:45:30 -0700492 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800493 handle = self.sendline( cmdStr )
pingping-lin763ee042015-05-20 17:45:30 -0700494 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400495 return handle
pingping-lin763ee042015-05-20 17:45:30 -0700496 except TypeError:
497 main.log.exception( self.name + ": Object not as expected" )
498 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800500 main.log.error( self.name + ": EOF exception found" )
501 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400502 main.cleanup()
503 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700504 except Exception:
505 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400506 main.cleanup()
507 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800508
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800510 """
pingping-lin763ee042015-05-20 17:45:30 -0700511 Installs a specified feature by issuing command:
512 'feature:install <feature_str>'
513 NOTE: This is now deprecated, you should use the activateApp method
514 instead
kelvin8ec71442015-01-15 16:57:00 -0800515 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400516 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 cmdStr = "feature:install " + str( featureStr )
pingping-lin763ee042015-05-20 17:45:30 -0700518 handle = self.sendline( cmdStr )
519 if re.search( "Error", handle ):
520 main.log.error( "Error in installing feature" )
521 main.log.error( handle )
522 return main.FALSE
523 else:
524 return main.TRUE
525 except TypeError:
526 main.log.exception( self.name + ": Object not as expected" )
527 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800529 main.log.error( self.name + ": EOF exception found" )
530 main.log.error( self.name + ": " + self.handle.before )
531 main.log.report( "Failed to install feature" )
532 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400533 main.cleanup()
534 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700535 except Exception:
536 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800537 main.log.report( "Failed to install feature" )
538 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400539 main.cleanup()
540 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800541
kelvin-onlabd3b64892015-01-20 13:26:24 -0800542 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800543 """
pingping-lin763ee042015-05-20 17:45:30 -0700544 Uninstalls a specified feature by issuing command:
545 'feature:uninstall <feature_str>'
546 NOTE: This is now deprecated, you should use the deactivateApp method
547 instead
kelvin8ec71442015-01-15 16:57:00 -0800548 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 try:
pingping-lin763ee042015-05-20 17:45:30 -0700550 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
551 handle = self.sendline( cmdStr )
552 if handle != '':
553 cmdStr = "feature:uninstall " + str( featureStr )
554 output = self.sendline( cmdStr )
555 # TODO: Check for possible error responses from karaf
556 else:
557 main.log.info( "Feature needs to be installed before " +
558 "uninstalling it" )
559 return main.TRUE
560 if re.search( "Error", output ):
561 main.log.error( "Error in uninstalling feature" )
562 main.log.error( output )
563 return main.FALSE
564 else:
565 return main.TRUE
566 except TypeError:
567 main.log.exception( self.name + ": Object not as expected" )
568 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800570 main.log.error( self.name + ": EOF exception found" )
571 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 main.cleanup()
573 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700574 except Exception:
575 main.log.exception( self.name + ": Uncaught exception!" )
576 main.cleanup()
577 main.exit()
578
579 def deviceRemove( self, deviceId ):
580 """
581 Removes particular device from storage
582
583 TODO: refactor this function
584 """
585 try:
586 cmdStr = "device-remove " + str( deviceId )
587 handle = self.sendline( cmdStr )
588 if re.search( "Error", handle ):
589 main.log.error( "Error in removing device" )
590 main.log.error( handle )
591 return main.FALSE
592 else:
593 return main.TRUE
594 except TypeError:
595 main.log.exception( self.name + ": Object not as expected" )
596 return None
597 except pexpect.EOF:
598 main.log.error( self.name + ": EOF exception found" )
599 main.log.error( self.name + ": " + self.handle.before )
600 main.cleanup()
601 main.exit()
602 except Exception:
603 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400604 main.cleanup()
605 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800606
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800608 """
Jon Hall7b02d952014-10-17 20:14:54 -0400609 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400610 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800612 """
andrewonlab86dc3082014-10-13 18:18:38 -0400613 try:
pingping-lin763ee042015-05-20 17:45:30 -0700614 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700616 cmdStr += " -j"
617 handle = self.sendline( cmdStr )
618 return handle
619 except TypeError:
620 main.log.exception( self.name + ": Object not as expected" )
621 return None
andrewonlab7c211572014-10-15 16:45:20 -0400622 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800623 main.log.error( self.name + ": EOF exception found" )
624 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400625 main.cleanup()
626 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700627 except Exception:
628 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400629 main.cleanup()
630 main.exit()
631
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800633 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800634 This balances the devices across all controllers
635 by issuing command: 'onos> onos:balance-masters'
636 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800637 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800638 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 cmdStr = "onos:balance-masters"
pingping-lin763ee042015-05-20 17:45:30 -0700640 handle = self.sendline( cmdStr )
641 if re.search( "Error", handle ):
642 main.log.error( "Error in balancing masters" )
643 main.log.error( handle )
644 return main.FALSE
645 else:
646 return main.TRUE
647 except TypeError:
648 main.log.exception( self.name + ": Object not as expected" )
649 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800650 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800651 main.log.error( self.name + ": EOF exception found" )
652 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800653 main.cleanup()
654 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700655 except Exception:
656 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800657 main.cleanup()
658 main.exit()
659
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800661 """
Jon Halle8217482014-10-17 13:49:14 -0400662 Lists all core links
663 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800665 """
Jon Halle8217482014-10-17 13:49:14 -0400666 try:
pingping-lin763ee042015-05-20 17:45:30 -0700667 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700669 cmdStr += " -j"
670 handle = self.sendline( cmdStr )
671 return handle
672 except TypeError:
673 main.log.exception( self.name + ": Object not as expected" )
674 return None
Jon Halle8217482014-10-17 13:49:14 -0400675 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800676 main.log.error( self.name + ": EOF exception found" )
677 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400678 main.cleanup()
679 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700680 except Exception:
681 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400682 main.cleanup()
683 main.exit()
684
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800686 """
Jon Halle8217482014-10-17 13:49:14 -0400687 Lists all ports
688 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800690 """
Jon Halle8217482014-10-17 13:49:14 -0400691 try:
pingping-lin763ee042015-05-20 17:45:30 -0700692 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700694 cmdStr += " -j"
695 handle = self.sendline( cmdStr )
696 return handle
697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
Jon Halle8217482014-10-17 13:49:14 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400703 main.cleanup()
704 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700705 except Exception:
706 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400707 main.cleanup()
708 main.exit()
709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800711 """
Jon Hall983a1702014-10-28 18:44:22 -0400712 Lists all devices and the controllers with roles assigned to them
713 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800715 """
andrewonlab7c211572014-10-15 16:45:20 -0400716 try:
pingping-lin763ee042015-05-20 17:45:30 -0700717 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700719 cmdStr += " -j"
720 handle = self.sendline( cmdStr )
721 return handle
722 except TypeError:
723 main.log.exception( self.name + ": Object not as expected" )
724 return None
Jon Hall983a1702014-10-28 18:44:22 -0400725 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800726 main.log.error( self.name + ": EOF exception found" )
727 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400728 main.cleanup()
729 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700730 except Exception:
731 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400732 main.cleanup()
733 main.exit()
734
kelvin-onlabd3b64892015-01-20 13:26:24 -0800735 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800736 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800737 Given the a string containing the json representation of the "roles"
738 cli command and a partial or whole device id, returns a json object
739 containing the roles output for the first device whose id contains
740 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400741
742 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800743 A dict of the role assignments for the given device or
744 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800745 """
Jon Hall983a1702014-10-28 18:44:22 -0400746 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400748 return None
749 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 rawRoles = self.roles()
751 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800752 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800754 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400756 return device
757 return None
pingping-lin763ee042015-05-20 17:45:30 -0700758 except TypeError:
759 main.log.exception( self.name + ": Object not as expected" )
760 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400764 main.cleanup()
765 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700766 except Exception:
767 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400768 main.cleanup()
769 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800770
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Jon Hall94fd0472014-12-08 11:52:42 -0800773 Iterates through each device and checks if there is a master assigned
774 Returns: main.TRUE if each device has a master
775 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800776 """
Jon Hall94fd0472014-12-08 11:52:42 -0800777 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 rawRoles = self.roles()
779 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800780 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800782 # print device
783 if device[ 'master' ] == "none":
784 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800785 return main.FALSE
786 return main.TRUE
787
pingping-lin763ee042015-05-20 17:45:30 -0700788 except TypeError:
789 main.log.exception( self.name + ": Object not as expected" )
790 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800792 main.log.error( self.name + ": EOF exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800794 main.cleanup()
795 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700796 except Exception:
797 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800798 main.cleanup()
799 main.exit()
800
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400803 Returns string of paths, and the cost.
804 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800805 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400806 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
808 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800809 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800810 main.log.error( "Error in getting paths" )
811 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400812 else:
kelvin8ec71442015-01-15 16:57:00 -0800813 path = handle.split( ";" )[ 0 ]
814 cost = handle.split( ";" )[ 1 ]
815 return ( path, cost )
pingping-lin763ee042015-05-20 17:45:30 -0700816 except TypeError:
817 main.log.exception( self.name + ": Object not as expected" )
818 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400819 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800820 main.log.error( self.name + ": EOF exception found" )
821 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400822 main.cleanup()
823 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700824 except Exception:
825 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400826 main.cleanup()
827 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800828
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800830 """
Jon Hallffb386d2014-11-21 13:43:38 -0800831 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400832 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800833 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800834 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400835 try:
pingping-lin763ee042015-05-20 17:45:30 -0700836 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700838 cmdStr += " -j"
839 handle = self.sendline( cmdStr )
840 return handle
841 except TypeError:
842 main.log.exception( self.name + ": Object not as expected" )
843 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400844 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800845 main.log.error( self.name + ": EOF exception found" )
846 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400847 main.cleanup()
848 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700849 except Exception:
850 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400851 main.cleanup()
852 main.exit()
853
kelvin-onlabd3b64892015-01-20 13:26:24 -0800854 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800855 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400856 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800857
pingping-lin763ee042015-05-20 17:45:30 -0700858 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800859 partial mac address
860
Jon Hall42db6dc2014-10-24 19:03:48 -0400861 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800862 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400863 try:
kelvin8ec71442015-01-15 16:57:00 -0800864 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400865 return None
866 else:
867 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 rawHosts = self.hosts()
869 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800870 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800872 # print "%s in %s?" % ( mac, host[ 'id' ] )
pingping-lin763ee042015-05-20 17:45:30 -0700873 if not host:
874 pass
875 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400876 return host
877 return None
pingping-lin763ee042015-05-20 17:45:30 -0700878 except TypeError:
879 main.log.exception( self.name + ": Object not as expected" )
880 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400881 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800882 main.log.error( self.name + ": EOF exception found" )
883 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400884 main.cleanup()
885 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700886 except Exception:
887 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400888 main.cleanup()
889 main.exit()
890
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800892 """
893 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400894 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800895
andrewonlab3f0a4af2014-10-17 12:25:14 -0400896 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400898 IMPORTANT:
899 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800900 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400901 Furthermore, it assumes that value of VLAN is '-1'
902 Description:
kelvin8ec71442015-01-15 16:57:00 -0800903 Converts mininet hosts ( h1, h2, h3... ) into
904 ONOS format ( 00:00:00:00:00:01/-1 , ... )
905 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400906 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800910 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 hostHex = hex( int( host ) ).zfill( 12 )
912 hostHex = str( hostHex ).replace( 'x', '0' )
913 i = iter( str( hostHex ) )
914 hostHex = ":".join( a + b for a, b in zip( i, i ) )
915 hostHex = hostHex + "/-1"
916 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400917
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400919
pingping-lin763ee042015-05-20 17:45:30 -0700920 except TypeError:
921 main.log.exception( self.name + ": Object not as expected" )
922 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400923 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800924 main.log.error( self.name + ": EOF exception found" )
925 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400926 main.cleanup()
927 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700928 except Exception:
929 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400930 main.cleanup()
931 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400932
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800934 """
andrewonlabe6745342014-10-17 14:29:13 -0400935 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800936 * hostIdOne: ONOS host id for host1
937 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400938 Description:
pingping-lin763ee042015-05-20 17:45:30 -0700939 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500940 specifying the two hosts.
pingping-lin763ee042015-05-20 17:45:30 -0700941 Returns:
942 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800943 """
andrewonlabe6745342014-10-17 14:29:13 -0400944 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800945 cmdStr = "add-host-intent " + str( hostIdOne ) +\
946 " " + str( hostIdTwo )
947 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800948 if re.search( "Error", handle ):
949 main.log.error( "Error in adding Host intent" )
pingping-lin763ee042015-05-20 17:45:30 -0700950 main.log.debug( "Response from ONOS was: " + repr( handle ) )
951 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800952 else:
953 main.log.info( "Host intent installed between " +
pingping-lin763ee042015-05-20 17:45:30 -0700954 str( hostIdOne ) + " and " + str( hostIdTwo ) )
955 match = re.search('id=0x([\da-f]+),', handle)
956 if match:
957 return match.group()[3:-1]
958 else:
959 main.log.error( "Error, intent ID not found" )
960 main.log.debug( "Response from ONOS was: " +
961 repr( handle ) )
962 return None
963 except TypeError:
964 main.log.exception( self.name + ": Object not as expected" )
965 return None
andrewonlabe6745342014-10-17 14:29:13 -0400966 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800967 main.log.error( self.name + ": EOF exception found" )
968 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400969 main.cleanup()
970 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700971 except Exception:
972 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400973 main.cleanup()
974 main.exit()
975
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800977 """
andrewonlab7b31d232014-10-24 13:31:47 -0400978 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 * ingressDevice: device id of ingress device
980 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400981 Optional:
982 TODO: Still needs to be implemented via dev side
pingping-lin763ee042015-05-20 17:45:30 -0700983 Description:
984 Adds an optical intent by specifying an ingress and egress device
985 Returns:
986 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800987 """
andrewonlab7b31d232014-10-24 13:31:47 -0400988 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
990 " " + str( egressDevice )
991 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800992 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800993 if re.search( "Error", handle ):
pingping-lin763ee042015-05-20 17:45:30 -0700994 main.log.error( "Error in adding Optical intent" )
995 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400996 else:
pingping-lin763ee042015-05-20 17:45:30 -0700997 main.log.info( "Optical intent installed between " +
998 str( ingressDevice ) + " and " +
999 str( egressDevice ) )
1000 match = re.search('id=0x([\da-f]+),', handle)
1001 if match:
1002 return match.group()[3:-1]
1003 else:
1004 main.log.error( "Error, intent ID not found" )
1005 return None
1006 except TypeError:
1007 main.log.exception( self.name + ": Object not as expected" )
1008 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001012 main.cleanup()
1013 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001014 except Exception:
1015 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001016 main.cleanup()
1017 main.exit()
1018
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001020 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 ingressDevice,
1022 egressDevice,
1023 portIngress="",
1024 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001025 ethType="",
1026 ethSrc="",
1027 ethDst="",
1028 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001030 ipProto="",
1031 ipSrc="",
1032 ipDst="",
1033 tcpSrc="",
1034 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001036 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 * ingressDevice: device id of ingress device
1038 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001039 Optional:
1040 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001041 * ethSrc: specify ethSrc ( i.e. src mac addr )
1042 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001043 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001045 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001046 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001047 * ipSrc: specify ip source address
1048 * ipDst: specify ip destination address
1049 * tcpSrc: specify tcp source port
1050 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001051 Description:
kelvin8ec71442015-01-15 16:57:00 -08001052 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001053 specifying device id's and optional fields
pingping-lin763ee042015-05-20 17:45:30 -07001054 Returns:
1055 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001056
Jon Halle3f39ff2015-01-13 11:50:53 -08001057 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001058 options developers provide for point-to-point
1059 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001060 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001061 try:
kelvin8ec71442015-01-15 16:57:00 -08001062 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001063 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001065 and not ipProto and not ipSrc and not ipDst \
1066 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001067 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001068
andrewonlab289e4b72014-10-21 21:24:18 -04001069 else:
andrewonlab36af3822014-11-18 17:48:18 -05001070 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001071
andrewonlab0c0a6772014-10-22 12:31:18 -04001072 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001073 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001074 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001075 cmd += " --ethSrc " + str( ethSrc )
1076 if ethDst:
1077 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001078 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001079 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001081 cmd += " --lambda "
1082 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001083 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001084 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001085 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001086 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001087 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001088 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001089 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001090 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001091 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001092
kelvin8ec71442015-01-15 16:57:00 -08001093 # Check whether the user appended the port
1094 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 if "/" in ingressDevice:
1096 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001097 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 if not portIngress:
pingping-lin763ee042015-05-20 17:45:30 -07001099 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001100 # TODO: perhaps more meaningful return
pingping-lin763ee042015-05-20 17:45:30 -07001101 # Would it make sense to throw an exception and exit
1102 # the test?
1103 return None
andrewonlab36af3822014-11-18 17:48:18 -05001104
kelvin8ec71442015-01-15 16:57:00 -08001105 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 str( ingressDevice ) + "/" +\
1107 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 if "/" in egressDevice:
1110 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001111 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001112 if not portEgress:
pingping-lin763ee042015-05-20 17:45:30 -07001113 main.log.error( "You must specify the egress port" )
1114 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001115
kelvin8ec71442015-01-15 16:57:00 -08001116 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 str( egressDevice ) + "/" +\
1118 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001119
kelvin-onlab898a6c62015-01-16 14:13:53 -08001120 handle = self.sendline( cmd )
pingping-lin763ee042015-05-20 17:45:30 -07001121 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001122 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001123 main.log.error( "Error in adding point-to-point intent" )
pingping-lin763ee042015-05-20 17:45:30 -07001124 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001125 else:
pingping-lin763ee042015-05-20 17:45:30 -07001126 # TODO: print out all the options in this message?
1127 main.log.info( "Point-to-point intent installed between " +
1128 str( ingressDevice ) + " and " +
1129 str( egressDevice ) )
1130 match = re.search('id=0x([\da-f]+),', handle)
1131 if match:
1132 return match.group()[3:-1]
1133 else:
1134 main.log.error( "Error, intent ID not found" )
1135 return None
1136 except TypeError:
1137 main.log.exception( self.name + ": Object not as expected" )
1138 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001139 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001140 main.log.error( self.name + ": EOF exception found" )
1141 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001142 main.cleanup()
1143 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001144 except Exception:
1145 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001146 main.cleanup()
1147 main.exit()
1148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001150 self,
pingping-lin763ee042015-05-20 17:45:30 -07001151 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001152 egressDevice,
pingping-lin763ee042015-05-20 17:45:30 -07001153 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001155 ethType="",
1156 ethSrc="",
1157 ethDst="",
1158 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001160 ipProto="",
1161 ipSrc="",
1162 ipDst="",
1163 tcpSrc="",
1164 tcpDst="",
1165 setEthSrc="",
1166 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001167 """
shahshreyad0c80432014-12-04 16:56:05 -08001168 Note:
pingping-lin763ee042015-05-20 17:45:30 -07001169 This function assumes the format of all ingress devices
1170 is same. That is, all ingress devices include port numbers
1171 with a "/" or all ingress devices could specify device
1172 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001173 Required:
pingping-lin763ee042015-05-20 17:45:30 -07001174 * ingressDeviceList: List of device ids of ingress device
1175 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001177 Optional:
1178 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001179 * ethSrc: specify ethSrc ( i.e. src mac addr )
1180 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001181 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001183 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001184 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001185 * ipSrc: specify ip source address
1186 * ipDst: specify ip destination address
1187 * tcpSrc: specify tcp source port
1188 * tcpDst: specify tcp destination port
1189 * setEthSrc: action to Rewrite Source MAC Address
1190 * setEthDst: action to Rewrite Destination MAC Address
1191 Description:
kelvin8ec71442015-01-15 16:57:00 -08001192 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001193 specifying device id's and optional fields
pingping-lin763ee042015-05-20 17:45:30 -07001194 Returns:
1195 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001196
Jon Halle3f39ff2015-01-13 11:50:53 -08001197 NOTE: This function may change depending on the
pingping-lin763ee042015-05-20 17:45:30 -07001198 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001199 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001200 """
shahshreyad0c80432014-12-04 16:56:05 -08001201 try:
kelvin8ec71442015-01-15 16:57:00 -08001202 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001203 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001204 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001205 and not ipProto and not ipSrc and not ipDst\
1206 and not tcpSrc and not tcpDst and not setEthSrc\
1207 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001208 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001209
1210 else:
1211 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001212
shahshreyad0c80432014-12-04 16:56:05 -08001213 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001214 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001215 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " --ethSrc " + str( ethSrc )
1217 if ethDst:
1218 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001219 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001220 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001222 cmd += " --lambda "
1223 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001224 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001225 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001226 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001227 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001228 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001229 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001230 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001231 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001232 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001233 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001234 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001235 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001236 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001237
kelvin8ec71442015-01-15 16:57:00 -08001238 # Check whether the user appended the port
1239 # or provided it as an input
pingping-lin763ee042015-05-20 17:45:30 -07001240
1241 if portIngressList is None:
1242 for ingressDevice in ingressDeviceList:
1243 if "/" in ingressDevice:
1244 cmd += " " + str( ingressDevice )
1245 else:
1246 main.log.error( "You must specify " +
1247 "the ingress port" )
1248 # TODO: perhaps more meaningful return
1249 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001250 else:
pingping-lin763ee042015-05-20 17:45:30 -07001251 if len( ingressDeviceList ) == len( portIngressList ):
1252 for ingressDevice, portIngress in zip( ingressDeviceList,
1253 portIngressList ):
1254 cmd += " " + \
1255 str( ingressDevice ) + "/" +\
1256 str( portIngress ) + " "
1257 else:
1258 main.log.error( "Device list and port list does not " +
1259 "have the same length" )
shahshreyad0c80432014-12-04 16:56:05 -08001260 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 if "/" in egressDevice:
1262 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001263 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001265 main.log.error( "You must specify " +
1266 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001267 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001268
kelvin8ec71442015-01-15 16:57:00 -08001269 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 str( egressDevice ) + "/" +\
1271 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 handle = self.sendline( cmd )
pingping-lin763ee042015-05-20 17:45:30 -07001273 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001274 if re.search( "Error", handle ):
pingping-lin763ee042015-05-20 17:45:30 -07001275 main.log.error( "Error in adding multipoint-to-singlepoint " +
1276 "intent" )
1277 return None
shahshreyad0c80432014-12-04 16:56:05 -08001278 else:
pingping-lin763ee042015-05-20 17:45:30 -07001279 match = re.search('id=0x([\da-f]+),', handle)
1280 if match:
1281 return match.group()[3:-1]
1282 else:
1283 main.log.error( "Error, intent ID not found" )
1284 return None
1285 except TypeError:
1286 main.log.exception( self.name + ": Object not as expected" )
1287 return None
shahshreyad0c80432014-12-04 16:56:05 -08001288 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001289 main.log.error( self.name + ": EOF exception found" )
1290 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001291 main.cleanup()
1292 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001293 except Exception:
1294 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001295 main.cleanup()
1296 main.exit()
1297
pingping-lin763ee042015-05-20 17:45:30 -07001298 def addSinglepointToMultipointIntent(
1299 self,
1300 ingressDevice,
1301 egressDeviceList,
1302 portIngress="",
1303 portEgressList=None,
1304 ethType="",
1305 ethSrc="",
1306 ethDst="",
1307 bandwidth="",
1308 lambdaAlloc=False,
1309 ipProto="",
1310 ipSrc="",
1311 ipDst="",
1312 tcpSrc="",
1313 tcpDst="",
1314 setEthSrc="",
1315 setEthDst="" ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001316 """
pingping-lin763ee042015-05-20 17:45:30 -07001317 Note:
1318 This function assumes the format of all egress devices
1319 is same. That is, all egress devices include port numbers
1320 with a "/" or all egress devices could specify device
1321 ids and port numbers seperately.
1322 Required:
1323 * EgressDeviceList: List of device ids of egress device
1324 ( Atleast 2 eress devices required in the list )
1325 * ingressDevice: device id of ingress device
1326 Optional:
1327 * ethType: specify ethType
1328 * ethSrc: specify ethSrc ( i.e. src mac addr )
1329 * ethDst: specify ethDst ( i.e. dst mac addr )
1330 * bandwidth: specify bandwidth capacity of link
1331 * lambdaAlloc: if True, intent will allocate lambda
1332 for the specified intent
1333 * ipProto: specify ip protocol
1334 * ipSrc: specify ip source address
1335 * ipDst: specify ip destination address
1336 * tcpSrc: specify tcp source port
1337 * tcpDst: specify tcp destination port
1338 * setEthSrc: action to Rewrite Source MAC Address
1339 * setEthDst: action to Rewrite Destination MAC Address
1340 Description:
1341 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1342 specifying device id's and optional fields
1343 Returns:
1344 A string of the intent id or None on error
1345
1346 NOTE: This function may change depending on the
1347 options developers provide for singlepoint-to-multipoint
1348 intent via cli
1349 """
1350 try:
1351 # If there are no optional arguments
1352 if not ethType and not ethSrc and not ethDst\
1353 and not bandwidth and not lambdaAlloc\
1354 and not ipProto and not ipSrc and not ipDst\
1355 and not tcpSrc and not tcpDst and not setEthSrc\
1356 and not setEthDst:
1357 cmd = "add-single-to-multi-intent"
1358
1359 else:
1360 cmd = "add-single-to-multi-intent"
1361
1362 if ethType:
1363 cmd += " --ethType " + str( ethType )
1364 if ethSrc:
1365 cmd += " --ethSrc " + str( ethSrc )
1366 if ethDst:
1367 cmd += " --ethDst " + str( ethDst )
1368 if bandwidth:
1369 cmd += " --bandwidth " + str( bandwidth )
1370 if lambdaAlloc:
1371 cmd += " --lambda "
1372 if ipProto:
1373 cmd += " --ipProto " + str( ipProto )
1374 if ipSrc:
1375 cmd += " --ipSrc " + str( ipSrc )
1376 if ipDst:
1377 cmd += " --ipDst " + str( ipDst )
1378 if tcpSrc:
1379 cmd += " --tcpSrc " + str( tcpSrc )
1380 if tcpDst:
1381 cmd += " --tcpDst " + str( tcpDst )
1382 if setEthSrc:
1383 cmd += " --setEthSrc " + str( setEthSrc )
1384 if setEthDst:
1385 cmd += " --setEthDst " + str( setEthDst )
1386
1387 # Check whether the user appended the port
1388 # or provided it as an input
1389
1390 if "/" in ingressDevice:
1391 cmd += " " + str( ingressDevice )
1392 else:
1393 if not portIngress:
1394 main.log.error( "You must specify " +
1395 "the Ingress port" )
1396 return main.FALSE
1397
1398 cmd += " " +\
1399 str( ingressDevice ) + "/" +\
1400 str( portIngress )
1401
1402 if portEgressList is None:
1403 for egressDevice in egressDeviceList:
1404 if "/" in egressDevice:
1405 cmd += " " + str( egressDevice )
1406 else:
1407 main.log.error( "You must specify " +
1408 "the egress port" )
1409 # TODO: perhaps more meaningful return
1410 return main.FALSE
1411 else:
1412 if len( egressDeviceList ) == len( portEgressList ):
1413 for egressDevice, portEgress in zip( egressDeviceList,
1414 portEgressList ):
1415 cmd += " " + \
1416 str( egressDevice ) + "/" +\
1417 str( portEgress )
1418 else:
1419 main.log.error( "Device list and port list does not " +
1420 "have the same length" )
1421 return main.FALSE
1422 handle = self.sendline( cmd )
1423 # If error, return error message
1424 if re.search( "Error", handle ):
1425 main.log.error( "Error in adding singlepoint-to-multipoint " +
1426 "intent" )
1427 return None
1428 else:
1429 match = re.search('id=0x([\da-f]+),', handle)
1430 if match:
1431 return match.group()[3:-1]
1432 else:
1433 main.log.error( "Error, intent ID not found" )
1434 return None
1435 except TypeError:
1436 main.log.exception( self.name + ": Object not as expected" )
1437 return None
1438 except pexpect.EOF:
1439 main.log.error( self.name + ": EOF exception found" )
1440 main.log.error( self.name + ": " + self.handle.before )
1441 main.cleanup()
1442 main.exit()
1443 except Exception:
1444 main.log.exception( self.name + ": Uncaught exception!" )
1445 main.cleanup()
1446 main.exit()
1447
1448 def addMplsIntent(
1449 self,
1450 ingressDevice,
1451 egressDevice,
1452 ingressPort="",
1453 egressPort="",
1454 ethType="",
1455 ethSrc="",
1456 ethDst="",
1457 bandwidth="",
1458 lambdaAlloc=False,
1459 ipProto="",
1460 ipSrc="",
1461 ipDst="",
1462 tcpSrc="",
1463 tcpDst="",
1464 ingressLabel="",
1465 egressLabel="",
1466 priority=""):
1467 """
1468 Required:
1469 * ingressDevice: device id of ingress device
1470 * egressDevice: device id of egress device
1471 Optional:
1472 * ethType: specify ethType
1473 * ethSrc: specify ethSrc ( i.e. src mac addr )
1474 * ethDst: specify ethDst ( i.e. dst mac addr )
1475 * bandwidth: specify bandwidth capacity of link
1476 * lambdaAlloc: if True, intent will allocate lambda
1477 for the specified intent
1478 * ipProto: specify ip protocol
1479 * ipSrc: specify ip source address
1480 * ipDst: specify ip destination address
1481 * tcpSrc: specify tcp source port
1482 * tcpDst: specify tcp destination port
1483 * ingressLabel: Ingress MPLS label
1484 * egressLabel: Egress MPLS label
1485 Description:
1486 Adds MPLS intent by
1487 specifying device id's and optional fields
1488 Returns:
1489 A string of the intent id or None on error
1490
1491 NOTE: This function may change depending on the
1492 options developers provide for MPLS
1493 intent via cli
1494 """
1495 try:
1496 # If there are no optional arguments
1497 if not ethType and not ethSrc and not ethDst\
1498 and not bandwidth and not lambdaAlloc \
1499 and not ipProto and not ipSrc and not ipDst \
1500 and not tcpSrc and not tcpDst and not ingressLabel \
1501 and not egressLabel:
1502 cmd = "add-mpls-intent"
1503
1504 else:
1505 cmd = "add-mpls-intent"
1506
1507 if ethType:
1508 cmd += " --ethType " + str( ethType )
1509 if ethSrc:
1510 cmd += " --ethSrc " + str( ethSrc )
1511 if ethDst:
1512 cmd += " --ethDst " + str( ethDst )
1513 if bandwidth:
1514 cmd += " --bandwidth " + str( bandwidth )
1515 if lambdaAlloc:
1516 cmd += " --lambda "
1517 if ipProto:
1518 cmd += " --ipProto " + str( ipProto )
1519 if ipSrc:
1520 cmd += " --ipSrc " + str( ipSrc )
1521 if ipDst:
1522 cmd += " --ipDst " + str( ipDst )
1523 if tcpSrc:
1524 cmd += " --tcpSrc " + str( tcpSrc )
1525 if tcpDst:
1526 cmd += " --tcpDst " + str( tcpDst )
1527 if ingressLabel:
1528 cmd += " --ingressLabel " + str( ingressLabel )
1529 if egressLabel:
1530 cmd += " --egressLabel " + str( egressLabel )
1531 if priority:
1532 cmd += " --priority " + str( priority )
1533
1534 # Check whether the user appended the port
1535 # or provided it as an input
1536 if "/" in ingressDevice:
1537 cmd += " " + str( ingressDevice )
1538 else:
1539 if not ingressPort:
1540 main.log.error( "You must specify the ingress port" )
1541 return None
1542
1543 cmd += " " + \
1544 str( ingressDevice ) + "/" +\
1545 str( ingressPort ) + " "
1546
1547 if "/" in egressDevice:
1548 cmd += " " + str( egressDevice )
1549 else:
1550 if not egressPort:
1551 main.log.error( "You must specify the egress port" )
1552 return None
1553
1554 cmd += " " +\
1555 str( egressDevice ) + "/" +\
1556 str( egressPort )
1557
1558 handle = self.sendline( cmd )
1559 # If error, return error message
1560 if re.search( "Error", handle ):
1561 main.log.error( "Error in adding mpls intent" )
1562 return None
1563 else:
1564 # TODO: print out all the options in this message?
1565 main.log.info( "MPLS intent installed between " +
1566 str( ingressDevice ) + " and " +
1567 str( egressDevice ) )
1568 match = re.search('id=0x([\da-f]+),', handle)
1569 if match:
1570 return match.group()[3:-1]
1571 else:
1572 main.log.error( "Error, intent ID not found" )
1573 return None
1574 except TypeError:
1575 main.log.exception( self.name + ": Object not as expected" )
1576 return None
1577 except pexpect.EOF:
1578 main.log.error( self.name + ": EOF exception found" )
1579 main.log.error( self.name + ": " + self.handle.before )
1580 main.cleanup()
1581 main.exit()
1582 except Exception:
1583 main.log.exception( self.name + ": Uncaught exception!" )
1584 main.cleanup()
1585 main.exit()
1586
1587 def removeIntent( self, intentId, app='org.onosproject.cli',
1588 purge=False, sync=False ):
1589 """
1590 Remove intent for specified application id and intent id
1591 Optional args:-
1592 -s or --sync: Waits for the removal before returning
1593 -p or --purge: Purge the intent from the store after removal
Jon Halle3f39ff2015-01-13 11:50:53 -08001594
1595 Returns:
1596 main.False on error and
1597 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001598 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001599 try:
pingping-lin763ee042015-05-20 17:45:30 -07001600 cmdStr = "remove-intent"
1601 if purge:
1602 cmdStr += " -p"
1603 if sync:
1604 cmdStr += " -s"
1605
1606 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001608 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001609 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001610 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001611 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001612 # TODO: Should this be main.TRUE
1613 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001614 except TypeError:
1615 main.log.exception( self.name + ": Object not as expected" )
1616 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001617 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001618 main.log.error( self.name + ": EOF exception found" )
1619 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001620 main.cleanup()
1621 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001622 except Exception:
1623 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001624 main.cleanup()
1625 main.exit()
1626
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001628 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001629 NOTE: This method should be used after installing application:
1630 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001631 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001633 Description:
1634 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001635 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001636 try:
pingping-lin763ee042015-05-20 17:45:30 -07001637 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001639 cmdStr += " -j"
1640 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001641 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001642 except TypeError:
1643 main.log.exception( self.name + ": Object not as expected" )
1644 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001646 main.log.error( self.name + ": EOF exception found" )
1647 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001648 main.cleanup()
1649 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001650 except Exception:
1651 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001652 main.cleanup()
1653 main.exit()
1654
kelvin-onlabd3b64892015-01-20 13:26:24 -08001655 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001656 """
andrewonlab377693f2014-10-21 16:00:30 -04001657 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001658 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001659 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001660 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001661 """
andrewonlabe6745342014-10-17 14:29:13 -04001662 try:
pingping-lin763ee042015-05-20 17:45:30 -07001663 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001665 cmdStr += " -j"
1666 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001667 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001668 except TypeError:
1669 main.log.exception( self.name + ": Object not as expected" )
1670 return None
andrewonlabe6745342014-10-17 14:29:13 -04001671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001672 main.log.error( self.name + ": EOF exception found" )
1673 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001674 main.cleanup()
1675 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001676 except Exception:
1677 main.log.exception( self.name + ": Uncaught exception!" )
1678 main.cleanup()
1679 main.exit()
1680
1681 def getIntentState(self, intentsId, intentsJson=None):
1682 """
1683 Check intent state.
1684 Accepts a single intent ID (string type) or a list of intent IDs.
1685 Returns the state(string type) of the id if a single intent ID is
1686 accepted.
1687 Returns a dictionary with intent IDs as the key and its
1688 corresponding states as the values
1689 Parameters:
1690 intentId: intent ID (string type)
1691 intentsJson: parsed json object from the onos:intents api
1692 Returns:
1693 state = An intent's state- INSTALL,WITHDRAWN etc.
1694 stateDict = Dictionary of intent's state. intent ID as the keys and
1695 state as the values.
1696 """
1697 try:
1698 state = "State is Undefined"
1699 if not intentsJson:
1700 intentsJsonTemp = json.loads( self.intents() )
1701 else:
1702 intentsJsonTemp = json.loads( intentsJson )
1703 if isinstance( intentsId, types.StringType ):
1704 for intent in intentsJsonTemp:
1705 if intentsId == intent[ 'id' ]:
1706 state = intent[ 'state' ]
1707 return state
1708 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1709 " on the list" )
1710 return state
1711 elif isinstance( intentsId, types.ListType ):
1712 dictList = []
1713 for i in xrange( len( intentsId ) ):
1714 stateDict = {}
1715 for intents in intentsJsonTemp:
1716 if intentsId[ i ] == intents[ 'id' ]:
1717 stateDict[ 'state' ] = intents[ 'state' ]
1718 stateDict[ 'id' ] = intentsId[ i ]
1719 dictList.append( stateDict )
1720 break
1721 if len( intentsId ) != len( dictList ):
1722 main.log.info( "Cannot find some of the intent ID state" )
1723 return dictList
1724 else:
1725 main.log.info( "Invalid intents ID entry" )
1726 return None
1727 except TypeError:
1728 main.log.exception( self.name + ": Object not as expected" )
1729 return None
1730 except pexpect.EOF:
1731 main.log.error( self.name + ": EOF exception found" )
1732 main.log.error( self.name + ": " + self.handle.before )
1733 main.cleanup()
1734 main.exit()
1735 except Exception:
1736 main.log.exception( self.name + ": Uncaught exception!" )
1737 main.cleanup()
1738 main.exit()
1739
1740 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1741 """
1742 Description:
1743 Check intents state
1744 Required:
1745 intentsId - List of intents ID to be checked
1746 Optional:
1747 expectedState - Check this expected state of each intents state
1748 in the list. Defaults to INSTALLED
1749 Return:
1750 Returns main.TRUE only if all intent are the same as expectedState,
1751 , otherwise,returns main.FALSE.
1752 """
1753 try:
1754 # Generating a dictionary: intent id as a key and state as value
1755 intentsDict = self.getIntentState( intentsId )
1756 #print "len of intentsDict ", str( len( intentsDict ) )
1757 if len( intentsId ) != len( intentsDict ):
1758 main.log.info( self.name + "There is something wrong " +
1759 "getting intents state" )
1760 return main.FALSE
1761 returnValue = main.TRUE
1762 for intents in intentsDict:
1763 if intents.get( 'state' ) != expectedState:
1764 main.log.info( self.name + " : " + intents.get( 'id' ) +
1765 " actual state = " + intents.get( 'state' )
1766 + " does not equal expected state = "
1767 + expectedState )
1768 returnValue = main.FALSE
1769 if returnValue == main.TRUE:
1770 main.log.info( self.name + ": All " +
1771 str( len( intentsDict ) ) +
1772 " intents are in " + expectedState + " state")
1773 return returnValue
1774 except TypeError:
1775 main.log.exception( self.name + ": Object not as expected" )
1776 return None
1777 except pexpect.EOF:
1778 main.log.error( self.name + ": EOF exception found" )
1779 main.log.error( self.name + ": " + self.handle.before )
1780 main.cleanup()
1781 main.exit()
1782 except Exception:
1783 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001784 main.cleanup()
1785 main.exit()
1786
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001788 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001789 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001790 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001791 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001792 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001793 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001794 try:
pingping-lin763ee042015-05-20 17:45:30 -07001795 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001797 cmdStr += " -j"
1798 handle = self.sendline( cmdStr )
1799 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001800 main.log.error( self.name + ".flows() response: " +
1801 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001802 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001803 except TypeError:
1804 main.log.exception( self.name + ": Object not as expected" )
1805 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001806 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001807 main.log.error( self.name + ": EOF exception found" )
1808 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001809 main.cleanup()
1810 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001811 except Exception:
1812 main.log.exception( self.name + ": Uncaught exception!" )
1813 main.cleanup()
1814 main.exit()
1815
1816 def checkFlowsState( self ):
1817 """
1818 Description:
1819 Check the if all the current flows are in ADDED state or
1820 PENDING_ADD state
1821 Return:
1822 returnValue - Returns main.TRUE only if all flows are in
1823 ADDED state or PENDING_ADD, return main.FALSE
1824 otherwise.
1825 """
1826 try:
1827 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001828 #print tempFlows[0]
pingping-lin763ee042015-05-20 17:45:30 -07001829 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001830
pingping-lin763ee042015-05-20 17:45:30 -07001831 for device in tempFlows:
1832 for flow in device.get( 'flows' ):
1833 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1834 'PENDING_ADD':
1835 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf0594d72015-05-19 17:25:12 -07001836 flow.get( 'groupId' ) +
pingping-lin763ee042015-05-20 17:45:30 -07001837 " | state:" + flow.get( 'state' ) )
1838 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001839
pingping-lin763ee042015-05-20 17:45:30 -07001840 return returnValue
1841 except TypeError:
1842 main.log.exception( self.name + ": Object not as expected" )
1843 return None
1844 except pexpect.EOF:
1845 main.log.error( self.name + ": EOF exception found" )
1846 main.log.error( self.name + ": " + self.handle.before )
1847 main.cleanup()
1848 main.exit()
1849 except Exception:
1850 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001851 main.cleanup()
1852 main.exit()
1853
kelvin-onlabd3b64892015-01-20 13:26:24 -08001854 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
pingping-lin763ee042015-05-20 17:45:30 -07001855 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001856 """
andrewonlab87852b02014-11-19 18:44:19 -05001857 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001858 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001859 a specific point-to-point intent definition
1860 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 * dpidSrc: specify source dpid
1862 * dpidDst: specify destination dpid
1863 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001864 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001866 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001868 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001869 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001870 """
andrewonlab87852b02014-11-19 18:44:19 -05001871 try:
kelvin8ec71442015-01-15 16:57:00 -08001872 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001873 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1874 str( numIntents )
1875 if numMult:
1876 cmd += " " + str( numMult )
1877 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001878 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 if appId:
1880 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001881 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001882 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001883 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001884 main.log.info( handle )
1885 # Split result by newline
1886 newline = handle.split( "\r\r\n" )
1887 # Ignore the first object of list, which is empty
1888 newline = newline[ 1: ]
1889 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001890 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001891 result = result.split( ": " )
1892 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001893 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1894 main.log.info( latResult )
1895 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001896 else:
1897 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001898 except TypeError:
1899 main.log.exception( self.name + ": Object not as expected" )
1900 return None
andrewonlab87852b02014-11-19 18:44:19 -05001901 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001902 main.log.error( self.name + ": EOF exception found" )
1903 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001904 main.cleanup()
1905 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001906 except Exception:
1907 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001908 main.cleanup()
1909 main.exit()
1910
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001912 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001913 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001914 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001916 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001917 try:
pingping-lin763ee042015-05-20 17:45:30 -07001918 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001919 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001920 cmdStr += " -j"
1921 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001922 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001923 except TypeError:
1924 main.log.exception( self.name + ": Object not as expected" )
1925 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001926 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001927 main.log.error( self.name + ": EOF exception found" )
1928 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001929 main.cleanup()
1930 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001931 except Exception:
1932 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001933 main.cleanup()
1934 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001935
kelvin-onlabd3b64892015-01-20 13:26:24 -08001936 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001937 """
1938 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001939 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001940 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001941 """
andrewonlab867212a2014-10-22 20:13:38 -04001942 try:
pingping-lin763ee042015-05-20 17:45:30 -07001943 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001944 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001945 cmdStr += " -j"
1946 handle = self.sendline( cmdStr )
1947 if handle:
1948 return handle
1949 elif jsonFormat:
1950 # Return empty json
1951 return '{}'
andrewonlab867212a2014-10-22 20:13:38 -04001952 else:
pingping-lin763ee042015-05-20 17:45:30 -07001953 return handle
1954 except TypeError:
1955 main.log.exception( self.name + ": Object not as expected" )
1956 return None
andrewonlab867212a2014-10-22 20:13:38 -04001957 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001958 main.log.error( self.name + ": EOF exception found" )
1959 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001960 main.cleanup()
1961 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001962 except Exception:
1963 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001964 main.cleanup()
1965 main.exit()
1966
kelvin8ec71442015-01-15 16:57:00 -08001967 # Wrapper functions ****************
1968 # Wrapper functions use existing driver
1969 # functions and extends their use case.
1970 # For example, we may use the output of
1971 # a normal driver function, and parse it
1972 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001973
kelvin-onlabd3b64892015-01-20 13:26:24 -08001974 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001975 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001976 Description:
1977 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001978 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001979 try:
kelvin8ec71442015-01-15 16:57:00 -08001980 # Obtain output of intents function
pingping-lin763ee042015-05-20 17:45:30 -07001981 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001983
kelvin8ec71442015-01-15 16:57:00 -08001984 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001985 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1986 for intents in intentsList:
pingping-lin763ee042015-05-20 17:45:30 -07001987 match = re.search('id=0x([\da-f]+),', intents)
1988 if match:
1989 tmpId = match.group()[3:-1]
1990 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001991 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001992
pingping-lin763ee042015-05-20 17:45:30 -07001993 except TypeError:
1994 main.log.exception( self.name + ": Object not as expected" )
1995 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001996 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001997 main.log.error( self.name + ": EOF exception found" )
1998 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001999 main.cleanup()
2000 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002001 except Exception:
2002 main.log.exception( self.name + ": Uncaught exception!" )
2003 main.cleanup()
2004 main.exit()
2005
2006 def FlowAddedCount( self, deviceId ):
2007 """
2008 Determine the number of flow rules for the given device id that are
2009 in the added state
2010 """
2011 try:
2012 cmdStr = "flows any " + str( deviceId ) + " | " +\
2013 "grep 'state=ADDED' | wc -l"
2014 handle = self.sendline( cmdStr )
2015 return handle
2016 except pexpect.EOF:
2017 main.log.error( self.name + ": EOF exception found" )
2018 main.log.error( self.name + ": " + self.handle.before )
2019 main.cleanup()
2020 main.exit()
2021 except Exception:
2022 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002023 main.cleanup()
2024 main.exit()
2025
kelvin-onlabd3b64892015-01-20 13:26:24 -08002026 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002027 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002028 Use 'devices' function to obtain list of all devices
2029 and parse the result to obtain a list of all device
2030 id's. Returns this list. Returns empty list if no
2031 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002032 List is ordered sequentially
2033
andrewonlab3e15ead2014-10-15 14:21:34 -04002034 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002035 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002036 the ids. By obtaining the list of device ids on the fly,
2037 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002038 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002039 try:
kelvin8ec71442015-01-15 16:57:00 -08002040 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002041 devicesStr = self.devices( jsonFormat=False )
2042 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002043
kelvin-onlabd3b64892015-01-20 13:26:24 -08002044 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002045 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002046 return idList
kelvin8ec71442015-01-15 16:57:00 -08002047
2048 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002049 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002050 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002051 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002052 # Split list further into arguments before and after string
2053 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002054 # append to idList
2055 for arg in tempList:
2056 idList.append( arg.split( "id=" )[ 1 ] )
2057 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002058
pingping-lin763ee042015-05-20 17:45:30 -07002059 except TypeError:
2060 main.log.exception( self.name + ": Object not as expected" )
2061 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002063 main.log.error( self.name + ": EOF exception found" )
2064 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002065 main.cleanup()
2066 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002067 except Exception:
2068 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002069 main.cleanup()
2070 main.exit()
2071
kelvin-onlabd3b64892015-01-20 13:26:24 -08002072 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002073 """
andrewonlab7c211572014-10-15 16:45:20 -04002074 Uses 'nodes' function to obtain list of all nodes
2075 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002076 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002077 Returns:
2078 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002079 """
andrewonlab7c211572014-10-15 16:45:20 -04002080 try:
pingping-lin763ee042015-05-20 17:45:30 -07002081 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002082 idList = []
pingping-lin763ee042015-05-20 17:45:30 -07002083 # Sample nodesStr output
2084 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002085 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002086 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002087 return idList
pingping-lin763ee042015-05-20 17:45:30 -07002088 nodesJson = json.loads( nodesStr )
2089 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002090 return idList
kelvin8ec71442015-01-15 16:57:00 -08002091
pingping-lin763ee042015-05-20 17:45:30 -07002092 except TypeError:
2093 main.log.exception( self.name + ": Object not as expected" )
2094 return None
andrewonlab7c211572014-10-15 16:45:20 -04002095 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002096 main.log.error( self.name + ": EOF exception found" )
2097 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002098 main.cleanup()
2099 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002100 except Exception:
2101 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002102 main.cleanup()
2103 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002104
kelvin-onlabd3b64892015-01-20 13:26:24 -08002105 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002106 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002107 Return the first device from the devices api whose 'id' contains 'dpid'
2108 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002109 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002110 try:
kelvin8ec71442015-01-15 16:57:00 -08002111 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002112 return None
2113 else:
kelvin8ec71442015-01-15 16:57:00 -08002114 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002115 rawDevices = self.devices()
2116 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002117 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002118 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002119 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2120 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002121 return device
2122 return None
pingping-lin763ee042015-05-20 17:45:30 -07002123 except TypeError:
2124 main.log.exception( self.name + ": Object not as expected" )
2125 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002127 main.log.error( self.name + ": EOF exception found" )
2128 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002129 main.cleanup()
2130 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002131 except Exception:
2132 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002133 main.cleanup()
2134 main.exit()
2135
kelvin-onlabd3b64892015-01-20 13:26:24 -08002136 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002137 """
pingping-lin763ee042015-05-20 17:45:30 -07002138 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002139 supplied values. By default this will report to main.log, but the
pingping-lin763ee042015-05-20 17:45:30 -07002140 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002141
Jon Hall42db6dc2014-10-24 19:03:48 -04002142 Params: ip = ip used for the onos cli
2143 numoswitch = expected number of switches
pingping-lin763ee042015-05-20 17:45:30 -07002144 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002145 logLevel = level to log to. Currently accepts
2146 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002147
2148
kelvin-onlabd3b64892015-01-20 13:26:24 -08002149 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002150
pingping-lin763ee042015-05-20 17:45:30 -07002151 Returns: main.TRUE if the number of switches and links are correct,
2152 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002153 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002154 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002155 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002156 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002157 if topology == {}:
2158 return main.ERROR
2159 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002160 # Is the number of switches is what we expected
2161 devices = topology.get( 'devices', False )
2162 links = topology.get( 'links', False )
pingping-lin763ee042015-05-20 17:45:30 -07002163 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002164 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002165 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002166 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002167 linkCheck = ( int( links ) == int( numolink ) )
2168 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002169 # We expected the correct numbers
pingping-lin763ee042015-05-20 17:45:30 -07002170 output += "The number of links and switches match " +\
2171 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002172 result = main.TRUE
2173 else:
pingping-lin763ee042015-05-20 17:45:30 -07002174 output += "The number of links and switches does not match " +\
2175 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002176 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002177 output = output + "\n ONOS sees %i devices (%i expected) \
2178 and %i links (%i expected)" % (
2179 int( devices ), int( numoswitch ), int( links ),
2180 int( numolink ) )
2181 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002182 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002183 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002184 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002185 else:
pingping-lin763ee042015-05-20 17:45:30 -07002186 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002187 return result
pingping-lin763ee042015-05-20 17:45:30 -07002188 except TypeError:
2189 main.log.exception( self.name + ": Object not as expected" )
2190 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002191 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002192 main.log.error( self.name + ": EOF exception found" )
2193 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002194 main.cleanup()
2195 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002196 except Exception:
2197 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002198 main.cleanup()
2199 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002200
kelvin-onlabd3b64892015-01-20 13:26:24 -08002201 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002202 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002203 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002204 deviceId must be the id of a device as seen in the onos devices command
2205 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002206 role must be either master, standby, or none
2207
Jon Halle3f39ff2015-01-13 11:50:53 -08002208 Returns:
2209 main.TRUE or main.FALSE based on argument verification and
2210 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002211 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002212 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002213 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002214 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002215 cmdStr = "device-role " +\
2216 str( deviceId ) + " " +\
2217 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002218 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002219 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002220 if re.search( "Error", handle ):
2221 # end color output to escape any colours
2222 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002223 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002224 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002225 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002226 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002227 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002228 main.log.error( "Invalid 'role' given to device_role(). " +
2229 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002230 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002231 except TypeError:
2232 main.log.exception( self.name + ": Object not as expected" )
2233 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002234 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002235 main.log.error( self.name + ": EOF exception found" )
2236 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002237 main.cleanup()
2238 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002239 except Exception:
2240 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002241 main.cleanup()
2242 main.exit()
2243
kelvin-onlabd3b64892015-01-20 13:26:24 -08002244 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002245 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002246 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002247 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002248 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002249 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002250 try:
pingping-lin763ee042015-05-20 17:45:30 -07002251 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002252 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07002253 cmdStr += " -j"
2254 handle = self.sendline( cmdStr )
2255 return handle
2256 except TypeError:
2257 main.log.exception( self.name + ": Object not as expected" )
2258 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002260 main.log.error( self.name + ": EOF exception found" )
2261 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002262 main.cleanup()
2263 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002264 except Exception:
2265 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002266 main.cleanup()
2267 main.exit()
2268
kelvin-onlabd3b64892015-01-20 13:26:24 -08002269 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002270 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002271 CLI command to get the current leader for the Election test application
2272 NOTE: Requires installation of the onos-app-election feature
2273 Returns: Node IP of the leader if one exists
2274 None if none exists
2275 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002276 """
Jon Hall94fd0472014-12-08 11:52:42 -08002277 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002278 cmdStr = "election-test-leader"
2279 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002280 # Leader
2281 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002282 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 nodeSearch = re.search( leaderPattern, response )
2284 if nodeSearch:
2285 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002286 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002287 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002288 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002289 # no leader
2290 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002291 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 nullSearch = re.search( nullPattern, response )
2293 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002294 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002295 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002296 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002297 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002298 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002299 if re.search( errorPattern, response ):
2300 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002301 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002302 return main.FALSE
2303 else:
pingping-lin763ee042015-05-20 17:45:30 -07002304 main.log.error( "Error in electionTestLeader on " + self.name +
2305 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002306 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002307 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002308 except TypeError:
2309 main.log.exception( self.name + ": Object not as expected" )
2310 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002311 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002312 main.log.error( self.name + ": EOF exception found" )
2313 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002314 main.cleanup()
2315 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002316 except Exception:
2317 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002318 main.cleanup()
2319 main.exit()
2320
kelvin-onlabd3b64892015-01-20 13:26:24 -08002321 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002322 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002323 CLI command to run for leadership of the Election test application.
2324 NOTE: Requires installation of the onos-app-election feature
2325 Returns: Main.TRUE on success
2326 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002327 """
Jon Hall94fd0472014-12-08 11:52:42 -08002328 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002329 cmdStr = "election-test-run"
2330 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002331 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002332 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002333 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002334 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002335 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002336 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002337 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002338 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002339 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002340 errorPattern = "Command\snot\sfound"
2341 if re.search( errorPattern, response ):
2342 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002343 return main.FALSE
2344 else:
pingping-lin763ee042015-05-20 17:45:30 -07002345 main.log.error( "Error in electionTestRun on " + self.name +
2346 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002347 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002348 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002349 except TypeError:
2350 main.log.exception( self.name + ": Object not as expected" )
2351 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002352 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002353 main.log.error( self.name + ": EOF exception found" )
2354 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002355 main.cleanup()
2356 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002357 except Exception:
2358 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002359 main.cleanup()
2360 main.exit()
2361
kelvin-onlabd3b64892015-01-20 13:26:24 -08002362 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002363 """
Jon Hall94fd0472014-12-08 11:52:42 -08002364 * CLI command to withdraw the local node from leadership election for
2365 * the Election test application.
2366 #NOTE: Requires installation of the onos-app-election feature
2367 Returns: Main.TRUE on success
2368 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002369 """
Jon Hall94fd0472014-12-08 11:52:42 -08002370 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002371 cmdStr = "election-test-withdraw"
2372 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002373 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002374 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002375 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002376 if re.search( successPattern, response ):
2377 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002378 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002379 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002380 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002381 errorPattern = "Command\snot\sfound"
2382 if re.search( errorPattern, response ):
2383 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002384 return main.FALSE
2385 else:
pingping-lin763ee042015-05-20 17:45:30 -07002386 main.log.error( "Error in electionTestWithdraw on " +
2387 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002388 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002389 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002390 except TypeError:
2391 main.log.exception( self.name + ": Object not as expected" )
2392 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002394 main.log.error( self.name + ": EOF exception found" )
2395 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002396 main.cleanup()
2397 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002398 except Exception:
2399 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002400 main.cleanup()
2401 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002402
kelvin8ec71442015-01-15 16:57:00 -08002403 def getDevicePortsEnabledCount( self, dpid ):
2404 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002405 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002406 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002407 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002408 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002409 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2410 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002411 if re.search( "No such device", output ):
2412 main.log.error( "Error in getting ports" )
2413 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002414 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002415 return output
pingping-lin763ee042015-05-20 17:45:30 -07002416 except TypeError:
2417 main.log.exception( self.name + ": Object not as expected" )
2418 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002419 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002420 main.log.error( self.name + ": EOF exception found" )
2421 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002422 main.cleanup()
2423 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002424 except Exception:
2425 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002426 main.cleanup()
2427 main.exit()
2428
kelvin8ec71442015-01-15 16:57:00 -08002429 def getDeviceLinksActiveCount( self, dpid ):
2430 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002431 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002432 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002433 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002434 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002435 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2436 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002437 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002438 main.log.error( "Error in getting ports " )
2439 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002440 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002441 return output
pingping-lin763ee042015-05-20 17:45:30 -07002442 except TypeError:
2443 main.log.exception( self.name + ": Object not as expected" )
2444 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002445 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002446 main.log.error( self.name + ": EOF exception found" )
2447 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002448 main.cleanup()
2449 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002450 except Exception:
2451 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002452 main.cleanup()
2453 main.exit()
2454
kelvin8ec71442015-01-15 16:57:00 -08002455 def getAllIntentIds( self ):
2456 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002457 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002458 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002459 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002460 cmdStr = "onos:intents | grep id="
2461 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002462 if re.search( "Error", output ):
2463 main.log.error( "Error in getting ports" )
2464 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002465 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002466 return output
pingping-lin763ee042015-05-20 17:45:30 -07002467 except TypeError:
2468 main.log.exception( self.name + ": Object not as expected" )
2469 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002470 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002471 main.log.error( self.name + ": EOF exception found" )
2472 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002473 main.cleanup()
2474 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002475 except Exception:
2476 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002477 main.cleanup()
2478 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002479
2480 def intentSummary( self ):
2481 """
2482 Returns a dictionary containing the current intent states and the count
2483 """
2484 try:
2485 intents = self.intents( )
2486 states = []
2487 for intent in json.loads( intents ):
2488 states.append( intent.get( 'state', None ) )
2489 out = [ ( i, states.count( i ) ) for i in set( states ) ]
2490 main.log.info( dict( out ) )
2491 return dict( out )
2492 except TypeError:
2493 main.log.exception( self.name + ": Object not as expected" )
2494 return None
2495 except pexpect.EOF:
2496 main.log.error( self.name + ": EOF exception found" )
2497 main.log.error( self.name + ": " + self.handle.before )
2498 main.cleanup()
2499 main.exit()
2500 except Exception:
2501 main.log.exception( self.name + ": Uncaught exception!" )
2502 main.cleanup()
2503 main.exit()
2504
2505 def leaders( self, jsonFormat=True ):
2506 """
2507 Returns the output of the leaders command.
2508 Optional argument:
2509 * jsonFormat - boolean indicating if you want output in json
2510 """
2511 # FIXME: add json output
2512 # Sample JSON
2513 # {
2514 # "electedTime": "13m ago",
2515 # "epoch": 4,
2516 # "leader": "10.128.30.17",
2517 # "topic": "intent-partition-3"
2518 # },
2519 try:
2520 cmdStr = "onos:leaders"
2521 if jsonFormat:
2522 cmdStr += " -j"
2523 output = self.sendline( cmdStr )
2524 return output
2525 except TypeError:
2526 main.log.exception( self.name + ": Object not as expected" )
2527 return None
2528 except pexpect.EOF:
2529 main.log.error( self.name + ": EOF exception found" )
2530 main.log.error( self.name + ": " + self.handle.before )
2531 main.cleanup()
2532 main.exit()
2533 except Exception:
2534 main.log.exception( self.name + ": Uncaught exception!" )
2535 main.cleanup()
2536 main.exit()
2537
2538 def pendingMap( self, jsonFormat=True ):
2539 """
2540 Returns the output of the intent Pending map.
2541 """
2542 try:
2543 cmdStr = "onos:intents -p"
2544 if jsonFormat:
2545 cmdStr += " -j"
2546 output = self.sendline( cmdStr )
2547 return output
2548 except TypeError:
2549 main.log.exception( self.name + ": Object not as expected" )
2550 return None
2551 except pexpect.EOF:
2552 main.log.error( self.name + ": EOF exception found" )
2553 main.log.error( self.name + ": " + self.handle.before )
2554 main.cleanup()
2555 main.exit()
2556 except Exception:
2557 main.log.exception( self.name + ": Uncaught exception!" )
2558 main.cleanup()
2559 main.exit()
2560
2561 def partitions( self, jsonFormat=True ):
2562 """
2563 Returns the output of the raft partitions command for ONOS.
2564 """
2565 # Sample JSON
2566 # {
2567 # "leader": "tcp://10.128.30.11:7238",
2568 # "members": [
2569 # "tcp://10.128.30.11:7238",
2570 # "tcp://10.128.30.17:7238",
2571 # "tcp://10.128.30.13:7238",
2572 # ],
2573 # "name": "p1",
2574 # "term": 3
2575 # },
2576 try:
2577 cmdStr = "onos:partitions"
2578 if jsonFormat:
2579 cmdStr += " -j"
2580 output = self.sendline( cmdStr )
2581 return output
2582 except TypeError:
2583 main.log.exception( self.name + ": Object not as expected" )
2584 return None
2585 except pexpect.EOF:
2586 main.log.error( self.name + ": EOF exception found" )
2587 main.log.error( self.name + ": " + self.handle.before )
2588 main.cleanup()
2589 main.exit()
2590 except Exception:
2591 main.log.exception( self.name + ": Uncaught exception!" )
2592 main.cleanup()
2593 main.exit()
2594
2595 def apps( self, jsonFormat=True ):
2596 """
2597 Returns the output of the apps command for ONOS. This command lists
2598 information about installed ONOS applications
2599 """
2600 # Sample JSON object
2601 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2602 # "description":"ONOS OpenFlow protocol southbound providers",
2603 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2604 # "features":"[onos-openflow]","state":"ACTIVE"}]
2605 try:
2606 cmdStr = "onos:apps"
2607 if jsonFormat:
2608 cmdStr += " -j"
2609 output = self.sendline( cmdStr )
2610 assert "Error executing command" not in output
2611 return output
2612 # FIXME: look at specific exceptions/Errors
2613 except AssertionError:
2614 main.log.error( "Error in processing onos:app command: " +
2615 str( output ) )
2616 return None
2617 except TypeError:
2618 main.log.exception( self.name + ": Object not as expected" )
2619 return None
2620 except pexpect.EOF:
2621 main.log.error( self.name + ": EOF exception found" )
2622 main.log.error( self.name + ": " + self.handle.before )
2623 main.cleanup()
2624 main.exit()
2625 except Exception:
2626 main.log.exception( self.name + ": Uncaught exception!" )
2627 main.cleanup()
2628 main.exit()
2629
2630 def appStatus( self, appName ):
2631 """
2632 Uses the onos:apps cli command to return the status of an application.
2633 Returns:
2634 "ACTIVE" - If app is installed and activated
2635 "INSTALLED" - If app is installed and deactivated
2636 "UNINSTALLED" - If app is not installed
2637 None - on error
2638 """
2639 try:
2640 if not isinstance( appName, types.StringType ):
2641 main.log.error( self.name + ".appStatus(): appName must be" +
2642 " a string" )
2643 return None
2644 output = self.apps( jsonFormat=True )
2645 appsJson = json.loads( output )
2646 state = None
2647 for app in appsJson:
2648 if appName == app.get('name'):
2649 state = app.get('state')
2650 break
2651 if state == "ACTIVE" or state == "INSTALLED":
2652 return state
2653 elif state is None:
2654 return "UNINSTALLED"
2655 elif state:
2656 main.log.error( "Unexpected state from 'onos:apps': " +
2657 str( state ) )
2658 return state
2659 except TypeError:
2660 main.log.exception( self.name + ": Object not as expected" )
2661 return None
2662 except pexpect.EOF:
2663 main.log.error( self.name + ": EOF exception found" )
2664 main.log.error( self.name + ": " + self.handle.before )
2665 main.cleanup()
2666 main.exit()
2667 except Exception:
2668 main.log.exception( self.name + ": Uncaught exception!" )
2669 main.cleanup()
2670 main.exit()
2671
2672 def app( self, appName, option ):
2673 """
2674 Interacts with the app command for ONOS. This command manages
2675 application inventory.
2676 """
2677 try:
2678 # Validate argument types
2679 valid = True
2680 if not isinstance( appName, types.StringType ):
2681 main.log.error( self.name + ".app(): appName must be a " +
2682 "string" )
2683 valid = False
2684 if not isinstance( option, types.StringType ):
2685 main.log.error( self.name + ".app(): option must be a string" )
2686 valid = False
2687 if not valid:
2688 return main.FALSE
2689 # Validate Option
2690 option = option.lower()
2691 # NOTE: Install may become a valid option
2692 if option == "activate":
2693 pass
2694 elif option == "deactivate":
2695 pass
2696 elif option == "uninstall":
2697 pass
2698 else:
2699 # Invalid option
2700 main.log.error( "The ONOS app command argument only takes " +
2701 "the values: (activate|deactivate|uninstall)" +
2702 "; was given '" + option + "'")
2703 return main.FALSE
2704 cmdStr = "onos:app " + option + " " + appName
2705 output = self.sendline( cmdStr )
2706 if "Error executing command" in output:
2707 main.log.error( "Error in processing onos:app command: " +
2708 str( output ) )
2709 return main.FALSE
2710 elif "No such application" in output:
2711 main.log.error( "The application '" + appName +
2712 "' is not installed in ONOS" )
2713 return main.FALSE
2714 elif "Command not found:" in output:
2715 main.log.error( "Error in processing onos:app command: " +
2716 str( output ) )
2717 return main.FALSE
2718 elif "Unsupported command:" in output:
2719 main.log.error( "Incorrect command given to 'app': " +
2720 str( output ) )
2721 # NOTE: we may need to add more checks here
2722 # else: Command was successful
2723 # main.log.debug( "app response: " + repr( output ) )
2724 return main.TRUE
2725 except TypeError:
2726 main.log.exception( self.name + ": Object not as expected" )
2727 return main.ERROR
2728 except pexpect.EOF:
2729 main.log.error( self.name + ": EOF exception found" )
2730 main.log.error( self.name + ": " + self.handle.before )
2731 main.cleanup()
2732 main.exit()
2733 except Exception:
2734 main.log.exception( self.name + ": Uncaught exception!" )
2735 main.cleanup()
2736 main.exit()
2737
2738 def activateApp( self, appName, check=True ):
2739 """
2740 Activate an app that is already installed in ONOS
2741 appName is the hierarchical app name, not the feature name
2742 If check is True, method will check the status of the app after the
2743 command is issued
2744 Returns main.TRUE if the command was successfully sent
2745 main.FALSE if the cli responded with an error or given
2746 incorrect input
2747 """
2748 try:
2749 if not isinstance( appName, types.StringType ):
2750 main.log.error( self.name + ".activateApp(): appName must be" +
2751 " a string" )
2752 return main.FALSE
2753 status = self.appStatus( appName )
2754 if status == "INSTALLED":
2755 response = self.app( appName, "activate" )
2756 if check and response == main.TRUE:
2757 for i in range(10): # try 10 times then give up
2758 # TODO: Check with Thomas about this delay
2759 status = self.appStatus( appName )
2760 if status == "ACTIVE":
2761 return main.TRUE
2762 else:
2763 main.log.debug( "The state of application " +
2764 appName + " is " + status )
2765 time.sleep( 1 )
2766 return main.FALSE
2767 else: # not 'check' or command didn't succeed
2768 return response
2769 elif status == "ACTIVE":
2770 return main.TRUE
2771 elif status == "UNINSTALLED":
2772 main.log.error( self.name + ": Tried to activate the " +
2773 "application '" + appName + "' which is not " +
2774 "installed." )
2775 else:
2776 main.log.error( "Unexpected return value from appStatus: " +
2777 str( status ) )
2778 return main.ERROR
2779 except TypeError:
2780 main.log.exception( self.name + ": Object not as expected" )
2781 return main.ERROR
2782 except pexpect.EOF:
2783 main.log.error( self.name + ": EOF exception found" )
2784 main.log.error( self.name + ": " + self.handle.before )
2785 main.cleanup()
2786 main.exit()
2787 except Exception:
2788 main.log.exception( self.name + ": Uncaught exception!" )
2789 main.cleanup()
2790 main.exit()
2791
2792 def deactivateApp( self, appName, check=True ):
2793 """
2794 Deactivate an app that is already activated in ONOS
2795 appName is the hierarchical app name, not the feature name
2796 If check is True, method will check the status of the app after the
2797 command is issued
2798 Returns main.TRUE if the command was successfully sent
2799 main.FALSE if the cli responded with an error or given
2800 incorrect input
2801 """
2802 try:
2803 if not isinstance( appName, types.StringType ):
2804 main.log.error( self.name + ".deactivateApp(): appName must " +
2805 "be a string" )
2806 return main.FALSE
2807 status = self.appStatus( appName )
2808 if status == "INSTALLED":
2809 return main.TRUE
2810 elif status == "ACTIVE":
2811 response = self.app( appName, "deactivate" )
2812 if check and response == main.TRUE:
2813 for i in range(10): # try 10 times then give up
2814 status = self.appStatus( appName )
2815 if status == "INSTALLED":
2816 return main.TRUE
2817 else:
2818 time.sleep( 1 )
2819 return main.FALSE
2820 else: # not check or command didn't succeed
2821 return response
2822 elif status == "UNINSTALLED":
2823 main.log.warn( self.name + ": Tried to deactivate the " +
2824 "application '" + appName + "' which is not " +
2825 "installed." )
2826 return main.TRUE
2827 else:
2828 main.log.error( "Unexpected return value from appStatus: " +
2829 str( status ) )
2830 return main.ERROR
2831 except TypeError:
2832 main.log.exception( self.name + ": Object not as expected" )
2833 return main.ERROR
2834 except pexpect.EOF:
2835 main.log.error( self.name + ": EOF exception found" )
2836 main.log.error( self.name + ": " + self.handle.before )
2837 main.cleanup()
2838 main.exit()
2839 except Exception:
2840 main.log.exception( self.name + ": Uncaught exception!" )
2841 main.cleanup()
2842 main.exit()
2843
2844 def uninstallApp( self, appName, check=True ):
2845 """
2846 Uninstall an app that is already installed in ONOS
2847 appName is the hierarchical app name, not the feature name
2848 If check is True, method will check the status of the app after the
2849 command is issued
2850 Returns main.TRUE if the command was successfully sent
2851 main.FALSE if the cli responded with an error or given
2852 incorrect input
2853 """
2854 # TODO: check with Thomas about the state machine for apps
2855 try:
2856 if not isinstance( appName, types.StringType ):
2857 main.log.error( self.name + ".uninstallApp(): appName must " +
2858 "be a string" )
2859 return main.FALSE
2860 status = self.appStatus( appName )
2861 if status == "INSTALLED":
2862 response = self.app( appName, "uninstall" )
2863 if check and response == main.TRUE:
2864 for i in range(10): # try 10 times then give up
2865 status = self.appStatus( appName )
2866 if status == "UNINSTALLED":
2867 return main.TRUE
2868 else:
2869 time.sleep( 1 )
2870 return main.FALSE
2871 else: # not check or command didn't succeed
2872 return response
2873 elif status == "ACTIVE":
2874 main.log.warn( self.name + ": Tried to uninstall the " +
2875 "application '" + appName + "' which is " +
2876 "currently active." )
2877 response = self.app( appName, "uninstall" )
2878 if check and response == main.TRUE:
2879 for i in range(10): # try 10 times then give up
2880 status = self.appStatus( appName )
2881 if status == "UNINSTALLED":
2882 return main.TRUE
2883 else:
2884 time.sleep( 1 )
2885 return main.FALSE
2886 else: # not check or command didn't succeed
2887 return response
2888 elif status == "UNINSTALLED":
2889 return main.TRUE
2890 else:
2891 main.log.error( "Unexpected return value from appStatus: " +
2892 str( status ) )
2893 return main.ERROR
2894 except TypeError:
2895 main.log.exception( self.name + ": Object not as expected" )
2896 return main.ERROR
2897 except pexpect.EOF:
2898 main.log.error( self.name + ": EOF exception found" )
2899 main.log.error( self.name + ": " + self.handle.before )
2900 main.cleanup()
2901 main.exit()
2902 except Exception:
2903 main.log.exception( self.name + ": Uncaught exception!" )
2904 main.cleanup()
2905 main.exit()
2906
2907 def appIDs( self, jsonFormat=True ):
2908 """
2909 Show the mappings between app id and app names given by the 'app-ids'
2910 cli command
2911 """
2912 try:
2913 cmdStr = "app-ids"
2914 if jsonFormat:
2915 cmdStr += " -j"
2916 output = self.sendline( cmdStr )
2917 assert "Error executing command" not in output
2918 return output
2919 except AssertionError:
2920 main.log.error( "Error in processing onos:app-ids command: " +
2921 str( output ) )
2922 return None
2923 except TypeError:
2924 main.log.exception( self.name + ": Object not as expected" )
2925 return None
2926 except pexpect.EOF:
2927 main.log.error( self.name + ": EOF exception found" )
2928 main.log.error( self.name + ": " + self.handle.before )
2929 main.cleanup()
2930 main.exit()
2931 except Exception:
2932 main.log.exception( self.name + ": Uncaught exception!" )
2933 main.cleanup()
2934 main.exit()
2935
2936 def appToIDCheck( self ):
2937 """
2938 This method will check that each application's ID listed in 'apps' is
2939 the same as the ID listed in 'app-ids'. The check will also check that
2940 there are no duplicate IDs issued. Note that an app ID should be
2941 a globaly unique numerical identifier for app/app-like features. Once
2942 an ID is registered, the ID is never freed up so that if an app is
2943 reinstalled it will have the same ID.
2944
2945 Returns: main.TRUE if the check passes and
2946 main.FALSE if the check fails or
2947 main.ERROR if there is some error in processing the test
2948 """
2949 try:
2950 bail = False
2951 ids = self.appIDs( jsonFormat=True )
2952 if ids:
2953 ids = json.loads( ids )
2954 else:
2955 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2956 bail = True
2957 apps = self.apps( jsonFormat=True )
2958 if apps:
2959 apps = json.loads( apps )
2960 else:
2961 main.log.error( "apps returned nothing:" + repr( apps ) )
2962 bail = True
2963 if bail:
2964 return main.FALSE
2965 result = main.TRUE
2966 for app in apps:
2967 appID = app.get( 'id' )
2968 if appID is None:
2969 main.log.error( "Error parsing app: " + str( app ) )
2970 result = main.FALSE
2971 appName = app.get( 'name' )
2972 if appName is None:
2973 main.log.error( "Error parsing app: " + str( app ) )
2974 result = main.FALSE
2975 # get the entry in ids that has the same appID
2976 current = filter( lambda item: item[ 'id' ] == appID, ids )
2977 # main.log.debug( "Comparing " + str( app ) + " to " +
2978 # str( current ) )
2979 if not current: # if ids doesn't have this id
2980 result = main.FALSE
2981 main.log.error( "'app-ids' does not have the ID for " +
2982 str( appName ) + " that apps does." )
2983 elif len( current ) > 1:
2984 # there is more than one app with this ID
2985 result = main.FALSE
2986 # We will log this later in the method
2987 elif not current[0][ 'name' ] == appName:
2988 currentName = current[0][ 'name' ]
2989 result = main.FALSE
2990 main.log.error( "'app-ids' has " + str( currentName ) +
2991 " registered under id:" + str( appID ) +
2992 " but 'apps' has " + str( appName ) )
2993 else:
2994 pass # id and name match!
2995 # now make sure that app-ids has no duplicates
2996 idsList = []
2997 namesList = []
2998 for item in ids:
2999 idsList.append( item[ 'id' ] )
3000 namesList.append( item[ 'name' ] )
3001 if len( idsList ) != len( set( idsList ) ) or\
3002 len( namesList ) != len( set( namesList ) ):
3003 main.log.error( "'app-ids' has some duplicate entries: \n"
3004 + json.dumps( ids,
3005 sort_keys=True,
3006 indent=4,
3007 separators=( ',', ': ' ) ) )
3008 result = main.FALSE
3009 return result
3010 except ( ValueError, TypeError ):
3011 main.log.exception( self.name + ": Object not as expected" )
3012 return main.ERROR
3013 except pexpect.EOF:
3014 main.log.error( self.name + ": EOF exception found" )
3015 main.log.error( self.name + ": " + self.handle.before )
3016 main.cleanup()
3017 main.exit()
3018 except Exception:
3019 main.log.exception( self.name + ": Uncaught exception!" )
3020 main.cleanup()
3021 main.exit()
3022
3023 def getCfg( self, component=None, propName=None, short=False,
3024 jsonFormat=True ):
3025 """
3026 Get configuration settings from onos cli
3027 Optional arguments:
3028 component - Optionally only list configurations for a specific
3029 component. If None, all components with configurations
3030 are displayed. Case Sensitive string.
3031 propName - If component is specified, propName option will show
3032 only this specific configuration from that component.
3033 Case Sensitive string.
3034 jsonFormat - Returns output as json. Note that this will override
3035 the short option
3036 short - Short, less verbose, version of configurations.
3037 This is overridden by the json option
3038 returns:
3039 Output from cli as a string or None on error
3040 """
3041 try:
3042 baseStr = "cfg"
3043 cmdStr = " get"
3044 componentStr = ""
3045 if component:
3046 componentStr += " " + component
3047 if propName:
3048 componentStr += " " + propName
3049 if jsonFormat:
3050 baseStr += " -j"
3051 elif short:
3052 baseStr += " -s"
3053 output = self.sendline( baseStr + cmdStr + componentStr )
3054 assert "Error executing command" not in output
3055 return output
3056 except AssertionError:
3057 main.log.error( "Error in processing 'cfg get' command: " +
3058 str( output ) )
3059 return None
3060 except TypeError:
3061 main.log.exception( self.name + ": Object not as expected" )
3062 return None
3063 except pexpect.EOF:
3064 main.log.error( self.name + ": EOF exception found" )
3065 main.log.error( self.name + ": " + self.handle.before )
3066 main.cleanup()
3067 main.exit()
3068 except Exception:
3069 main.log.exception( self.name + ": Uncaught exception!" )
3070 main.cleanup()
3071 main.exit()
3072
3073 def setCfg( self, component, propName, value=None, check=True ):
3074 """
3075 Set/Unset configuration settings from ONOS cli
3076 Required arguments:
3077 component - The case sensitive name of the component whose
3078 property is to be set
3079 propName - The case sensitive name of the property to be set/unset
3080 Optional arguments:
3081 value - The value to set the property to. If None, will unset the
3082 property and revert it to it's default value(if applicable)
3083 check - Boolean, Check whether the option was successfully set this
3084 only applies when a value is given.
3085 returns:
3086 main.TRUE on success or main.FALSE on failure. If check is False,
3087 will return main.TRUE unless there is an error
3088 """
3089 try:
3090 baseStr = "cfg"
3091 cmdStr = " set " + str( component ) + " " + str( propName )
3092 if value is not None:
3093 cmdStr += " " + str( value )
3094 output = self.sendline( baseStr + cmdStr )
3095 assert "Error executing command" not in output
3096 if value and check:
3097 results = self.getCfg( component=str( component ),
3098 propName=str( propName ),
3099 jsonFormat=True )
3100 # Check if current value is what we just set
3101 try:
3102 jsonOutput = json.loads( results )
3103 current = jsonOutput[ 'value' ]
3104 except ( ValueError, TypeError ):
3105 main.log.exception( "Error parsing cfg output" )
3106 main.log.error( "output:" + repr( results ) )
3107 return main.FALSE
3108 if current == str( value ):
3109 return main.TRUE
3110 return main.FALSE
3111 return main.TRUE
3112 except AssertionError:
3113 main.log.error( "Error in processing 'cfg set' command: " +
3114 str( output ) )
3115 return main.FALSE
3116 except TypeError:
3117 main.log.exception( self.name + ": Object not as expected" )
3118 return main.FALSE
3119 except pexpect.EOF:
3120 main.log.error( self.name + ": EOF exception found" )
3121 main.log.error( self.name + ": " + self.handle.before )
3122 main.cleanup()
3123 main.exit()
3124 except Exception:
3125 main.log.exception( self.name + ": Uncaught exception!" )
3126 main.cleanup()
3127 main.exit()
3128
3129 def setTestAdd( self, setName, values ):
3130 """
3131 CLI command to add elements to a distributed set.
3132 Arguments:
3133 setName - The name of the set to add to.
3134 values - The value(s) to add to the set, space seperated.
3135 Example usages:
3136 setTestAdd( "set1", "a b c" )
3137 setTestAdd( "set2", "1" )
3138 returns:
3139 main.TRUE on success OR
3140 main.FALSE if elements were already in the set OR
3141 main.ERROR on error
3142 """
3143 try:
3144 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3145 output = self.sendline( cmdStr )
3146 try:
3147 # TODO: Maybe make this less hardcoded
3148 # ConsistentMap Exceptions
3149 assert "org.onosproject.store.service" not in output
3150 # Node not leader
3151 assert "java.lang.IllegalStateException" not in output
3152 except AssertionError:
3153 main.log.error( "Error in processing 'set-test-add' " +
3154 "command: " + str( output ) )
3155 retryTime = 30 # Conservative time, given by Madan
3156 main.log.info( "Waiting " + str( retryTime ) +
3157 "seconds before retrying." )
3158 time.sleep( retryTime ) # Due to change in mastership
3159 output = self.sendline( cmdStr )
3160 assert "Error executing command" not in output
3161 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3162 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3163 main.log.info( self.name + ": " + output )
3164 if re.search( positiveMatch, output):
3165 return main.TRUE
3166 elif re.search( negativeMatch, output):
3167 return main.FALSE
3168 else:
3169 main.log.error( self.name + ": setTestAdd did not" +
3170 " match expected output" )
pingping-lin763ee042015-05-20 17:45:30 -07003171 main.log.debug( self.name + " actual: " + repr( output ) )
3172 return main.ERROR
3173 except AssertionError:
3174 main.log.error( "Error in processing 'set-test-add' command: " +
3175 str( output ) )
3176 return main.ERROR
3177 except TypeError:
3178 main.log.exception( self.name + ": Object not as expected" )
3179 return main.ERROR
3180 except pexpect.EOF:
3181 main.log.error( self.name + ": EOF exception found" )
3182 main.log.error( self.name + ": " + self.handle.before )
3183 main.cleanup()
3184 main.exit()
3185 except Exception:
3186 main.log.exception( self.name + ": Uncaught exception!" )
3187 main.cleanup()
3188 main.exit()
3189
3190 def setTestRemove( self, setName, values, clear=False, retain=False ):
3191 """
3192 CLI command to remove elements from a distributed set.
3193 Required arguments:
3194 setName - The name of the set to remove from.
3195 values - The value(s) to remove from the set, space seperated.
3196 Optional arguments:
3197 clear - Clear all elements from the set
3198 retain - Retain only the given values. (intersection of the
3199 original set and the given set)
3200 returns:
3201 main.TRUE on success OR
3202 main.FALSE if the set was not changed OR
3203 main.ERROR on error
3204 """
3205 try:
3206 cmdStr = "set-test-remove "
3207 if clear:
3208 cmdStr += "-c " + str( setName )
3209 elif retain:
3210 cmdStr += "-r " + str( setName ) + " " + str( values )
3211 else:
3212 cmdStr += str( setName ) + " " + str( values )
3213 output = self.sendline( cmdStr )
3214 try:
3215 # TODO: Maybe make this less hardcoded
3216 # ConsistentMap Exceptions
3217 assert "org.onosproject.store.service" not in output
3218 # Node not leader
3219 assert "java.lang.IllegalStateException" not in output
3220 except AssertionError:
3221 main.log.error( "Error in processing 'set-test-add' " +
3222 "command: " + str( output ) )
3223 retryTime = 30 # Conservative time, given by Madan
3224 main.log.info( "Waiting " + str( retryTime ) +
3225 "seconds before retrying." )
3226 time.sleep( retryTime ) # Due to change in mastership
3227 output = self.sendline( cmdStr )
3228 assert "Error executing command" not in output
3229 main.log.info( self.name + ": " + output )
3230 if clear:
3231 pattern = "Set " + str( setName ) + " cleared"
3232 if re.search( pattern, output ):
3233 return main.TRUE
3234 elif retain:
3235 positivePattern = str( setName ) + " was pruned to contain " +\
3236 "only elements of set \[(.*)\]"
3237 negativePattern = str( setName ) + " was not changed by " +\
3238 "retaining only elements of the set " +\
3239 "\[(.*)\]"
3240 if re.search( positivePattern, output ):
3241 return main.TRUE
3242 elif re.search( negativePattern, output ):
3243 return main.FALSE
3244 else:
3245 positivePattern = "\[(.*)\] was removed from the set " +\
3246 str( setName )
3247 if ( len( values.split() ) == 1 ):
3248 negativePattern = "\[(.*)\] was not in set " +\
3249 str( setName )
3250 else:
3251 negativePattern = "No element of \[(.*)\] was in set " +\
3252 str( setName )
3253 if re.search( positivePattern, output ):
3254 return main.TRUE
3255 elif re.search( negativePattern, output ):
3256 return main.FALSE
3257 main.log.error( self.name + ": setTestRemove did not" +
3258 " match expected output" )
3259 main.log.debug( self.name + " expected: " + pattern )
3260 main.log.debug( self.name + " actual: " + repr( output ) )
3261 return main.ERROR
3262 except AssertionError:
3263 main.log.error( "Error in processing 'set-test-remove' command: " +
3264 str( output ) )
3265 return main.ERROR
3266 except TypeError:
3267 main.log.exception( self.name + ": Object not as expected" )
3268 return main.ERROR
3269 except pexpect.EOF:
3270 main.log.error( self.name + ": EOF exception found" )
3271 main.log.error( self.name + ": " + self.handle.before )
3272 main.cleanup()
3273 main.exit()
3274 except Exception:
3275 main.log.exception( self.name + ": Uncaught exception!" )
3276 main.cleanup()
3277 main.exit()
3278
3279 def setTestGet( self, setName, values="" ):
3280 """
3281 CLI command to get the elements in a distributed set.
3282 Required arguments:
3283 setName - The name of the set to remove from.
3284 Optional arguments:
3285 values - The value(s) to check if in the set, space seperated.
3286 returns:
3287 main.ERROR on error OR
3288 A list of elements in the set if no optional arguments are
3289 supplied OR
3290 A tuple containing the list then:
3291 main.FALSE if the given values are not in the set OR
3292 main.TRUE if the given values are in the set OR
3293 """
3294 try:
3295 values = str( values ).strip()
3296 setName = str( setName ).strip()
3297 length = len( values.split() )
3298 containsCheck = None
3299 # Patterns to match
3300 setPattern = "\[(.*)\]"
3301 pattern = "Items in set " + setName + ":\n" + setPattern
3302 containsTrue = "Set " + setName + " contains the value " + values
3303 containsFalse = "Set " + setName + " did not contain the value " +\
3304 values
3305 containsAllTrue = "Set " + setName + " contains the the subset " +\
3306 setPattern
3307 containsAllFalse = "Set " + setName + " did not contain the the" +\
3308 " subset " + setPattern
3309
3310 cmdStr = "set-test-get "
3311 cmdStr += setName + " " + values
3312 output = self.sendline( cmdStr )
3313 try:
3314 # TODO: Maybe make this less hardcoded
3315 # ConsistentMap Exceptions
3316 assert "org.onosproject.store.service" not in output
3317 # Node not leader
3318 assert "java.lang.IllegalStateException" not in output
3319 except AssertionError:
3320 main.log.error( "Error in processing 'set-test-add' " +
3321 "command: " + str( output ) )
3322 retryTime = 30 # Conservative time, given by Madan
3323 main.log.info( "Waiting " + str( retryTime ) +
3324 "seconds before retrying." )
3325 time.sleep( retryTime ) # Due to change in mastership
3326 output = self.sendline( cmdStr )
3327 assert "Error executing command" not in output
3328 main.log.info( self.name + ": " + output )
3329
3330 if length == 0:
3331 match = re.search( pattern, output )
3332 else: # if given values
3333 if length == 1: # Contains output
3334 patternTrue = pattern + "\n" + containsTrue
3335 patternFalse = pattern + "\n" + containsFalse
3336 else: # ContainsAll output
3337 patternTrue = pattern + "\n" + containsAllTrue
3338 patternFalse = pattern + "\n" + containsAllFalse
3339 matchTrue = re.search( patternTrue, output )
3340 matchFalse = re.search( patternFalse, output )
3341 if matchTrue:
3342 containsCheck = main.TRUE
3343 match = matchTrue
3344 elif matchFalse:
3345 containsCheck = main.FALSE
3346 match = matchFalse
3347 else:
3348 main.log.error( self.name + " setTestGet did not match " +\
3349 "expected output" )
3350 main.log.debug( self.name + " expected: " + pattern )
3351 main.log.debug( self.name + " actual: " + repr( output ) )
3352 match = None
3353 if match:
3354 setMatch = match.group( 1 )
3355 if setMatch == '':
3356 setList = []
3357 else:
3358 setList = setMatch.split( ", " )
3359 if length > 0:
3360 return ( setList, containsCheck )
3361 else:
3362 return setList
3363 else: # no match
3364 main.log.error( self.name + ": setTestGet did not" +
3365 " match expected output" )
3366 main.log.debug( self.name + " expected: " + pattern )
3367 main.log.debug( self.name + " actual: " + repr( output ) )
3368 return main.ERROR
3369 except AssertionError:
3370 main.log.error( "Error in processing 'set-test-get' command: " +
3371 str( output ) )
3372 return main.ERROR
3373 except TypeError:
3374 main.log.exception( self.name + ": Object not as expected" )
3375 return main.ERROR
3376 except pexpect.EOF:
3377 main.log.error( self.name + ": EOF exception found" )
3378 main.log.error( self.name + ": " + self.handle.before )
3379 main.cleanup()
3380 main.exit()
3381 except Exception:
3382 main.log.exception( self.name + ": Uncaught exception!" )
3383 main.cleanup()
3384 main.exit()
3385
3386 def setTestSize( self, setName ):
3387 """
3388 CLI command to get the elements in a distributed set.
3389 Required arguments:
3390 setName - The name of the set to remove from.
3391 returns:
3392 The integer value of the size returned or
3393 None on error
3394 """
3395 try:
3396 # TODO: Should this check against the number of elements returned
3397 # and then return true/false based on that?
3398 setName = str( setName ).strip()
3399 # Patterns to match
3400 setPattern = "\[(.*)\]"
3401 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3402 setPattern
3403 cmdStr = "set-test-get -s "
3404 cmdStr += setName
3405 output = self.sendline( cmdStr )
3406 try:
3407 # TODO: Maybe make this less hardcoded
3408 # ConsistentMap Exceptions
3409 assert "org.onosproject.store.service" not in output
3410 # Node not leader
3411 assert "java.lang.IllegalStateException" not in output
3412 except AssertionError:
3413 main.log.error( "Error in processing 'set-test-add' " +
3414 "command: " + str( output ) )
3415 retryTime = 30 # Conservative time, given by Madan
3416 main.log.info( "Waiting " + str( retryTime ) +
3417 "seconds before retrying." )
3418 time.sleep( retryTime ) # Due to change in mastership
3419 output = self.sendline( cmdStr )
3420 assert "Error executing command" not in output
3421 main.log.info( self.name + ": " + output )
3422 match = re.search( pattern, output )
3423 if match:
3424 setSize = int( match.group( 1 ) )
3425 setMatch = match.group( 2 )
3426 if len( setMatch.split() ) == setSize:
3427 main.log.info( "The size returned by " + self.name +
3428 " matches the number of elements in " +
3429 "the returned set" )
3430 else:
3431 main.log.error( "The size returned by " + self.name +
3432 " does not match the number of " +
3433 "elements in the returned set." )
3434 return setSize
3435 else: # no match
3436 main.log.error( self.name + ": setTestGet did not" +
3437 " match expected output" )
3438 main.log.debug( self.name + " expected: " + pattern )
3439 main.log.debug( self.name + " actual: " + repr( output ) )
3440 return None
3441 except AssertionError:
3442 main.log.error( "Error in processing 'set-test-get' command: " +
3443 str( output ) )
3444 return None
3445 except TypeError:
3446 main.log.exception( self.name + ": Object not as expected" )
3447 return None
3448 except pexpect.EOF:
3449 main.log.error( self.name + ": EOF exception found" )
3450 main.log.error( self.name + ": " + self.handle.before )
3451 main.cleanup()
3452 main.exit()
3453 except Exception:
3454 main.log.exception( self.name + ": Uncaught exception!" )
3455 main.cleanup()
3456 main.exit()
3457
Jon Hall80daded2015-05-27 16:07:00 -07003458 def counters( self, jsonFormat=True ):
pingping-lin763ee042015-05-20 17:45:30 -07003459 """
3460 Command to list the various counters in the system.
3461 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003462 if jsonFormat, a string of the json object returned by the cli
3463 command
3464 if not jsonFormat, the normal string output of the cli command
pingping-lin763ee042015-05-20 17:45:30 -07003465 None on error
3466 """
pingping-lin763ee042015-05-20 17:45:30 -07003467 try:
3468 counters = {}
3469 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003470 if jsonFormat:
3471 cmdStr += " -j"
pingping-lin763ee042015-05-20 17:45:30 -07003472 output = self.sendline( cmdStr )
3473 assert "Error executing command" not in output
3474 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003475 return output
pingping-lin763ee042015-05-20 17:45:30 -07003476 except AssertionError:
3477 main.log.error( "Error in processing 'counters' command: " +
3478 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003479 return None
pingping-lin763ee042015-05-20 17:45:30 -07003480 except TypeError:
3481 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003482 return None
pingping-lin763ee042015-05-20 17:45:30 -07003483 except pexpect.EOF:
3484 main.log.error( self.name + ": EOF exception found" )
3485 main.log.error( self.name + ": " + self.handle.before )
3486 main.cleanup()
3487 main.exit()
3488 except Exception:
3489 main.log.exception( self.name + ": Uncaught exception!" )
3490 main.cleanup()
3491 main.exit()
3492
3493 def counterTestIncrement( self, counter, inMemory=False ):
3494 """
3495 CLI command to increment and get a distributed counter.
3496 Required arguments:
3497 counter - The name of the counter to increment.
3498 Optional arguments:
3499 inMemory - use in memory map for the counter
3500 returns:
3501 integer value of the counter or
3502 None on Error
3503 """
3504 try:
3505 counter = str( counter )
3506 cmdStr = "counter-test-increment "
3507 if inMemory:
3508 cmdStr += "-i "
3509 cmdStr += counter
3510 output = self.sendline( cmdStr )
3511 try:
3512 # TODO: Maybe make this less hardcoded
3513 # ConsistentMap Exceptions
3514 assert "org.onosproject.store.service" not in output
3515 # Node not leader
3516 assert "java.lang.IllegalStateException" not in output
3517 except AssertionError:
3518 main.log.error( "Error in processing 'set-test-add' " +
3519 "command: " + str( output ) )
3520 retryTime = 30 # Conservative time, given by Madan
3521 main.log.info( "Waiting " + str( retryTime ) +
3522 "seconds before retrying." )
3523 time.sleep( retryTime ) # Due to change in mastership
3524 output = self.sendline( cmdStr )
3525 assert "Error executing command" not in output
3526 main.log.info( self.name + ": " + output )
3527 pattern = counter + " was incremented to (\d+)"
3528 match = re.search( pattern, output )
3529 if match:
3530 return int( match.group( 1 ) )
3531 else:
3532 main.log.error( self.name + ": counterTestIncrement did not" +
3533 " match expected output." )
3534 main.log.debug( self.name + " expected: " + pattern )
3535 main.log.debug( self.name + " actual: " + repr( output ) )
3536 return None
3537 except AssertionError:
3538 main.log.error( "Error in processing 'counter-test-increment'" +
3539 " command: " + str( output ) )
3540 return None
3541 except TypeError:
3542 main.log.exception( self.name + ": Object not as expected" )
3543 return None
3544 except pexpect.EOF:
3545 main.log.error( self.name + ": EOF exception found" )
3546 main.log.error( self.name + ": " + self.handle.before )
3547 main.cleanup()
3548 main.exit()
3549 except Exception:
3550 main.log.exception( self.name + ": Uncaught exception!" )
3551 main.cleanup()
3552 main.exit()
3553