blob: 1d5727106849e3b12707ac257682aecacd48f16e [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
Jon Hall30b82fa2015-03-04 17:15:43 -080022import json
23import types
Jon Hallbd16b922015-03-26 17:53:15 -070024import 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 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 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 ]
andrew@onlab.us658ec012015-03-11 15:13:09 -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
kelvin-onlabfb521662015-02-27 09:52:40 -080052 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070053 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
Jon Halld4d4b372015-01-28 16:02:41 -080070 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()
Jon Hallfebb1c72015-03-05 13:30:09 -080078 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080079 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 """
Jon Halld61331b2015-02-17 16:35:47 -080087 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040088 try:
Jon Hall61282e32015-03-19 11:34:11 -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" )
Jon Halld4d4b372015-01-28 16:02:41 -080096 except TypeError:
97 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080098 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 )
Jon Hall61282e32015-03-19 11:34:11 -0700102 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700103 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700104 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 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
Jon Hall61282e32015-03-19 11:34:11 -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:
Jon Hall61282e32015-03-19 11:34:11 -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
Jon Halld4d4b372015-01-28 16:02:41 -0800133 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" )
Jon Hall61282e32015-03-19 11:34:11 -0700138 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 main.cleanup()
140 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700141 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700142 main.log.error( self.name +
143 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800145 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
Cameron Franke9c94fb02015-01-21 10:20:20 -0800165 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800166 handleBefore = self.handle.before
167 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800168 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800169 self.handle.sendline("")
170 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -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
Jon Halld4d4b372015-01-28 16:02:41 -0800178 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800186 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800187 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 """
Jon Hallefbd9792015-03-05 16:11:36 -0800194 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
Jon Halld4d4b372015-01-28 16:02:41 -0800257 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800265 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800266 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400267 main.cleanup()
268 main.exit()
269
Jon Hallefbd9792015-03-05 16:11:36 -0800270 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800271 """
272 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800273 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800274 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800275 Available level: DEBUG, TRACE, INFO, WARN, ERROR
276 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800277 """
278 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800279 lvlStr = ""
280 if level:
281 lvlStr = "--level=" + level
282
kelvin-onlab9f541032015-02-04 16:19:53 -0800283 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>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800289 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700290 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800291 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800292
kelvin-onlab9f541032015-02-04 16:19:53 -0800293 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()
kelvin-onlab9f541032015-02-04 16:19:53 -0800301 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800306 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800307 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400308 main.cleanup()
309 main.exit()
310
Jon Hallc6358dd2015-04-10 12:44:28 -0700311 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:
kelvin-onlab338f5512015-02-06 10:53:16 -0800321 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
322 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800323 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800324 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
325 response = self.handle.before
326 if i == 2:
327 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700328 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800329 response += self.handle.before
330 print response
331 try:
332 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700333 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800334 pass
335 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800336 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800337 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700338 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700339 main.log.debug( self.name + ": Raw output" )
340 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700341
342 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800343 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800344 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700345 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700346 main.log.debug( self.name + ": ansiEscape output" )
347 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700348
kelvin-onlabfb521662015-02-27 09:52:40 -0800349 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800350 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700351 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700352 main.log.debug( self.name + ": Removed extra returns " +
353 "from output" )
354 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700355
356 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800357 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700358 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700359 main.log.debug( self.name + ": parsed and stripped output" )
360 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700361
Jon Hall63604932015-02-26 17:09:50 -0800362 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700363 output = response.split( cmdStr.strip(), 1 )
364 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700365 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700366 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700367 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700368 return output[1].strip()
369 except IndexError:
370 main.log.exception( self.name + ": Object not as expected" )
371 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800372 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800380 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800381 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
Jon Halld4d4b372015-01-28 16:02:41 -0800412 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800420 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800421 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 )
Jon Hall08f61bc2015-04-13 16:00:30 -0700435 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700436 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
Jon Halld4d4b372015-01-28 16:02:41 -0800442 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800450 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800451 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
Jon Hall61282e32015-03-19 11:34:11 -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'
Jon Hall61282e32015-03-19 11:34:11 -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:
Jon Hallc6358dd2015-04-10 12:44:28 -0700463 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700464 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700465 cmdStr += " -j"
466 output = self.sendline( cmdStr )
467 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800468 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800477 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 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700483 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700484 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700485 Return:
486 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800487 """
andrewonlab95ce8322014-10-13 14:12:04 -0400488 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700489 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700491 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400492 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800493 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800501 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800502 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 """
Jon Hallc6358dd2015-04-10 12:44:28 -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 )
Jon Hallc6358dd2015-04-10 12:44:28 -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
Jon Halld4d4b372015-01-28 16:02:41 -0800522 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800532 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800533 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 """
Jon Hallc6358dd2015-04-10 12:44:28 -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:
Jon Hall30b82fa2015-03-04 17:15:43 -0800547 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
548 handle = self.sendline( cmdStr )
549 if handle != '':
550 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700551 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800552 # TODO: Check for possible error responses from karaf
553 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800554 main.log.info( "Feature needs to be installed before " +
555 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700556 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
Jon Halld4d4b372015-01-28 16:02:41 -0800563 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800571 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800572 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400573 main.cleanup()
574 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800575
jenkins7ead5a82015-03-13 10:28:21 -0700576 def deviceRemove( self, deviceId ):
577 """
578 Removes particular device from storage
579
580 TODO: refactor this function
581 """
582 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700583 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
jenkins7ead5a82015-03-13 10:28:21 -0700591 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!" )
601 main.cleanup()
602 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700603
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:
Jon Hallc6358dd2015-04-10 12:44:28 -0700611 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700613 cmdStr += " -j"
614 handle = self.sendline( cmdStr )
615 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800616 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800624 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800625 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"
Jon Hallc6358dd2015-04-10 12:44:28 -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
Jon Halld4d4b372015-01-28 16:02:41 -0800644 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800652 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800653 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:
Jon Hallc6358dd2015-04-10 12:44:28 -0700664 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700666 cmdStr += " -j"
667 handle = self.sendline( cmdStr )
668 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800669 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800677 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800678 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:
Jon Hallc6358dd2015-04-10 12:44:28 -0700689 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr += " -j"
692 handle = self.sendline( cmdStr )
693 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800694 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800702 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800703 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:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700716 cmdStr += " -j"
717 handle = self.sendline( cmdStr )
718 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800719 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800727 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800728 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
Jon Halld4d4b372015-01-28 16:02:41 -0800755 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 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
Jon Halld4d4b372015-01-28 16:02:41 -0800785 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800793 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800794 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 )
Jon Halld4d4b372015-01-28 16:02:41 -0800813 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800821 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800822 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:
Jon Hallc6358dd2015-04-10 12:44:28 -0700833 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800834 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700835 cmdStr += " -j"
836 handle = self.sendline( cmdStr )
837 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800838 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800846 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800847 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
Jon Hallefbd9792015-03-05 16:11:36 -0800855 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' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800870 if not host:
871 pass
872 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400873 return host
874 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800875 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 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
Jon Halld4d4b372015-01-28 16:02:41 -0800917 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800925 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800926 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:
Jon Hallefbd9792015-03-05 16:11:36 -0800936 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500937 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800938 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" )
Jon Hall61282e32015-03-19 11:34:11 -0700947 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800948 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800949 else:
950 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800951 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" )
Jon Hall61282e32015-03-19 11:34:11 -0700957 main.log.debug( "Response from ONOS was: " +
958 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800959 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800960 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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800968 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800969 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
kelvin-onlabfb521662015-02-27 09:52:40 -0800980 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 ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800991 main.log.error( "Error in adding Optical intent" )
992 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400993 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800994 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
Jon Halld4d4b372015-01-28 16:02:41 -08001003 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001011 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001012 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
kelvin-onlabfb521662015-02-27 09:52:40 -08001051 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:
kelvin-onlabfb521662015-02-27 09:52:40 -08001096 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001097 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001098 # 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:
kelvin-onlabfb521662015-02-27 09:52:40 -08001110 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 )
kelvin-onlabfb521662015-02-27 09:52:40 -08001118 # 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" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001121 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001122 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001123 # 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
Jon Halld4d4b372015-01-28 16:02:41 -08001133 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001141 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001142 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,
shahshreyac2f97072015-03-19 17:04:29 -07001148 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -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:
shahshreya70622b12015-03-19 17:19:00 -07001166 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001167 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:
Jon Hallbe379602015-03-24 13:39:32 -07001171 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001172 ( 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
kelvin-onlabfb521662015-02-27 09:52:40 -08001191 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
Jon Hallefbd9792015-03-05 16:11:36 -08001195 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
shahshreyac2f97072015-03-19 17:04:29 -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 " +
Jon Hallbe379602015-03-24 13:39:32 -07001244 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001245 # TODO: perhaps more meaningful return
1246 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001247 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001248 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001249 for ingressDevice, portIngress in zip( ingressDeviceList,
1250 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001251 cmd += " " + \
1252 str( ingressDevice ) + "/" +\
1253 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001254 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001255 main.log.error( "Device list and port list does not " +
1256 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001257 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 )
kelvin-onlabfb521662015-02-27 09:52:40 -08001270 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001271 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001272 main.log.error( "Error in adding multipoint-to-singlepoint " +
1273 "intent" )
1274 return None
shahshreyad0c80432014-12-04 16:56:05 -08001275 else:
kelvin-onlabb9408212015-04-01 13:34:04 -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
1285 except pexpect.EOF:
1286 main.log.error( self.name + ": EOF exception found" )
1287 main.log.error( self.name + ": " + self.handle.before )
1288 main.cleanup()
1289 main.exit()
1290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception!" )
1292 main.cleanup()
1293 main.exit()
1294
1295 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="" ):
1313 """
1314 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
Jon Hall08f61bc2015-04-13 16:00:30 -07001386
kelvin-onlabb9408212015-04-01 13:34:04 -07001387 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 ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001410 for egressDevice, portEgress in zip( egressDeviceList,
1411 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001412 cmd += " " + \
1413 str( egressDevice ) + "/" +\
1414 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001415 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001416 main.log.error( "Device list and port list does not " +
1417 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001418 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001419 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" )
shahshreyac2f97072015-03-19 17:04:29 -07001424 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001425 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
Jon Halld4d4b372015-01-28 16:02:41 -08001432 except TypeError:
1433 main.log.exception( self.name + ": Object not as expected" )
1434 return None
shahshreyad0c80432014-12-04 16:56:05 -08001435 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001436 main.log.error( self.name + ": EOF exception found" )
1437 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001438 main.cleanup()
1439 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001440 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001441 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001442 main.cleanup()
1443 main.exit()
1444
Hari Krishna9e232602015-04-13 17:29:08 -07001445 def addMplsIntent(
1446 self,
1447 ingressDevice,
1448 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001449 ingressPort="",
1450 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001451 ethType="",
1452 ethSrc="",
1453 ethDst="",
1454 bandwidth="",
1455 lambdaAlloc=False,
1456 ipProto="",
1457 ipSrc="",
1458 ipDst="",
1459 tcpSrc="",
1460 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001461 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001462 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001463 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:
Hari Krishna87a17f12015-04-13 17:42:23 -07001536 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001537 main.log.error( "You must specify the ingress port" )
1538 return None
1539
1540 cmd += " " + \
1541 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001542 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001543
1544 if "/" in egressDevice:
1545 cmd += " " + str( egressDevice )
1546 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001547 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001548 main.log.error( "You must specify the egress port" )
1549 return None
1550
1551 cmd += " " +\
1552 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001553 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001554
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
Jon Hallefbd9792015-03-05 16:11:36 -08001584 def removeIntent( self, intentId, app='org.onosproject.cli',
1585 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001586 """
shahshreya1c818fc2015-02-26 13:44:08 -08001587 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001588 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001589 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001590 -p or --purge: Purge the intent from the store after removal
1591
Jon Halle3f39ff2015-01-13 11:50:53 -08001592 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:
Jon Hallc6358dd2015-04-10 12:44:28 -07001597 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001598 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
Jon Halld4d4b372015-01-28 16:02:41 -08001611 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001620 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:
Jon Hallc6358dd2015-04-10 12:44:28 -07001634 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001636 cmdStr += " -j"
1637 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001638 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001639 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001648 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:
Jon Hallc6358dd2015-04-10 12:44:28 -07001660 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001662 cmdStr += " -j"
1663 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001664 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001665 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001673 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001674 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001675 main.cleanup()
1676 main.exit()
1677
kelvin-onlab54400a92015-02-26 18:05:51 -08001678 def getIntentState(self, intentsId, intentsJson=None):
1679 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001680 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.
Jon Hallefbd9792015-03-05 16:11:36 -08001684 Returns a dictionary with intent IDs as the key and its
1685 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001686 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001687 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 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001694 try:
1695 state = "State is Undefined"
1696 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001697 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001698 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001699 intentsJsonTemp = json.loads( intentsJson )
1700 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001701 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001702 if intentsId == intent[ 'id' ]:
1703 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001704 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001705 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1706 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001707 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001708 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001709 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001710 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001711 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001712 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001713 if intentsId[ i ] == intents[ 'id' ]:
1714 stateDict[ 'state' ] = intents[ 'state' ]
1715 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001716 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001717 break
Jon Hallefbd9792015-03-05 16:11:36 -08001718 if len( intentsId ) != len( dictList ):
1719 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001720 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001721 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001722 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001723 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001724 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001732 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001733 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001734 main.cleanup()
1735 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001736
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001737 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 )
Jon Hall390696c2015-05-05 17:13:41 -07001753 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001754 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:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001761 if intents.get( 'state' ) == "INSTALLING":
1762 main.log.debug( self.name + " : Intent ID - " +
1763 intents.get( 'id' ) +
1764 " is in INSTALLING state" )
1765 returnValue = main.TRUE
1766 else:
1767 main.log.info( self.name + " : Intent ID - " +
1768 intents.get( 'id' ) +
1769 " actual state = " +
1770 intents.get( 'state' )
1771 + " does not equal expected state = "
1772 + expectedState )
1773 returnValue = main.FALSE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001774 if returnValue == main.TRUE:
1775 main.log.info( self.name + ": All " +
1776 str( len( intentsDict ) ) +
1777 " intents are in " + expectedState + " state")
1778 return returnValue
1779 except TypeError:
1780 main.log.exception( self.name + ": Object not as expected" )
1781 return None
1782 except pexpect.EOF:
1783 main.log.error( self.name + ": EOF exception found" )
1784 main.log.error( self.name + ": " + self.handle.before )
1785 main.cleanup()
1786 main.exit()
1787 except Exception:
1788 main.log.exception( self.name + ": Uncaught exception!" )
1789 main.cleanup()
1790 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001791
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001793 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001794 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001796 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001797 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001798 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001799 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001800 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001802 cmdStr += " -j"
1803 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001804 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001805 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001806 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001807 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001808 except TypeError:
1809 main.log.exception( self.name + ": Object not as expected" )
1810 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001811 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001812 main.log.error( self.name + ": EOF exception found" )
1813 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001814 main.cleanup()
1815 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001817 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001818 main.cleanup()
1819 main.exit()
1820
kelvin-onlab4df89f22015-04-13 18:10:23 -07001821 def checkFlowsState( self ):
1822 """
1823 Description:
1824 Check the if all the current flows are in ADDED state or
1825 PENDING_ADD state
1826 Return:
1827 returnValue - Returns main.TRUE only if all flows are in
1828 ADDED state or PENDING_ADD, return main.FALSE
1829 otherwise.
1830 """
1831 try:
1832 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001833 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001834 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001835
kelvin-onlab4df89f22015-04-13 18:10:23 -07001836 for device in tempFlows:
1837 for flow in device.get( 'flows' ):
1838 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1839 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001840
kelvin-onlab4df89f22015-04-13 18:10:23 -07001841 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001842 str( flow.get( 'groupId' ) ) +
1843 " | state:" +
1844 str( flow.get( 'state' ) ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07001845 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001846
kelvin-onlab4df89f22015-04-13 18:10:23 -07001847 return returnValue
1848 except TypeError:
1849 main.log.exception( self.name + ": Object not as expected" )
1850 return None
1851 except pexpect.EOF:
1852 main.log.error( self.name + ": EOF exception found" )
1853 main.log.error( self.name + ": " + self.handle.before )
1854 main.cleanup()
1855 main.exit()
1856 except Exception:
1857 main.log.exception( self.name + ": Uncaught exception!" )
1858 main.cleanup()
1859 main.exit()
1860
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001862 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001863 """
andrewonlab87852b02014-11-19 18:44:19 -05001864 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001865 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001866 a specific point-to-point intent definition
1867 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001868 * dpidSrc: specify source dpid
1869 * dpidDst: specify destination dpid
1870 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001871 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001872 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001873 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001874 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001875 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001876 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001877 """
andrewonlab87852b02014-11-19 18:44:19 -05001878 try:
kelvin8ec71442015-01-15 16:57:00 -08001879 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001880 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1881 str( numIntents )
1882 if numMult:
1883 cmd += " " + str( numMult )
1884 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001885 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001886 if appId:
1887 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001888 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001889 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001890 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001891 main.log.info( handle )
1892 # Split result by newline
1893 newline = handle.split( "\r\r\n" )
1894 # Ignore the first object of list, which is empty
1895 newline = newline[ 1: ]
1896 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001897 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001898 result = result.split( ": " )
1899 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001900 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1901 main.log.info( latResult )
1902 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001903 else:
1904 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001905 except TypeError:
1906 main.log.exception( self.name + ": Object not as expected" )
1907 return None
andrewonlab87852b02014-11-19 18:44:19 -05001908 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001909 main.log.error( self.name + ": EOF exception found" )
1910 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001911 main.cleanup()
1912 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001913 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001914 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001915 main.cleanup()
1916 main.exit()
1917
kelvin-onlabd3b64892015-01-20 13:26:24 -08001918 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001919 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001921 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001922 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001923 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001924 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001925 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001926 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001927 cmdStr += " -j"
1928 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001929 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001930 except TypeError:
1931 main.log.exception( self.name + ": Object not as expected" )
1932 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001933 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001934 main.log.error( self.name + ": EOF exception found" )
1935 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001936 main.cleanup()
1937 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001938 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001939 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001940 main.cleanup()
1941 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001942
kelvin-onlabd3b64892015-01-20 13:26:24 -08001943 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001944 """
1945 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001946 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001947 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001948 """
andrewonlab867212a2014-10-22 20:13:38 -04001949 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001950 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001951 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001952 cmdStr += " -j"
1953 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001954 if handle:
1955 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001956 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001957 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001958 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001959 else:
1960 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001961 except TypeError:
1962 main.log.exception( self.name + ": Object not as expected" )
1963 return None
andrewonlab867212a2014-10-22 20:13:38 -04001964 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001965 main.log.error( self.name + ": EOF exception found" )
1966 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001967 main.cleanup()
1968 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001969 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001970 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001971 main.cleanup()
1972 main.exit()
1973
kelvin8ec71442015-01-15 16:57:00 -08001974 # Wrapper functions ****************
1975 # Wrapper functions use existing driver
1976 # functions and extends their use case.
1977 # For example, we may use the output of
1978 # a normal driver function, and parse it
1979 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001980
kelvin-onlabd3b64892015-01-20 13:26:24 -08001981 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001982 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001983 Description:
1984 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001985 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001986 try:
kelvin8ec71442015-01-15 16:57:00 -08001987 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001988 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001989 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001990
kelvin8ec71442015-01-15 16:57:00 -08001991 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001992 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1993 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001994 match = re.search('id=0x([\da-f]+),', intents)
1995 if match:
1996 tmpId = match.group()[3:-1]
1997 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001998 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001999
Jon Halld4d4b372015-01-28 16:02:41 -08002000 except TypeError:
2001 main.log.exception( self.name + ": Object not as expected" )
2002 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002003 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002004 main.log.error( self.name + ": EOF exception found" )
2005 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002006 main.cleanup()
2007 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002008 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002009 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002010 main.cleanup()
2011 main.exit()
2012
Jon Hall30b82fa2015-03-04 17:15:43 -08002013 def FlowAddedCount( self, deviceId ):
2014 """
2015 Determine the number of flow rules for the given device id that are
2016 in the added state
2017 """
2018 try:
2019 cmdStr = "flows any " + str( deviceId ) + " | " +\
2020 "grep 'state=ADDED' | wc -l"
2021 handle = self.sendline( cmdStr )
2022 return handle
2023 except pexpect.EOF:
2024 main.log.error( self.name + ": EOF exception found" )
2025 main.log.error( self.name + ": " + self.handle.before )
2026 main.cleanup()
2027 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002028 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002029 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002030 main.cleanup()
2031 main.exit()
2032
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002034 """
andrewonlab95ce8322014-10-13 14:12:04 -04002035 Use 'devices' function to obtain list of all devices
2036 and parse the result to obtain a list of all device
2037 id's. Returns this list. Returns empty list if no
2038 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002039 List is ordered sequentially
2040
andrewonlab95ce8322014-10-13 14:12:04 -04002041 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002042 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002043 the ids. By obtaining the list of device ids on the fly,
2044 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002045 """
andrewonlab95ce8322014-10-13 14:12:04 -04002046 try:
kelvin8ec71442015-01-15 16:57:00 -08002047 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002048 devicesStr = self.devices( jsonFormat=False )
2049 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002050
kelvin-onlabd3b64892015-01-20 13:26:24 -08002051 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002052 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002053 return idList
kelvin8ec71442015-01-15 16:57:00 -08002054
2055 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002057 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002058 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002059 # Split list further into arguments before and after string
2060 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002061 # append to idList
2062 for arg in tempList:
2063 idList.append( arg.split( "id=" )[ 1 ] )
2064 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002065
Jon Halld4d4b372015-01-28 16:02:41 -08002066 except TypeError:
2067 main.log.exception( self.name + ": Object not as expected" )
2068 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002070 main.log.error( self.name + ": EOF exception found" )
2071 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002072 main.cleanup()
2073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002075 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002076 main.cleanup()
2077 main.exit()
2078
kelvin-onlabd3b64892015-01-20 13:26:24 -08002079 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002080 """
andrewonlab7c211572014-10-15 16:45:20 -04002081 Uses 'nodes' function to obtain list of all nodes
2082 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002083 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002084 Returns:
2085 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002086 """
andrewonlab7c211572014-10-15 16:45:20 -04002087 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002088 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002089 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002090 # Sample nodesStr output
2091 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002092 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002093 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002094 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002095 nodesJson = json.loads( nodesStr )
2096 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 return idList
kelvin8ec71442015-01-15 16:57:00 -08002098
Jon Halld4d4b372015-01-28 16:02:41 -08002099 except TypeError:
2100 main.log.exception( self.name + ": Object not as expected" )
2101 return None
andrewonlab7c211572014-10-15 16:45:20 -04002102 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002103 main.log.error( self.name + ": EOF exception found" )
2104 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002105 main.cleanup()
2106 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002107 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002108 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002109 main.cleanup()
2110 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002111
kelvin-onlabd3b64892015-01-20 13:26:24 -08002112 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002113 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002114 Return the first device from the devices api whose 'id' contains 'dpid'
2115 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002116 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002117 try:
kelvin8ec71442015-01-15 16:57:00 -08002118 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002119 return None
2120 else:
kelvin8ec71442015-01-15 16:57:00 -08002121 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002122 rawDevices = self.devices()
2123 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002124 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002125 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002126 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2127 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002128 return device
2129 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002130 except TypeError:
2131 main.log.exception( self.name + ": Object not as expected" )
2132 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002133 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002134 main.log.error( self.name + ": EOF exception found" )
2135 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002136 main.cleanup()
2137 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002138 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002139 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002140 main.cleanup()
2141 main.exit()
2142
kelvin-onlabd3b64892015-01-20 13:26:24 -08002143 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002144 """
Jon Hallefbd9792015-03-05 16:11:36 -08002145 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002146 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002147 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002148
Jon Hall42db6dc2014-10-24 19:03:48 -04002149 Params: ip = ip used for the onos cli
2150 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002151 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002152 logLevel = level to log to. Currently accepts
2153 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002154
2155
kelvin-onlabd3b64892015-01-20 13:26:24 -08002156 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002157
Jon Hallefbd9792015-03-05 16:11:36 -08002158 Returns: main.TRUE if the number of switches and links are correct,
2159 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002160 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002161 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002162 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002163 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002164 if topology == {}:
2165 return main.ERROR
2166 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002167 # Is the number of switches is what we expected
2168 devices = topology.get( 'devices', False )
2169 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002170 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002171 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002172 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002173 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 linkCheck = ( int( links ) == int( numolink ) )
2175 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002176 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002177 output += "The number of links and switches match " +\
2178 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002179 result = main.TRUE
2180 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002181 output += "The number of links and switches does not match " +\
2182 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002183 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002184 output = output + "\n ONOS sees %i devices (%i expected) \
2185 and %i links (%i expected)" % (
2186 int( devices ), int( numoswitch ), int( links ),
2187 int( numolink ) )
2188 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002189 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002191 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002192 else:
Jon Hall390696c2015-05-05 17:13:41 -07002193 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002194 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002195 except TypeError:
2196 main.log.exception( self.name + ": Object not as expected" )
2197 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002198 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002199 main.log.error( self.name + ": EOF exception found" )
2200 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002201 main.cleanup()
2202 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002203 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002204 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002205 main.cleanup()
2206 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002207
kelvin-onlabd3b64892015-01-20 13:26:24 -08002208 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002209 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002210 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002211 deviceId must be the id of a device as seen in the onos devices command
2212 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002213 role must be either master, standby, or none
2214
Jon Halle3f39ff2015-01-13 11:50:53 -08002215 Returns:
2216 main.TRUE or main.FALSE based on argument verification and
2217 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002218 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002219 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002220 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002221 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002222 cmdStr = "device-role " +\
2223 str( deviceId ) + " " +\
2224 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002225 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002226 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002227 if re.search( "Error", handle ):
2228 # end color output to escape any colours
2229 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002230 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002231 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002232 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002233 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002234 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002235 main.log.error( "Invalid 'role' given to device_role(). " +
2236 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002237 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002238 except TypeError:
2239 main.log.exception( self.name + ": Object not as expected" )
2240 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002241 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002242 main.log.error( self.name + ": EOF exception found" )
2243 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002244 main.cleanup()
2245 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002246 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002247 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002248 main.cleanup()
2249 main.exit()
2250
kelvin-onlabd3b64892015-01-20 13:26:24 -08002251 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002252 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002253 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002254 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002255 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002256 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002257 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002258 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002259 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002260 cmdStr += " -j"
2261 handle = self.sendline( cmdStr )
2262 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002263 except TypeError:
2264 main.log.exception( self.name + ": Object not as expected" )
2265 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002267 main.log.error( self.name + ": EOF exception found" )
2268 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002269 main.cleanup()
2270 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002271 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002272 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002273 main.cleanup()
2274 main.exit()
2275
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002277 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002278 CLI command to get the current leader for the Election test application
2279 NOTE: Requires installation of the onos-app-election feature
2280 Returns: Node IP of the leader if one exists
2281 None if none exists
2282 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002283 """
Jon Hall94fd0472014-12-08 11:52:42 -08002284 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 cmdStr = "election-test-leader"
2286 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002287 # Leader
2288 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002289 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 nodeSearch = re.search( leaderPattern, response )
2291 if nodeSearch:
2292 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002293 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002294 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002295 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002296 # no leader
2297 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002298 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002299 nullSearch = re.search( nullPattern, response )
2300 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002301 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002302 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002303 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002304 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002305 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002306 if re.search( errorPattern, response ):
2307 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002308 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002309 return main.FALSE
2310 else:
Jon Hall390696c2015-05-05 17:13:41 -07002311 main.log.error( "Error in electionTestLeader on " + self.name +
2312 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002313 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002314 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002315 except TypeError:
2316 main.log.exception( self.name + ": Object not as expected" )
2317 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002318 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002319 main.log.error( self.name + ": EOF exception found" )
2320 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002321 main.cleanup()
2322 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002323 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002324 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002325 main.cleanup()
2326 main.exit()
2327
kelvin-onlabd3b64892015-01-20 13:26:24 -08002328 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002329 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002330 CLI command to run for leadership of the Election test application.
2331 NOTE: Requires installation of the onos-app-election feature
2332 Returns: Main.TRUE on success
2333 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002334 """
Jon Hall94fd0472014-12-08 11:52:42 -08002335 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002336 cmdStr = "election-test-run"
2337 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002338 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002339 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002340 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002341 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002342 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002343 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002344 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002345 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002346 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002347 errorPattern = "Command\snot\sfound"
2348 if re.search( errorPattern, response ):
2349 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002350 return main.FALSE
2351 else:
Jon Hall390696c2015-05-05 17:13:41 -07002352 main.log.error( "Error in electionTestRun on " + self.name +
2353 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002354 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002355 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002356 except TypeError:
2357 main.log.exception( self.name + ": Object not as expected" )
2358 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002359 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002360 main.log.error( self.name + ": EOF exception found" )
2361 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002362 main.cleanup()
2363 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002364 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002365 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002366 main.cleanup()
2367 main.exit()
2368
kelvin-onlabd3b64892015-01-20 13:26:24 -08002369 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002370 """
Jon Hall94fd0472014-12-08 11:52:42 -08002371 * CLI command to withdraw the local node from leadership election for
2372 * the Election test application.
2373 #NOTE: Requires installation of the onos-app-election feature
2374 Returns: Main.TRUE on success
2375 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002376 """
Jon Hall94fd0472014-12-08 11:52:42 -08002377 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002378 cmdStr = "election-test-withdraw"
2379 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002380 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002381 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002382 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002383 if re.search( successPattern, response ):
2384 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002385 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002386 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002387 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002388 errorPattern = "Command\snot\sfound"
2389 if re.search( errorPattern, response ):
2390 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002391 return main.FALSE
2392 else:
Jon Hall390696c2015-05-05 17:13:41 -07002393 main.log.error( "Error in electionTestWithdraw on " +
2394 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002395 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002396 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002397 except TypeError:
2398 main.log.exception( self.name + ": Object not as expected" )
2399 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002401 main.log.error( self.name + ": EOF exception found" )
2402 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002403 main.cleanup()
2404 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002405 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002406 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002407 main.cleanup()
2408 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002409
kelvin8ec71442015-01-15 16:57:00 -08002410 def getDevicePortsEnabledCount( self, dpid ):
2411 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002412 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002413 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002414 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002415 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002416 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2417 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002418 if re.search( "No such device", output ):
2419 main.log.error( "Error in getting ports" )
2420 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002421 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002422 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002423 except TypeError:
2424 main.log.exception( self.name + ": Object not as expected" )
2425 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002427 main.log.error( self.name + ": EOF exception found" )
2428 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002429 main.cleanup()
2430 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002431 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002432 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002433 main.cleanup()
2434 main.exit()
2435
kelvin8ec71442015-01-15 16:57:00 -08002436 def getDeviceLinksActiveCount( self, dpid ):
2437 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002438 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002439 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002440 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002441 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002442 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2443 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002444 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002445 main.log.error( "Error in getting ports " )
2446 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002447 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002448 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002449 except TypeError:
2450 main.log.exception( self.name + ": Object not as expected" )
2451 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002452 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002453 main.log.error( self.name + ": EOF exception found" )
2454 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002455 main.cleanup()
2456 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002457 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002458 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002459 main.cleanup()
2460 main.exit()
2461
kelvin8ec71442015-01-15 16:57:00 -08002462 def getAllIntentIds( self ):
2463 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002464 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002465 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002466 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002467 cmdStr = "onos:intents | grep id="
2468 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002469 if re.search( "Error", output ):
2470 main.log.error( "Error in getting ports" )
2471 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002472 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002473 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002474 except TypeError:
2475 main.log.exception( self.name + ": Object not as expected" )
2476 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002477 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002478 main.log.error( self.name + ": EOF exception found" )
2479 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002480 main.cleanup()
2481 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002482 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002483 main.log.exception( self.name + ": Uncaught exception!" )
2484 main.cleanup()
2485 main.exit()
2486
Jon Hall73509952015-02-24 16:42:56 -08002487 def intentSummary( self ):
2488 """
Jon Hallefbd9792015-03-05 16:11:36 -08002489 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002490 """
2491 try:
2492 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002493 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002494 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002495 states.append( intent.get( 'state', None ) )
2496 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002497 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002498 return dict( out )
2499 except TypeError:
2500 main.log.exception( self.name + ": Object not as expected" )
2501 return None
2502 except pexpect.EOF:
2503 main.log.error( self.name + ": EOF exception found" )
2504 main.log.error( self.name + ": " + self.handle.before )
2505 main.cleanup()
2506 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002507 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002508 main.log.exception( self.name + ": Uncaught exception!" )
2509 main.cleanup()
2510 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002511
Jon Hall61282e32015-03-19 11:34:11 -07002512 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002513 """
2514 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002515 Optional argument:
2516 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002517 """
2518 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002519 # Sample JSON
2520 # {
2521 # "electedTime": "13m ago",
2522 # "epoch": 4,
2523 # "leader": "10.128.30.17",
2524 # "topic": "intent-partition-3"
2525 # },
Jon Hall63604932015-02-26 17:09:50 -08002526 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002527 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002528 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002529 cmdStr += " -j"
2530 output = self.sendline( cmdStr )
2531 return output
Jon Hall63604932015-02-26 17:09:50 -08002532 except TypeError:
2533 main.log.exception( self.name + ": Object not as expected" )
2534 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002535 except pexpect.EOF:
2536 main.log.error( self.name + ": EOF exception found" )
2537 main.log.error( self.name + ": " + self.handle.before )
2538 main.cleanup()
2539 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002540 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002541 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002542 main.cleanup()
2543 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002544
Jon Hall61282e32015-03-19 11:34:11 -07002545 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002546 """
2547 Returns the output of the intent Pending map.
2548 """
Jon Hall63604932015-02-26 17:09:50 -08002549 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002550 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002551 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002552 cmdStr += " -j"
2553 output = self.sendline( cmdStr )
2554 return output
Jon Hall63604932015-02-26 17:09:50 -08002555 except TypeError:
2556 main.log.exception( self.name + ": Object not as expected" )
2557 return None
2558 except pexpect.EOF:
2559 main.log.error( self.name + ": EOF exception found" )
2560 main.log.error( self.name + ": " + self.handle.before )
2561 main.cleanup()
2562 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002563 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002564 main.log.exception( self.name + ": Uncaught exception!" )
2565 main.cleanup()
2566 main.exit()
2567
Jon Hall61282e32015-03-19 11:34:11 -07002568 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002569 """
2570 Returns the output of the raft partitions command for ONOS.
2571 """
Jon Hall61282e32015-03-19 11:34:11 -07002572 # Sample JSON
2573 # {
2574 # "leader": "tcp://10.128.30.11:7238",
2575 # "members": [
2576 # "tcp://10.128.30.11:7238",
2577 # "tcp://10.128.30.17:7238",
2578 # "tcp://10.128.30.13:7238",
2579 # ],
2580 # "name": "p1",
2581 # "term": 3
2582 # },
Jon Hall63604932015-02-26 17:09:50 -08002583 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002584 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002585 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002586 cmdStr += " -j"
2587 output = self.sendline( cmdStr )
2588 return output
Jon Hall63604932015-02-26 17:09:50 -08002589 except TypeError:
2590 main.log.exception( self.name + ": Object not as expected" )
2591 return None
2592 except pexpect.EOF:
2593 main.log.error( self.name + ": EOF exception found" )
2594 main.log.error( self.name + ": " + self.handle.before )
2595 main.cleanup()
2596 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002597 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002598 main.log.exception( self.name + ": Uncaught exception!" )
2599 main.cleanup()
2600 main.exit()
2601
Jon Hallbe379602015-03-24 13:39:32 -07002602 def apps( self, jsonFormat=True ):
2603 """
2604 Returns the output of the apps command for ONOS. This command lists
2605 information about installed ONOS applications
2606 """
2607 # Sample JSON object
2608 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2609 # "description":"ONOS OpenFlow protocol southbound providers",
2610 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2611 # "features":"[onos-openflow]","state":"ACTIVE"}]
2612 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002613 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002614 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002615 cmdStr += " -j"
2616 output = self.sendline( cmdStr )
2617 assert "Error executing command" not in output
2618 return output
Jon Hallbe379602015-03-24 13:39:32 -07002619 # FIXME: look at specific exceptions/Errors
2620 except AssertionError:
2621 main.log.error( "Error in processing onos:app command: " +
2622 str( output ) )
2623 return None
2624 except TypeError:
2625 main.log.exception( self.name + ": Object not as expected" )
2626 return None
2627 except pexpect.EOF:
2628 main.log.error( self.name + ": EOF exception found" )
2629 main.log.error( self.name + ": " + self.handle.before )
2630 main.cleanup()
2631 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002632 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002633 main.log.exception( self.name + ": Uncaught exception!" )
2634 main.cleanup()
2635 main.exit()
2636
Jon Hall146f1522015-03-24 15:33:24 -07002637 def appStatus( self, appName ):
2638 """
2639 Uses the onos:apps cli command to return the status of an application.
2640 Returns:
2641 "ACTIVE" - If app is installed and activated
2642 "INSTALLED" - If app is installed and deactivated
2643 "UNINSTALLED" - If app is not installed
2644 None - on error
2645 """
Jon Hall146f1522015-03-24 15:33:24 -07002646 try:
2647 if not isinstance( appName, types.StringType ):
2648 main.log.error( self.name + ".appStatus(): appName must be" +
2649 " a string" )
2650 return None
2651 output = self.apps( jsonFormat=True )
2652 appsJson = json.loads( output )
2653 state = None
2654 for app in appsJson:
2655 if appName == app.get('name'):
2656 state = app.get('state')
2657 break
2658 if state == "ACTIVE" or state == "INSTALLED":
2659 return state
2660 elif state is None:
2661 return "UNINSTALLED"
2662 elif state:
2663 main.log.error( "Unexpected state from 'onos:apps': " +
2664 str( state ) )
2665 return state
2666 except TypeError:
2667 main.log.exception( self.name + ": Object not as expected" )
2668 return None
2669 except pexpect.EOF:
2670 main.log.error( self.name + ": EOF exception found" )
2671 main.log.error( self.name + ": " + self.handle.before )
2672 main.cleanup()
2673 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002674 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002675 main.log.exception( self.name + ": Uncaught exception!" )
2676 main.cleanup()
2677 main.exit()
2678
Jon Hallbe379602015-03-24 13:39:32 -07002679 def app( self, appName, option ):
2680 """
2681 Interacts with the app command for ONOS. This command manages
2682 application inventory.
2683 """
Jon Hallbe379602015-03-24 13:39:32 -07002684 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002685 # Validate argument types
2686 valid = True
2687 if not isinstance( appName, types.StringType ):
2688 main.log.error( self.name + ".app(): appName must be a " +
2689 "string" )
2690 valid = False
2691 if not isinstance( option, types.StringType ):
2692 main.log.error( self.name + ".app(): option must be a string" )
2693 valid = False
2694 if not valid:
2695 return main.FALSE
2696 # Validate Option
2697 option = option.lower()
2698 # NOTE: Install may become a valid option
2699 if option == "activate":
2700 pass
2701 elif option == "deactivate":
2702 pass
2703 elif option == "uninstall":
2704 pass
2705 else:
2706 # Invalid option
2707 main.log.error( "The ONOS app command argument only takes " +
2708 "the values: (activate|deactivate|uninstall)" +
2709 "; was given '" + option + "'")
2710 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002711 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002712 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002713 if "Error executing command" in output:
2714 main.log.error( "Error in processing onos:app command: " +
2715 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002716 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002717 elif "No such application" in output:
2718 main.log.error( "The application '" + appName +
2719 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002720 return main.FALSE
2721 elif "Command not found:" in output:
2722 main.log.error( "Error in processing onos:app command: " +
2723 str( output ) )
2724 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002725 elif "Unsupported command:" in output:
2726 main.log.error( "Incorrect command given to 'app': " +
2727 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002728 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002729 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002730 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002731 return main.TRUE
2732 except TypeError:
2733 main.log.exception( self.name + ": Object not as expected" )
2734 return main.ERROR
2735 except pexpect.EOF:
2736 main.log.error( self.name + ": EOF exception found" )
2737 main.log.error( self.name + ": " + self.handle.before )
2738 main.cleanup()
2739 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002740 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002741 main.log.exception( self.name + ": Uncaught exception!" )
2742 main.cleanup()
2743 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002744
Jon Hallbd16b922015-03-26 17:53:15 -07002745 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002746 """
2747 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002748 appName is the hierarchical app name, not the feature name
2749 If check is True, method will check the status of the app after the
2750 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002751 Returns main.TRUE if the command was successfully sent
2752 main.FALSE if the cli responded with an error or given
2753 incorrect input
2754 """
2755 try:
2756 if not isinstance( appName, types.StringType ):
2757 main.log.error( self.name + ".activateApp(): appName must be" +
2758 " a string" )
2759 return main.FALSE
2760 status = self.appStatus( appName )
2761 if status == "INSTALLED":
2762 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002763 if check and response == main.TRUE:
2764 for i in range(10): # try 10 times then give up
2765 # TODO: Check with Thomas about this delay
2766 status = self.appStatus( appName )
2767 if status == "ACTIVE":
2768 return main.TRUE
2769 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002770 main.log.debug( "The state of application " +
2771 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002772 time.sleep( 1 )
2773 return main.FALSE
2774 else: # not 'check' or command didn't succeed
2775 return response
Jon Hall146f1522015-03-24 15:33:24 -07002776 elif status == "ACTIVE":
2777 return main.TRUE
2778 elif status == "UNINSTALLED":
2779 main.log.error( self.name + ": Tried to activate the " +
2780 "application '" + appName + "' which is not " +
2781 "installed." )
2782 else:
2783 main.log.error( "Unexpected return value from appStatus: " +
2784 str( status ) )
2785 return main.ERROR
2786 except TypeError:
2787 main.log.exception( self.name + ": Object not as expected" )
2788 return main.ERROR
2789 except pexpect.EOF:
2790 main.log.error( self.name + ": EOF exception found" )
2791 main.log.error( self.name + ": " + self.handle.before )
2792 main.cleanup()
2793 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002794 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002795 main.log.exception( self.name + ": Uncaught exception!" )
2796 main.cleanup()
2797 main.exit()
2798
Jon Hallbd16b922015-03-26 17:53:15 -07002799 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002800 """
2801 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002802 appName is the hierarchical app name, not the feature name
2803 If check is True, method will check the status of the app after the
2804 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002805 Returns main.TRUE if the command was successfully sent
2806 main.FALSE if the cli responded with an error or given
2807 incorrect input
2808 """
2809 try:
2810 if not isinstance( appName, types.StringType ):
2811 main.log.error( self.name + ".deactivateApp(): appName must " +
2812 "be a string" )
2813 return main.FALSE
2814 status = self.appStatus( appName )
2815 if status == "INSTALLED":
2816 return main.TRUE
2817 elif status == "ACTIVE":
2818 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002819 if check and response == main.TRUE:
2820 for i in range(10): # try 10 times then give up
2821 status = self.appStatus( appName )
2822 if status == "INSTALLED":
2823 return main.TRUE
2824 else:
2825 time.sleep( 1 )
2826 return main.FALSE
2827 else: # not check or command didn't succeed
2828 return response
Jon Hall146f1522015-03-24 15:33:24 -07002829 elif status == "UNINSTALLED":
2830 main.log.warn( self.name + ": Tried to deactivate the " +
2831 "application '" + appName + "' which is not " +
2832 "installed." )
2833 return main.TRUE
2834 else:
2835 main.log.error( "Unexpected return value from appStatus: " +
2836 str( status ) )
2837 return main.ERROR
2838 except TypeError:
2839 main.log.exception( self.name + ": Object not as expected" )
2840 return main.ERROR
2841 except pexpect.EOF:
2842 main.log.error( self.name + ": EOF exception found" )
2843 main.log.error( self.name + ": " + self.handle.before )
2844 main.cleanup()
2845 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002846 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002847 main.log.exception( self.name + ": Uncaught exception!" )
2848 main.cleanup()
2849 main.exit()
2850
Jon Hallbd16b922015-03-26 17:53:15 -07002851 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002852 """
2853 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002854 appName is the hierarchical app name, not the feature name
2855 If check is True, method will check the status of the app after the
2856 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002857 Returns main.TRUE if the command was successfully sent
2858 main.FALSE if the cli responded with an error or given
2859 incorrect input
2860 """
2861 # TODO: check with Thomas about the state machine for apps
2862 try:
2863 if not isinstance( appName, types.StringType ):
2864 main.log.error( self.name + ".uninstallApp(): appName must " +
2865 "be a string" )
2866 return main.FALSE
2867 status = self.appStatus( appName )
2868 if status == "INSTALLED":
2869 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002870 if check and response == main.TRUE:
2871 for i in range(10): # try 10 times then give up
2872 status = self.appStatus( appName )
2873 if status == "UNINSTALLED":
2874 return main.TRUE
2875 else:
2876 time.sleep( 1 )
2877 return main.FALSE
2878 else: # not check or command didn't succeed
2879 return response
Jon Hall146f1522015-03-24 15:33:24 -07002880 elif status == "ACTIVE":
2881 main.log.warn( self.name + ": Tried to uninstall the " +
2882 "application '" + appName + "' which is " +
2883 "currently active." )
2884 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002885 if check and response == main.TRUE:
2886 for i in range(10): # try 10 times then give up
2887 status = self.appStatus( appName )
2888 if status == "UNINSTALLED":
2889 return main.TRUE
2890 else:
2891 time.sleep( 1 )
2892 return main.FALSE
2893 else: # not check or command didn't succeed
2894 return response
Jon Hall146f1522015-03-24 15:33:24 -07002895 elif status == "UNINSTALLED":
2896 return main.TRUE
2897 else:
2898 main.log.error( "Unexpected return value from appStatus: " +
2899 str( status ) )
2900 return main.ERROR
2901 except TypeError:
2902 main.log.exception( self.name + ": Object not as expected" )
2903 return main.ERROR
2904 except pexpect.EOF:
2905 main.log.error( self.name + ": EOF exception found" )
2906 main.log.error( self.name + ": " + self.handle.before )
2907 main.cleanup()
2908 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002909 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002910 main.log.exception( self.name + ": Uncaught exception!" )
2911 main.cleanup()
2912 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002913
2914 def appIDs( self, jsonFormat=True ):
2915 """
2916 Show the mappings between app id and app names given by the 'app-ids'
2917 cli command
2918 """
2919 try:
2920 cmdStr = "app-ids"
2921 if jsonFormat:
2922 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002923 output = self.sendline( cmdStr )
2924 assert "Error executing command" not in output
2925 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002926 except AssertionError:
2927 main.log.error( "Error in processing onos:app-ids command: " +
2928 str( output ) )
2929 return None
2930 except TypeError:
2931 main.log.exception( self.name + ": Object not as expected" )
2932 return None
2933 except pexpect.EOF:
2934 main.log.error( self.name + ": EOF exception found" )
2935 main.log.error( self.name + ": " + self.handle.before )
2936 main.cleanup()
2937 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002938 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002939 main.log.exception( self.name + ": Uncaught exception!" )
2940 main.cleanup()
2941 main.exit()
2942
2943 def appToIDCheck( self ):
2944 """
2945 This method will check that each application's ID listed in 'apps' is
2946 the same as the ID listed in 'app-ids'. The check will also check that
2947 there are no duplicate IDs issued. Note that an app ID should be
2948 a globaly unique numerical identifier for app/app-like features. Once
2949 an ID is registered, the ID is never freed up so that if an app is
2950 reinstalled it will have the same ID.
2951
2952 Returns: main.TRUE if the check passes and
2953 main.FALSE if the check fails or
2954 main.ERROR if there is some error in processing the test
2955 """
2956 try:
Jon Hall390696c2015-05-05 17:13:41 -07002957 bail = False
2958 ids = self.appIDs( jsonFormat=True )
2959 if ids:
2960 ids = json.loads( ids )
2961 else:
2962 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2963 bail = True
2964 apps = self.apps( jsonFormat=True )
2965 if apps:
2966 apps = json.loads( apps )
2967 else:
2968 main.log.error( "apps returned nothing:" + repr( apps ) )
2969 bail = True
2970 if bail:
2971 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002972 result = main.TRUE
2973 for app in apps:
2974 appID = app.get( 'id' )
2975 if appID is None:
2976 main.log.error( "Error parsing app: " + str( app ) )
2977 result = main.FALSE
2978 appName = app.get( 'name' )
2979 if appName is None:
2980 main.log.error( "Error parsing app: " + str( app ) )
2981 result = main.FALSE
2982 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07002983 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07002984 # main.log.debug( "Comparing " + str( app ) + " to " +
2985 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002986 if not current: # if ids doesn't have this id
2987 result = main.FALSE
2988 main.log.error( "'app-ids' does not have the ID for " +
2989 str( appName ) + " that apps does." )
2990 elif len( current ) > 1:
2991 # there is more than one app with this ID
2992 result = main.FALSE
2993 # We will log this later in the method
2994 elif not current[0][ 'name' ] == appName:
2995 currentName = current[0][ 'name' ]
2996 result = main.FALSE
2997 main.log.error( "'app-ids' has " + str( currentName ) +
2998 " registered under id:" + str( appID ) +
2999 " but 'apps' has " + str( appName ) )
3000 else:
3001 pass # id and name match!
3002 # now make sure that app-ids has no duplicates
3003 idsList = []
3004 namesList = []
3005 for item in ids:
3006 idsList.append( item[ 'id' ] )
3007 namesList.append( item[ 'name' ] )
3008 if len( idsList ) != len( set( idsList ) ) or\
3009 len( namesList ) != len( set( namesList ) ):
3010 main.log.error( "'app-ids' has some duplicate entries: \n"
3011 + json.dumps( ids,
3012 sort_keys=True,
3013 indent=4,
3014 separators=( ',', ': ' ) ) )
3015 result = main.FALSE
3016 return result
3017 except ( ValueError, TypeError ):
3018 main.log.exception( self.name + ": Object not as expected" )
3019 return main.ERROR
3020 except pexpect.EOF:
3021 main.log.error( self.name + ": EOF exception found" )
3022 main.log.error( self.name + ": " + self.handle.before )
3023 main.cleanup()
3024 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003025 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003026 main.log.exception( self.name + ": Uncaught exception!" )
3027 main.cleanup()
3028 main.exit()
3029
Jon Hallfb760a02015-04-13 15:35:03 -07003030 def getCfg( self, component=None, propName=None, short=False,
3031 jsonFormat=True ):
3032 """
3033 Get configuration settings from onos cli
3034 Optional arguments:
3035 component - Optionally only list configurations for a specific
3036 component. If None, all components with configurations
3037 are displayed. Case Sensitive string.
3038 propName - If component is specified, propName option will show
3039 only this specific configuration from that component.
3040 Case Sensitive string.
3041 jsonFormat - Returns output as json. Note that this will override
3042 the short option
3043 short - Short, less verbose, version of configurations.
3044 This is overridden by the json option
3045 returns:
3046 Output from cli as a string or None on error
3047 """
3048 try:
3049 baseStr = "cfg"
3050 cmdStr = " get"
3051 componentStr = ""
3052 if component:
3053 componentStr += " " + component
3054 if propName:
3055 componentStr += " " + propName
3056 if jsonFormat:
3057 baseStr += " -j"
3058 elif short:
3059 baseStr += " -s"
3060 output = self.sendline( baseStr + cmdStr + componentStr )
3061 assert "Error executing command" not in output
3062 return output
3063 except AssertionError:
3064 main.log.error( "Error in processing 'cfg get' command: " +
3065 str( output ) )
3066 return None
3067 except TypeError:
3068 main.log.exception( self.name + ": Object not as expected" )
3069 return None
3070 except pexpect.EOF:
3071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
3073 main.cleanup()
3074 main.exit()
3075 except Exception:
3076 main.log.exception( self.name + ": Uncaught exception!" )
3077 main.cleanup()
3078 main.exit()
3079
3080 def setCfg( self, component, propName, value=None, check=True ):
3081 """
3082 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003083 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003084 component - The case sensitive name of the component whose
3085 property is to be set
3086 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003087 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003088 value - The value to set the property to. If None, will unset the
3089 property and revert it to it's default value(if applicable)
3090 check - Boolean, Check whether the option was successfully set this
3091 only applies when a value is given.
3092 returns:
3093 main.TRUE on success or main.FALSE on failure. If check is False,
3094 will return main.TRUE unless there is an error
3095 """
3096 try:
3097 baseStr = "cfg"
3098 cmdStr = " set " + str( component ) + " " + str( propName )
3099 if value is not None:
3100 cmdStr += " " + str( value )
3101 output = self.sendline( baseStr + cmdStr )
3102 assert "Error executing command" not in output
3103 if value and check:
3104 results = self.getCfg( component=str( component ),
3105 propName=str( propName ),
3106 jsonFormat=True )
3107 # Check if current value is what we just set
3108 try:
3109 jsonOutput = json.loads( results )
3110 current = jsonOutput[ 'value' ]
3111 except ( ValueError, TypeError ):
3112 main.log.exception( "Error parsing cfg output" )
3113 main.log.error( "output:" + repr( results ) )
3114 return main.FALSE
3115 if current == str( value ):
3116 return main.TRUE
3117 return main.FALSE
3118 return main.TRUE
3119 except AssertionError:
3120 main.log.error( "Error in processing 'cfg set' command: " +
3121 str( output ) )
3122 return main.FALSE
3123 except TypeError:
3124 main.log.exception( self.name + ": Object not as expected" )
3125 return main.FALSE
3126 except pexpect.EOF:
3127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
3129 main.cleanup()
3130 main.exit()
3131 except Exception:
3132 main.log.exception( self.name + ": Uncaught exception!" )
3133 main.cleanup()
3134 main.exit()
3135
Jon Hall390696c2015-05-05 17:13:41 -07003136 def setTestAdd( self, setName, values ):
3137 """
3138 CLI command to add elements to a distributed set.
3139 Arguments:
3140 setName - The name of the set to add to.
3141 values - The value(s) to add to the set, space seperated.
3142 Example usages:
3143 setTestAdd( "set1", "a b c" )
3144 setTestAdd( "set2", "1" )
3145 returns:
3146 main.TRUE on success OR
3147 main.FALSE if elements were already in the set OR
3148 main.ERROR on error
3149 """
3150 try:
3151 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3152 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003153 try:
3154 # TODO: Maybe make this less hardcoded
3155 # ConsistentMap Exceptions
3156 assert "org.onosproject.store.service" not in output
3157 # Node not leader
3158 assert "java.lang.IllegalStateException" not in output
3159 except AssertionError:
3160 main.log.error( "Error in processing 'set-test-add' " +
3161 "command: " + str( output ) )
3162 retryTime = 30 # Conservative time, given by Madan
3163 main.log.info( "Waiting " + str( retryTime ) +
3164 "seconds before retrying." )
3165 time.sleep( retryTime ) # Due to change in mastership
3166 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003167 assert "Error executing command" not in output
3168 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3169 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3170 main.log.info( self.name + ": " + output )
3171 if re.search( positiveMatch, output):
3172 return main.TRUE
3173 elif re.search( negativeMatch, output):
3174 return main.FALSE
3175 else:
3176 main.log.error( self.name + ": setTestAdd did not" +
3177 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003178 main.log.debug( self.name + " actual: " + repr( output ) )
3179 return main.ERROR
3180 except AssertionError:
3181 main.log.error( "Error in processing 'set-test-add' command: " +
3182 str( output ) )
3183 return main.ERROR
3184 except TypeError:
3185 main.log.exception( self.name + ": Object not as expected" )
3186 return main.ERROR
3187 except pexpect.EOF:
3188 main.log.error( self.name + ": EOF exception found" )
3189 main.log.error( self.name + ": " + self.handle.before )
3190 main.cleanup()
3191 main.exit()
3192 except Exception:
3193 main.log.exception( self.name + ": Uncaught exception!" )
3194 main.cleanup()
3195 main.exit()
3196
3197 def setTestRemove( self, setName, values, clear=False, retain=False ):
3198 """
3199 CLI command to remove elements from a distributed set.
3200 Required arguments:
3201 setName - The name of the set to remove from.
3202 values - The value(s) to remove from the set, space seperated.
3203 Optional arguments:
3204 clear - Clear all elements from the set
3205 retain - Retain only the given values. (intersection of the
3206 original set and the given set)
3207 returns:
3208 main.TRUE on success OR
3209 main.FALSE if the set was not changed OR
3210 main.ERROR on error
3211 """
3212 try:
3213 cmdStr = "set-test-remove "
3214 if clear:
3215 cmdStr += "-c " + str( setName )
3216 elif retain:
3217 cmdStr += "-r " + str( setName ) + " " + str( values )
3218 else:
3219 cmdStr += str( setName ) + " " + str( values )
3220 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003221 try:
3222 # TODO: Maybe make this less hardcoded
3223 # ConsistentMap Exceptions
3224 assert "org.onosproject.store.service" not in output
3225 # Node not leader
3226 assert "java.lang.IllegalStateException" not in output
3227 except AssertionError:
3228 main.log.error( "Error in processing 'set-test-add' " +
3229 "command: " + str( output ) )
3230 retryTime = 30 # Conservative time, given by Madan
3231 main.log.info( "Waiting " + str( retryTime ) +
3232 "seconds before retrying." )
3233 time.sleep( retryTime ) # Due to change in mastership
3234 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003235 assert "Error executing command" not in output
3236 main.log.info( self.name + ": " + output )
3237 if clear:
3238 pattern = "Set " + str( setName ) + " cleared"
3239 if re.search( pattern, output ):
3240 return main.TRUE
3241 elif retain:
3242 positivePattern = str( setName ) + " was pruned to contain " +\
3243 "only elements of set \[(.*)\]"
3244 negativePattern = str( setName ) + " was not changed by " +\
3245 "retaining only elements of the set " +\
3246 "\[(.*)\]"
3247 if re.search( positivePattern, output ):
3248 return main.TRUE
3249 elif re.search( negativePattern, output ):
3250 return main.FALSE
3251 else:
3252 positivePattern = "\[(.*)\] was removed from the set " +\
3253 str( setName )
3254 if ( len( values.split() ) == 1 ):
3255 negativePattern = "\[(.*)\] was not in set " +\
3256 str( setName )
3257 else:
3258 negativePattern = "No element of \[(.*)\] was in set " +\
3259 str( setName )
3260 if re.search( positivePattern, output ):
3261 return main.TRUE
3262 elif re.search( negativePattern, output ):
3263 return main.FALSE
3264 main.log.error( self.name + ": setTestRemove did not" +
3265 " match expected output" )
3266 main.log.debug( self.name + " expected: " + pattern )
3267 main.log.debug( self.name + " actual: " + repr( output ) )
3268 return main.ERROR
3269 except AssertionError:
3270 main.log.error( "Error in processing 'set-test-remove' command: " +
3271 str( output ) )
3272 return main.ERROR
3273 except TypeError:
3274 main.log.exception( self.name + ": Object not as expected" )
3275 return main.ERROR
3276 except pexpect.EOF:
3277 main.log.error( self.name + ": EOF exception found" )
3278 main.log.error( self.name + ": " + self.handle.before )
3279 main.cleanup()
3280 main.exit()
3281 except Exception:
3282 main.log.exception( self.name + ": Uncaught exception!" )
3283 main.cleanup()
3284 main.exit()
3285
3286 def setTestGet( self, setName, values="" ):
3287 """
3288 CLI command to get the elements in a distributed set.
3289 Required arguments:
3290 setName - The name of the set to remove from.
3291 Optional arguments:
3292 values - The value(s) to check if in the set, space seperated.
3293 returns:
3294 main.ERROR on error OR
3295 A list of elements in the set if no optional arguments are
3296 supplied OR
3297 A tuple containing the list then:
3298 main.FALSE if the given values are not in the set OR
3299 main.TRUE if the given values are in the set OR
3300 """
3301 try:
3302 values = str( values ).strip()
3303 setName = str( setName ).strip()
3304 length = len( values.split() )
3305 containsCheck = None
3306 # Patterns to match
3307 setPattern = "\[(.*)\]"
3308 pattern = "Items in set " + setName + ":\n" + setPattern
3309 containsTrue = "Set " + setName + " contains the value " + values
3310 containsFalse = "Set " + setName + " did not contain the value " +\
3311 values
3312 containsAllTrue = "Set " + setName + " contains the the subset " +\
3313 setPattern
3314 containsAllFalse = "Set " + setName + " did not contain the the" +\
3315 " subset " + setPattern
3316
3317 cmdStr = "set-test-get "
3318 cmdStr += setName + " " + values
3319 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003320 try:
3321 # TODO: Maybe make this less hardcoded
3322 # ConsistentMap Exceptions
3323 assert "org.onosproject.store.service" not in output
3324 # Node not leader
3325 assert "java.lang.IllegalStateException" not in output
3326 except AssertionError:
3327 main.log.error( "Error in processing 'set-test-add' " +
3328 "command: " + str( output ) )
3329 retryTime = 30 # Conservative time, given by Madan
3330 main.log.info( "Waiting " + str( retryTime ) +
3331 "seconds before retrying." )
3332 time.sleep( retryTime ) # Due to change in mastership
3333 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003334 assert "Error executing command" not in output
3335 main.log.info( self.name + ": " + output )
3336
3337 if length == 0:
3338 match = re.search( pattern, output )
3339 else: # if given values
3340 if length == 1: # Contains output
3341 patternTrue = pattern + "\n" + containsTrue
3342 patternFalse = pattern + "\n" + containsFalse
3343 else: # ContainsAll output
3344 patternTrue = pattern + "\n" + containsAllTrue
3345 patternFalse = pattern + "\n" + containsAllFalse
3346 matchTrue = re.search( patternTrue, output )
3347 matchFalse = re.search( patternFalse, output )
3348 if matchTrue:
3349 containsCheck = main.TRUE
3350 match = matchTrue
3351 elif matchFalse:
3352 containsCheck = main.FALSE
3353 match = matchFalse
3354 else:
3355 main.log.error( self.name + " setTestGet did not match " +\
3356 "expected output" )
3357 main.log.debug( self.name + " expected: " + pattern )
3358 main.log.debug( self.name + " actual: " + repr( output ) )
3359 match = None
3360 if match:
3361 setMatch = match.group( 1 )
3362 if setMatch == '':
3363 setList = []
3364 else:
3365 setList = setMatch.split( ", " )
3366 if length > 0:
3367 return ( setList, containsCheck )
3368 else:
3369 return setList
3370 else: # no match
3371 main.log.error( self.name + ": setTestGet did not" +
3372 " match expected output" )
3373 main.log.debug( self.name + " expected: " + pattern )
3374 main.log.debug( self.name + " actual: " + repr( output ) )
3375 return main.ERROR
3376 except AssertionError:
3377 main.log.error( "Error in processing 'set-test-get' command: " +
3378 str( output ) )
3379 return main.ERROR
3380 except TypeError:
3381 main.log.exception( self.name + ": Object not as expected" )
3382 return main.ERROR
3383 except pexpect.EOF:
3384 main.log.error( self.name + ": EOF exception found" )
3385 main.log.error( self.name + ": " + self.handle.before )
3386 main.cleanup()
3387 main.exit()
3388 except Exception:
3389 main.log.exception( self.name + ": Uncaught exception!" )
3390 main.cleanup()
3391 main.exit()
3392
3393 def setTestSize( self, setName ):
3394 """
3395 CLI command to get the elements in a distributed set.
3396 Required arguments:
3397 setName - The name of the set to remove from.
3398 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003399 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003400 None on error
3401 """
3402 try:
3403 # TODO: Should this check against the number of elements returned
3404 # and then return true/false based on that?
3405 setName = str( setName ).strip()
3406 # Patterns to match
3407 setPattern = "\[(.*)\]"
3408 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3409 setPattern
3410 cmdStr = "set-test-get -s "
3411 cmdStr += setName
3412 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003413 try:
3414 # TODO: Maybe make this less hardcoded
3415 # ConsistentMap Exceptions
3416 assert "org.onosproject.store.service" not in output
3417 # Node not leader
3418 assert "java.lang.IllegalStateException" not in output
3419 except AssertionError:
3420 main.log.error( "Error in processing 'set-test-add' " +
3421 "command: " + str( output ) )
3422 retryTime = 30 # Conservative time, given by Madan
3423 main.log.info( "Waiting " + str( retryTime ) +
3424 "seconds before retrying." )
3425 time.sleep( retryTime ) # Due to change in mastership
3426 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003427 assert "Error executing command" not in output
3428 main.log.info( self.name + ": " + output )
3429 match = re.search( pattern, output )
3430 if match:
3431 setSize = int( match.group( 1 ) )
3432 setMatch = match.group( 2 )
3433 if len( setMatch.split() ) == setSize:
3434 main.log.info( "The size returned by " + self.name +
3435 " matches the number of elements in " +
3436 "the returned set" )
3437 else:
3438 main.log.error( "The size returned by " + self.name +
3439 " does not match the number of " +
3440 "elements in the returned set." )
3441 return setSize
3442 else: # no match
3443 main.log.error( self.name + ": setTestGet did not" +
3444 " match expected output" )
3445 main.log.debug( self.name + " expected: " + pattern )
3446 main.log.debug( self.name + " actual: " + repr( output ) )
3447 return None
3448 except AssertionError:
3449 main.log.error( "Error in processing 'set-test-get' command: " +
3450 str( output ) )
3451 return None
3452 except TypeError:
3453 main.log.exception( self.name + ": Object not as expected" )
3454 return None
3455 except pexpect.EOF:
3456 main.log.error( self.name + ": EOF exception found" )
3457 main.log.error( self.name + ": " + self.handle.before )
3458 main.cleanup()
3459 main.exit()
3460 except Exception:
3461 main.log.exception( self.name + ": Uncaught exception!" )
3462 main.cleanup()
3463 main.exit()
3464
Jon Hall80daded2015-05-27 16:07:00 -07003465 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003466 """
3467 Command to list the various counters in the system.
3468 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003469 if jsonFormat, a string of the json object returned by the cli
3470 command
3471 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003472 None on error
3473 """
Jon Hall390696c2015-05-05 17:13:41 -07003474 try:
3475 counters = {}
3476 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003477 if jsonFormat:
3478 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003479 output = self.sendline( cmdStr )
3480 assert "Error executing command" not in output
3481 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003482 return output
Jon Hall390696c2015-05-05 17:13:41 -07003483 except AssertionError:
3484 main.log.error( "Error in processing 'counters' command: " +
3485 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003486 return None
Jon Hall390696c2015-05-05 17:13:41 -07003487 except TypeError:
3488 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003489 return None
Jon Hall390696c2015-05-05 17:13:41 -07003490 except pexpect.EOF:
3491 main.log.error( self.name + ": EOF exception found" )
3492 main.log.error( self.name + ": " + self.handle.before )
3493 main.cleanup()
3494 main.exit()
3495 except Exception:
3496 main.log.exception( self.name + ": Uncaught exception!" )
3497 main.cleanup()
3498 main.exit()
3499
3500 def counterTestIncrement( self, counter, inMemory=False ):
3501 """
3502 CLI command to increment and get a distributed counter.
3503 Required arguments:
3504 counter - The name of the counter to increment.
3505 Optional arguments:
3506 inMemory - use in memory map for the counter
3507 returns:
3508 integer value of the counter or
3509 None on Error
3510 """
3511 try:
3512 counter = str( counter )
3513 cmdStr = "counter-test-increment "
3514 if inMemory:
3515 cmdStr += "-i "
3516 cmdStr += counter
3517 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003518 try:
3519 # TODO: Maybe make this less hardcoded
3520 # ConsistentMap Exceptions
3521 assert "org.onosproject.store.service" not in output
3522 # Node not leader
3523 assert "java.lang.IllegalStateException" not in output
3524 except AssertionError:
3525 main.log.error( "Error in processing 'set-test-add' " +
3526 "command: " + str( output ) )
3527 retryTime = 30 # Conservative time, given by Madan
3528 main.log.info( "Waiting " + str( retryTime ) +
3529 "seconds before retrying." )
3530 time.sleep( retryTime ) # Due to change in mastership
3531 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003532 assert "Error executing command" not in output
3533 main.log.info( self.name + ": " + output )
3534 pattern = counter + " was incremented to (\d+)"
3535 match = re.search( pattern, output )
3536 if match:
3537 return int( match.group( 1 ) )
3538 else:
3539 main.log.error( self.name + ": counterTestIncrement did not" +
3540 " match expected output." )
3541 main.log.debug( self.name + " expected: " + pattern )
3542 main.log.debug( self.name + " actual: " + repr( output ) )
3543 return None
3544 except AssertionError:
3545 main.log.error( "Error in processing 'counter-test-increment'" +
3546 " command: " + str( output ) )
3547 return None
3548 except TypeError:
3549 main.log.exception( self.name + ": Object not as expected" )
3550 return None
3551 except pexpect.EOF:
3552 main.log.error( self.name + ": EOF exception found" )
3553 main.log.error( self.name + ": " + self.handle.before )
3554 main.cleanup()
3555 main.exit()
3556 except Exception:
3557 main.log.exception( self.name + ": Uncaught exception!" )
3558 main.cleanup()
3559 main.exit()
3560
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003561 def summary( self, jsonFormat=True ):
3562 """
3563 Description: Execute summary command in onos
3564 Returns: json object ( summary -j ), returns main.FALSE if there is
3565 no output
3566
3567 """
3568 try:
3569 cmdStr = "summary"
3570 if jsonFormat:
3571 cmdStr += " -j"
3572 handle = self.sendline( cmdStr )
3573
3574 if re.search( "Error:", handle ):
3575 main.log.error( self.name + ": summary() response: " +
3576 str( handle ) )
3577 if not handle:
3578 main.log.error( self.name + ": There is no output in " +
3579 "summary command" )
3580 return main.FALSE
3581 return handle
3582 except TypeError:
3583 main.log.exception( self.name + ": Object not as expected" )
3584 return None
3585 except pexpect.EOF:
3586 main.log.error( self.name + ": EOF exception found" )
3587 main.log.error( self.name + ": " + self.handle.before )
3588 main.cleanup()
3589 main.exit()
3590 except Exception:
3591 main.log.exception( self.name + ": Uncaught exception!" )
3592 main.cleanup()
3593 main.exit()