blob: 5207f1e35dab410c4dcc7295119c04e43f6fc425 [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 Hall80daded2015-05-27 16:07:00 -0700284 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ] )
285 # TODO: look for bash prompt as well
286 if i == 1:
287 self.handle.sendline( "" )
288 self.handle.expect( "onos>" )
pingping-lin763ee042015-05-20 17:45:30 -0700289 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
290 self.handle.expect( "log:log" )
291 self.handle.expect( "onos>" )
292
293 response = self.handle.before
294 if re.search( "Error", response ):
295 return main.FALSE
296 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700297 except pexpect.TIMEOUT:
298 main.log.exception( self.name + ": TIMEOUT exception found" )
299 main.cleanup()
300 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700301 except pexpect.EOF:
302 main.log.error( self.name + ": EOF exception found" )
303 main.log.error( self.name + ": " + self.handle.before )
304 main.cleanup()
305 main.exit()
306 except Exception:
307 main.log.exception( self.name + ": Uncaught exception!" )
308 main.cleanup()
309 main.exit()
310
311 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800312 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800313 Send a completely user specified string to
314 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400315 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800316
andrewonlaba18f6bf2014-10-13 19:31:54 -0400317 Warning: There are no sanity checking to commands
318 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800319 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400320 try:
pingping-lin763ee042015-05-20 17:45:30 -0700321 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
322 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800323 self.handle.sendline( cmdStr )
pingping-lin763ee042015-05-20 17:45:30 -0700324 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
325 response = self.handle.before
326 if i == 2:
327 self.handle.sendline()
328 self.handle.expect( ["\$", pexpect.TIMEOUT] )
329 response += self.handle.before
330 print response
331 try:
332 print self.handle.after
333 except TypeError:
334 pass
335 # TODO: do something with i
Jon Hallaea67aa2015-01-23 13:30:57 -0800336 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
337 + self.name + "." )
pingping-lin763ee042015-05-20 17:45:30 -0700338 if debug:
339 main.log.debug( self.name + ": Raw output" )
340 main.log.debug( self.name + ": " + repr( response ) )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400341
pingping-lin763ee042015-05-20 17:45:30 -0700342 # Remove ANSI color control strings from output
Jon Hall7bdfc122015-01-23 11:45:32 -0800343 ansiEscape = re.compile( r'\x1b[^m]*m' )
pingping-lin763ee042015-05-20 17:45:30 -0700344 response = ansiEscape.sub( '', response )
345 if debug:
346 main.log.debug( self.name + ": ansiEscape output" )
347 main.log.debug( self.name + ": " + repr( response ) )
kelvin8ec71442015-01-15 16:57:00 -0800348
pingping-lin763ee042015-05-20 17:45:30 -0700349 # Remove extra return chars that get added
350 response = re.sub( r"\s\r", "", response )
351 if debug:
352 main.log.debug( self.name + ": Removed extra returns " +
353 "from output" )
354 main.log.debug( self.name + ": " + repr( response ) )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400355
pingping-lin763ee042015-05-20 17:45:30 -0700356 # Strip excess whitespace
357 response = response.strip()
358 if debug:
359 main.log.debug( self.name + ": parsed and stripped output" )
360 main.log.debug( self.name + ": " + repr( response ) )
361
362 # parse for just the output, remove the cmd from response
363 output = response.split( cmdStr.strip(), 1 )
364 if debug:
365 main.log.debug( self.name + ": split output" )
366 for r in output:
367 main.log.debug( self.name + ": " + repr( r ) )
368 return output[1].strip()
369 except IndexError:
370 main.log.exception( self.name + ": Object not as expected" )
371 return None
372 except TypeError:
373 main.log.exception( self.name + ": Object not as expected" )
374 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400375 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800376 main.log.error( self.name + ": EOF exception found" )
377 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400378 main.cleanup()
379 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700380 except Exception:
381 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400382 main.cleanup()
383 main.exit()
384
kelvin8ec71442015-01-15 16:57:00 -0800385 # IMPORTANT NOTE:
386 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800387 # the cli command changing 'a:b' with 'aB'.
388 # Ex ) onos:topology > onosTopology
389 # onos:links > onosLinks
390 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800391
kelvin-onlabd3b64892015-01-20 13:26:24 -0800392 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800393 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400394 Adds a new cluster node by ID and address information.
395 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800396 * nodeId
397 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400398 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800399 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800400 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400401 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 cmdStr = "add-node " + str( nodeId ) + " " +\
403 str( ONOSIp ) + " " + str( tcpPort )
404 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800405 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800406 main.log.error( "Error in adding node" )
407 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800408 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400409 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800410 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400411 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700412 except TypeError:
413 main.log.exception( self.name + ": Object not as expected" )
414 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400415 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800416 main.log.error( self.name + ": EOF exception found" )
417 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400418 main.cleanup()
419 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700420 except Exception:
421 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400422 main.cleanup()
423 main.exit()
424
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800426 """
andrewonlab86dc3082014-10-13 18:18:38 -0400427 Removes a cluster by ID
428 Issues command: 'remove-node [<node-id>]'
429 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800431 """
andrewonlab86dc3082014-10-13 18:18:38 -0400432 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400433
kelvin-onlabd3b64892015-01-20 13:26:24 -0800434 cmdStr = "remove-node " + str( nodeId )
pingping-lin763ee042015-05-20 17:45:30 -0700435 handle = self.sendline( cmdStr )
436 if re.search( "Error", handle ):
437 main.log.error( "Error in removing node" )
438 main.log.error( handle )
439 return main.FALSE
440 else:
441 return main.TRUE
442 except TypeError:
443 main.log.exception( self.name + ": Object not as expected" )
444 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400445 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800446 main.log.error( self.name + ": EOF exception found" )
447 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400448 main.cleanup()
449 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700450 except Exception:
451 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400452 main.cleanup()
453 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400454
pingping-lin763ee042015-05-20 17:45:30 -0700455 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800456 """
andrewonlab7c211572014-10-15 16:45:20 -0400457 List the nodes currently visible
458 Issues command: 'nodes'
pingping-lin763ee042015-05-20 17:45:30 -0700459 Optional argument:
460 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800461 """
andrewonlab7c211572014-10-15 16:45:20 -0400462 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800463 cmdStr = "nodes"
pingping-lin763ee042015-05-20 17:45:30 -0700464 if jsonFormat:
465 cmdStr += " -j"
466 output = self.sendline( cmdStr )
467 return output
468 except TypeError:
469 main.log.exception( self.name + ": Object not as expected" )
470 return None
andrewonlab7c211572014-10-15 16:45:20 -0400471 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800472 main.log.error( self.name + ": EOF exception found" )
473 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400474 main.cleanup()
475 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700476 except Exception:
477 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400478 main.cleanup()
479 main.exit()
480
kelvin8ec71442015-01-15 16:57:00 -0800481 def topology( self ):
482 """
pingping-lin763ee042015-05-20 17:45:30 -0700483 Definition:
484 Returns the output of topology command.
485 Return:
486 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800487 """
andrewonlab95ce8322014-10-13 14:12:04 -0400488 try:
pingping-lin763ee042015-05-20 17:45:30 -0700489 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 handle = self.sendline( cmdStr )
pingping-lin763ee042015-05-20 17:45:30 -0700491 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400492 return handle
pingping-lin763ee042015-05-20 17:45:30 -0700493 except TypeError:
494 main.log.exception( self.name + ": Object not as expected" )
495 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400496 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800497 main.log.error( self.name + ": EOF exception found" )
498 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400499 main.cleanup()
500 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700501 except Exception:
502 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400503 main.cleanup()
504 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800505
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800507 """
pingping-lin763ee042015-05-20 17:45:30 -0700508 Installs a specified feature by issuing command:
509 'feature:install <feature_str>'
510 NOTE: This is now deprecated, you should use the activateApp method
511 instead
kelvin8ec71442015-01-15 16:57:00 -0800512 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400513 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800514 cmdStr = "feature:install " + str( featureStr )
pingping-lin763ee042015-05-20 17:45:30 -0700515 handle = self.sendline( cmdStr )
516 if re.search( "Error", handle ):
517 main.log.error( "Error in installing feature" )
518 main.log.error( handle )
519 return main.FALSE
520 else:
521 return main.TRUE
522 except TypeError:
523 main.log.exception( self.name + ": Object not as expected" )
524 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400525 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800526 main.log.error( self.name + ": EOF exception found" )
527 main.log.error( self.name + ": " + self.handle.before )
528 main.log.report( "Failed to install feature" )
529 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400530 main.cleanup()
531 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700532 except Exception:
533 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800534 main.log.report( "Failed to install feature" )
535 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400536 main.cleanup()
537 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800538
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800540 """
pingping-lin763ee042015-05-20 17:45:30 -0700541 Uninstalls a specified feature by issuing command:
542 'feature:uninstall <feature_str>'
543 NOTE: This is now deprecated, you should use the deactivateApp method
544 instead
kelvin8ec71442015-01-15 16:57:00 -0800545 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400546 try:
pingping-lin763ee042015-05-20 17:45:30 -0700547 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
548 handle = self.sendline( cmdStr )
549 if handle != '':
550 cmdStr = "feature:uninstall " + str( featureStr )
551 output = self.sendline( cmdStr )
552 # TODO: Check for possible error responses from karaf
553 else:
554 main.log.info( "Feature needs to be installed before " +
555 "uninstalling it" )
556 return main.TRUE
557 if re.search( "Error", output ):
558 main.log.error( "Error in uninstalling feature" )
559 main.log.error( output )
560 return main.FALSE
561 else:
562 return main.TRUE
563 except TypeError:
564 main.log.exception( self.name + ": Object not as expected" )
565 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error( self.name + ": EOF exception found" )
568 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 main.cleanup()
570 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700571 except Exception:
572 main.log.exception( self.name + ": Uncaught exception!" )
573 main.cleanup()
574 main.exit()
575
576 def deviceRemove( self, deviceId ):
577 """
578 Removes particular device from storage
579
580 TODO: refactor this function
581 """
582 try:
583 cmdStr = "device-remove " + str( deviceId )
584 handle = self.sendline( cmdStr )
585 if re.search( "Error", handle ):
586 main.log.error( "Error in removing device" )
587 main.log.error( handle )
588 return main.FALSE
589 else:
590 return main.TRUE
591 except TypeError:
592 main.log.exception( self.name + ": Object not as expected" )
593 return None
594 except pexpect.EOF:
595 main.log.error( self.name + ": EOF exception found" )
596 main.log.error( self.name + ": " + self.handle.before )
597 main.cleanup()
598 main.exit()
599 except Exception:
600 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 main.cleanup()
602 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800603
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800605 """
Jon Hall7b02d952014-10-17 20:14:54 -0400606 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400607 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800608 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800609 """
andrewonlab86dc3082014-10-13 18:18:38 -0400610 try:
pingping-lin763ee042015-05-20 17:45:30 -0700611 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700613 cmdStr += " -j"
614 handle = self.sendline( cmdStr )
615 return handle
616 except TypeError:
617 main.log.exception( self.name + ": Object not as expected" )
618 return None
andrewonlab7c211572014-10-15 16:45:20 -0400619 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800620 main.log.error( self.name + ": EOF exception found" )
621 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400622 main.cleanup()
623 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700624 except Exception:
625 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400626 main.cleanup()
627 main.exit()
628
kelvin-onlabd3b64892015-01-20 13:26:24 -0800629 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800630 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800631 This balances the devices across all controllers
632 by issuing command: 'onos> onos:balance-masters'
633 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800634 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800635 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 cmdStr = "onos:balance-masters"
pingping-lin763ee042015-05-20 17:45:30 -0700637 handle = self.sendline( cmdStr )
638 if re.search( "Error", handle ):
639 main.log.error( "Error in balancing masters" )
640 main.log.error( handle )
641 return main.FALSE
642 else:
643 return main.TRUE
644 except TypeError:
645 main.log.exception( self.name + ": Object not as expected" )
646 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800647 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800648 main.log.error( self.name + ": EOF exception found" )
649 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800650 main.cleanup()
651 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700652 except Exception:
653 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800654 main.cleanup()
655 main.exit()
656
kelvin-onlabd3b64892015-01-20 13:26:24 -0800657 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800658 """
Jon Halle8217482014-10-17 13:49:14 -0400659 Lists all core links
660 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800662 """
Jon Halle8217482014-10-17 13:49:14 -0400663 try:
pingping-lin763ee042015-05-20 17:45:30 -0700664 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700666 cmdStr += " -j"
667 handle = self.sendline( cmdStr )
668 return handle
669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
Jon Halle8217482014-10-17 13:49:14 -0400672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400675 main.cleanup()
676 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700677 except Exception:
678 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400679 main.cleanup()
680 main.exit()
681
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800683 """
Jon Halle8217482014-10-17 13:49:14 -0400684 Lists all ports
685 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800687 """
Jon Halle8217482014-10-17 13:49:14 -0400688 try:
pingping-lin763ee042015-05-20 17:45:30 -0700689 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700691 cmdStr += " -j"
692 handle = self.sendline( cmdStr )
693 return handle
694 except TypeError:
695 main.log.exception( self.name + ": Object not as expected" )
696 return None
Jon Halle8217482014-10-17 13:49:14 -0400697 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400700 main.cleanup()
701 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700702 except Exception:
703 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400704 main.cleanup()
705 main.exit()
706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800708 """
Jon Hall983a1702014-10-28 18:44:22 -0400709 Lists all devices and the controllers with roles assigned to them
710 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800712 """
andrewonlab7c211572014-10-15 16:45:20 -0400713 try:
pingping-lin763ee042015-05-20 17:45:30 -0700714 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700716 cmdStr += " -j"
717 handle = self.sendline( cmdStr )
718 return handle
719 except TypeError:
720 main.log.exception( self.name + ": Object not as expected" )
721 return None
Jon Hall983a1702014-10-28 18:44:22 -0400722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400725 main.cleanup()
726 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700727 except Exception:
728 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400729 main.cleanup()
730 main.exit()
731
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800733 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800734 Given the a string containing the json representation of the "roles"
735 cli command and a partial or whole device id, returns a json object
736 containing the roles output for the first device whose id contains
737 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400738
739 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800740 A dict of the role assignments for the given device or
741 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800742 """
Jon Hall983a1702014-10-28 18:44:22 -0400743 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400745 return None
746 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 rawRoles = self.roles()
748 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800749 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800751 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400753 return device
754 return None
pingping-lin763ee042015-05-20 17:45:30 -0700755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400761 main.cleanup()
762 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700763 except Exception:
764 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400765 main.cleanup()
766 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800767
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800769 """
Jon Hall94fd0472014-12-08 11:52:42 -0800770 Iterates through each device and checks if there is a master assigned
771 Returns: main.TRUE if each device has a master
772 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800773 """
Jon Hall94fd0472014-12-08 11:52:42 -0800774 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 rawRoles = self.roles()
776 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800777 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800779 # print device
780 if device[ 'master' ] == "none":
781 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800782 return main.FALSE
783 return main.TRUE
784
pingping-lin763ee042015-05-20 17:45:30 -0700785 except TypeError:
786 main.log.exception( self.name + ": Object not as expected" )
787 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800788 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800791 main.cleanup()
792 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700793 except Exception:
794 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800795 main.cleanup()
796 main.exit()
797
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800799 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400800 Returns string of paths, and the cost.
801 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400803 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800804 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
805 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800806 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800807 main.log.error( "Error in getting paths" )
808 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400809 else:
kelvin8ec71442015-01-15 16:57:00 -0800810 path = handle.split( ";" )[ 0 ]
811 cost = handle.split( ";" )[ 1 ]
812 return ( path, cost )
pingping-lin763ee042015-05-20 17:45:30 -0700813 except TypeError:
814 main.log.exception( self.name + ": Object not as expected" )
815 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400816 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800817 main.log.error( self.name + ": EOF exception found" )
818 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400819 main.cleanup()
820 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700821 except Exception:
822 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400823 main.cleanup()
824 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800825
kelvin-onlabd3b64892015-01-20 13:26:24 -0800826 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800827 """
Jon Hallffb386d2014-11-21 13:43:38 -0800828 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400829 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800830 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800831 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400832 try:
pingping-lin763ee042015-05-20 17:45:30 -0700833 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800834 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -0700835 cmdStr += " -j"
836 handle = self.sendline( cmdStr )
837 return handle
838 except TypeError:
839 main.log.exception( self.name + ": Object not as expected" )
840 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400841 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800842 main.log.error( self.name + ": EOF exception found" )
843 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400844 main.cleanup()
845 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700846 except Exception:
847 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400848 main.cleanup()
849 main.exit()
850
kelvin-onlabd3b64892015-01-20 13:26:24 -0800851 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800852 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400853 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800854
pingping-lin763ee042015-05-20 17:45:30 -0700855 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800856 partial mac address
857
Jon Hall42db6dc2014-10-24 19:03:48 -0400858 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800859 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400860 try:
kelvin8ec71442015-01-15 16:57:00 -0800861 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400862 return None
863 else:
864 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 rawHosts = self.hosts()
866 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800867 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800869 # print "%s in %s?" % ( mac, host[ 'id' ] )
pingping-lin763ee042015-05-20 17:45:30 -0700870 if not host:
871 pass
872 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400873 return host
874 return None
pingping-lin763ee042015-05-20 17:45:30 -0700875 except TypeError:
876 main.log.exception( self.name + ": Object not as expected" )
877 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400881 main.cleanup()
882 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700883 except Exception:
884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
890 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400891 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800892
andrewonlab3f0a4af2014-10-17 12:25:14 -0400893 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400895 IMPORTANT:
896 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800897 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400898 Furthermore, it assumes that value of VLAN is '-1'
899 Description:
kelvin8ec71442015-01-15 16:57:00 -0800900 Converts mininet hosts ( h1, h2, h3... ) into
901 ONOS format ( 00:00:00:00:00:01/-1 , ... )
902 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400903 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800907 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 hostHex = hex( int( host ) ).zfill( 12 )
909 hostHex = str( hostHex ).replace( 'x', '0' )
910 i = iter( str( hostHex ) )
911 hostHex = ":".join( a + b for a, b in zip( i, i ) )
912 hostHex = hostHex + "/-1"
913 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400914
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400916
pingping-lin763ee042015-05-20 17:45:30 -0700917 except TypeError:
918 main.log.exception( self.name + ": Object not as expected" )
919 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400920 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800921 main.log.error( self.name + ": EOF exception found" )
922 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400923 main.cleanup()
924 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700925 except Exception:
926 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400927 main.cleanup()
928 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400929
kelvin-onlabd3b64892015-01-20 13:26:24 -0800930 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800931 """
andrewonlabe6745342014-10-17 14:29:13 -0400932 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 * hostIdOne: ONOS host id for host1
934 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400935 Description:
pingping-lin763ee042015-05-20 17:45:30 -0700936 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500937 specifying the two hosts.
pingping-lin763ee042015-05-20 17:45:30 -0700938 Returns:
939 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800940 """
andrewonlabe6745342014-10-17 14:29:13 -0400941 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 cmdStr = "add-host-intent " + str( hostIdOne ) +\
943 " " + str( hostIdTwo )
944 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800945 if re.search( "Error", handle ):
946 main.log.error( "Error in adding Host intent" )
pingping-lin763ee042015-05-20 17:45:30 -0700947 main.log.debug( "Response from ONOS was: " + repr( handle ) )
948 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800949 else:
950 main.log.info( "Host intent installed between " +
pingping-lin763ee042015-05-20 17:45:30 -0700951 str( hostIdOne ) + " and " + str( hostIdTwo ) )
952 match = re.search('id=0x([\da-f]+),', handle)
953 if match:
954 return match.group()[3:-1]
955 else:
956 main.log.error( "Error, intent ID not found" )
957 main.log.debug( "Response from ONOS was: " +
958 repr( handle ) )
959 return None
960 except TypeError:
961 main.log.exception( self.name + ": Object not as expected" )
962 return None
andrewonlabe6745342014-10-17 14:29:13 -0400963 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800964 main.log.error( self.name + ": EOF exception found" )
965 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400966 main.cleanup()
967 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700968 except Exception:
969 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400970 main.cleanup()
971 main.exit()
972
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800974 """
andrewonlab7b31d232014-10-24 13:31:47 -0400975 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 * ingressDevice: device id of ingress device
977 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400978 Optional:
979 TODO: Still needs to be implemented via dev side
pingping-lin763ee042015-05-20 17:45:30 -0700980 Description:
981 Adds an optical intent by specifying an ingress and egress device
982 Returns:
983 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800984 """
andrewonlab7b31d232014-10-24 13:31:47 -0400985 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
987 " " + str( egressDevice )
988 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800989 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800990 if re.search( "Error", handle ):
pingping-lin763ee042015-05-20 17:45:30 -0700991 main.log.error( "Error in adding Optical intent" )
992 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400993 else:
pingping-lin763ee042015-05-20 17:45:30 -0700994 main.log.info( "Optical intent installed between " +
995 str( ingressDevice ) + " and " +
996 str( egressDevice ) )
997 match = re.search('id=0x([\da-f]+),', handle)
998 if match:
999 return match.group()[3:-1]
1000 else:
1001 main.log.error( "Error, intent ID not found" )
1002 return None
1003 except TypeError:
1004 main.log.exception( self.name + ": Object not as expected" )
1005 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001009 main.cleanup()
1010 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001011 except Exception:
1012 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001013 main.cleanup()
1014 main.exit()
1015
kelvin-onlabd3b64892015-01-20 13:26:24 -08001016 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001017 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 ingressDevice,
1019 egressDevice,
1020 portIngress="",
1021 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001022 ethType="",
1023 ethSrc="",
1024 ethDst="",
1025 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001027 ipProto="",
1028 ipSrc="",
1029 ipDst="",
1030 tcpSrc="",
1031 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001032 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001033 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 * ingressDevice: device id of ingress device
1035 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001036 Optional:
1037 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001038 * ethSrc: specify ethSrc ( i.e. src mac addr )
1039 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001040 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001042 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001043 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001044 * ipSrc: specify ip source address
1045 * ipDst: specify ip destination address
1046 * tcpSrc: specify tcp source port
1047 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001048 Description:
kelvin8ec71442015-01-15 16:57:00 -08001049 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001050 specifying device id's and optional fields
pingping-lin763ee042015-05-20 17:45:30 -07001051 Returns:
1052 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001053
Jon Halle3f39ff2015-01-13 11:50:53 -08001054 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001055 options developers provide for point-to-point
1056 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001057 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001058 try:
kelvin8ec71442015-01-15 16:57:00 -08001059 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001060 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001062 and not ipProto and not ipSrc and not ipDst \
1063 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001064 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001065
andrewonlab289e4b72014-10-21 21:24:18 -04001066 else:
andrewonlab36af3822014-11-18 17:48:18 -05001067 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001068
andrewonlab0c0a6772014-10-22 12:31:18 -04001069 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001070 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001071 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001072 cmd += " --ethSrc " + str( ethSrc )
1073 if ethDst:
1074 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001075 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001076 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001078 cmd += " --lambda "
1079 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001080 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001081 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001082 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001083 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001084 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001085 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001086 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001087 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001088 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001089
kelvin8ec71442015-01-15 16:57:00 -08001090 # Check whether the user appended the port
1091 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 if "/" in ingressDevice:
1093 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001094 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 if not portIngress:
pingping-lin763ee042015-05-20 17:45:30 -07001096 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001097 # TODO: perhaps more meaningful return
pingping-lin763ee042015-05-20 17:45:30 -07001098 # Would it make sense to throw an exception and exit
1099 # the test?
1100 return None
andrewonlab36af3822014-11-18 17:48:18 -05001101
kelvin8ec71442015-01-15 16:57:00 -08001102 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 str( ingressDevice ) + "/" +\
1104 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001105
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 if "/" in egressDevice:
1107 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001108 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 if not portEgress:
pingping-lin763ee042015-05-20 17:45:30 -07001110 main.log.error( "You must specify the egress port" )
1111 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001112
kelvin8ec71442015-01-15 16:57:00 -08001113 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 str( egressDevice ) + "/" +\
1115 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001116
kelvin-onlab898a6c62015-01-16 14:13:53 -08001117 handle = self.sendline( cmd )
pingping-lin763ee042015-05-20 17:45:30 -07001118 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001119 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001120 main.log.error( "Error in adding point-to-point intent" )
pingping-lin763ee042015-05-20 17:45:30 -07001121 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001122 else:
pingping-lin763ee042015-05-20 17:45:30 -07001123 # TODO: print out all the options in this message?
1124 main.log.info( "Point-to-point intent installed between " +
1125 str( ingressDevice ) + " and " +
1126 str( egressDevice ) )
1127 match = re.search('id=0x([\da-f]+),', handle)
1128 if match:
1129 return match.group()[3:-1]
1130 else:
1131 main.log.error( "Error, intent ID not found" )
1132 return None
1133 except TypeError:
1134 main.log.exception( self.name + ": Object not as expected" )
1135 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001137 main.log.error( self.name + ": EOF exception found" )
1138 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001139 main.cleanup()
1140 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001141 except Exception:
1142 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001143 main.cleanup()
1144 main.exit()
1145
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001147 self,
pingping-lin763ee042015-05-20 17:45:30 -07001148 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 egressDevice,
pingping-lin763ee042015-05-20 17:45:30 -07001150 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001152 ethType="",
1153 ethSrc="",
1154 ethDst="",
1155 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001157 ipProto="",
1158 ipSrc="",
1159 ipDst="",
1160 tcpSrc="",
1161 tcpDst="",
1162 setEthSrc="",
1163 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001164 """
shahshreyad0c80432014-12-04 16:56:05 -08001165 Note:
pingping-lin763ee042015-05-20 17:45:30 -07001166 This function assumes the format of all ingress devices
1167 is same. That is, all ingress devices include port numbers
1168 with a "/" or all ingress devices could specify device
1169 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001170 Required:
pingping-lin763ee042015-05-20 17:45:30 -07001171 * ingressDeviceList: List of device ids of ingress device
1172 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001174 Optional:
1175 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001176 * ethSrc: specify ethSrc ( i.e. src mac addr )
1177 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001178 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001180 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001181 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001182 * ipSrc: specify ip source address
1183 * ipDst: specify ip destination address
1184 * tcpSrc: specify tcp source port
1185 * tcpDst: specify tcp destination port
1186 * setEthSrc: action to Rewrite Source MAC Address
1187 * setEthDst: action to Rewrite Destination MAC Address
1188 Description:
kelvin8ec71442015-01-15 16:57:00 -08001189 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001190 specifying device id's and optional fields
pingping-lin763ee042015-05-20 17:45:30 -07001191 Returns:
1192 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001193
Jon Halle3f39ff2015-01-13 11:50:53 -08001194 NOTE: This function may change depending on the
pingping-lin763ee042015-05-20 17:45:30 -07001195 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001196 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001197 """
shahshreyad0c80432014-12-04 16:56:05 -08001198 try:
kelvin8ec71442015-01-15 16:57:00 -08001199 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001200 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001202 and not ipProto and not ipSrc and not ipDst\
1203 and not tcpSrc and not tcpDst and not setEthSrc\
1204 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001205 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001206
1207 else:
1208 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001209
shahshreyad0c80432014-12-04 16:56:05 -08001210 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001211 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001212 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " --ethSrc " + str( ethSrc )
1214 if ethDst:
1215 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001216 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001217 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001219 cmd += " --lambda "
1220 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001221 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001222 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001223 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001224 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001225 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001226 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001227 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001228 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001229 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001230 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001231 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001232 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001233 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001234
kelvin8ec71442015-01-15 16:57:00 -08001235 # Check whether the user appended the port
1236 # or provided it as an input
pingping-lin763ee042015-05-20 17:45:30 -07001237
1238 if portIngressList is None:
1239 for ingressDevice in ingressDeviceList:
1240 if "/" in ingressDevice:
1241 cmd += " " + str( ingressDevice )
1242 else:
1243 main.log.error( "You must specify " +
1244 "the ingress port" )
1245 # TODO: perhaps more meaningful return
1246 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001247 else:
pingping-lin763ee042015-05-20 17:45:30 -07001248 if len( ingressDeviceList ) == len( portIngressList ):
1249 for ingressDevice, portIngress in zip( ingressDeviceList,
1250 portIngressList ):
1251 cmd += " " + \
1252 str( ingressDevice ) + "/" +\
1253 str( portIngress ) + " "
1254 else:
1255 main.log.error( "Device list and port list does not " +
1256 "have the same length" )
shahshreyad0c80432014-12-04 16:56:05 -08001257 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 if "/" in egressDevice:
1259 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001260 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001262 main.log.error( "You must specify " +
1263 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001264 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001265
kelvin8ec71442015-01-15 16:57:00 -08001266 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 str( egressDevice ) + "/" +\
1268 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 handle = self.sendline( cmd )
pingping-lin763ee042015-05-20 17:45:30 -07001270 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001271 if re.search( "Error", handle ):
pingping-lin763ee042015-05-20 17:45:30 -07001272 main.log.error( "Error in adding multipoint-to-singlepoint " +
1273 "intent" )
1274 return None
shahshreyad0c80432014-12-04 16:56:05 -08001275 else:
pingping-lin763ee042015-05-20 17:45:30 -07001276 match = re.search('id=0x([\da-f]+),', handle)
1277 if match:
1278 return match.group()[3:-1]
1279 else:
1280 main.log.error( "Error, intent ID not found" )
1281 return None
1282 except TypeError:
1283 main.log.exception( self.name + ": Object not as expected" )
1284 return None
shahshreyad0c80432014-12-04 16:56:05 -08001285 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001286 main.log.error( self.name + ": EOF exception found" )
1287 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001288 main.cleanup()
1289 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001292 main.cleanup()
1293 main.exit()
1294
pingping-lin763ee042015-05-20 17:45:30 -07001295 def addSinglepointToMultipointIntent(
1296 self,
1297 ingressDevice,
1298 egressDeviceList,
1299 portIngress="",
1300 portEgressList=None,
1301 ethType="",
1302 ethSrc="",
1303 ethDst="",
1304 bandwidth="",
1305 lambdaAlloc=False,
1306 ipProto="",
1307 ipSrc="",
1308 ipDst="",
1309 tcpSrc="",
1310 tcpDst="",
1311 setEthSrc="",
1312 setEthDst="" ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001313 """
pingping-lin763ee042015-05-20 17:45:30 -07001314 Note:
1315 This function assumes the format of all egress devices
1316 is same. That is, all egress devices include port numbers
1317 with a "/" or all egress devices could specify device
1318 ids and port numbers seperately.
1319 Required:
1320 * EgressDeviceList: List of device ids of egress device
1321 ( Atleast 2 eress devices required in the list )
1322 * ingressDevice: device id of ingress device
1323 Optional:
1324 * ethType: specify ethType
1325 * ethSrc: specify ethSrc ( i.e. src mac addr )
1326 * ethDst: specify ethDst ( i.e. dst mac addr )
1327 * bandwidth: specify bandwidth capacity of link
1328 * lambdaAlloc: if True, intent will allocate lambda
1329 for the specified intent
1330 * ipProto: specify ip protocol
1331 * ipSrc: specify ip source address
1332 * ipDst: specify ip destination address
1333 * tcpSrc: specify tcp source port
1334 * tcpDst: specify tcp destination port
1335 * setEthSrc: action to Rewrite Source MAC Address
1336 * setEthDst: action to Rewrite Destination MAC Address
1337 Description:
1338 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1339 specifying device id's and optional fields
1340 Returns:
1341 A string of the intent id or None on error
1342
1343 NOTE: This function may change depending on the
1344 options developers provide for singlepoint-to-multipoint
1345 intent via cli
1346 """
1347 try:
1348 # If there are no optional arguments
1349 if not ethType and not ethSrc and not ethDst\
1350 and not bandwidth and not lambdaAlloc\
1351 and not ipProto and not ipSrc and not ipDst\
1352 and not tcpSrc and not tcpDst and not setEthSrc\
1353 and not setEthDst:
1354 cmd = "add-single-to-multi-intent"
1355
1356 else:
1357 cmd = "add-single-to-multi-intent"
1358
1359 if ethType:
1360 cmd += " --ethType " + str( ethType )
1361 if ethSrc:
1362 cmd += " --ethSrc " + str( ethSrc )
1363 if ethDst:
1364 cmd += " --ethDst " + str( ethDst )
1365 if bandwidth:
1366 cmd += " --bandwidth " + str( bandwidth )
1367 if lambdaAlloc:
1368 cmd += " --lambda "
1369 if ipProto:
1370 cmd += " --ipProto " + str( ipProto )
1371 if ipSrc:
1372 cmd += " --ipSrc " + str( ipSrc )
1373 if ipDst:
1374 cmd += " --ipDst " + str( ipDst )
1375 if tcpSrc:
1376 cmd += " --tcpSrc " + str( tcpSrc )
1377 if tcpDst:
1378 cmd += " --tcpDst " + str( tcpDst )
1379 if setEthSrc:
1380 cmd += " --setEthSrc " + str( setEthSrc )
1381 if setEthDst:
1382 cmd += " --setEthDst " + str( setEthDst )
1383
1384 # Check whether the user appended the port
1385 # or provided it as an input
1386
1387 if "/" in ingressDevice:
1388 cmd += " " + str( ingressDevice )
1389 else:
1390 if not portIngress:
1391 main.log.error( "You must specify " +
1392 "the Ingress port" )
1393 return main.FALSE
1394
1395 cmd += " " +\
1396 str( ingressDevice ) + "/" +\
1397 str( portIngress )
1398
1399 if portEgressList is None:
1400 for egressDevice in egressDeviceList:
1401 if "/" in egressDevice:
1402 cmd += " " + str( egressDevice )
1403 else:
1404 main.log.error( "You must specify " +
1405 "the egress port" )
1406 # TODO: perhaps more meaningful return
1407 return main.FALSE
1408 else:
1409 if len( egressDeviceList ) == len( portEgressList ):
1410 for egressDevice, portEgress in zip( egressDeviceList,
1411 portEgressList ):
1412 cmd += " " + \
1413 str( egressDevice ) + "/" +\
1414 str( portEgress )
1415 else:
1416 main.log.error( "Device list and port list does not " +
1417 "have the same length" )
1418 return main.FALSE
1419 handle = self.sendline( cmd )
1420 # If error, return error message
1421 if re.search( "Error", handle ):
1422 main.log.error( "Error in adding singlepoint-to-multipoint " +
1423 "intent" )
1424 return None
1425 else:
1426 match = re.search('id=0x([\da-f]+),', handle)
1427 if match:
1428 return match.group()[3:-1]
1429 else:
1430 main.log.error( "Error, intent ID not found" )
1431 return None
1432 except TypeError:
1433 main.log.exception( self.name + ": Object not as expected" )
1434 return None
1435 except pexpect.EOF:
1436 main.log.error( self.name + ": EOF exception found" )
1437 main.log.error( self.name + ": " + self.handle.before )
1438 main.cleanup()
1439 main.exit()
1440 except Exception:
1441 main.log.exception( self.name + ": Uncaught exception!" )
1442 main.cleanup()
1443 main.exit()
1444
1445 def addMplsIntent(
1446 self,
1447 ingressDevice,
1448 egressDevice,
1449 ingressPort="",
1450 egressPort="",
1451 ethType="",
1452 ethSrc="",
1453 ethDst="",
1454 bandwidth="",
1455 lambdaAlloc=False,
1456 ipProto="",
1457 ipSrc="",
1458 ipDst="",
1459 tcpSrc="",
1460 tcpDst="",
1461 ingressLabel="",
1462 egressLabel="",
1463 priority=""):
1464 """
1465 Required:
1466 * ingressDevice: device id of ingress device
1467 * egressDevice: device id of egress device
1468 Optional:
1469 * ethType: specify ethType
1470 * ethSrc: specify ethSrc ( i.e. src mac addr )
1471 * ethDst: specify ethDst ( i.e. dst mac addr )
1472 * bandwidth: specify bandwidth capacity of link
1473 * lambdaAlloc: if True, intent will allocate lambda
1474 for the specified intent
1475 * ipProto: specify ip protocol
1476 * ipSrc: specify ip source address
1477 * ipDst: specify ip destination address
1478 * tcpSrc: specify tcp source port
1479 * tcpDst: specify tcp destination port
1480 * ingressLabel: Ingress MPLS label
1481 * egressLabel: Egress MPLS label
1482 Description:
1483 Adds MPLS intent by
1484 specifying device id's and optional fields
1485 Returns:
1486 A string of the intent id or None on error
1487
1488 NOTE: This function may change depending on the
1489 options developers provide for MPLS
1490 intent via cli
1491 """
1492 try:
1493 # If there are no optional arguments
1494 if not ethType and not ethSrc and not ethDst\
1495 and not bandwidth and not lambdaAlloc \
1496 and not ipProto and not ipSrc and not ipDst \
1497 and not tcpSrc and not tcpDst and not ingressLabel \
1498 and not egressLabel:
1499 cmd = "add-mpls-intent"
1500
1501 else:
1502 cmd = "add-mpls-intent"
1503
1504 if ethType:
1505 cmd += " --ethType " + str( ethType )
1506 if ethSrc:
1507 cmd += " --ethSrc " + str( ethSrc )
1508 if ethDst:
1509 cmd += " --ethDst " + str( ethDst )
1510 if bandwidth:
1511 cmd += " --bandwidth " + str( bandwidth )
1512 if lambdaAlloc:
1513 cmd += " --lambda "
1514 if ipProto:
1515 cmd += " --ipProto " + str( ipProto )
1516 if ipSrc:
1517 cmd += " --ipSrc " + str( ipSrc )
1518 if ipDst:
1519 cmd += " --ipDst " + str( ipDst )
1520 if tcpSrc:
1521 cmd += " --tcpSrc " + str( tcpSrc )
1522 if tcpDst:
1523 cmd += " --tcpDst " + str( tcpDst )
1524 if ingressLabel:
1525 cmd += " --ingressLabel " + str( ingressLabel )
1526 if egressLabel:
1527 cmd += " --egressLabel " + str( egressLabel )
1528 if priority:
1529 cmd += " --priority " + str( priority )
1530
1531 # Check whether the user appended the port
1532 # or provided it as an input
1533 if "/" in ingressDevice:
1534 cmd += " " + str( ingressDevice )
1535 else:
1536 if not ingressPort:
1537 main.log.error( "You must specify the ingress port" )
1538 return None
1539
1540 cmd += " " + \
1541 str( ingressDevice ) + "/" +\
1542 str( ingressPort ) + " "
1543
1544 if "/" in egressDevice:
1545 cmd += " " + str( egressDevice )
1546 else:
1547 if not egressPort:
1548 main.log.error( "You must specify the egress port" )
1549 return None
1550
1551 cmd += " " +\
1552 str( egressDevice ) + "/" +\
1553 str( egressPort )
1554
1555 handle = self.sendline( cmd )
1556 # If error, return error message
1557 if re.search( "Error", handle ):
1558 main.log.error( "Error in adding mpls intent" )
1559 return None
1560 else:
1561 # TODO: print out all the options in this message?
1562 main.log.info( "MPLS intent installed between " +
1563 str( ingressDevice ) + " and " +
1564 str( egressDevice ) )
1565 match = re.search('id=0x([\da-f]+),', handle)
1566 if match:
1567 return match.group()[3:-1]
1568 else:
1569 main.log.error( "Error, intent ID not found" )
1570 return None
1571 except TypeError:
1572 main.log.exception( self.name + ": Object not as expected" )
1573 return None
1574 except pexpect.EOF:
1575 main.log.error( self.name + ": EOF exception found" )
1576 main.log.error( self.name + ": " + self.handle.before )
1577 main.cleanup()
1578 main.exit()
1579 except Exception:
1580 main.log.exception( self.name + ": Uncaught exception!" )
1581 main.cleanup()
1582 main.exit()
1583
1584 def removeIntent( self, intentId, app='org.onosproject.cli',
1585 purge=False, sync=False ):
1586 """
1587 Remove intent for specified application id and intent id
1588 Optional args:-
1589 -s or --sync: Waits for the removal before returning
1590 -p or --purge: Purge the intent from the store after removal
Jon Halle3f39ff2015-01-13 11:50:53 -08001591
1592 Returns:
1593 main.False on error and
1594 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001595 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001596 try:
pingping-lin763ee042015-05-20 17:45:30 -07001597 cmdStr = "remove-intent"
1598 if purge:
1599 cmdStr += " -p"
1600 if sync:
1601 cmdStr += " -s"
1602
1603 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001605 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001606 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001607 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001608 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001609 # TODO: Should this be main.TRUE
1610 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001611 except TypeError:
1612 main.log.exception( self.name + ": Object not as expected" )
1613 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001615 main.log.error( self.name + ": EOF exception found" )
1616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001617 main.cleanup()
1618 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001619 except Exception:
1620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001621 main.cleanup()
1622 main.exit()
1623
kelvin-onlabd3b64892015-01-20 13:26:24 -08001624 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001625 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001626 NOTE: This method should be used after installing application:
1627 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001628 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001630 Description:
1631 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001632 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001633 try:
pingping-lin763ee042015-05-20 17:45:30 -07001634 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001636 cmdStr += " -j"
1637 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001638 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001639 except TypeError:
1640 main.log.exception( self.name + ": Object not as expected" )
1641 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001643 main.log.error( self.name + ": EOF exception found" )
1644 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001645 main.cleanup()
1646 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001647 except Exception:
1648 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001649 main.cleanup()
1650 main.exit()
1651
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001653 """
andrewonlab377693f2014-10-21 16:00:30 -04001654 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001655 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001656 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001657 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001658 """
andrewonlabe6745342014-10-17 14:29:13 -04001659 try:
pingping-lin763ee042015-05-20 17:45:30 -07001660 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001662 cmdStr += " -j"
1663 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001664 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001665 except TypeError:
1666 main.log.exception( self.name + ": Object not as expected" )
1667 return None
andrewonlabe6745342014-10-17 14:29:13 -04001668 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001669 main.log.error( self.name + ": EOF exception found" )
1670 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001671 main.cleanup()
1672 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001673 except Exception:
1674 main.log.exception( self.name + ": Uncaught exception!" )
1675 main.cleanup()
1676 main.exit()
1677
1678 def getIntentState(self, intentsId, intentsJson=None):
1679 """
1680 Check intent state.
1681 Accepts a single intent ID (string type) or a list of intent IDs.
1682 Returns the state(string type) of the id if a single intent ID is
1683 accepted.
1684 Returns a dictionary with intent IDs as the key and its
1685 corresponding states as the values
1686 Parameters:
1687 intentId: intent ID (string type)
1688 intentsJson: parsed json object from the onos:intents api
1689 Returns:
1690 state = An intent's state- INSTALL,WITHDRAWN etc.
1691 stateDict = Dictionary of intent's state. intent ID as the keys and
1692 state as the values.
1693 """
1694 try:
1695 state = "State is Undefined"
1696 if not intentsJson:
1697 intentsJsonTemp = json.loads( self.intents() )
1698 else:
1699 intentsJsonTemp = json.loads( intentsJson )
1700 if isinstance( intentsId, types.StringType ):
1701 for intent in intentsJsonTemp:
1702 if intentsId == intent[ 'id' ]:
1703 state = intent[ 'state' ]
1704 return state
1705 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1706 " on the list" )
1707 return state
1708 elif isinstance( intentsId, types.ListType ):
1709 dictList = []
1710 for i in xrange( len( intentsId ) ):
1711 stateDict = {}
1712 for intents in intentsJsonTemp:
1713 if intentsId[ i ] == intents[ 'id' ]:
1714 stateDict[ 'state' ] = intents[ 'state' ]
1715 stateDict[ 'id' ] = intentsId[ i ]
1716 dictList.append( stateDict )
1717 break
1718 if len( intentsId ) != len( dictList ):
1719 main.log.info( "Cannot find some of the intent ID state" )
1720 return dictList
1721 else:
1722 main.log.info( "Invalid intents ID entry" )
1723 return None
1724 except TypeError:
1725 main.log.exception( self.name + ": Object not as expected" )
1726 return None
1727 except pexpect.EOF:
1728 main.log.error( self.name + ": EOF exception found" )
1729 main.log.error( self.name + ": " + self.handle.before )
1730 main.cleanup()
1731 main.exit()
1732 except Exception:
1733 main.log.exception( self.name + ": Uncaught exception!" )
1734 main.cleanup()
1735 main.exit()
1736
1737 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1738 """
1739 Description:
1740 Check intents state
1741 Required:
1742 intentsId - List of intents ID to be checked
1743 Optional:
1744 expectedState - Check this expected state of each intents state
1745 in the list. Defaults to INSTALLED
1746 Return:
1747 Returns main.TRUE only if all intent are the same as expectedState,
1748 , otherwise,returns main.FALSE.
1749 """
1750 try:
1751 # Generating a dictionary: intent id as a key and state as value
1752 intentsDict = self.getIntentState( intentsId )
1753 #print "len of intentsDict ", str( len( intentsDict ) )
1754 if len( intentsId ) != len( intentsDict ):
1755 main.log.info( self.name + "There is something wrong " +
1756 "getting intents state" )
1757 return main.FALSE
1758 returnValue = main.TRUE
1759 for intents in intentsDict:
1760 if intents.get( 'state' ) != expectedState:
1761 main.log.info( self.name + " : " + intents.get( 'id' ) +
1762 " actual state = " + intents.get( 'state' )
1763 + " does not equal expected state = "
1764 + expectedState )
1765 returnValue = main.FALSE
1766 if returnValue == main.TRUE:
1767 main.log.info( self.name + ": All " +
1768 str( len( intentsDict ) ) +
1769 " intents are in " + expectedState + " state")
1770 return returnValue
1771 except TypeError:
1772 main.log.exception( self.name + ": Object not as expected" )
1773 return None
1774 except pexpect.EOF:
1775 main.log.error( self.name + ": EOF exception found" )
1776 main.log.error( self.name + ": " + self.handle.before )
1777 main.cleanup()
1778 main.exit()
1779 except Exception:
1780 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001781 main.cleanup()
1782 main.exit()
1783
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001785 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001786 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001788 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001789 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001790 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001791 try:
pingping-lin763ee042015-05-20 17:45:30 -07001792 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001794 cmdStr += " -j"
1795 handle = self.sendline( cmdStr )
1796 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001797 main.log.error( self.name + ".flows() response: " +
1798 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001799 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001800 except TypeError:
1801 main.log.exception( self.name + ": Object not as expected" )
1802 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001803 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001804 main.log.error( self.name + ": EOF exception found" )
1805 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001806 main.cleanup()
1807 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001808 except Exception:
1809 main.log.exception( self.name + ": Uncaught exception!" )
1810 main.cleanup()
1811 main.exit()
1812
1813 def checkFlowsState( self ):
1814 """
1815 Description:
1816 Check the if all the current flows are in ADDED state or
1817 PENDING_ADD state
1818 Return:
1819 returnValue - Returns main.TRUE only if all flows are in
1820 ADDED state or PENDING_ADD, return main.FALSE
1821 otherwise.
1822 """
1823 try:
1824 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001825 #print tempFlows[0]
pingping-lin763ee042015-05-20 17:45:30 -07001826 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001827
pingping-lin763ee042015-05-20 17:45:30 -07001828 for device in tempFlows:
1829 for flow in device.get( 'flows' ):
1830 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1831 'PENDING_ADD':
1832 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf0594d72015-05-19 17:25:12 -07001833 flow.get( 'groupId' ) +
pingping-lin763ee042015-05-20 17:45:30 -07001834 " | state:" + flow.get( 'state' ) )
1835 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001836
pingping-lin763ee042015-05-20 17:45:30 -07001837 return returnValue
1838 except TypeError:
1839 main.log.exception( self.name + ": Object not as expected" )
1840 return None
1841 except pexpect.EOF:
1842 main.log.error( self.name + ": EOF exception found" )
1843 main.log.error( self.name + ": " + self.handle.before )
1844 main.cleanup()
1845 main.exit()
1846 except Exception:
1847 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001848 main.cleanup()
1849 main.exit()
1850
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
pingping-lin763ee042015-05-20 17:45:30 -07001852 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001853 """
andrewonlab87852b02014-11-19 18:44:19 -05001854 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001856 a specific point-to-point intent definition
1857 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 * dpidSrc: specify source dpid
1859 * dpidDst: specify destination dpid
1860 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001861 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001862 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001863 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001864 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001865 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001866 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001867 """
andrewonlab87852b02014-11-19 18:44:19 -05001868 try:
kelvin8ec71442015-01-15 16:57:00 -08001869 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001870 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1871 str( numIntents )
1872 if numMult:
1873 cmd += " " + str( numMult )
1874 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001875 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001876 if appId:
1877 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001878 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001879 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001880 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001881 main.log.info( handle )
1882 # Split result by newline
1883 newline = handle.split( "\r\r\n" )
1884 # Ignore the first object of list, which is empty
1885 newline = newline[ 1: ]
1886 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001887 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001888 result = result.split( ": " )
1889 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001890 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1891 main.log.info( latResult )
1892 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001893 else:
1894 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001895 except TypeError:
1896 main.log.exception( self.name + ": Object not as expected" )
1897 return None
andrewonlab87852b02014-11-19 18:44:19 -05001898 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001899 main.log.error( self.name + ": EOF exception found" )
1900 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001901 main.cleanup()
1902 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001903 except Exception:
1904 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001905 main.cleanup()
1906 main.exit()
1907
kelvin-onlabd3b64892015-01-20 13:26:24 -08001908 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001909 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001910 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001911 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001912 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001913 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001914 try:
pingping-lin763ee042015-05-20 17:45:30 -07001915 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001917 cmdStr += " -j"
1918 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001919 return handle
pingping-lin763ee042015-05-20 17:45:30 -07001920 except TypeError:
1921 main.log.exception( self.name + ": Object not as expected" )
1922 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001923 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001924 main.log.error( self.name + ": EOF exception found" )
1925 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001926 main.cleanup()
1927 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001928 except Exception:
1929 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001930 main.cleanup()
1931 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001932
kelvin-onlabd3b64892015-01-20 13:26:24 -08001933 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001934 """
1935 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001936 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001937 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001938 """
andrewonlab867212a2014-10-22 20:13:38 -04001939 try:
pingping-lin763ee042015-05-20 17:45:30 -07001940 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001941 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07001942 cmdStr += " -j"
1943 handle = self.sendline( cmdStr )
1944 if handle:
1945 return handle
1946 elif jsonFormat:
1947 # Return empty json
1948 return '{}'
andrewonlab867212a2014-10-22 20:13:38 -04001949 else:
pingping-lin763ee042015-05-20 17:45:30 -07001950 return handle
1951 except TypeError:
1952 main.log.exception( self.name + ": Object not as expected" )
1953 return None
andrewonlab867212a2014-10-22 20:13:38 -04001954 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001955 main.log.error( self.name + ": EOF exception found" )
1956 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001957 main.cleanup()
1958 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001959 except Exception:
1960 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001961 main.cleanup()
1962 main.exit()
1963
kelvin8ec71442015-01-15 16:57:00 -08001964 # Wrapper functions ****************
1965 # Wrapper functions use existing driver
1966 # functions and extends their use case.
1967 # For example, we may use the output of
1968 # a normal driver function, and parse it
1969 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001970
kelvin-onlabd3b64892015-01-20 13:26:24 -08001971 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001972 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001973 Description:
1974 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001975 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001976 try:
kelvin8ec71442015-01-15 16:57:00 -08001977 # Obtain output of intents function
pingping-lin763ee042015-05-20 17:45:30 -07001978 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001979 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001980
kelvin8ec71442015-01-15 16:57:00 -08001981 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1983 for intents in intentsList:
pingping-lin763ee042015-05-20 17:45:30 -07001984 match = re.search('id=0x([\da-f]+),', intents)
1985 if match:
1986 tmpId = match.group()[3:-1]
1987 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001989
pingping-lin763ee042015-05-20 17:45:30 -07001990 except TypeError:
1991 main.log.exception( self.name + ": Object not as expected" )
1992 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001993 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001994 main.log.error( self.name + ": EOF exception found" )
1995 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001996 main.cleanup()
1997 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001998 except Exception:
1999 main.log.exception( self.name + ": Uncaught exception!" )
2000 main.cleanup()
2001 main.exit()
2002
2003 def FlowAddedCount( self, deviceId ):
2004 """
2005 Determine the number of flow rules for the given device id that are
2006 in the added state
2007 """
2008 try:
2009 cmdStr = "flows any " + str( deviceId ) + " | " +\
2010 "grep 'state=ADDED' | wc -l"
2011 handle = self.sendline( cmdStr )
2012 return handle
2013 except pexpect.EOF:
2014 main.log.error( self.name + ": EOF exception found" )
2015 main.log.error( self.name + ": " + self.handle.before )
2016 main.cleanup()
2017 main.exit()
2018 except Exception:
2019 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002020 main.cleanup()
2021 main.exit()
2022
kelvin-onlabd3b64892015-01-20 13:26:24 -08002023 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002024 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002025 Use 'devices' function to obtain list of all devices
2026 and parse the result to obtain a list of all device
2027 id's. Returns this list. Returns empty list if no
2028 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002029 List is ordered sequentially
2030
andrewonlab3e15ead2014-10-15 14:21:34 -04002031 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002032 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002033 the ids. By obtaining the list of device ids on the fly,
2034 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002035 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002036 try:
kelvin8ec71442015-01-15 16:57:00 -08002037 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002038 devicesStr = self.devices( jsonFormat=False )
2039 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002040
kelvin-onlabd3b64892015-01-20 13:26:24 -08002041 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002042 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002043 return idList
kelvin8ec71442015-01-15 16:57:00 -08002044
2045 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002046 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002047 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002048 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002049 # Split list further into arguments before and after string
2050 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002051 # append to idList
2052 for arg in tempList:
2053 idList.append( arg.split( "id=" )[ 1 ] )
2054 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002055
pingping-lin763ee042015-05-20 17:45:30 -07002056 except TypeError:
2057 main.log.exception( self.name + ": Object not as expected" )
2058 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002059 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002060 main.log.error( self.name + ": EOF exception found" )
2061 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002062 main.cleanup()
2063 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002064 except Exception:
2065 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002066 main.cleanup()
2067 main.exit()
2068
kelvin-onlabd3b64892015-01-20 13:26:24 -08002069 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002070 """
andrewonlab7c211572014-10-15 16:45:20 -04002071 Uses 'nodes' function to obtain list of all nodes
2072 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002073 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002074 Returns:
2075 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002076 """
andrewonlab7c211572014-10-15 16:45:20 -04002077 try:
pingping-lin763ee042015-05-20 17:45:30 -07002078 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002079 idList = []
pingping-lin763ee042015-05-20 17:45:30 -07002080 # Sample nodesStr output
2081 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002082 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002083 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002084 return idList
pingping-lin763ee042015-05-20 17:45:30 -07002085 nodesJson = json.loads( nodesStr )
2086 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002087 return idList
kelvin8ec71442015-01-15 16:57:00 -08002088
pingping-lin763ee042015-05-20 17:45:30 -07002089 except TypeError:
2090 main.log.exception( self.name + ": Object not as expected" )
2091 return None
andrewonlab7c211572014-10-15 16:45:20 -04002092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002093 main.log.error( self.name + ": EOF exception found" )
2094 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002095 main.cleanup()
2096 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002097 except Exception:
2098 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002099 main.cleanup()
2100 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002101
kelvin-onlabd3b64892015-01-20 13:26:24 -08002102 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002103 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002104 Return the first device from the devices api whose 'id' contains 'dpid'
2105 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002106 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002107 try:
kelvin8ec71442015-01-15 16:57:00 -08002108 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002109 return None
2110 else:
kelvin8ec71442015-01-15 16:57:00 -08002111 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002112 rawDevices = self.devices()
2113 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002114 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002115 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002116 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2117 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002118 return device
2119 return None
pingping-lin763ee042015-05-20 17:45:30 -07002120 except TypeError:
2121 main.log.exception( self.name + ": Object not as expected" )
2122 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002124 main.log.error( self.name + ": EOF exception found" )
2125 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002126 main.cleanup()
2127 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002128 except Exception:
2129 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002130 main.cleanup()
2131 main.exit()
2132
kelvin-onlabd3b64892015-01-20 13:26:24 -08002133 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002134 """
pingping-lin763ee042015-05-20 17:45:30 -07002135 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002136 supplied values. By default this will report to main.log, but the
pingping-lin763ee042015-05-20 17:45:30 -07002137 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002138
Jon Hall42db6dc2014-10-24 19:03:48 -04002139 Params: ip = ip used for the onos cli
2140 numoswitch = expected number of switches
pingping-lin763ee042015-05-20 17:45:30 -07002141 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002142 logLevel = level to log to. Currently accepts
2143 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002144
2145
kelvin-onlabd3b64892015-01-20 13:26:24 -08002146 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002147
pingping-lin763ee042015-05-20 17:45:30 -07002148 Returns: main.TRUE if the number of switches and links are correct,
2149 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002150 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002151 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002152 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002153 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002154 if topology == {}:
2155 return main.ERROR
2156 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002157 # Is the number of switches is what we expected
2158 devices = topology.get( 'devices', False )
2159 links = topology.get( 'links', False )
pingping-lin763ee042015-05-20 17:45:30 -07002160 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002161 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002162 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002163 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002164 linkCheck = ( int( links ) == int( numolink ) )
2165 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002166 # We expected the correct numbers
pingping-lin763ee042015-05-20 17:45:30 -07002167 output += "The number of links and switches match " +\
2168 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002169 result = main.TRUE
2170 else:
pingping-lin763ee042015-05-20 17:45:30 -07002171 output += "The number of links and switches does not match " +\
2172 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002173 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 output = output + "\n ONOS sees %i devices (%i expected) \
2175 and %i links (%i expected)" % (
2176 int( devices ), int( numoswitch ), int( links ),
2177 int( numolink ) )
2178 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002179 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002180 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002181 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002182 else:
pingping-lin763ee042015-05-20 17:45:30 -07002183 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002184 return result
pingping-lin763ee042015-05-20 17:45:30 -07002185 except TypeError:
2186 main.log.exception( self.name + ": Object not as expected" )
2187 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002188 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002189 main.log.error( self.name + ": EOF exception found" )
2190 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002191 main.cleanup()
2192 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002193 except Exception:
2194 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002195 main.cleanup()
2196 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002197
kelvin-onlabd3b64892015-01-20 13:26:24 -08002198 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002199 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002200 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002201 deviceId must be the id of a device as seen in the onos devices command
2202 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002203 role must be either master, standby, or none
2204
Jon Halle3f39ff2015-01-13 11:50:53 -08002205 Returns:
2206 main.TRUE or main.FALSE based on argument verification and
2207 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002208 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002209 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002210 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002211 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002212 cmdStr = "device-role " +\
2213 str( deviceId ) + " " +\
2214 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002215 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002216 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002217 if re.search( "Error", handle ):
2218 # end color output to escape any colours
2219 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002220 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002221 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002222 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002223 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002224 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002225 main.log.error( "Invalid 'role' given to device_role(). " +
2226 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002227 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002228 except TypeError:
2229 main.log.exception( self.name + ": Object not as expected" )
2230 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002231 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002232 main.log.error( self.name + ": EOF exception found" )
2233 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002234 main.cleanup()
2235 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002236 except Exception:
2237 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002238 main.cleanup()
2239 main.exit()
2240
kelvin-onlabd3b64892015-01-20 13:26:24 -08002241 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002242 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002243 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002244 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002245 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002246 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002247 try:
pingping-lin763ee042015-05-20 17:45:30 -07002248 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002249 if jsonFormat:
pingping-lin763ee042015-05-20 17:45:30 -07002250 cmdStr += " -j"
2251 handle = self.sendline( cmdStr )
2252 return handle
2253 except TypeError:
2254 main.log.exception( self.name + ": Object not as expected" )
2255 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002256 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002257 main.log.error( self.name + ": EOF exception found" )
2258 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002259 main.cleanup()
2260 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002261 except Exception:
2262 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002263 main.cleanup()
2264 main.exit()
2265
kelvin-onlabd3b64892015-01-20 13:26:24 -08002266 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002267 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002268 CLI command to get the current leader for the Election test application
2269 NOTE: Requires installation of the onos-app-election feature
2270 Returns: Node IP of the leader if one exists
2271 None if none exists
2272 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002273 """
Jon Hall94fd0472014-12-08 11:52:42 -08002274 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002275 cmdStr = "election-test-leader"
2276 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002277 # Leader
2278 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002279 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002280 nodeSearch = re.search( leaderPattern, response )
2281 if nodeSearch:
2282 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002283 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002284 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002285 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002286 # no leader
2287 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 nullSearch = re.search( nullPattern, response )
2290 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002291 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002292 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002293 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002294 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002295 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002296 if re.search( errorPattern, response ):
2297 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002298 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002299 return main.FALSE
2300 else:
pingping-lin763ee042015-05-20 17:45:30 -07002301 main.log.error( "Error in electionTestLeader on " + self.name +
2302 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002303 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002304 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002305 except TypeError:
2306 main.log.exception( self.name + ": Object not as expected" )
2307 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002308 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002309 main.log.error( self.name + ": EOF exception found" )
2310 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002311 main.cleanup()
2312 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002313 except Exception:
2314 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002315 main.cleanup()
2316 main.exit()
2317
kelvin-onlabd3b64892015-01-20 13:26:24 -08002318 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002319 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002320 CLI command to run for leadership of the Election test application.
2321 NOTE: Requires installation of the onos-app-election feature
2322 Returns: Main.TRUE on success
2323 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002324 """
Jon Hall94fd0472014-12-08 11:52:42 -08002325 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002326 cmdStr = "election-test-run"
2327 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002328 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002329 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002330 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002331 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002332 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002333 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002334 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002335 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002336 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002337 errorPattern = "Command\snot\sfound"
2338 if re.search( errorPattern, response ):
2339 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002340 return main.FALSE
2341 else:
pingping-lin763ee042015-05-20 17:45:30 -07002342 main.log.error( "Error in electionTestRun on " + self.name +
2343 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002344 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002345 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002346 except TypeError:
2347 main.log.exception( self.name + ": Object not as expected" )
2348 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002350 main.log.error( self.name + ": EOF exception found" )
2351 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002352 main.cleanup()
2353 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002354 except Exception:
2355 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002356 main.cleanup()
2357 main.exit()
2358
kelvin-onlabd3b64892015-01-20 13:26:24 -08002359 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002360 """
Jon Hall94fd0472014-12-08 11:52:42 -08002361 * CLI command to withdraw the local node from leadership election for
2362 * the Election test application.
2363 #NOTE: Requires installation of the onos-app-election feature
2364 Returns: Main.TRUE on success
2365 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002366 """
Jon Hall94fd0472014-12-08 11:52:42 -08002367 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002368 cmdStr = "election-test-withdraw"
2369 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002370 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002371 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002372 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002373 if re.search( successPattern, response ):
2374 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002375 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002376 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002377 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002378 errorPattern = "Command\snot\sfound"
2379 if re.search( errorPattern, response ):
2380 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002381 return main.FALSE
2382 else:
pingping-lin763ee042015-05-20 17:45:30 -07002383 main.log.error( "Error in electionTestWithdraw on " +
2384 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002385 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002386 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07002387 except TypeError:
2388 main.log.exception( self.name + ": Object not as expected" )
2389 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002390 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002391 main.log.error( self.name + ": EOF exception found" )
2392 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002393 main.cleanup()
2394 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002395 except Exception:
2396 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002397 main.cleanup()
2398 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002399
kelvin8ec71442015-01-15 16:57:00 -08002400 def getDevicePortsEnabledCount( self, dpid ):
2401 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002402 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002403 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002404 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002405 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002406 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2407 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002408 if re.search( "No such device", output ):
2409 main.log.error( "Error in getting ports" )
2410 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002411 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002412 return output
pingping-lin763ee042015-05-20 17:45:30 -07002413 except TypeError:
2414 main.log.exception( self.name + ": Object not as expected" )
2415 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002416 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002417 main.log.error( self.name + ": EOF exception found" )
2418 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002419 main.cleanup()
2420 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002421 except Exception:
2422 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002423 main.cleanup()
2424 main.exit()
2425
kelvin8ec71442015-01-15 16:57:00 -08002426 def getDeviceLinksActiveCount( self, dpid ):
2427 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002428 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002429 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002430 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002431 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002432 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2433 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002434 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002435 main.log.error( "Error in getting ports " )
2436 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002437 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002438 return output
pingping-lin763ee042015-05-20 17:45:30 -07002439 except TypeError:
2440 main.log.exception( self.name + ": Object not as expected" )
2441 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002442 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002443 main.log.error( self.name + ": EOF exception found" )
2444 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002445 main.cleanup()
2446 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002447 except Exception:
2448 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002449 main.cleanup()
2450 main.exit()
2451
kelvin8ec71442015-01-15 16:57:00 -08002452 def getAllIntentIds( self ):
2453 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002454 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002455 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002456 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 cmdStr = "onos:intents | grep id="
2458 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002459 if re.search( "Error", output ):
2460 main.log.error( "Error in getting ports" )
2461 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002462 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002463 return output
pingping-lin763ee042015-05-20 17:45:30 -07002464 except TypeError:
2465 main.log.exception( self.name + ": Object not as expected" )
2466 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002467 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002468 main.log.error( self.name + ": EOF exception found" )
2469 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002470 main.cleanup()
2471 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002472 except Exception:
2473 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002474 main.cleanup()
2475 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07002476
2477 def intentSummary( self ):
2478 """
2479 Returns a dictionary containing the current intent states and the count
2480 """
2481 try:
2482 intents = self.intents( )
2483 states = []
2484 for intent in json.loads( intents ):
2485 states.append( intent.get( 'state', None ) )
2486 out = [ ( i, states.count( i ) ) for i in set( states ) ]
2487 main.log.info( dict( out ) )
2488 return dict( out )
2489 except TypeError:
2490 main.log.exception( self.name + ": Object not as expected" )
2491 return None
2492 except pexpect.EOF:
2493 main.log.error( self.name + ": EOF exception found" )
2494 main.log.error( self.name + ": " + self.handle.before )
2495 main.cleanup()
2496 main.exit()
2497 except Exception:
2498 main.log.exception( self.name + ": Uncaught exception!" )
2499 main.cleanup()
2500 main.exit()
2501
2502 def leaders( self, jsonFormat=True ):
2503 """
2504 Returns the output of the leaders command.
2505 Optional argument:
2506 * jsonFormat - boolean indicating if you want output in json
2507 """
2508 # FIXME: add json output
2509 # Sample JSON
2510 # {
2511 # "electedTime": "13m ago",
2512 # "epoch": 4,
2513 # "leader": "10.128.30.17",
2514 # "topic": "intent-partition-3"
2515 # },
2516 try:
2517 cmdStr = "onos:leaders"
2518 if jsonFormat:
2519 cmdStr += " -j"
2520 output = self.sendline( cmdStr )
2521 return output
2522 except TypeError:
2523 main.log.exception( self.name + ": Object not as expected" )
2524 return None
2525 except pexpect.EOF:
2526 main.log.error( self.name + ": EOF exception found" )
2527 main.log.error( self.name + ": " + self.handle.before )
2528 main.cleanup()
2529 main.exit()
2530 except Exception:
2531 main.log.exception( self.name + ": Uncaught exception!" )
2532 main.cleanup()
2533 main.exit()
2534
2535 def pendingMap( self, jsonFormat=True ):
2536 """
2537 Returns the output of the intent Pending map.
2538 """
2539 try:
2540 cmdStr = "onos:intents -p"
2541 if jsonFormat:
2542 cmdStr += " -j"
2543 output = self.sendline( cmdStr )
2544 return output
2545 except TypeError:
2546 main.log.exception( self.name + ": Object not as expected" )
2547 return None
2548 except pexpect.EOF:
2549 main.log.error( self.name + ": EOF exception found" )
2550 main.log.error( self.name + ": " + self.handle.before )
2551 main.cleanup()
2552 main.exit()
2553 except Exception:
2554 main.log.exception( self.name + ": Uncaught exception!" )
2555 main.cleanup()
2556 main.exit()
2557
2558 def partitions( self, jsonFormat=True ):
2559 """
2560 Returns the output of the raft partitions command for ONOS.
2561 """
2562 # Sample JSON
2563 # {
2564 # "leader": "tcp://10.128.30.11:7238",
2565 # "members": [
2566 # "tcp://10.128.30.11:7238",
2567 # "tcp://10.128.30.17:7238",
2568 # "tcp://10.128.30.13:7238",
2569 # ],
2570 # "name": "p1",
2571 # "term": 3
2572 # },
2573 try:
2574 cmdStr = "onos:partitions"
2575 if jsonFormat:
2576 cmdStr += " -j"
2577 output = self.sendline( cmdStr )
2578 return output
2579 except TypeError:
2580 main.log.exception( self.name + ": Object not as expected" )
2581 return None
2582 except pexpect.EOF:
2583 main.log.error( self.name + ": EOF exception found" )
2584 main.log.error( self.name + ": " + self.handle.before )
2585 main.cleanup()
2586 main.exit()
2587 except Exception:
2588 main.log.exception( self.name + ": Uncaught exception!" )
2589 main.cleanup()
2590 main.exit()
2591
2592 def apps( self, jsonFormat=True ):
2593 """
2594 Returns the output of the apps command for ONOS. This command lists
2595 information about installed ONOS applications
2596 """
2597 # Sample JSON object
2598 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2599 # "description":"ONOS OpenFlow protocol southbound providers",
2600 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2601 # "features":"[onos-openflow]","state":"ACTIVE"}]
2602 try:
2603 cmdStr = "onos:apps"
2604 if jsonFormat:
2605 cmdStr += " -j"
2606 output = self.sendline( cmdStr )
2607 assert "Error executing command" not in output
2608 return output
2609 # FIXME: look at specific exceptions/Errors
2610 except AssertionError:
2611 main.log.error( "Error in processing onos:app command: " +
2612 str( output ) )
2613 return None
2614 except TypeError:
2615 main.log.exception( self.name + ": Object not as expected" )
2616 return None
2617 except pexpect.EOF:
2618 main.log.error( self.name + ": EOF exception found" )
2619 main.log.error( self.name + ": " + self.handle.before )
2620 main.cleanup()
2621 main.exit()
2622 except Exception:
2623 main.log.exception( self.name + ": Uncaught exception!" )
2624 main.cleanup()
2625 main.exit()
2626
2627 def appStatus( self, appName ):
2628 """
2629 Uses the onos:apps cli command to return the status of an application.
2630 Returns:
2631 "ACTIVE" - If app is installed and activated
2632 "INSTALLED" - If app is installed and deactivated
2633 "UNINSTALLED" - If app is not installed
2634 None - on error
2635 """
2636 try:
2637 if not isinstance( appName, types.StringType ):
2638 main.log.error( self.name + ".appStatus(): appName must be" +
2639 " a string" )
2640 return None
2641 output = self.apps( jsonFormat=True )
2642 appsJson = json.loads( output )
2643 state = None
2644 for app in appsJson:
2645 if appName == app.get('name'):
2646 state = app.get('state')
2647 break
2648 if state == "ACTIVE" or state == "INSTALLED":
2649 return state
2650 elif state is None:
2651 return "UNINSTALLED"
2652 elif state:
2653 main.log.error( "Unexpected state from 'onos:apps': " +
2654 str( state ) )
2655 return state
2656 except TypeError:
2657 main.log.exception( self.name + ": Object not as expected" )
2658 return None
2659 except pexpect.EOF:
2660 main.log.error( self.name + ": EOF exception found" )
2661 main.log.error( self.name + ": " + self.handle.before )
2662 main.cleanup()
2663 main.exit()
2664 except Exception:
2665 main.log.exception( self.name + ": Uncaught exception!" )
2666 main.cleanup()
2667 main.exit()
2668
2669 def app( self, appName, option ):
2670 """
2671 Interacts with the app command for ONOS. This command manages
2672 application inventory.
2673 """
2674 try:
2675 # Validate argument types
2676 valid = True
2677 if not isinstance( appName, types.StringType ):
2678 main.log.error( self.name + ".app(): appName must be a " +
2679 "string" )
2680 valid = False
2681 if not isinstance( option, types.StringType ):
2682 main.log.error( self.name + ".app(): option must be a string" )
2683 valid = False
2684 if not valid:
2685 return main.FALSE
2686 # Validate Option
2687 option = option.lower()
2688 # NOTE: Install may become a valid option
2689 if option == "activate":
2690 pass
2691 elif option == "deactivate":
2692 pass
2693 elif option == "uninstall":
2694 pass
2695 else:
2696 # Invalid option
2697 main.log.error( "The ONOS app command argument only takes " +
2698 "the values: (activate|deactivate|uninstall)" +
2699 "; was given '" + option + "'")
2700 return main.FALSE
2701 cmdStr = "onos:app " + option + " " + appName
2702 output = self.sendline( cmdStr )
2703 if "Error executing command" in output:
2704 main.log.error( "Error in processing onos:app command: " +
2705 str( output ) )
2706 return main.FALSE
2707 elif "No such application" in output:
2708 main.log.error( "The application '" + appName +
2709 "' is not installed in ONOS" )
2710 return main.FALSE
2711 elif "Command not found:" in output:
2712 main.log.error( "Error in processing onos:app command: " +
2713 str( output ) )
2714 return main.FALSE
2715 elif "Unsupported command:" in output:
2716 main.log.error( "Incorrect command given to 'app': " +
2717 str( output ) )
2718 # NOTE: we may need to add more checks here
2719 # else: Command was successful
2720 # main.log.debug( "app response: " + repr( output ) )
2721 return main.TRUE
2722 except TypeError:
2723 main.log.exception( self.name + ": Object not as expected" )
2724 return main.ERROR
2725 except pexpect.EOF:
2726 main.log.error( self.name + ": EOF exception found" )
2727 main.log.error( self.name + ": " + self.handle.before )
2728 main.cleanup()
2729 main.exit()
2730 except Exception:
2731 main.log.exception( self.name + ": Uncaught exception!" )
2732 main.cleanup()
2733 main.exit()
2734
2735 def activateApp( self, appName, check=True ):
2736 """
2737 Activate an app that is already installed in ONOS
2738 appName is the hierarchical app name, not the feature name
2739 If check is True, method will check the status of the app after the
2740 command is issued
2741 Returns main.TRUE if the command was successfully sent
2742 main.FALSE if the cli responded with an error or given
2743 incorrect input
2744 """
2745 try:
2746 if not isinstance( appName, types.StringType ):
2747 main.log.error( self.name + ".activateApp(): appName must be" +
2748 " a string" )
2749 return main.FALSE
2750 status = self.appStatus( appName )
2751 if status == "INSTALLED":
2752 response = self.app( appName, "activate" )
2753 if check and response == main.TRUE:
2754 for i in range(10): # try 10 times then give up
2755 # TODO: Check with Thomas about this delay
2756 status = self.appStatus( appName )
2757 if status == "ACTIVE":
2758 return main.TRUE
2759 else:
2760 main.log.debug( "The state of application " +
2761 appName + " is " + status )
2762 time.sleep( 1 )
2763 return main.FALSE
2764 else: # not 'check' or command didn't succeed
2765 return response
2766 elif status == "ACTIVE":
2767 return main.TRUE
2768 elif status == "UNINSTALLED":
2769 main.log.error( self.name + ": Tried to activate the " +
2770 "application '" + appName + "' which is not " +
2771 "installed." )
2772 else:
2773 main.log.error( "Unexpected return value from appStatus: " +
2774 str( status ) )
2775 return main.ERROR
2776 except TypeError:
2777 main.log.exception( self.name + ": Object not as expected" )
2778 return main.ERROR
2779 except pexpect.EOF:
2780 main.log.error( self.name + ": EOF exception found" )
2781 main.log.error( self.name + ": " + self.handle.before )
2782 main.cleanup()
2783 main.exit()
2784 except Exception:
2785 main.log.exception( self.name + ": Uncaught exception!" )
2786 main.cleanup()
2787 main.exit()
2788
2789 def deactivateApp( self, appName, check=True ):
2790 """
2791 Deactivate an app that is already activated in ONOS
2792 appName is the hierarchical app name, not the feature name
2793 If check is True, method will check the status of the app after the
2794 command is issued
2795 Returns main.TRUE if the command was successfully sent
2796 main.FALSE if the cli responded with an error or given
2797 incorrect input
2798 """
2799 try:
2800 if not isinstance( appName, types.StringType ):
2801 main.log.error( self.name + ".deactivateApp(): appName must " +
2802 "be a string" )
2803 return main.FALSE
2804 status = self.appStatus( appName )
2805 if status == "INSTALLED":
2806 return main.TRUE
2807 elif status == "ACTIVE":
2808 response = self.app( appName, "deactivate" )
2809 if check and response == main.TRUE:
2810 for i in range(10): # try 10 times then give up
2811 status = self.appStatus( appName )
2812 if status == "INSTALLED":
2813 return main.TRUE
2814 else:
2815 time.sleep( 1 )
2816 return main.FALSE
2817 else: # not check or command didn't succeed
2818 return response
2819 elif status == "UNINSTALLED":
2820 main.log.warn( self.name + ": Tried to deactivate the " +
2821 "application '" + appName + "' which is not " +
2822 "installed." )
2823 return main.TRUE
2824 else:
2825 main.log.error( "Unexpected return value from appStatus: " +
2826 str( status ) )
2827 return main.ERROR
2828 except TypeError:
2829 main.log.exception( self.name + ": Object not as expected" )
2830 return main.ERROR
2831 except pexpect.EOF:
2832 main.log.error( self.name + ": EOF exception found" )
2833 main.log.error( self.name + ": " + self.handle.before )
2834 main.cleanup()
2835 main.exit()
2836 except Exception:
2837 main.log.exception( self.name + ": Uncaught exception!" )
2838 main.cleanup()
2839 main.exit()
2840
2841 def uninstallApp( self, appName, check=True ):
2842 """
2843 Uninstall an app that is already installed in ONOS
2844 appName is the hierarchical app name, not the feature name
2845 If check is True, method will check the status of the app after the
2846 command is issued
2847 Returns main.TRUE if the command was successfully sent
2848 main.FALSE if the cli responded with an error or given
2849 incorrect input
2850 """
2851 # TODO: check with Thomas about the state machine for apps
2852 try:
2853 if not isinstance( appName, types.StringType ):
2854 main.log.error( self.name + ".uninstallApp(): appName must " +
2855 "be a string" )
2856 return main.FALSE
2857 status = self.appStatus( appName )
2858 if status == "INSTALLED":
2859 response = self.app( appName, "uninstall" )
2860 if check and response == main.TRUE:
2861 for i in range(10): # try 10 times then give up
2862 status = self.appStatus( appName )
2863 if status == "UNINSTALLED":
2864 return main.TRUE
2865 else:
2866 time.sleep( 1 )
2867 return main.FALSE
2868 else: # not check or command didn't succeed
2869 return response
2870 elif status == "ACTIVE":
2871 main.log.warn( self.name + ": Tried to uninstall the " +
2872 "application '" + appName + "' which is " +
2873 "currently active." )
2874 response = self.app( appName, "uninstall" )
2875 if check and response == main.TRUE:
2876 for i in range(10): # try 10 times then give up
2877 status = self.appStatus( appName )
2878 if status == "UNINSTALLED":
2879 return main.TRUE
2880 else:
2881 time.sleep( 1 )
2882 return main.FALSE
2883 else: # not check or command didn't succeed
2884 return response
2885 elif status == "UNINSTALLED":
2886 return main.TRUE
2887 else:
2888 main.log.error( "Unexpected return value from appStatus: " +
2889 str( status ) )
2890 return main.ERROR
2891 except TypeError:
2892 main.log.exception( self.name + ": Object not as expected" )
2893 return main.ERROR
2894 except pexpect.EOF:
2895 main.log.error( self.name + ": EOF exception found" )
2896 main.log.error( self.name + ": " + self.handle.before )
2897 main.cleanup()
2898 main.exit()
2899 except Exception:
2900 main.log.exception( self.name + ": Uncaught exception!" )
2901 main.cleanup()
2902 main.exit()
2903
2904 def appIDs( self, jsonFormat=True ):
2905 """
2906 Show the mappings between app id and app names given by the 'app-ids'
2907 cli command
2908 """
2909 try:
2910 cmdStr = "app-ids"
2911 if jsonFormat:
2912 cmdStr += " -j"
2913 output = self.sendline( cmdStr )
2914 assert "Error executing command" not in output
2915 return output
2916 except AssertionError:
2917 main.log.error( "Error in processing onos:app-ids command: " +
2918 str( output ) )
2919 return None
2920 except TypeError:
2921 main.log.exception( self.name + ": Object not as expected" )
2922 return None
2923 except pexpect.EOF:
2924 main.log.error( self.name + ": EOF exception found" )
2925 main.log.error( self.name + ": " + self.handle.before )
2926 main.cleanup()
2927 main.exit()
2928 except Exception:
2929 main.log.exception( self.name + ": Uncaught exception!" )
2930 main.cleanup()
2931 main.exit()
2932
2933 def appToIDCheck( self ):
2934 """
2935 This method will check that each application's ID listed in 'apps' is
2936 the same as the ID listed in 'app-ids'. The check will also check that
2937 there are no duplicate IDs issued. Note that an app ID should be
2938 a globaly unique numerical identifier for app/app-like features. Once
2939 an ID is registered, the ID is never freed up so that if an app is
2940 reinstalled it will have the same ID.
2941
2942 Returns: main.TRUE if the check passes and
2943 main.FALSE if the check fails or
2944 main.ERROR if there is some error in processing the test
2945 """
2946 try:
2947 bail = False
2948 ids = self.appIDs( jsonFormat=True )
2949 if ids:
2950 ids = json.loads( ids )
2951 else:
2952 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2953 bail = True
2954 apps = self.apps( jsonFormat=True )
2955 if apps:
2956 apps = json.loads( apps )
2957 else:
2958 main.log.error( "apps returned nothing:" + repr( apps ) )
2959 bail = True
2960 if bail:
2961 return main.FALSE
2962 result = main.TRUE
2963 for app in apps:
2964 appID = app.get( 'id' )
2965 if appID is None:
2966 main.log.error( "Error parsing app: " + str( app ) )
2967 result = main.FALSE
2968 appName = app.get( 'name' )
2969 if appName is None:
2970 main.log.error( "Error parsing app: " + str( app ) )
2971 result = main.FALSE
2972 # get the entry in ids that has the same appID
2973 current = filter( lambda item: item[ 'id' ] == appID, ids )
2974 # main.log.debug( "Comparing " + str( app ) + " to " +
2975 # str( current ) )
2976 if not current: # if ids doesn't have this id
2977 result = main.FALSE
2978 main.log.error( "'app-ids' does not have the ID for " +
2979 str( appName ) + " that apps does." )
2980 elif len( current ) > 1:
2981 # there is more than one app with this ID
2982 result = main.FALSE
2983 # We will log this later in the method
2984 elif not current[0][ 'name' ] == appName:
2985 currentName = current[0][ 'name' ]
2986 result = main.FALSE
2987 main.log.error( "'app-ids' has " + str( currentName ) +
2988 " registered under id:" + str( appID ) +
2989 " but 'apps' has " + str( appName ) )
2990 else:
2991 pass # id and name match!
2992 # now make sure that app-ids has no duplicates
2993 idsList = []
2994 namesList = []
2995 for item in ids:
2996 idsList.append( item[ 'id' ] )
2997 namesList.append( item[ 'name' ] )
2998 if len( idsList ) != len( set( idsList ) ) or\
2999 len( namesList ) != len( set( namesList ) ):
3000 main.log.error( "'app-ids' has some duplicate entries: \n"
3001 + json.dumps( ids,
3002 sort_keys=True,
3003 indent=4,
3004 separators=( ',', ': ' ) ) )
3005 result = main.FALSE
3006 return result
3007 except ( ValueError, TypeError ):
3008 main.log.exception( self.name + ": Object not as expected" )
3009 return main.ERROR
3010 except pexpect.EOF:
3011 main.log.error( self.name + ": EOF exception found" )
3012 main.log.error( self.name + ": " + self.handle.before )
3013 main.cleanup()
3014 main.exit()
3015 except Exception:
3016 main.log.exception( self.name + ": Uncaught exception!" )
3017 main.cleanup()
3018 main.exit()
3019
3020 def getCfg( self, component=None, propName=None, short=False,
3021 jsonFormat=True ):
3022 """
3023 Get configuration settings from onos cli
3024 Optional arguments:
3025 component - Optionally only list configurations for a specific
3026 component. If None, all components with configurations
3027 are displayed. Case Sensitive string.
3028 propName - If component is specified, propName option will show
3029 only this specific configuration from that component.
3030 Case Sensitive string.
3031 jsonFormat - Returns output as json. Note that this will override
3032 the short option
3033 short - Short, less verbose, version of configurations.
3034 This is overridden by the json option
3035 returns:
3036 Output from cli as a string or None on error
3037 """
3038 try:
3039 baseStr = "cfg"
3040 cmdStr = " get"
3041 componentStr = ""
3042 if component:
3043 componentStr += " " + component
3044 if propName:
3045 componentStr += " " + propName
3046 if jsonFormat:
3047 baseStr += " -j"
3048 elif short:
3049 baseStr += " -s"
3050 output = self.sendline( baseStr + cmdStr + componentStr )
3051 assert "Error executing command" not in output
3052 return output
3053 except AssertionError:
3054 main.log.error( "Error in processing 'cfg get' command: " +
3055 str( output ) )
3056 return None
3057 except TypeError:
3058 main.log.exception( self.name + ": Object not as expected" )
3059 return None
3060 except pexpect.EOF:
3061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
3063 main.cleanup()
3064 main.exit()
3065 except Exception:
3066 main.log.exception( self.name + ": Uncaught exception!" )
3067 main.cleanup()
3068 main.exit()
3069
3070 def setCfg( self, component, propName, value=None, check=True ):
3071 """
3072 Set/Unset configuration settings from ONOS cli
3073 Required arguments:
3074 component - The case sensitive name of the component whose
3075 property is to be set
3076 propName - The case sensitive name of the property to be set/unset
3077 Optional arguments:
3078 value - The value to set the property to. If None, will unset the
3079 property and revert it to it's default value(if applicable)
3080 check - Boolean, Check whether the option was successfully set this
3081 only applies when a value is given.
3082 returns:
3083 main.TRUE on success or main.FALSE on failure. If check is False,
3084 will return main.TRUE unless there is an error
3085 """
3086 try:
3087 baseStr = "cfg"
3088 cmdStr = " set " + str( component ) + " " + str( propName )
3089 if value is not None:
3090 cmdStr += " " + str( value )
3091 output = self.sendline( baseStr + cmdStr )
3092 assert "Error executing command" not in output
3093 if value and check:
3094 results = self.getCfg( component=str( component ),
3095 propName=str( propName ),
3096 jsonFormat=True )
3097 # Check if current value is what we just set
3098 try:
3099 jsonOutput = json.loads( results )
3100 current = jsonOutput[ 'value' ]
3101 except ( ValueError, TypeError ):
3102 main.log.exception( "Error parsing cfg output" )
3103 main.log.error( "output:" + repr( results ) )
3104 return main.FALSE
3105 if current == str( value ):
3106 return main.TRUE
3107 return main.FALSE
3108 return main.TRUE
3109 except AssertionError:
3110 main.log.error( "Error in processing 'cfg set' command: " +
3111 str( output ) )
3112 return main.FALSE
3113 except TypeError:
3114 main.log.exception( self.name + ": Object not as expected" )
3115 return main.FALSE
3116 except pexpect.EOF:
3117 main.log.error( self.name + ": EOF exception found" )
3118 main.log.error( self.name + ": " + self.handle.before )
3119 main.cleanup()
3120 main.exit()
3121 except Exception:
3122 main.log.exception( self.name + ": Uncaught exception!" )
3123 main.cleanup()
3124 main.exit()
3125
3126 def setTestAdd( self, setName, values ):
3127 """
3128 CLI command to add elements to a distributed set.
3129 Arguments:
3130 setName - The name of the set to add to.
3131 values - The value(s) to add to the set, space seperated.
3132 Example usages:
3133 setTestAdd( "set1", "a b c" )
3134 setTestAdd( "set2", "1" )
3135 returns:
3136 main.TRUE on success OR
3137 main.FALSE if elements were already in the set OR
3138 main.ERROR on error
3139 """
3140 try:
3141 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3142 output = self.sendline( cmdStr )
3143 try:
3144 # TODO: Maybe make this less hardcoded
3145 # ConsistentMap Exceptions
3146 assert "org.onosproject.store.service" not in output
3147 # Node not leader
3148 assert "java.lang.IllegalStateException" not in output
3149 except AssertionError:
3150 main.log.error( "Error in processing 'set-test-add' " +
3151 "command: " + str( output ) )
3152 retryTime = 30 # Conservative time, given by Madan
3153 main.log.info( "Waiting " + str( retryTime ) +
3154 "seconds before retrying." )
3155 time.sleep( retryTime ) # Due to change in mastership
3156 output = self.sendline( cmdStr )
3157 assert "Error executing command" not in output
3158 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3159 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3160 main.log.info( self.name + ": " + output )
3161 if re.search( positiveMatch, output):
3162 return main.TRUE
3163 elif re.search( negativeMatch, output):
3164 return main.FALSE
3165 else:
3166 main.log.error( self.name + ": setTestAdd did not" +
3167 " match expected output" )
pingping-lin763ee042015-05-20 17:45:30 -07003168 main.log.debug( self.name + " actual: " + repr( output ) )
3169 return main.ERROR
3170 except AssertionError:
3171 main.log.error( "Error in processing 'set-test-add' command: " +
3172 str( output ) )
3173 return main.ERROR
3174 except TypeError:
3175 main.log.exception( self.name + ": Object not as expected" )
3176 return main.ERROR
3177 except pexpect.EOF:
3178 main.log.error( self.name + ": EOF exception found" )
3179 main.log.error( self.name + ": " + self.handle.before )
3180 main.cleanup()
3181 main.exit()
3182 except Exception:
3183 main.log.exception( self.name + ": Uncaught exception!" )
3184 main.cleanup()
3185 main.exit()
3186
3187 def setTestRemove( self, setName, values, clear=False, retain=False ):
3188 """
3189 CLI command to remove elements from a distributed set.
3190 Required arguments:
3191 setName - The name of the set to remove from.
3192 values - The value(s) to remove from the set, space seperated.
3193 Optional arguments:
3194 clear - Clear all elements from the set
3195 retain - Retain only the given values. (intersection of the
3196 original set and the given set)
3197 returns:
3198 main.TRUE on success OR
3199 main.FALSE if the set was not changed OR
3200 main.ERROR on error
3201 """
3202 try:
3203 cmdStr = "set-test-remove "
3204 if clear:
3205 cmdStr += "-c " + str( setName )
3206 elif retain:
3207 cmdStr += "-r " + str( setName ) + " " + str( values )
3208 else:
3209 cmdStr += str( setName ) + " " + str( values )
3210 output = self.sendline( cmdStr )
3211 try:
3212 # TODO: Maybe make this less hardcoded
3213 # ConsistentMap Exceptions
3214 assert "org.onosproject.store.service" not in output
3215 # Node not leader
3216 assert "java.lang.IllegalStateException" not in output
3217 except AssertionError:
3218 main.log.error( "Error in processing 'set-test-add' " +
3219 "command: " + str( output ) )
3220 retryTime = 30 # Conservative time, given by Madan
3221 main.log.info( "Waiting " + str( retryTime ) +
3222 "seconds before retrying." )
3223 time.sleep( retryTime ) # Due to change in mastership
3224 output = self.sendline( cmdStr )
3225 assert "Error executing command" not in output
3226 main.log.info( self.name + ": " + output )
3227 if clear:
3228 pattern = "Set " + str( setName ) + " cleared"
3229 if re.search( pattern, output ):
3230 return main.TRUE
3231 elif retain:
3232 positivePattern = str( setName ) + " was pruned to contain " +\
3233 "only elements of set \[(.*)\]"
3234 negativePattern = str( setName ) + " was not changed by " +\
3235 "retaining only elements of the set " +\
3236 "\[(.*)\]"
3237 if re.search( positivePattern, output ):
3238 return main.TRUE
3239 elif re.search( negativePattern, output ):
3240 return main.FALSE
3241 else:
3242 positivePattern = "\[(.*)\] was removed from the set " +\
3243 str( setName )
3244 if ( len( values.split() ) == 1 ):
3245 negativePattern = "\[(.*)\] was not in set " +\
3246 str( setName )
3247 else:
3248 negativePattern = "No element of \[(.*)\] was in set " +\
3249 str( setName )
3250 if re.search( positivePattern, output ):
3251 return main.TRUE
3252 elif re.search( negativePattern, output ):
3253 return main.FALSE
3254 main.log.error( self.name + ": setTestRemove did not" +
3255 " match expected output" )
3256 main.log.debug( self.name + " expected: " + pattern )
3257 main.log.debug( self.name + " actual: " + repr( output ) )
3258 return main.ERROR
3259 except AssertionError:
3260 main.log.error( "Error in processing 'set-test-remove' command: " +
3261 str( output ) )
3262 return main.ERROR
3263 except TypeError:
3264 main.log.exception( self.name + ": Object not as expected" )
3265 return main.ERROR
3266 except pexpect.EOF:
3267 main.log.error( self.name + ": EOF exception found" )
3268 main.log.error( self.name + ": " + self.handle.before )
3269 main.cleanup()
3270 main.exit()
3271 except Exception:
3272 main.log.exception( self.name + ": Uncaught exception!" )
3273 main.cleanup()
3274 main.exit()
3275
3276 def setTestGet( self, setName, values="" ):
3277 """
3278 CLI command to get the elements in a distributed set.
3279 Required arguments:
3280 setName - The name of the set to remove from.
3281 Optional arguments:
3282 values - The value(s) to check if in the set, space seperated.
3283 returns:
3284 main.ERROR on error OR
3285 A list of elements in the set if no optional arguments are
3286 supplied OR
3287 A tuple containing the list then:
3288 main.FALSE if the given values are not in the set OR
3289 main.TRUE if the given values are in the set OR
3290 """
3291 try:
3292 values = str( values ).strip()
3293 setName = str( setName ).strip()
3294 length = len( values.split() )
3295 containsCheck = None
3296 # Patterns to match
3297 setPattern = "\[(.*)\]"
3298 pattern = "Items in set " + setName + ":\n" + setPattern
3299 containsTrue = "Set " + setName + " contains the value " + values
3300 containsFalse = "Set " + setName + " did not contain the value " +\
3301 values
3302 containsAllTrue = "Set " + setName + " contains the the subset " +\
3303 setPattern
3304 containsAllFalse = "Set " + setName + " did not contain the the" +\
3305 " subset " + setPattern
3306
3307 cmdStr = "set-test-get "
3308 cmdStr += setName + " " + values
3309 output = self.sendline( cmdStr )
3310 try:
3311 # TODO: Maybe make this less hardcoded
3312 # ConsistentMap Exceptions
3313 assert "org.onosproject.store.service" not in output
3314 # Node not leader
3315 assert "java.lang.IllegalStateException" not in output
3316 except AssertionError:
3317 main.log.error( "Error in processing 'set-test-add' " +
3318 "command: " + str( output ) )
3319 retryTime = 30 # Conservative time, given by Madan
3320 main.log.info( "Waiting " + str( retryTime ) +
3321 "seconds before retrying." )
3322 time.sleep( retryTime ) # Due to change in mastership
3323 output = self.sendline( cmdStr )
3324 assert "Error executing command" not in output
3325 main.log.info( self.name + ": " + output )
3326
3327 if length == 0:
3328 match = re.search( pattern, output )
3329 else: # if given values
3330 if length == 1: # Contains output
3331 patternTrue = pattern + "\n" + containsTrue
3332 patternFalse = pattern + "\n" + containsFalse
3333 else: # ContainsAll output
3334 patternTrue = pattern + "\n" + containsAllTrue
3335 patternFalse = pattern + "\n" + containsAllFalse
3336 matchTrue = re.search( patternTrue, output )
3337 matchFalse = re.search( patternFalse, output )
3338 if matchTrue:
3339 containsCheck = main.TRUE
3340 match = matchTrue
3341 elif matchFalse:
3342 containsCheck = main.FALSE
3343 match = matchFalse
3344 else:
3345 main.log.error( self.name + " setTestGet did not match " +\
3346 "expected output" )
3347 main.log.debug( self.name + " expected: " + pattern )
3348 main.log.debug( self.name + " actual: " + repr( output ) )
3349 match = None
3350 if match:
3351 setMatch = match.group( 1 )
3352 if setMatch == '':
3353 setList = []
3354 else:
3355 setList = setMatch.split( ", " )
3356 if length > 0:
3357 return ( setList, containsCheck )
3358 else:
3359 return setList
3360 else: # no match
3361 main.log.error( self.name + ": setTestGet did not" +
3362 " match expected output" )
3363 main.log.debug( self.name + " expected: " + pattern )
3364 main.log.debug( self.name + " actual: " + repr( output ) )
3365 return main.ERROR
3366 except AssertionError:
3367 main.log.error( "Error in processing 'set-test-get' command: " +
3368 str( output ) )
3369 return main.ERROR
3370 except TypeError:
3371 main.log.exception( self.name + ": Object not as expected" )
3372 return main.ERROR
3373 except pexpect.EOF:
3374 main.log.error( self.name + ": EOF exception found" )
3375 main.log.error( self.name + ": " + self.handle.before )
3376 main.cleanup()
3377 main.exit()
3378 except Exception:
3379 main.log.exception( self.name + ": Uncaught exception!" )
3380 main.cleanup()
3381 main.exit()
3382
3383 def setTestSize( self, setName ):
3384 """
3385 CLI command to get the elements in a distributed set.
3386 Required arguments:
3387 setName - The name of the set to remove from.
3388 returns:
3389 The integer value of the size returned or
3390 None on error
3391 """
3392 try:
3393 # TODO: Should this check against the number of elements returned
3394 # and then return true/false based on that?
3395 setName = str( setName ).strip()
3396 # Patterns to match
3397 setPattern = "\[(.*)\]"
3398 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3399 setPattern
3400 cmdStr = "set-test-get -s "
3401 cmdStr += setName
3402 output = self.sendline( cmdStr )
3403 try:
3404 # TODO: Maybe make this less hardcoded
3405 # ConsistentMap Exceptions
3406 assert "org.onosproject.store.service" not in output
3407 # Node not leader
3408 assert "java.lang.IllegalStateException" not in output
3409 except AssertionError:
3410 main.log.error( "Error in processing 'set-test-add' " +
3411 "command: " + str( output ) )
3412 retryTime = 30 # Conservative time, given by Madan
3413 main.log.info( "Waiting " + str( retryTime ) +
3414 "seconds before retrying." )
3415 time.sleep( retryTime ) # Due to change in mastership
3416 output = self.sendline( cmdStr )
3417 assert "Error executing command" not in output
3418 main.log.info( self.name + ": " + output )
3419 match = re.search( pattern, output )
3420 if match:
3421 setSize = int( match.group( 1 ) )
3422 setMatch = match.group( 2 )
3423 if len( setMatch.split() ) == setSize:
3424 main.log.info( "The size returned by " + self.name +
3425 " matches the number of elements in " +
3426 "the returned set" )
3427 else:
3428 main.log.error( "The size returned by " + self.name +
3429 " does not match the number of " +
3430 "elements in the returned set." )
3431 return setSize
3432 else: # no match
3433 main.log.error( self.name + ": setTestGet did not" +
3434 " match expected output" )
3435 main.log.debug( self.name + " expected: " + pattern )
3436 main.log.debug( self.name + " actual: " + repr( output ) )
3437 return None
3438 except AssertionError:
3439 main.log.error( "Error in processing 'set-test-get' command: " +
3440 str( output ) )
3441 return None
3442 except TypeError:
3443 main.log.exception( self.name + ": Object not as expected" )
3444 return None
3445 except pexpect.EOF:
3446 main.log.error( self.name + ": EOF exception found" )
3447 main.log.error( self.name + ": " + self.handle.before )
3448 main.cleanup()
3449 main.exit()
3450 except Exception:
3451 main.log.exception( self.name + ": Uncaught exception!" )
3452 main.cleanup()
3453 main.exit()
3454
Jon Hall80daded2015-05-27 16:07:00 -07003455 def counters( self, jsonFormat=True ):
pingping-lin763ee042015-05-20 17:45:30 -07003456 """
3457 Command to list the various counters in the system.
3458 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003459 if jsonFormat, a string of the json object returned by the cli
3460 command
3461 if not jsonFormat, the normal string output of the cli command
pingping-lin763ee042015-05-20 17:45:30 -07003462 None on error
3463 """
pingping-lin763ee042015-05-20 17:45:30 -07003464 try:
3465 counters = {}
3466 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003467 if jsonFormat:
3468 cmdStr += " -j"
pingping-lin763ee042015-05-20 17:45:30 -07003469 output = self.sendline( cmdStr )
3470 assert "Error executing command" not in output
3471 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003472 return output
pingping-lin763ee042015-05-20 17:45:30 -07003473 except AssertionError:
3474 main.log.error( "Error in processing 'counters' command: " +
3475 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003476 return None
pingping-lin763ee042015-05-20 17:45:30 -07003477 except TypeError:
3478 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003479 return None
pingping-lin763ee042015-05-20 17:45:30 -07003480 except pexpect.EOF:
3481 main.log.error( self.name + ": EOF exception found" )
3482 main.log.error( self.name + ": " + self.handle.before )
3483 main.cleanup()
3484 main.exit()
3485 except Exception:
3486 main.log.exception( self.name + ": Uncaught exception!" )
3487 main.cleanup()
3488 main.exit()
3489
3490 def counterTestIncrement( self, counter, inMemory=False ):
3491 """
3492 CLI command to increment and get a distributed counter.
3493 Required arguments:
3494 counter - The name of the counter to increment.
3495 Optional arguments:
3496 inMemory - use in memory map for the counter
3497 returns:
3498 integer value of the counter or
3499 None on Error
3500 """
3501 try:
3502 counter = str( counter )
3503 cmdStr = "counter-test-increment "
3504 if inMemory:
3505 cmdStr += "-i "
3506 cmdStr += counter
3507 output = self.sendline( cmdStr )
3508 try:
3509 # TODO: Maybe make this less hardcoded
3510 # ConsistentMap Exceptions
3511 assert "org.onosproject.store.service" not in output
3512 # Node not leader
3513 assert "java.lang.IllegalStateException" not in output
3514 except AssertionError:
3515 main.log.error( "Error in processing 'set-test-add' " +
3516 "command: " + str( output ) )
3517 retryTime = 30 # Conservative time, given by Madan
3518 main.log.info( "Waiting " + str( retryTime ) +
3519 "seconds before retrying." )
3520 time.sleep( retryTime ) # Due to change in mastership
3521 output = self.sendline( cmdStr )
3522 assert "Error executing command" not in output
3523 main.log.info( self.name + ": " + output )
3524 pattern = counter + " was incremented to (\d+)"
3525 match = re.search( pattern, output )
3526 if match:
3527 return int( match.group( 1 ) )
3528 else:
3529 main.log.error( self.name + ": counterTestIncrement did not" +
3530 " match expected output." )
3531 main.log.debug( self.name + " expected: " + pattern )
3532 main.log.debug( self.name + " actual: " + repr( output ) )
3533 return None
3534 except AssertionError:
3535 main.log.error( "Error in processing 'counter-test-increment'" +
3536 " command: " + str( output ) )
3537 return None
3538 except TypeError:
3539 main.log.exception( self.name + ": Object not as expected" )
3540 return None
3541 except pexpect.EOF:
3542 main.log.error( self.name + ": EOF exception found" )
3543 main.log.error( self.name + ": " + self.handle.before )
3544 main.cleanup()
3545 main.exit()
3546 except Exception:
3547 main.log.exception( self.name + ": Uncaught exception!" )
3548 main.cleanup()
3549 main.exit()
3550