blob: 5da4a714b70e04d85e58f24584fe75f587b7a0d2 [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
Hari Krishna0ce0e152015-06-23 09:55:29 -07001627 def purgeIntents( self ):
1628 """
1629 Purges all WITHDRAWN Intents
1630 """
1631 try:
1632 cmdStr = "purge-intents"
1633 handle = self.sendline( cmdStr )
1634 if re.search( "Error", handle ):
1635 main.log.error( "Error in purging intents" )
1636 return main.FALSE
1637 else:
1638 return main.TRUE
1639 except TypeError:
1640 main.log.exception( self.name + ": Object not as expected" )
1641 return None
1642 except pexpect.EOF:
1643 main.log.error( self.name + ": EOF exception found" )
1644 main.log.error( self.name + ": " + self.handle.before )
1645 main.cleanup()
1646 main.exit()
1647 except Exception:
1648 main.log.exception( self.name + ": Uncaught exception!" )
1649 main.cleanup()
1650 main.exit()
1651
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001653 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001654 NOTE: This method should be used after installing application:
1655 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001656 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001658 Description:
1659 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001660 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001661 try:
pingping-lin763ee042015-05-20 17:45:30 -07001662 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001664 cmdStr += " -j"
1665 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001666 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001667 except TypeError:
1668 main.log.exception( self.name + ": Object not as expected" )
1669 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001670 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001671 main.log.error( self.name + ": EOF exception found" )
1672 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001673 main.cleanup()
1674 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001675 except Exception:
1676 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001677 main.cleanup()
1678 main.exit()
1679
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001681 """
andrewonlab377693f2014-10-21 16:00:30 -04001682 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001684 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001685 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001686 """
andrewonlabe6745342014-10-17 14:29:13 -04001687 try:
pingping-lin763ee042015-05-20 17:45:30 -07001688 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001690 cmdStr += " -j"
1691 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001692 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001693 except TypeError:
1694 main.log.exception( self.name + ": Object not as expected" )
1695 return None
andrewonlabe6745342014-10-17 14:29:13 -04001696 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001697 main.log.error( self.name + ": EOF exception found" )
1698 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001699 main.cleanup()
1700 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001701 except Exception:
1702 main.log.exception( self.name + ": Uncaught exception!" )
1703 main.cleanup()
1704 main.exit()
1705
1706 def getIntentState(self, intentsId, intentsJson=None):
1707 """
1708 Check intent state.
1709 Accepts a single intent ID (string type) or a list of intent IDs.
1710 Returns the state(string type) of the id if a single intent ID is
1711 accepted.
1712 Returns a dictionary with intent IDs as the key and its
1713 corresponding states as the values
1714 Parameters:
1715 intentId: intent ID (string type)
1716 intentsJson: parsed json object from the onos:intents api
1717 Returns:
1718 state = An intent's state- INSTALL,WITHDRAWN etc.
1719 stateDict = Dictionary of intent's state. intent ID as the keys and
1720 state as the values.
1721 """
1722 try:
1723 state = "State is Undefined"
1724 if not intentsJson:
1725 intentsJsonTemp = json.loads( self.intents() )
1726 else:
1727 intentsJsonTemp = json.loads( intentsJson )
1728 if isinstance( intentsId, types.StringType ):
1729 for intent in intentsJsonTemp:
1730 if intentsId == intent[ 'id' ]:
1731 state = intent[ 'state' ]
1732 return state
1733 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1734 " on the list" )
1735 return state
1736 elif isinstance( intentsId, types.ListType ):
1737 dictList = []
1738 for i in xrange( len( intentsId ) ):
1739 stateDict = {}
1740 for intents in intentsJsonTemp:
1741 if intentsId[ i ] == intents[ 'id' ]:
1742 stateDict[ 'state' ] = intents[ 'state' ]
1743 stateDict[ 'id' ] = intentsId[ i ]
1744 dictList.append( stateDict )
1745 break
1746 if len( intentsId ) != len( dictList ):
1747 main.log.info( "Cannot find some of the intent ID state" )
1748 return dictList
1749 else:
1750 main.log.info( "Invalid intents ID entry" )
1751 return None
1752 except TypeError:
1753 main.log.exception( self.name + ": Object not as expected" )
1754 return None
1755 except pexpect.EOF:
1756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + ": " + self.handle.before )
1758 main.cleanup()
1759 main.exit()
1760 except Exception:
1761 main.log.exception( self.name + ": Uncaught exception!" )
1762 main.cleanup()
1763 main.exit()
1764
1765 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1766 """
1767 Description:
1768 Check intents state
1769 Required:
1770 intentsId - List of intents ID to be checked
1771 Optional:
1772 expectedState - Check this expected state of each intents state
1773 in the list. Defaults to INSTALLED
1774 Return:
1775 Returns main.TRUE only if all intent are the same as expectedState,
1776 , otherwise,returns main.FALSE.
1777 """
1778 try:
1779 # Generating a dictionary: intent id as a key and state as value
1780 intentsDict = self.getIntentState( intentsId )
1781 #print "len of intentsDict ", str( len( intentsDict ) )
1782 if len( intentsId ) != len( intentsDict ):
1783 main.log.info( self.name + "There is something wrong " +
1784 "getting intents state" )
1785 return main.FALSE
1786 returnValue = main.TRUE
1787 for intents in intentsDict:
1788 if intents.get( 'state' ) != expectedState:
1789 main.log.info( self.name + " : " + intents.get( 'id' ) +
1790 " actual state = " + intents.get( 'state' )
1791 + " does not equal expected state = "
1792 + expectedState )
1793 returnValue = main.FALSE
1794 if returnValue == main.TRUE:
1795 main.log.info( self.name + ": All " +
1796 str( len( intentsDict ) ) +
1797 " intents are in " + expectedState + " state")
1798 return returnValue
1799 except TypeError:
1800 main.log.exception( self.name + ": Object not as expected" )
1801 return None
1802 except pexpect.EOF:
1803 main.log.error( self.name + ": EOF exception found" )
1804 main.log.error( self.name + ": " + self.handle.before )
1805 main.cleanup()
1806 main.exit()
1807 except Exception:
1808 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001809 main.cleanup()
1810 main.exit()
1811
kelvin-onlabd3b64892015-01-20 13:26:24 -08001812 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001813 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001814 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001816 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001817 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001818 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001819 try:
pingping-lin763ee042015-05-20 17:45:30 -07001820 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001821 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001822 cmdStr += " -j"
1823 handle = self.sendline( cmdStr )
1824 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001825 main.log.error( self.name + ".flows() response: " +
1826 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001827 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001828 except TypeError:
1829 main.log.exception( self.name + ": Object not as expected" )
1830 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001832 main.log.error( self.name + ": EOF exception found" )
1833 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001834 main.cleanup()
1835 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001836 except Exception:
1837 main.log.exception( self.name + ": Uncaught exception!" )
1838 main.cleanup()
1839 main.exit()
1840
1841 def checkFlowsState( self ):
1842 """
1843 Description:
1844 Check the if all the current flows are in ADDED state or
1845 PENDING_ADD state
1846 Return:
1847 returnValue - Returns main.TRUE only if all flows are in
1848 ADDED state or PENDING_ADD, return main.FALSE
1849 otherwise.
1850 """
1851 try:
1852 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001853 #print tempFlows[0]
pingping-lin763ee042015-05-20 17:45:30 -07001854 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001855
pingping-lin763ee042015-05-20 17:45:30 -07001856 for device in tempFlows:
1857 for flow in device.get( 'flows' ):
1858 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1859 'PENDING_ADD':
1860 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf0594d72015-05-19 17:25:12 -07001861 flow.get( 'groupId' ) +
pingping-lin763ee042015-05-20 17:45:30 -07001862 " | state:" + flow.get( 'state' ) )
1863 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001864
pingping-lin763ee042015-05-20 17:45:30 -07001865 return returnValue
1866 except TypeError:
1867 main.log.exception( self.name + ": Object not as expected" )
1868 return None
1869 except pexpect.EOF:
1870 main.log.error( self.name + ": EOF exception found" )
1871 main.log.error( self.name + ": " + self.handle.before )
1872 main.cleanup()
1873 main.exit()
1874 except Exception:
1875 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001876 main.cleanup()
1877 main.exit()
1878
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
pingping-lin763ee042015-05-20 17:45:30 -07001880 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001881 """
andrewonlab87852b02014-11-19 18:44:19 -05001882 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001883 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001884 a specific point-to-point intent definition
1885 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001886 * dpidSrc: specify source dpid
1887 * dpidDst: specify destination dpid
1888 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001889 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001890 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001891 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001892 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001893 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001894 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001895 """
andrewonlab87852b02014-11-19 18:44:19 -05001896 try:
kelvin8ec71442015-01-15 16:57:00 -08001897 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001898 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1899 str( numIntents )
1900 if numMult:
1901 cmd += " " + str( numMult )
1902 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001903 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001904 if appId:
1905 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001906 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001907 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001908 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001909 main.log.info( handle )
1910 # Split result by newline
1911 newline = handle.split( "\r\r\n" )
1912 # Ignore the first object of list, which is empty
1913 newline = newline[ 1: ]
1914 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001915 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001916 result = result.split( ": " )
1917 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001918 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1919 main.log.info( latResult )
1920 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001921 else:
1922 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001923 except TypeError:
1924 main.log.exception( self.name + ": Object not as expected" )
1925 return None
andrewonlab87852b02014-11-19 18:44:19 -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 )
andrewonlab87852b02014-11-19 18:44:19 -05001929 main.cleanup()
1930 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001931 except Exception:
1932 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001933 main.cleanup()
1934 main.exit()
1935
kelvin-onlabd3b64892015-01-20 13:26:24 -08001936 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001937 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001938 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001939 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001940 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001941 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001942 try:
pingping-lin763ee042015-05-20 17:45:30 -07001943 cmdStr = "intents-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 )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001947 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001948 except TypeError:
1949 main.log.exception( self.name + ": Object not as expected" )
1950 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001951 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001952 main.log.error( self.name + ": EOF exception found" )
1953 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001954 main.cleanup()
1955 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001956 except Exception:
1957 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001958 main.cleanup()
1959 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001960
kelvin-onlabd3b64892015-01-20 13:26:24 -08001961 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001962 """
1963 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001964 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001965 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001966 """
andrewonlab867212a2014-10-22 20:13:38 -04001967 try:
pingping-lin763ee042015-05-20 17:45:30 -07001968 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001970 cmdStr += " -j"
1971 handle = self.sendline( cmdStr )
1972 if handle:
1973 return handle
1974 elif jsonFormat:
1975 # Return empty json
1976 return '{}'
andrewonlab867212a2014-10-22 20:13:38 -04001977 else:
pingping-lin763ee042015-05-20 17:45:30 -07001978 return handle
1979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return None
andrewonlab867212a2014-10-22 20:13:38 -04001982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001985 main.cleanup()
1986 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001987 except Exception:
1988 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001989 main.cleanup()
1990 main.exit()
1991
kelvin8ec71442015-01-15 16:57:00 -08001992 # Wrapper functions ****************
1993 # Wrapper functions use existing driver
1994 # functions and extends their use case.
1995 # For example, we may use the output of
1996 # a normal driver function, and parse it
1997 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001998
kelvin-onlabd3b64892015-01-20 13:26:24 -08001999 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002000 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002001 Description:
2002 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002003 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002004 try:
kelvin8ec71442015-01-15 16:57:00 -08002005 # Obtain output of intents function
pingping-lin763ee042015-05-20 17:45:30 -07002006 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002007 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002008
kelvin8ec71442015-01-15 16:57:00 -08002009 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002010 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2011 for intents in intentsList:
pingping-lin763ee042015-05-20 17:45:30 -07002012 match = re.search('id=0x([\da-f]+),', intents)
2013 if match:
2014 tmpId = match.group()[3:-1]
2015 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002016 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002017
pingping-lin763ee042015-05-20 17:45:30 -07002018 except TypeError:
2019 main.log.exception( self.name + ": Object not as expected" )
2020 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002021 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002022 main.log.error( self.name + ": EOF exception found" )
2023 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002024 main.cleanup()
2025 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002026 except Exception:
2027 main.log.exception( self.name + ": Uncaught exception!" )
2028 main.cleanup()
2029 main.exit()
2030
2031 def FlowAddedCount( self, deviceId ):
2032 """
2033 Determine the number of flow rules for the given device id that are
2034 in the added state
2035 """
2036 try:
2037 cmdStr = "flows any " + str( deviceId ) + " | " +\
2038 "grep 'state=ADDED' | wc -l"
2039 handle = self.sendline( cmdStr )
2040 return handle
2041 except pexpect.EOF:
2042 main.log.error( self.name + ": EOF exception found" )
2043 main.log.error( self.name + ": " + self.handle.before )
2044 main.cleanup()
2045 main.exit()
2046 except Exception:
2047 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002048 main.cleanup()
2049 main.exit()
2050
kelvin-onlabd3b64892015-01-20 13:26:24 -08002051 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002052 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002053 Use 'devices' function to obtain list of all devices
2054 and parse the result to obtain a list of all device
2055 id's. Returns this list. Returns empty list if no
2056 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002057 List is ordered sequentially
2058
andrewonlab3e15ead2014-10-15 14:21:34 -04002059 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002060 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002061 the ids. By obtaining the list of device ids on the fly,
2062 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002063 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002064 try:
kelvin8ec71442015-01-15 16:57:00 -08002065 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002066 devicesStr = self.devices( jsonFormat=False )
2067 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002068
kelvin-onlabd3b64892015-01-20 13:26:24 -08002069 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002070 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 return idList
kelvin8ec71442015-01-15 16:57:00 -08002072
2073 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002075 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002077 # Split list further into arguments before and after string
2078 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002079 # append to idList
2080 for arg in tempList:
2081 idList.append( arg.split( "id=" )[ 1 ] )
2082 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002083
pingping-lin763ee042015-05-20 17:45:30 -07002084 except TypeError:
2085 main.log.exception( self.name + ": Object not as expected" )
2086 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002087 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002088 main.log.error( self.name + ": EOF exception found" )
2089 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002090 main.cleanup()
2091 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002092 except Exception:
2093 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002094 main.cleanup()
2095 main.exit()
2096
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002098 """
andrewonlab7c211572014-10-15 16:45:20 -04002099 Uses 'nodes' function to obtain list of all nodes
2100 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002101 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002102 Returns:
2103 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002104 """
andrewonlab7c211572014-10-15 16:45:20 -04002105 try:
pingping-lin763ee042015-05-20 17:45:30 -07002106 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002107 idList = []
pingping-lin763ee042015-05-20 17:45:30 -07002108 # Sample nodesStr output
2109 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002110 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002111 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002112 return idList
pingping-lin763ee042015-05-20 17:45:30 -07002113 nodesJson = json.loads( nodesStr )
2114 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002115 return idList
kelvin8ec71442015-01-15 16:57:00 -08002116
pingping-lin763ee042015-05-20 17:45:30 -07002117 except TypeError:
2118 main.log.exception( self.name + ": Object not as expected" )
2119 return None
andrewonlab7c211572014-10-15 16:45:20 -04002120 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002121 main.log.error( self.name + ": EOF exception found" )
2122 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002123 main.cleanup()
2124 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002125 except Exception:
2126 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002127 main.cleanup()
2128 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002129
kelvin-onlabd3b64892015-01-20 13:26:24 -08002130 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002131 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002132 Return the first device from the devices api whose 'id' contains 'dpid'
2133 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002134 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002135 try:
kelvin8ec71442015-01-15 16:57:00 -08002136 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002137 return None
2138 else:
kelvin8ec71442015-01-15 16:57:00 -08002139 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 rawDevices = self.devices()
2141 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002142 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002143 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002144 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2145 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002146 return device
2147 return None
pingping-lin763ee042015-05-20 17:45:30 -07002148 except TypeError:
2149 main.log.exception( self.name + ": Object not as expected" )
2150 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002151 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002152 main.log.error( self.name + ": EOF exception found" )
2153 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002154 main.cleanup()
2155 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002156 except Exception:
2157 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002158 main.cleanup()
2159 main.exit()
2160
kelvin-onlabd3b64892015-01-20 13:26:24 -08002161 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002162 """
pingping-lin763ee042015-05-20 17:45:30 -07002163 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002164 supplied values. By default this will report to main.log, but the
pingping-lin763ee042015-05-20 17:45:30 -07002165 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002166
Jon Hall42db6dc2014-10-24 19:03:48 -04002167 Params: ip = ip used for the onos cli
2168 numoswitch = expected number of switches
pingping-lin763ee042015-05-20 17:45:30 -07002169 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002170 logLevel = level to log to. Currently accepts
2171 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002172
2173
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002175
pingping-lin763ee042015-05-20 17:45:30 -07002176 Returns: main.TRUE if the number of switches and links are correct,
2177 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002178 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002179 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002180 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002181 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002182 if topology == {}:
2183 return main.ERROR
2184 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002185 # Is the number of switches is what we expected
2186 devices = topology.get( 'devices', False )
2187 links = topology.get( 'links', False )
pingping-lin763ee042015-05-20 17:45:30 -07002188 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002189 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002191 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002192 linkCheck = ( int( links ) == int( numolink ) )
2193 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002194 # We expected the correct numbers
pingping-lin763ee042015-05-20 17:45:30 -07002195 output += "The number of links and switches match " +\
2196 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002197 result = main.TRUE
2198 else:
pingping-lin763ee042015-05-20 17:45:30 -07002199 output += "The number of links and switches does not match " +\
2200 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002201 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002202 output = output + "\n ONOS sees %i devices (%i expected) \
2203 and %i links (%i expected)" % (
2204 int( devices ), int( numoswitch ), int( links ),
2205 int( numolink ) )
2206 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002207 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002208 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002209 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002210 else:
pingping-lin763ee042015-05-20 17:45:30 -07002211 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002212 return result
pingping-lin763ee042015-05-20 17:45:30 -07002213 except TypeError:
2214 main.log.exception( self.name + ": Object not as expected" )
2215 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002216 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002217 main.log.error( self.name + ": EOF exception found" )
2218 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002219 main.cleanup()
2220 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002221 except Exception:
2222 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002223 main.cleanup()
2224 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002225
kelvin-onlabd3b64892015-01-20 13:26:24 -08002226 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002227 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002228 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002229 deviceId must be the id of a device as seen in the onos devices command
2230 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002231 role must be either master, standby, or none
2232
Jon Halle3f39ff2015-01-13 11:50:53 -08002233 Returns:
2234 main.TRUE or main.FALSE based on argument verification and
2235 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002236 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002237 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002238 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002239 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002240 cmdStr = "device-role " +\
2241 str( deviceId ) + " " +\
2242 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002243 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002244 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002245 if re.search( "Error", handle ):
2246 # end color output to escape any colours
2247 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002248 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002249 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002250 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002251 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002252 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002253 main.log.error( "Invalid 'role' given to device_role(). " +
2254 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002255 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002256 except TypeError:
2257 main.log.exception( self.name + ": Object not as expected" )
2258 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002259 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 Hall1c9e8732014-10-27 19:29:27 -04002262 main.cleanup()
2263 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002264 except Exception:
2265 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002266 main.cleanup()
2267 main.exit()
2268
kelvin-onlabd3b64892015-01-20 13:26:24 -08002269 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002270 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002271 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002272 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002273 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002274 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002275 try:
pingping-lin763ee042015-05-20 17:45:30 -07002276 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002277 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07002278 cmdStr += " -j"
2279 handle = self.sendline( cmdStr )
2280 return handle
2281 except TypeError:
2282 main.log.exception( self.name + ": Object not as expected" )
2283 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002284 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002285 main.log.error( self.name + ": EOF exception found" )
2286 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002287 main.cleanup()
2288 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002289 except Exception:
2290 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002291 main.cleanup()
2292 main.exit()
2293
kelvin-onlabd3b64892015-01-20 13:26:24 -08002294 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002295 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002296 CLI command to get the current leader for the Election test application
2297 NOTE: Requires installation of the onos-app-election feature
2298 Returns: Node IP of the leader if one exists
2299 None if none exists
2300 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002301 """
Jon Hall94fd0472014-12-08 11:52:42 -08002302 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002303 cmdStr = "election-test-leader"
2304 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002305 # Leader
2306 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002307 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002308 nodeSearch = re.search( leaderPattern, response )
2309 if nodeSearch:
2310 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002311 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002312 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002313 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002314 # no leader
2315 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002316 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002317 nullSearch = re.search( nullPattern, response )
2318 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002319 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002320 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002321 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002322 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002323 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002324 if re.search( errorPattern, response ):
2325 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002326 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002327 return main.FALSE
2328 else:
pingping-lin763ee042015-05-20 17:45:30 -07002329 main.log.error( "Error in electionTestLeader on " + self.name +
2330 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002331 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002332 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002333 except TypeError:
2334 main.log.exception( self.name + ": Object not as expected" )
2335 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002336 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002337 main.log.error( self.name + ": EOF exception found" )
2338 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002339 main.cleanup()
2340 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002341 except Exception:
2342 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002343 main.cleanup()
2344 main.exit()
2345
kelvin-onlabd3b64892015-01-20 13:26:24 -08002346 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002347 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002348 CLI command to run for leadership of the Election test application.
2349 NOTE: Requires installation of the onos-app-election feature
2350 Returns: Main.TRUE on success
2351 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002352 """
Jon Hall94fd0472014-12-08 11:52:42 -08002353 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002354 cmdStr = "election-test-run"
2355 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002356 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002357 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002358 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002359 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002360 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002361 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002362 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002363 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002364 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002365 errorPattern = "Command\snot\sfound"
2366 if re.search( errorPattern, response ):
2367 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002368 return main.FALSE
2369 else:
pingping-lin763ee042015-05-20 17:45:30 -07002370 main.log.error( "Error in electionTestRun on " + self.name +
2371 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002372 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002373 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002374 except TypeError:
2375 main.log.exception( self.name + ": Object not as expected" )
2376 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002377 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002378 main.log.error( self.name + ": EOF exception found" )
2379 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002380 main.cleanup()
2381 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002382 except Exception:
2383 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002384 main.cleanup()
2385 main.exit()
2386
kelvin-onlabd3b64892015-01-20 13:26:24 -08002387 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002388 """
Jon Hall94fd0472014-12-08 11:52:42 -08002389 * CLI command to withdraw the local node from leadership election for
2390 * the Election test application.
2391 #NOTE: Requires installation of the onos-app-election feature
2392 Returns: Main.TRUE on success
2393 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002394 """
Jon Hall94fd0472014-12-08 11:52:42 -08002395 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002396 cmdStr = "election-test-withdraw"
2397 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002398 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002399 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002400 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002401 if re.search( successPattern, response ):
2402 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002403 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002404 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002405 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002406 errorPattern = "Command\snot\sfound"
2407 if re.search( errorPattern, response ):
2408 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002409 return main.FALSE
2410 else:
pingping-lin763ee042015-05-20 17:45:30 -07002411 main.log.error( "Error in electionTestWithdraw on " +
2412 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002413 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002414 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002415 except TypeError:
2416 main.log.exception( self.name + ": Object not as expected" )
2417 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002419 main.log.error( self.name + ": EOF exception found" )
2420 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002421 main.cleanup()
2422 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002423 except Exception:
2424 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002425 main.cleanup()
2426 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002427
kelvin8ec71442015-01-15 16:57:00 -08002428 def getDevicePortsEnabledCount( self, dpid ):
2429 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002430 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002431 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002432 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002433 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002434 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2435 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002436 if re.search( "No such device", output ):
2437 main.log.error( "Error in getting ports" )
2438 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002439 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002440 return output
pingping-lin763ee042015-05-20 17:45:30 -07002441 except TypeError:
2442 main.log.exception( self.name + ": Object not as expected" )
2443 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002444 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002445 main.log.error( self.name + ": EOF exception found" )
2446 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002447 main.cleanup()
2448 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002449 except Exception:
2450 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002451 main.cleanup()
2452 main.exit()
2453
kelvin8ec71442015-01-15 16:57:00 -08002454 def getDeviceLinksActiveCount( self, dpid ):
2455 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002456 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002457 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002458 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002459 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002460 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2461 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002462 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002463 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()
2479
kelvin8ec71442015-01-15 16:57:00 -08002480 def getAllIntentIds( self ):
2481 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002482 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002483 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002484 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002485 cmdStr = "onos:intents | grep id="
2486 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002487 if re.search( "Error", output ):
2488 main.log.error( "Error in getting ports" )
2489 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002490 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002491 return output
pingping-lin763ee042015-05-20 17:45:30 -07002492 except TypeError:
2493 main.log.exception( self.name + ": Object not as expected" )
2494 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002495 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002496 main.log.error( self.name + ": EOF exception found" )
2497 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002498 main.cleanup()
2499 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002500 except Exception:
2501 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002502 main.cleanup()
2503 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002504
2505 def intentSummary( self ):
2506 """
2507 Returns a dictionary containing the current intent states and the count
2508 """
2509 try:
2510 intents = self.intents( )
2511 states = []
2512 for intent in json.loads( intents ):
2513 states.append( intent.get( 'state', None ) )
2514 out = [ ( i, states.count( i ) ) for i in set( states ) ]
2515 main.log.info( dict( out ) )
2516 return dict( out )
2517 except TypeError:
2518 main.log.exception( self.name + ": Object not as expected" )
2519 return None
2520 except pexpect.EOF:
2521 main.log.error( self.name + ": EOF exception found" )
2522 main.log.error( self.name + ": " + self.handle.before )
2523 main.cleanup()
2524 main.exit()
2525 except Exception:
2526 main.log.exception( self.name + ": Uncaught exception!" )
2527 main.cleanup()
2528 main.exit()
2529
2530 def leaders( self, jsonFormat=True ):
2531 """
2532 Returns the output of the leaders command.
2533 Optional argument:
2534 * jsonFormat - boolean indicating if you want output in json
2535 """
2536 # FIXME: add json output
2537 # Sample JSON
2538 # {
2539 # "electedTime": "13m ago",
2540 # "epoch": 4,
2541 # "leader": "10.128.30.17",
2542 # "topic": "intent-partition-3"
2543 # },
2544 try:
2545 cmdStr = "onos:leaders"
2546 if jsonFormat:
2547 cmdStr += " -j"
2548 output = self.sendline( cmdStr )
2549 return output
2550 except TypeError:
2551 main.log.exception( self.name + ": Object not as expected" )
2552 return None
2553 except pexpect.EOF:
2554 main.log.error( self.name + ": EOF exception found" )
2555 main.log.error( self.name + ": " + self.handle.before )
2556 main.cleanup()
2557 main.exit()
2558 except Exception:
2559 main.log.exception( self.name + ": Uncaught exception!" )
2560 main.cleanup()
2561 main.exit()
2562
2563 def pendingMap( self, jsonFormat=True ):
2564 """
2565 Returns the output of the intent Pending map.
2566 """
2567 try:
2568 cmdStr = "onos:intents -p"
2569 if jsonFormat:
2570 cmdStr += " -j"
2571 output = self.sendline( cmdStr )
2572 return output
2573 except TypeError:
2574 main.log.exception( self.name + ": Object not as expected" )
2575 return None
2576 except pexpect.EOF:
2577 main.log.error( self.name + ": EOF exception found" )
2578 main.log.error( self.name + ": " + self.handle.before )
2579 main.cleanup()
2580 main.exit()
2581 except Exception:
2582 main.log.exception( self.name + ": Uncaught exception!" )
2583 main.cleanup()
2584 main.exit()
2585
2586 def partitions( self, jsonFormat=True ):
2587 """
2588 Returns the output of the raft partitions command for ONOS.
2589 """
2590 # Sample JSON
2591 # {
2592 # "leader": "tcp://10.128.30.11:7238",
2593 # "members": [
2594 # "tcp://10.128.30.11:7238",
2595 # "tcp://10.128.30.17:7238",
2596 # "tcp://10.128.30.13:7238",
2597 # ],
2598 # "name": "p1",
2599 # "term": 3
2600 # },
2601 try:
2602 cmdStr = "onos:partitions"
2603 if jsonFormat:
2604 cmdStr += " -j"
2605 output = self.sendline( cmdStr )
2606 return output
2607 except TypeError:
2608 main.log.exception( self.name + ": Object not as expected" )
2609 return None
2610 except pexpect.EOF:
2611 main.log.error( self.name + ": EOF exception found" )
2612 main.log.error( self.name + ": " + self.handle.before )
2613 main.cleanup()
2614 main.exit()
2615 except Exception:
2616 main.log.exception( self.name + ": Uncaught exception!" )
2617 main.cleanup()
2618 main.exit()
2619
2620 def apps( self, jsonFormat=True ):
2621 """
2622 Returns the output of the apps command for ONOS. This command lists
2623 information about installed ONOS applications
2624 """
2625 # Sample JSON object
2626 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2627 # "description":"ONOS OpenFlow protocol southbound providers",
2628 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2629 # "features":"[onos-openflow]","state":"ACTIVE"}]
2630 try:
2631 cmdStr = "onos:apps"
2632 if jsonFormat:
2633 cmdStr += " -j"
2634 output = self.sendline( cmdStr )
2635 assert "Error executing command" not in output
2636 return output
2637 # FIXME: look at specific exceptions/Errors
2638 except AssertionError:
2639 main.log.error( "Error in processing onos:app command: " +
2640 str( output ) )
2641 return None
2642 except TypeError:
2643 main.log.exception( self.name + ": Object not as expected" )
2644 return None
2645 except pexpect.EOF:
2646 main.log.error( self.name + ": EOF exception found" )
2647 main.log.error( self.name + ": " + self.handle.before )
2648 main.cleanup()
2649 main.exit()
2650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
2652 main.cleanup()
2653 main.exit()
2654
2655 def appStatus( self, appName ):
2656 """
2657 Uses the onos:apps cli command to return the status of an application.
2658 Returns:
2659 "ACTIVE" - If app is installed and activated
2660 "INSTALLED" - If app is installed and deactivated
2661 "UNINSTALLED" - If app is not installed
2662 None - on error
2663 """
2664 try:
2665 if not isinstance( appName, types.StringType ):
2666 main.log.error( self.name + ".appStatus(): appName must be" +
2667 " a string" )
2668 return None
2669 output = self.apps( jsonFormat=True )
2670 appsJson = json.loads( output )
2671 state = None
2672 for app in appsJson:
2673 if appName == app.get('name'):
2674 state = app.get('state')
2675 break
2676 if state == "ACTIVE" or state == "INSTALLED":
2677 return state
2678 elif state is None:
2679 return "UNINSTALLED"
2680 elif state:
2681 main.log.error( "Unexpected state from 'onos:apps': " +
2682 str( state ) )
2683 return state
2684 except TypeError:
2685 main.log.exception( self.name + ": Object not as expected" )
2686 return None
2687 except pexpect.EOF:
2688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
2690 main.cleanup()
2691 main.exit()
2692 except Exception:
2693 main.log.exception( self.name + ": Uncaught exception!" )
2694 main.cleanup()
2695 main.exit()
2696
2697 def app( self, appName, option ):
2698 """
2699 Interacts with the app command for ONOS. This command manages
2700 application inventory.
2701 """
2702 try:
2703 # Validate argument types
2704 valid = True
2705 if not isinstance( appName, types.StringType ):
2706 main.log.error( self.name + ".app(): appName must be a " +
2707 "string" )
2708 valid = False
2709 if not isinstance( option, types.StringType ):
2710 main.log.error( self.name + ".app(): option must be a string" )
2711 valid = False
2712 if not valid:
2713 return main.FALSE
2714 # Validate Option
2715 option = option.lower()
2716 # NOTE: Install may become a valid option
2717 if option == "activate":
2718 pass
2719 elif option == "deactivate":
2720 pass
2721 elif option == "uninstall":
2722 pass
2723 else:
2724 # Invalid option
2725 main.log.error( "The ONOS app command argument only takes " +
2726 "the values: (activate|deactivate|uninstall)" +
2727 "; was given '" + option + "'")
2728 return main.FALSE
2729 cmdStr = "onos:app " + option + " " + appName
2730 output = self.sendline( cmdStr )
2731 if "Error executing command" in output:
2732 main.log.error( "Error in processing onos:app command: " +
2733 str( output ) )
2734 return main.FALSE
2735 elif "No such application" in output:
2736 main.log.error( "The application '" + appName +
2737 "' is not installed in ONOS" )
2738 return main.FALSE
2739 elif "Command not found:" in output:
2740 main.log.error( "Error in processing onos:app command: " +
2741 str( output ) )
2742 return main.FALSE
2743 elif "Unsupported command:" in output:
2744 main.log.error( "Incorrect command given to 'app': " +
2745 str( output ) )
2746 # NOTE: we may need to add more checks here
2747 # else: Command was successful
2748 # main.log.debug( "app response: " + repr( output ) )
2749 return main.TRUE
2750 except TypeError:
2751 main.log.exception( self.name + ": Object not as expected" )
2752 return main.ERROR
2753 except pexpect.EOF:
2754 main.log.error( self.name + ": EOF exception found" )
2755 main.log.error( self.name + ": " + self.handle.before )
2756 main.cleanup()
2757 main.exit()
2758 except Exception:
2759 main.log.exception( self.name + ": Uncaught exception!" )
2760 main.cleanup()
2761 main.exit()
2762
2763 def activateApp( self, appName, check=True ):
2764 """
2765 Activate an app that is already installed in ONOS
2766 appName is the hierarchical app name, not the feature name
2767 If check is True, method will check the status of the app after the
2768 command is issued
2769 Returns main.TRUE if the command was successfully sent
2770 main.FALSE if the cli responded with an error or given
2771 incorrect input
2772 """
2773 try:
2774 if not isinstance( appName, types.StringType ):
2775 main.log.error( self.name + ".activateApp(): appName must be" +
2776 " a string" )
2777 return main.FALSE
2778 status = self.appStatus( appName )
2779 if status == "INSTALLED":
2780 response = self.app( appName, "activate" )
2781 if check and response == main.TRUE:
2782 for i in range(10): # try 10 times then give up
2783 # TODO: Check with Thomas about this delay
2784 status = self.appStatus( appName )
2785 if status == "ACTIVE":
2786 return main.TRUE
2787 else:
2788 main.log.debug( "The state of application " +
2789 appName + " is " + status )
2790 time.sleep( 1 )
2791 return main.FALSE
2792 else: # not 'check' or command didn't succeed
2793 return response
2794 elif status == "ACTIVE":
2795 return main.TRUE
2796 elif status == "UNINSTALLED":
2797 main.log.error( self.name + ": Tried to activate the " +
2798 "application '" + appName + "' which is not " +
2799 "installed." )
2800 else:
2801 main.log.error( "Unexpected return value from appStatus: " +
2802 str( status ) )
2803 return main.ERROR
2804 except TypeError:
2805 main.log.exception( self.name + ": Object not as expected" )
2806 return main.ERROR
2807 except pexpect.EOF:
2808 main.log.error( self.name + ": EOF exception found" )
2809 main.log.error( self.name + ": " + self.handle.before )
2810 main.cleanup()
2811 main.exit()
2812 except Exception:
2813 main.log.exception( self.name + ": Uncaught exception!" )
2814 main.cleanup()
2815 main.exit()
2816
2817 def deactivateApp( self, appName, check=True ):
2818 """
2819 Deactivate an app that is already activated in ONOS
2820 appName is the hierarchical app name, not the feature name
2821 If check is True, method will check the status of the app after the
2822 command is issued
2823 Returns main.TRUE if the command was successfully sent
2824 main.FALSE if the cli responded with an error or given
2825 incorrect input
2826 """
2827 try:
2828 if not isinstance( appName, types.StringType ):
2829 main.log.error( self.name + ".deactivateApp(): appName must " +
2830 "be a string" )
2831 return main.FALSE
2832 status = self.appStatus( appName )
2833 if status == "INSTALLED":
2834 return main.TRUE
2835 elif status == "ACTIVE":
2836 response = self.app( appName, "deactivate" )
2837 if check and response == main.TRUE:
2838 for i in range(10): # try 10 times then give up
2839 status = self.appStatus( appName )
2840 if status == "INSTALLED":
2841 return main.TRUE
2842 else:
2843 time.sleep( 1 )
2844 return main.FALSE
2845 else: # not check or command didn't succeed
2846 return response
2847 elif status == "UNINSTALLED":
2848 main.log.warn( self.name + ": Tried to deactivate the " +
2849 "application '" + appName + "' which is not " +
2850 "installed." )
2851 return main.TRUE
2852 else:
2853 main.log.error( "Unexpected return value from appStatus: " +
2854 str( status ) )
2855 return main.ERROR
2856 except TypeError:
2857 main.log.exception( self.name + ": Object not as expected" )
2858 return main.ERROR
2859 except pexpect.EOF:
2860 main.log.error( self.name + ": EOF exception found" )
2861 main.log.error( self.name + ": " + self.handle.before )
2862 main.cleanup()
2863 main.exit()
2864 except Exception:
2865 main.log.exception( self.name + ": Uncaught exception!" )
2866 main.cleanup()
2867 main.exit()
2868
2869 def uninstallApp( self, appName, check=True ):
2870 """
2871 Uninstall an app that is already installed in ONOS
2872 appName is the hierarchical app name, not the feature name
2873 If check is True, method will check the status of the app after the
2874 command is issued
2875 Returns main.TRUE if the command was successfully sent
2876 main.FALSE if the cli responded with an error or given
2877 incorrect input
2878 """
2879 # TODO: check with Thomas about the state machine for apps
2880 try:
2881 if not isinstance( appName, types.StringType ):
2882 main.log.error( self.name + ".uninstallApp(): appName must " +
2883 "be a string" )
2884 return main.FALSE
2885 status = self.appStatus( appName )
2886 if status == "INSTALLED":
2887 response = self.app( appName, "uninstall" )
2888 if check and response == main.TRUE:
2889 for i in range(10): # try 10 times then give up
2890 status = self.appStatus( appName )
2891 if status == "UNINSTALLED":
2892 return main.TRUE
2893 else:
2894 time.sleep( 1 )
2895 return main.FALSE
2896 else: # not check or command didn't succeed
2897 return response
2898 elif status == "ACTIVE":
2899 main.log.warn( self.name + ": Tried to uninstall the " +
2900 "application '" + appName + "' which is " +
2901 "currently active." )
2902 response = self.app( appName, "uninstall" )
2903 if check and response == main.TRUE:
2904 for i in range(10): # try 10 times then give up
2905 status = self.appStatus( appName )
2906 if status == "UNINSTALLED":
2907 return main.TRUE
2908 else:
2909 time.sleep( 1 )
2910 return main.FALSE
2911 else: # not check or command didn't succeed
2912 return response
2913 elif status == "UNINSTALLED":
2914 return main.TRUE
2915 else:
2916 main.log.error( "Unexpected return value from appStatus: " +
2917 str( status ) )
2918 return main.ERROR
2919 except TypeError:
2920 main.log.exception( self.name + ": Object not as expected" )
2921 return main.ERROR
2922 except pexpect.EOF:
2923 main.log.error( self.name + ": EOF exception found" )
2924 main.log.error( self.name + ": " + self.handle.before )
2925 main.cleanup()
2926 main.exit()
2927 except Exception:
2928 main.log.exception( self.name + ": Uncaught exception!" )
2929 main.cleanup()
2930 main.exit()
2931
2932 def appIDs( self, jsonFormat=True ):
2933 """
2934 Show the mappings between app id and app names given by the 'app-ids'
2935 cli command
2936 """
2937 try:
2938 cmdStr = "app-ids"
2939 if jsonFormat:
2940 cmdStr += " -j"
2941 output = self.sendline( cmdStr )
2942 assert "Error executing command" not in output
2943 return output
2944 except AssertionError:
2945 main.log.error( "Error in processing onos:app-ids command: " +
2946 str( output ) )
2947 return None
2948 except TypeError:
2949 main.log.exception( self.name + ": Object not as expected" )
2950 return None
2951 except pexpect.EOF:
2952 main.log.error( self.name + ": EOF exception found" )
2953 main.log.error( self.name + ": " + self.handle.before )
2954 main.cleanup()
2955 main.exit()
2956 except Exception:
2957 main.log.exception( self.name + ": Uncaught exception!" )
2958 main.cleanup()
2959 main.exit()
2960
2961 def appToIDCheck( self ):
2962 """
2963 This method will check that each application's ID listed in 'apps' is
2964 the same as the ID listed in 'app-ids'. The check will also check that
2965 there are no duplicate IDs issued. Note that an app ID should be
2966 a globaly unique numerical identifier for app/app-like features. Once
2967 an ID is registered, the ID is never freed up so that if an app is
2968 reinstalled it will have the same ID.
2969
2970 Returns: main.TRUE if the check passes and
2971 main.FALSE if the check fails or
2972 main.ERROR if there is some error in processing the test
2973 """
2974 try:
2975 bail = False
2976 ids = self.appIDs( jsonFormat=True )
2977 if ids:
2978 ids = json.loads( ids )
2979 else:
2980 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2981 bail = True
2982 apps = self.apps( jsonFormat=True )
2983 if apps:
2984 apps = json.loads( apps )
2985 else:
2986 main.log.error( "apps returned nothing:" + repr( apps ) )
2987 bail = True
2988 if bail:
2989 return main.FALSE
2990 result = main.TRUE
2991 for app in apps:
2992 appID = app.get( 'id' )
2993 if appID is None:
2994 main.log.error( "Error parsing app: " + str( app ) )
2995 result = main.FALSE
2996 appName = app.get( 'name' )
2997 if appName is None:
2998 main.log.error( "Error parsing app: " + str( app ) )
2999 result = main.FALSE
3000 # get the entry in ids that has the same appID
3001 current = filter( lambda item: item[ 'id' ] == appID, ids )
3002 # main.log.debug( "Comparing " + str( app ) + " to " +
3003 # str( current ) )
3004 if not current: # if ids doesn't have this id
3005 result = main.FALSE
3006 main.log.error( "'app-ids' does not have the ID for " +
3007 str( appName ) + " that apps does." )
3008 elif len( current ) > 1:
3009 # there is more than one app with this ID
3010 result = main.FALSE
3011 # We will log this later in the method
3012 elif not current[0][ 'name' ] == appName:
3013 currentName = current[0][ 'name' ]
3014 result = main.FALSE
3015 main.log.error( "'app-ids' has " + str( currentName ) +
3016 " registered under id:" + str( appID ) +
3017 " but 'apps' has " + str( appName ) )
3018 else:
3019 pass # id and name match!
3020 # now make sure that app-ids has no duplicates
3021 idsList = []
3022 namesList = []
3023 for item in ids:
3024 idsList.append( item[ 'id' ] )
3025 namesList.append( item[ 'name' ] )
3026 if len( idsList ) != len( set( idsList ) ) or\
3027 len( namesList ) != len( set( namesList ) ):
3028 main.log.error( "'app-ids' has some duplicate entries: \n"
3029 + json.dumps( ids,
3030 sort_keys=True,
3031 indent=4,
3032 separators=( ',', ': ' ) ) )
3033 result = main.FALSE
3034 return result
3035 except ( ValueError, TypeError ):
3036 main.log.exception( self.name + ": Object not as expected" )
3037 return main.ERROR
3038 except pexpect.EOF:
3039 main.log.error( self.name + ": EOF exception found" )
3040 main.log.error( self.name + ": " + self.handle.before )
3041 main.cleanup()
3042 main.exit()
3043 except Exception:
3044 main.log.exception( self.name + ": Uncaught exception!" )
3045 main.cleanup()
3046 main.exit()
3047
3048 def getCfg( self, component=None, propName=None, short=False,
3049 jsonFormat=True ):
3050 """
3051 Get configuration settings from onos cli
3052 Optional arguments:
3053 component - Optionally only list configurations for a specific
3054 component. If None, all components with configurations
3055 are displayed. Case Sensitive string.
3056 propName - If component is specified, propName option will show
3057 only this specific configuration from that component.
3058 Case Sensitive string.
3059 jsonFormat - Returns output as json. Note that this will override
3060 the short option
3061 short - Short, less verbose, version of configurations.
3062 This is overridden by the json option
3063 returns:
3064 Output from cli as a string or None on error
3065 """
3066 try:
3067 baseStr = "cfg"
3068 cmdStr = " get"
3069 componentStr = ""
3070 if component:
3071 componentStr += " " + component
3072 if propName:
3073 componentStr += " " + propName
3074 if jsonFormat:
3075 baseStr += " -j"
3076 elif short:
3077 baseStr += " -s"
3078 output = self.sendline( baseStr + cmdStr + componentStr )
3079 assert "Error executing command" not in output
3080 return output
3081 except AssertionError:
3082 main.log.error( "Error in processing 'cfg get' command: " +
3083 str( output ) )
3084 return None
3085 except TypeError:
3086 main.log.exception( self.name + ": Object not as expected" )
3087 return None
3088 except pexpect.EOF:
3089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
3091 main.cleanup()
3092 main.exit()
3093 except Exception:
3094 main.log.exception( self.name + ": Uncaught exception!" )
3095 main.cleanup()
3096 main.exit()
3097
3098 def setCfg( self, component, propName, value=None, check=True ):
3099 """
3100 Set/Unset configuration settings from ONOS cli
3101 Required arguments:
3102 component - The case sensitive name of the component whose
3103 property is to be set
3104 propName - The case sensitive name of the property to be set/unset
3105 Optional arguments:
3106 value - The value to set the property to. If None, will unset the
3107 property and revert it to it's default value(if applicable)
3108 check - Boolean, Check whether the option was successfully set this
3109 only applies when a value is given.
3110 returns:
3111 main.TRUE on success or main.FALSE on failure. If check is False,
3112 will return main.TRUE unless there is an error
3113 """
3114 try:
3115 baseStr = "cfg"
3116 cmdStr = " set " + str( component ) + " " + str( propName )
3117 if value is not None:
3118 cmdStr += " " + str( value )
3119 output = self.sendline( baseStr + cmdStr )
3120 assert "Error executing command" not in output
3121 if value and check:
3122 results = self.getCfg( component=str( component ),
3123 propName=str( propName ),
3124 jsonFormat=True )
3125 # Check if current value is what we just set
3126 try:
3127 jsonOutput = json.loads( results )
3128 current = jsonOutput[ 'value' ]
3129 except ( ValueError, TypeError ):
3130 main.log.exception( "Error parsing cfg output" )
3131 main.log.error( "output:" + repr( results ) )
3132 return main.FALSE
3133 if current == str( value ):
3134 return main.TRUE
3135 return main.FALSE
3136 return main.TRUE
3137 except AssertionError:
3138 main.log.error( "Error in processing 'cfg set' command: " +
3139 str( output ) )
3140 return main.FALSE
3141 except TypeError:
3142 main.log.exception( self.name + ": Object not as expected" )
3143 return main.FALSE
3144 except pexpect.EOF:
3145 main.log.error( self.name + ": EOF exception found" )
3146 main.log.error( self.name + ": " + self.handle.before )
3147 main.cleanup()
3148 main.exit()
3149 except Exception:
3150 main.log.exception( self.name + ": Uncaught exception!" )
3151 main.cleanup()
3152 main.exit()
3153
3154 def setTestAdd( self, setName, values ):
3155 """
3156 CLI command to add elements to a distributed set.
3157 Arguments:
3158 setName - The name of the set to add to.
3159 values - The value(s) to add to the set, space seperated.
3160 Example usages:
3161 setTestAdd( "set1", "a b c" )
3162 setTestAdd( "set2", "1" )
3163 returns:
3164 main.TRUE on success OR
3165 main.FALSE if elements were already in the set OR
3166 main.ERROR on error
3167 """
3168 try:
3169 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3170 output = self.sendline( cmdStr )
3171 try:
3172 # TODO: Maybe make this less hardcoded
3173 # ConsistentMap Exceptions
3174 assert "org.onosproject.store.service" not in output
3175 # Node not leader
3176 assert "java.lang.IllegalStateException" not in output
3177 except AssertionError:
3178 main.log.error( "Error in processing 'set-test-add' " +
3179 "command: " + str( output ) )
3180 retryTime = 30 # Conservative time, given by Madan
3181 main.log.info( "Waiting " + str( retryTime ) +
3182 "seconds before retrying." )
3183 time.sleep( retryTime ) # Due to change in mastership
3184 output = self.sendline( cmdStr )
3185 assert "Error executing command" not in output
3186 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3187 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3188 main.log.info( self.name + ": " + output )
3189 if re.search( positiveMatch, output):
3190 return main.TRUE
3191 elif re.search( negativeMatch, output):
3192 return main.FALSE
3193 else:
3194 main.log.error( self.name + ": setTestAdd did not" +
3195 " match expected output" )
pingping-lin763ee042015-05-20 17:45:30 -07003196 main.log.debug( self.name + " actual: " + repr( output ) )
3197 return main.ERROR
3198 except AssertionError:
3199 main.log.error( "Error in processing 'set-test-add' command: " +
3200 str( output ) )
3201 return main.ERROR
3202 except TypeError:
3203 main.log.exception( self.name + ": Object not as expected" )
3204 return main.ERROR
3205 except pexpect.EOF:
3206 main.log.error( self.name + ": EOF exception found" )
3207 main.log.error( self.name + ": " + self.handle.before )
3208 main.cleanup()
3209 main.exit()
3210 except Exception:
3211 main.log.exception( self.name + ": Uncaught exception!" )
3212 main.cleanup()
3213 main.exit()
3214
3215 def setTestRemove( self, setName, values, clear=False, retain=False ):
3216 """
3217 CLI command to remove elements from a distributed set.
3218 Required arguments:
3219 setName - The name of the set to remove from.
3220 values - The value(s) to remove from the set, space seperated.
3221 Optional arguments:
3222 clear - Clear all elements from the set
3223 retain - Retain only the given values. (intersection of the
3224 original set and the given set)
3225 returns:
3226 main.TRUE on success OR
3227 main.FALSE if the set was not changed OR
3228 main.ERROR on error
3229 """
3230 try:
3231 cmdStr = "set-test-remove "
3232 if clear:
3233 cmdStr += "-c " + str( setName )
3234 elif retain:
3235 cmdStr += "-r " + str( setName ) + " " + str( values )
3236 else:
3237 cmdStr += str( setName ) + " " + str( values )
3238 output = self.sendline( cmdStr )
3239 try:
3240 # TODO: Maybe make this less hardcoded
3241 # ConsistentMap Exceptions
3242 assert "org.onosproject.store.service" not in output
3243 # Node not leader
3244 assert "java.lang.IllegalStateException" not in output
3245 except AssertionError:
3246 main.log.error( "Error in processing 'set-test-add' " +
3247 "command: " + str( output ) )
3248 retryTime = 30 # Conservative time, given by Madan
3249 main.log.info( "Waiting " + str( retryTime ) +
3250 "seconds before retrying." )
3251 time.sleep( retryTime ) # Due to change in mastership
3252 output = self.sendline( cmdStr )
3253 assert "Error executing command" not in output
3254 main.log.info( self.name + ": " + output )
3255 if clear:
3256 pattern = "Set " + str( setName ) + " cleared"
3257 if re.search( pattern, output ):
3258 return main.TRUE
3259 elif retain:
3260 positivePattern = str( setName ) + " was pruned to contain " +\
3261 "only elements of set \[(.*)\]"
3262 negativePattern = str( setName ) + " was not changed by " +\
3263 "retaining only elements of the set " +\
3264 "\[(.*)\]"
3265 if re.search( positivePattern, output ):
3266 return main.TRUE
3267 elif re.search( negativePattern, output ):
3268 return main.FALSE
3269 else:
3270 positivePattern = "\[(.*)\] was removed from the set " +\
3271 str( setName )
3272 if ( len( values.split() ) == 1 ):
3273 negativePattern = "\[(.*)\] was not in set " +\
3274 str( setName )
3275 else:
3276 negativePattern = "No element of \[(.*)\] was in set " +\
3277 str( setName )
3278 if re.search( positivePattern, output ):
3279 return main.TRUE
3280 elif re.search( negativePattern, output ):
3281 return main.FALSE
3282 main.log.error( self.name + ": setTestRemove did not" +
3283 " match expected output" )
3284 main.log.debug( self.name + " expected: " + pattern )
3285 main.log.debug( self.name + " actual: " + repr( output ) )
3286 return main.ERROR
3287 except AssertionError:
3288 main.log.error( "Error in processing 'set-test-remove' command: " +
3289 str( output ) )
3290 return main.ERROR
3291 except TypeError:
3292 main.log.exception( self.name + ": Object not as expected" )
3293 return main.ERROR
3294 except pexpect.EOF:
3295 main.log.error( self.name + ": EOF exception found" )
3296 main.log.error( self.name + ": " + self.handle.before )
3297 main.cleanup()
3298 main.exit()
3299 except Exception:
3300 main.log.exception( self.name + ": Uncaught exception!" )
3301 main.cleanup()
3302 main.exit()
3303
3304 def setTestGet( self, setName, values="" ):
3305 """
3306 CLI command to get the elements in a distributed set.
3307 Required arguments:
3308 setName - The name of the set to remove from.
3309 Optional arguments:
3310 values - The value(s) to check if in the set, space seperated.
3311 returns:
3312 main.ERROR on error OR
3313 A list of elements in the set if no optional arguments are
3314 supplied OR
3315 A tuple containing the list then:
3316 main.FALSE if the given values are not in the set OR
3317 main.TRUE if the given values are in the set OR
3318 """
3319 try:
3320 values = str( values ).strip()
3321 setName = str( setName ).strip()
3322 length = len( values.split() )
3323 containsCheck = None
3324 # Patterns to match
3325 setPattern = "\[(.*)\]"
3326 pattern = "Items in set " + setName + ":\n" + setPattern
3327 containsTrue = "Set " + setName + " contains the value " + values
3328 containsFalse = "Set " + setName + " did not contain the value " +\
3329 values
3330 containsAllTrue = "Set " + setName + " contains the the subset " +\
3331 setPattern
3332 containsAllFalse = "Set " + setName + " did not contain the the" +\
3333 " subset " + setPattern
3334
3335 cmdStr = "set-test-get "
3336 cmdStr += setName + " " + values
3337 output = self.sendline( cmdStr )
3338 try:
3339 # TODO: Maybe make this less hardcoded
3340 # ConsistentMap Exceptions
3341 assert "org.onosproject.store.service" not in output
3342 # Node not leader
3343 assert "java.lang.IllegalStateException" not in output
3344 except AssertionError:
3345 main.log.error( "Error in processing 'set-test-add' " +
3346 "command: " + str( output ) )
3347 retryTime = 30 # Conservative time, given by Madan
3348 main.log.info( "Waiting " + str( retryTime ) +
3349 "seconds before retrying." )
3350 time.sleep( retryTime ) # Due to change in mastership
3351 output = self.sendline( cmdStr )
3352 assert "Error executing command" not in output
3353 main.log.info( self.name + ": " + output )
3354
3355 if length == 0:
3356 match = re.search( pattern, output )
3357 else: # if given values
3358 if length == 1: # Contains output
3359 patternTrue = pattern + "\n" + containsTrue
3360 patternFalse = pattern + "\n" + containsFalse
3361 else: # ContainsAll output
3362 patternTrue = pattern + "\n" + containsAllTrue
3363 patternFalse = pattern + "\n" + containsAllFalse
3364 matchTrue = re.search( patternTrue, output )
3365 matchFalse = re.search( patternFalse, output )
3366 if matchTrue:
3367 containsCheck = main.TRUE
3368 match = matchTrue
3369 elif matchFalse:
3370 containsCheck = main.FALSE
3371 match = matchFalse
3372 else:
3373 main.log.error( self.name + " setTestGet did not match " +\
3374 "expected output" )
3375 main.log.debug( self.name + " expected: " + pattern )
3376 main.log.debug( self.name + " actual: " + repr( output ) )
3377 match = None
3378 if match:
3379 setMatch = match.group( 1 )
3380 if setMatch == '':
3381 setList = []
3382 else:
3383 setList = setMatch.split( ", " )
3384 if length > 0:
3385 return ( setList, containsCheck )
3386 else:
3387 return setList
3388 else: # no match
3389 main.log.error( self.name + ": setTestGet did not" +
3390 " match expected output" )
3391 main.log.debug( self.name + " expected: " + pattern )
3392 main.log.debug( self.name + " actual: " + repr( output ) )
3393 return main.ERROR
3394 except AssertionError:
3395 main.log.error( "Error in processing 'set-test-get' command: " +
3396 str( output ) )
3397 return main.ERROR
3398 except TypeError:
3399 main.log.exception( self.name + ": Object not as expected" )
3400 return main.ERROR
3401 except pexpect.EOF:
3402 main.log.error( self.name + ": EOF exception found" )
3403 main.log.error( self.name + ": " + self.handle.before )
3404 main.cleanup()
3405 main.exit()
3406 except Exception:
3407 main.log.exception( self.name + ": Uncaught exception!" )
3408 main.cleanup()
3409 main.exit()
3410
3411 def setTestSize( self, setName ):
3412 """
3413 CLI command to get the elements in a distributed set.
3414 Required arguments:
3415 setName - The name of the set to remove from.
3416 returns:
3417 The integer value of the size returned or
3418 None on error
3419 """
3420 try:
3421 # TODO: Should this check against the number of elements returned
3422 # and then return true/false based on that?
3423 setName = str( setName ).strip()
3424 # Patterns to match
3425 setPattern = "\[(.*)\]"
3426 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3427 setPattern
3428 cmdStr = "set-test-get -s "
3429 cmdStr += setName
3430 output = self.sendline( cmdStr )
3431 try:
3432 # TODO: Maybe make this less hardcoded
3433 # ConsistentMap Exceptions
3434 assert "org.onosproject.store.service" not in output
3435 # Node not leader
3436 assert "java.lang.IllegalStateException" not in output
3437 except AssertionError:
3438 main.log.error( "Error in processing 'set-test-add' " +
3439 "command: " + str( output ) )
3440 retryTime = 30 # Conservative time, given by Madan
3441 main.log.info( "Waiting " + str( retryTime ) +
3442 "seconds before retrying." )
3443 time.sleep( retryTime ) # Due to change in mastership
3444 output = self.sendline( cmdStr )
3445 assert "Error executing command" not in output
3446 main.log.info( self.name + ": " + output )
3447 match = re.search( pattern, output )
3448 if match:
3449 setSize = int( match.group( 1 ) )
3450 setMatch = match.group( 2 )
3451 if len( setMatch.split() ) == setSize:
3452 main.log.info( "The size returned by " + self.name +
3453 " matches the number of elements in " +
3454 "the returned set" )
3455 else:
3456 main.log.error( "The size returned by " + self.name +
3457 " does not match the number of " +
3458 "elements in the returned set." )
3459 return setSize
3460 else: # no match
3461 main.log.error( self.name + ": setTestGet did not" +
3462 " match expected output" )
3463 main.log.debug( self.name + " expected: " + pattern )
3464 main.log.debug( self.name + " actual: " + repr( output ) )
3465 return None
3466 except AssertionError:
3467 main.log.error( "Error in processing 'set-test-get' command: " +
3468 str( output ) )
3469 return None
3470 except TypeError:
3471 main.log.exception( self.name + ": Object not as expected" )
3472 return None
3473 except pexpect.EOF:
3474 main.log.error( self.name + ": EOF exception found" )
3475 main.log.error( self.name + ": " + self.handle.before )
3476 main.cleanup()
3477 main.exit()
3478 except Exception:
3479 main.log.exception( self.name + ": Uncaught exception!" )
3480 main.cleanup()
3481 main.exit()
3482
Jon Hall80daded2015-05-27 16:07:00 -07003483 def counters( self, jsonFormat=True ):
pingping-lin763ee042015-05-20 17:45:30 -07003484 """
3485 Command to list the various counters in the system.
3486 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003487 if jsonFormat, a string of the json object returned by the cli
3488 command
3489 if not jsonFormat, the normal string output of the cli command
pingping-lin763ee042015-05-20 17:45:30 -07003490 None on error
3491 """
pingping-lin763ee042015-05-20 17:45:30 -07003492 try:
3493 counters = {}
3494 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003495 if jsonFormat:
3496 cmdStr += " -j"
pingping-lin763ee042015-05-20 17:45:30 -07003497 output = self.sendline( cmdStr )
3498 assert "Error executing command" not in output
3499 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003500 return output
pingping-lin763ee042015-05-20 17:45:30 -07003501 except AssertionError:
3502 main.log.error( "Error in processing 'counters' command: " +
3503 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003504 return None
pingping-lin763ee042015-05-20 17:45:30 -07003505 except TypeError:
3506 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003507 return None
pingping-lin763ee042015-05-20 17:45:30 -07003508 except pexpect.EOF:
3509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
3511 main.cleanup()
3512 main.exit()
3513 except Exception:
3514 main.log.exception( self.name + ": Uncaught exception!" )
3515 main.cleanup()
3516 main.exit()
3517
3518 def counterTestIncrement( self, counter, inMemory=False ):
3519 """
3520 CLI command to increment and get a distributed counter.
3521 Required arguments:
3522 counter - The name of the counter to increment.
3523 Optional arguments:
3524 inMemory - use in memory map for the counter
3525 returns:
3526 integer value of the counter or
3527 None on Error
3528 """
3529 try:
3530 counter = str( counter )
3531 cmdStr = "counter-test-increment "
3532 if inMemory:
3533 cmdStr += "-i "
3534 cmdStr += counter
3535 output = self.sendline( cmdStr )
3536 try:
3537 # TODO: Maybe make this less hardcoded
3538 # ConsistentMap Exceptions
3539 assert "org.onosproject.store.service" not in output
3540 # Node not leader
3541 assert "java.lang.IllegalStateException" not in output
3542 except AssertionError:
3543 main.log.error( "Error in processing 'set-test-add' " +
3544 "command: " + str( output ) )
3545 retryTime = 30 # Conservative time, given by Madan
3546 main.log.info( "Waiting " + str( retryTime ) +
3547 "seconds before retrying." )
3548 time.sleep( retryTime ) # Due to change in mastership
3549 output = self.sendline( cmdStr )
3550 assert "Error executing command" not in output
3551 main.log.info( self.name + ": " + output )
3552 pattern = counter + " was incremented to (\d+)"
3553 match = re.search( pattern, output )
3554 if match:
3555 return int( match.group( 1 ) )
3556 else:
3557 main.log.error( self.name + ": counterTestIncrement did not" +
3558 " match expected output." )
3559 main.log.debug( self.name + " expected: " + pattern )
3560 main.log.debug( self.name + " actual: " + repr( output ) )
3561 return None
3562 except AssertionError:
3563 main.log.error( "Error in processing 'counter-test-increment'" +
3564 " command: " + str( output ) )
3565 return None
3566 except TypeError:
3567 main.log.exception( self.name + ": Object not as expected" )
3568 return None
3569 except pexpect.EOF:
3570 main.log.error( self.name + ": EOF exception found" )
3571 main.log.error( self.name + ": " + self.handle.before )
3572 main.cleanup()
3573 main.exit()
3574 except Exception:
3575 main.log.exception( self.name + ": Uncaught exception!" )
3576 main.cleanup()
3577 main.exit()
3578