blob: 41f5d85067fded942a94c3882ab12b8565b9abe4 [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
kelvin-onlabd3b64892015-01-20 13:26:24 -0800191 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800192 """
Jon Hallefbd9792015-03-05 16:11:36 -0800193 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800194 by user would be used to set the current karaf shell idle timeout.
195 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800196 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800197 Below is an example to start a session with 60 seconds idle timeout
198 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800199
Hari Krishna25d42f72015-01-05 15:08:28 -0800200 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800202
kelvin-onlabd3b64892015-01-20 13:26:24 -0800203 Note: karafTimeout is left as str so that this could be read
204 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800205 """
andrewonlab95ce8322014-10-13 14:12:04 -0400206 try:
kelvin8ec71442015-01-15 16:57:00 -0800207 self.handle.sendline( "" )
208 x = self.handle.expect( [
209 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500210
211 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800212 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500213 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400214
kelvin8ec71442015-01-15 16:57:00 -0800215 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800217 i = self.handle.expect( [
218 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800219 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400220
221 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800223 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800224 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800225 "config:property-set -p org.apache.karaf.shell\
226 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800227 karafTimeout )
228 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400231 return main.TRUE
232 else:
kelvin8ec71442015-01-15 16:57:00 -0800233 # If failed, send ctrl+c to process and try again
234 main.log.info( "Starting CLI failed. Retrying..." )
235 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800237 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
238 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400239 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800241 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800242 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800243 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 "config:property-set -p org.apache.karaf.shell\
245 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800246 karafTimeout )
247 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800249 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400250 return main.TRUE
251 else:
kelvin8ec71442015-01-15 16:57:00 -0800252 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400254 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400255
Jon Halld4d4b372015-01-28 16:02:41 -0800256 except TypeError:
257 main.log.exception( self.name + ": Object not as expected" )
258 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800260 main.log.error( self.name + ": EOF exception found" )
261 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400262 main.cleanup()
263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800265 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400266 main.cleanup()
267 main.exit()
268
Jon Hallefbd9792015-03-05 16:11:36 -0800269 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800270 """
271 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800272 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800273 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800274 Available level: DEBUG, TRACE, INFO, WARN, ERROR
275 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800276 """
277 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800278 lvlStr = ""
279 if level:
280 lvlStr = "--level=" + level
281
kelvin-onlab9f541032015-02-04 16:19:53 -0800282 self.handle.sendline( "" )
Jon Hall80daded2015-05-27 16:07:00 -0700283 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ] )
284 # TODO: look for bash prompt as well
285 if i == 1:
286 self.handle.sendline( "" )
287 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800288 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700289 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800290 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800291
kelvin-onlab9f541032015-02-04 16:19:53 -0800292 response = self.handle.before
293 if re.search( "Error", response ):
294 return main.FALSE
295 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700296 except pexpect.TIMEOUT:
297 main.log.exception( self.name + ": TIMEOUT exception found" )
298 main.cleanup()
299 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800300 except pexpect.EOF:
301 main.log.error( self.name + ": EOF exception found" )
302 main.log.error( self.name + ": " + self.handle.before )
303 main.cleanup()
304 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800305 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800306 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400307 main.cleanup()
308 main.exit()
309
Jon Hallc6358dd2015-04-10 12:44:28 -0700310 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800311 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800312 Send a completely user specified string to
313 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400314 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800315
andrewonlaba18f6bf2014-10-13 19:31:54 -0400316 Warning: There are no sanity checking to commands
317 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800318 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400319 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800320 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
321 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800322 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800323 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
324 response = self.handle.before
325 if i == 2:
326 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700327 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800328 response += self.handle.before
329 print response
330 try:
331 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700332 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800333 pass
334 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800335 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800336 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700337 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700338 main.log.debug( self.name + ": Raw output" )
339 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700340
341 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800342 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800343 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700344 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700345 main.log.debug( self.name + ": ansiEscape output" )
346 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700347
kelvin-onlabfb521662015-02-27 09:52:40 -0800348 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800349 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700350 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700351 main.log.debug( self.name + ": Removed extra returns " +
352 "from output" )
353 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700354
355 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800356 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700357 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700358 main.log.debug( self.name + ": parsed and stripped output" )
359 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700360
Jon Hall63604932015-02-26 17:09:50 -0800361 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700362 output = response.split( cmdStr.strip(), 1 )
363 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700364 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700365 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700366 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700367 return output[1].strip()
368 except IndexError:
369 main.log.exception( self.name + ": Object not as expected" )
370 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800371 except TypeError:
372 main.log.exception( self.name + ": Object not as expected" )
373 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400374 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800375 main.log.error( self.name + ": EOF exception found" )
376 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400377 main.cleanup()
378 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800379 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800380 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400381 main.cleanup()
382 main.exit()
383
kelvin8ec71442015-01-15 16:57:00 -0800384 # IMPORTANT NOTE:
385 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800386 # the cli command changing 'a:b' with 'aB'.
387 # Ex ) onos:topology > onosTopology
388 # onos:links > onosLinks
389 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800390
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800392 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400393 Adds a new cluster node by ID and address information.
394 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800395 * nodeId
396 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400397 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800398 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800399 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400400 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800401 cmdStr = "add-node " + str( nodeId ) + " " +\
402 str( ONOSIp ) + " " + str( tcpPort )
403 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800404 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800405 main.log.error( "Error in adding node" )
406 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800407 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400408 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800409 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400410 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800411 except TypeError:
412 main.log.exception( self.name + ": Object not as expected" )
413 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400414 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800415 main.log.error( self.name + ": EOF exception found" )
416 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400417 main.cleanup()
418 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800419 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800420 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 main.cleanup()
422 main.exit()
423
kelvin-onlabd3b64892015-01-20 13:26:24 -0800424 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800425 """
andrewonlab86dc3082014-10-13 18:18:38 -0400426 Removes a cluster by ID
427 Issues command: 'remove-node [<node-id>]'
428 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800429 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800430 """
andrewonlab86dc3082014-10-13 18:18:38 -0400431 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400432
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700434 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700435 if re.search( "Error", handle ):
436 main.log.error( "Error in removing node" )
437 main.log.error( handle )
438 return main.FALSE
439 else:
440 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800441 except TypeError:
442 main.log.exception( self.name + ": Object not as expected" )
443 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400444 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800445 main.log.error( self.name + ": EOF exception found" )
446 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400447 main.cleanup()
448 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800449 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800450 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400451 main.cleanup()
452 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400453
Jon Hall61282e32015-03-19 11:34:11 -0700454 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800455 """
andrewonlab7c211572014-10-15 16:45:20 -0400456 List the nodes currently visible
457 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700458 Optional argument:
459 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800460 """
andrewonlab7c211572014-10-15 16:45:20 -0400461 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700462 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700463 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700464 cmdStr += " -j"
465 output = self.sendline( cmdStr )
466 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800467 except TypeError:
468 main.log.exception( self.name + ": Object not as expected" )
469 return None
andrewonlab7c211572014-10-15 16:45:20 -0400470 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800471 main.log.error( self.name + ": EOF exception found" )
472 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400473 main.cleanup()
474 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800475 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800476 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400477 main.cleanup()
478 main.exit()
479
kelvin8ec71442015-01-15 16:57:00 -0800480 def topology( self ):
481 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700482 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700483 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700484 Return:
485 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800486 """
andrewonlab95ce8322014-10-13 14:12:04 -0400487 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700488 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800489 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400491 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800492 except TypeError:
493 main.log.exception( self.name + ": Object not as expected" )
494 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400495 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800496 main.log.error( self.name + ": EOF exception found" )
497 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400498 main.cleanup()
499 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800500 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800501 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400502 main.cleanup()
503 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800504
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800506 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 Installs a specified feature by issuing command:
508 'feature:install <feature_str>'
509 NOTE: This is now deprecated, you should use the activateApp method
510 instead
kelvin8ec71442015-01-15 16:57:00 -0800511 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400512 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800513 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 handle = self.sendline( cmdStr )
515 if re.search( "Error", handle ):
516 main.log.error( "Error in installing feature" )
517 main.log.error( handle )
518 return main.FALSE
519 else:
520 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800521 except TypeError:
522 main.log.exception( self.name + ": Object not as expected" )
523 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400524 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800525 main.log.error( self.name + ": EOF exception found" )
526 main.log.error( self.name + ": " + self.handle.before )
527 main.log.report( "Failed to install feature" )
528 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400529 main.cleanup()
530 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800531 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800532 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800533 main.log.report( "Failed to install feature" )
534 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400535 main.cleanup()
536 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800537
kelvin-onlabd3b64892015-01-20 13:26:24 -0800538 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800539 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 Uninstalls a specified feature by issuing command:
541 'feature:uninstall <feature_str>'
542 NOTE: This is now deprecated, you should use the deactivateApp method
543 instead
kelvin8ec71442015-01-15 16:57:00 -0800544 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400545 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800546 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
547 handle = self.sendline( cmdStr )
548 if handle != '':
549 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700550 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800551 # TODO: Check for possible error responses from karaf
552 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800553 main.log.info( "Feature needs to be installed before " +
554 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700555 return main.TRUE
556 if re.search( "Error", output ):
557 main.log.error( "Error in uninstalling feature" )
558 main.log.error( output )
559 return main.FALSE
560 else:
561 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800562 except TypeError:
563 main.log.exception( self.name + ": Object not as expected" )
564 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800566 main.log.error( self.name + ": EOF exception found" )
567 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400568 main.cleanup()
569 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800570 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800571 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 main.cleanup()
573 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800574
jenkins7ead5a82015-03-13 10:28:21 -0700575 def deviceRemove( self, deviceId ):
576 """
577 Removes particular device from storage
578
579 TODO: refactor this function
580 """
581 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700582 cmdStr = "device-remove " + str( deviceId )
583 handle = self.sendline( cmdStr )
584 if re.search( "Error", handle ):
585 main.log.error( "Error in removing device" )
586 main.log.error( handle )
587 return main.FALSE
588 else:
589 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700590 except TypeError:
591 main.log.exception( self.name + ": Object not as expected" )
592 return None
593 except pexpect.EOF:
594 main.log.error( self.name + ": EOF exception found" )
595 main.log.error( self.name + ": " + self.handle.before )
596 main.cleanup()
597 main.exit()
598 except Exception:
599 main.log.exception( self.name + ": Uncaught exception!" )
600 main.cleanup()
601 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700602
kelvin-onlabd3b64892015-01-20 13:26:24 -0800603 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800604 """
Jon Hall7b02d952014-10-17 20:14:54 -0400605 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400606 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800608 """
andrewonlab86dc3082014-10-13 18:18:38 -0400609 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700610 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700612 cmdStr += " -j"
613 handle = self.sendline( cmdStr )
614 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800615 except TypeError:
616 main.log.exception( self.name + ": Object not as expected" )
617 return None
andrewonlab7c211572014-10-15 16:45:20 -0400618 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800619 main.log.error( self.name + ": EOF exception found" )
620 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400621 main.cleanup()
622 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800623 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800624 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400625 main.cleanup()
626 main.exit()
627
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800629 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800630 This balances the devices across all controllers
631 by issuing command: 'onos> onos:balance-masters'
632 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800633 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800634 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 handle = self.sendline( cmdStr )
637 if re.search( "Error", handle ):
638 main.log.error( "Error in balancing masters" )
639 main.log.error( handle )
640 return main.FALSE
641 else:
642 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800643 except TypeError:
644 main.log.exception( self.name + ": Object not as expected" )
645 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800647 main.log.error( self.name + ": EOF exception found" )
648 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800649 main.cleanup()
650 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800651 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800652 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800653 main.cleanup()
654 main.exit()
655
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800657 """
Jon Halle8217482014-10-17 13:49:14 -0400658 Lists all core links
659 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800661 """
Jon Halle8217482014-10-17 13:49:14 -0400662 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700663 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 cmdStr += " -j"
666 handle = self.sendline( cmdStr )
667 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800668 except TypeError:
669 main.log.exception( self.name + ": Object not as expected" )
670 return None
Jon Halle8217482014-10-17 13:49:14 -0400671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800672 main.log.error( self.name + ": EOF exception found" )
673 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400674 main.cleanup()
675 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400678 main.cleanup()
679 main.exit()
680
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800682 """
Jon Halle8217482014-10-17 13:49:14 -0400683 Lists all ports
684 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800686 """
Jon Halle8217482014-10-17 13:49:14 -0400687 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700688 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700690 cmdStr += " -j"
691 handle = self.sendline( cmdStr )
692 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800693 except TypeError:
694 main.log.exception( self.name + ": Object not as expected" )
695 return None
Jon Halle8217482014-10-17 13:49:14 -0400696 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800697 main.log.error( self.name + ": EOF exception found" )
698 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400699 main.cleanup()
700 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800701 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800702 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400703 main.cleanup()
704 main.exit()
705
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800707 """
Jon Hall983a1702014-10-28 18:44:22 -0400708 Lists all devices and the controllers with roles assigned to them
709 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800711 """
andrewonlab7c211572014-10-15 16:45:20 -0400712 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700713 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700715 cmdStr += " -j"
716 handle = self.sendline( cmdStr )
717 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800718 except TypeError:
719 main.log.exception( self.name + ": Object not as expected" )
720 return None
Jon Hall983a1702014-10-28 18:44:22 -0400721 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800722 main.log.error( self.name + ": EOF exception found" )
723 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400724 main.cleanup()
725 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800726 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800727 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400728 main.cleanup()
729 main.exit()
730
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800732 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800733 Given the a string containing the json representation of the "roles"
734 cli command and a partial or whole device id, returns a json object
735 containing the roles output for the first device whose id contains
736 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400737
738 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800739 A dict of the role assignments for the given device or
740 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800741 """
Jon Hall983a1702014-10-28 18:44:22 -0400742 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400744 return None
745 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 rawRoles = self.roles()
747 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800748 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800749 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800750 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800751 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400752 return device
753 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800754 except TypeError:
755 main.log.exception( self.name + ": Object not as expected" )
756 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400757 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800758 main.log.error( self.name + ": EOF exception found" )
759 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400760 main.cleanup()
761 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800763 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400764 main.cleanup()
765 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800766
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800768 """
Jon Hall94fd0472014-12-08 11:52:42 -0800769 Iterates through each device and checks if there is a master assigned
770 Returns: main.TRUE if each device has a master
771 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Jon Hall94fd0472014-12-08 11:52:42 -0800773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 rawRoles = self.roles()
775 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800776 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800777 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800778 # print device
779 if device[ 'master' ] == "none":
780 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800781 return main.FALSE
782 return main.TRUE
783
Jon Halld4d4b372015-01-28 16:02:41 -0800784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800790 main.cleanup()
791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800794 main.cleanup()
795 main.exit()
796
kelvin-onlabd3b64892015-01-20 13:26:24 -0800797 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800798 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400799 Returns string of paths, and the cost.
800 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800801 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400802 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
804 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800805 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800806 main.log.error( "Error in getting paths" )
807 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400808 else:
kelvin8ec71442015-01-15 16:57:00 -0800809 path = handle.split( ";" )[ 0 ]
810 cost = handle.split( ";" )[ 1 ]
811 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800812 except TypeError:
813 main.log.exception( self.name + ": Object not as expected" )
814 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400815 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800816 main.log.error( self.name + ": EOF exception found" )
817 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400818 main.cleanup()
819 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800820 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800821 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400822 main.cleanup()
823 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800824
kelvin-onlabd3b64892015-01-20 13:26:24 -0800825 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800826 """
Jon Hallffb386d2014-11-21 13:43:38 -0800827 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400828 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800830 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400831 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700832 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800833 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700834 cmdStr += " -j"
835 handle = self.sendline( cmdStr )
836 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800837 except TypeError:
838 main.log.exception( self.name + ": Object not as expected" )
839 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400840 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800841 main.log.error( self.name + ": EOF exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400843 main.cleanup()
844 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800845 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800846 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400847 main.cleanup()
848 main.exit()
849
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800853
Jon Hallefbd9792015-03-05 16:11:36 -0800854 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800855 partial mac address
856
Jon Hall42db6dc2014-10-24 19:03:48 -0400857 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800858 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400859 try:
kelvin8ec71442015-01-15 16:57:00 -0800860 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400861 return None
862 else:
863 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 rawHosts = self.hosts()
865 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800866 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800868 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800869 if not host:
870 pass
871 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400872 return host
873 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800874 except TypeError:
875 main.log.exception( self.name + ": Object not as expected" )
876 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400877 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800878 main.log.error( self.name + ": EOF exception found" )
879 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400880 main.cleanup()
881 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800882 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800883 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400884 main.cleanup()
885 main.exit()
886
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800888 """
889 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400890 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800891
andrewonlab3f0a4af2014-10-17 12:25:14 -0400892 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400894 IMPORTANT:
895 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800896 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400897 Furthermore, it assumes that value of VLAN is '-1'
898 Description:
kelvin8ec71442015-01-15 16:57:00 -0800899 Converts mininet hosts ( h1, h2, h3... ) into
900 ONOS format ( 00:00:00:00:00:01/-1 , ... )
901 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400902 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400904
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800906 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 hostHex = hex( int( host ) ).zfill( 12 )
908 hostHex = str( hostHex ).replace( 'x', '0' )
909 i = iter( str( hostHex ) )
910 hostHex = ":".join( a + b for a, b in zip( i, i ) )
911 hostHex = hostHex + "/-1"
912 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400913
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400915
Jon Halld4d4b372015-01-28 16:02:41 -0800916 except TypeError:
917 main.log.exception( self.name + ": Object not as expected" )
918 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800920 main.log.error( self.name + ": EOF exception found" )
921 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400922 main.cleanup()
923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800925 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400926 main.cleanup()
927 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlabe6745342014-10-17 14:29:13 -0400931 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 * hostIdOne: ONOS host id for host1
933 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400934 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800935 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500936 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800937 Returns:
938 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800939 """
andrewonlabe6745342014-10-17 14:29:13 -0400940 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 cmdStr = "add-host-intent " + str( hostIdOne ) +\
942 " " + str( hostIdTwo )
943 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800944 if re.search( "Error", handle ):
945 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700946 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800947 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800948 else:
949 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800950 str( hostIdOne ) + " and " + str( hostIdTwo ) )
951 match = re.search('id=0x([\da-f]+),', handle)
952 if match:
953 return match.group()[3:-1]
954 else:
955 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700956 main.log.debug( "Response from ONOS was: " +
957 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800958 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800959 except TypeError:
960 main.log.exception( self.name + ": Object not as expected" )
961 return None
andrewonlabe6745342014-10-17 14:29:13 -0400962 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800963 main.log.error( self.name + ": EOF exception found" )
964 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400965 main.cleanup()
966 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800968 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400969 main.cleanup()
970 main.exit()
971
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800973 """
andrewonlab7b31d232014-10-24 13:31:47 -0400974 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 * ingressDevice: device id of ingress device
976 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400977 Optional:
978 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -0800979 Description:
980 Adds an optical intent by specifying an ingress and egress device
981 Returns:
982 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800983 """
andrewonlab7b31d232014-10-24 13:31:47 -0400984 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
986 " " + str( egressDevice )
987 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800988 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800989 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800990 main.log.error( "Error in adding Optical intent" )
991 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400992 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800993 main.log.info( "Optical intent installed between " +
994 str( ingressDevice ) + " and " +
995 str( egressDevice ) )
996 match = re.search('id=0x([\da-f]+),', handle)
997 if match:
998 return match.group()[3:-1]
999 else:
1000 main.log.error( "Error, intent ID not found" )
1001 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001002 except TypeError:
1003 main.log.exception( self.name + ": Object not as expected" )
1004 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001008 main.cleanup()
1009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001012 main.cleanup()
1013 main.exit()
1014
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001016 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 ingressDevice,
1018 egressDevice,
1019 portIngress="",
1020 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001021 ethType="",
1022 ethSrc="",
1023 ethDst="",
1024 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001026 ipProto="",
1027 ipSrc="",
1028 ipDst="",
1029 tcpSrc="",
1030 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001031 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001032 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * ingressDevice: device id of ingress device
1034 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001035 Optional:
1036 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001037 * ethSrc: specify ethSrc ( i.e. src mac addr )
1038 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001039 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001040 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001041 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001042 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001043 * ipSrc: specify ip source address
1044 * ipDst: specify ip destination address
1045 * tcpSrc: specify tcp source port
1046 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001047 Description:
kelvin8ec71442015-01-15 16:57:00 -08001048 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001049 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001050 Returns:
1051 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001052
Jon Halle3f39ff2015-01-13 11:50:53 -08001053 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001054 options developers provide for point-to-point
1055 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001056 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001057 try:
kelvin8ec71442015-01-15 16:57:00 -08001058 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001059 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001061 and not ipProto and not ipSrc and not ipDst \
1062 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001063 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001064
andrewonlab289e4b72014-10-21 21:24:18 -04001065 else:
andrewonlab36af3822014-11-18 17:48:18 -05001066 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001067
andrewonlab0c0a6772014-10-22 12:31:18 -04001068 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001069 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001070 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001071 cmd += " --ethSrc " + str( ethSrc )
1072 if ethDst:
1073 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001074 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001075 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001077 cmd += " --lambda "
1078 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001079 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001080 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001081 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001082 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001083 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001084 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001085 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001086 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001087 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001088
kelvin8ec71442015-01-15 16:57:00 -08001089 # Check whether the user appended the port
1090 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 if "/" in ingressDevice:
1092 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001093 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001095 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001096 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001097 # Would it make sense to throw an exception and exit
1098 # the test?
1099 return None
andrewonlab36af3822014-11-18 17:48:18 -05001100
kelvin8ec71442015-01-15 16:57:00 -08001101 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 str( ingressDevice ) + "/" +\
1103 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001104
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 if "/" in egressDevice:
1106 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001107 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001109 main.log.error( "You must specify the egress port" )
1110 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001111
kelvin8ec71442015-01-15 16:57:00 -08001112 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 str( egressDevice ) + "/" +\
1114 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001115
kelvin-onlab898a6c62015-01-16 14:13:53 -08001116 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001117 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001118 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001119 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001120 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001121 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001122 # TODO: print out all the options in this message?
1123 main.log.info( "Point-to-point intent installed between " +
1124 str( ingressDevice ) + " and " +
1125 str( egressDevice ) )
1126 match = re.search('id=0x([\da-f]+),', handle)
1127 if match:
1128 return match.group()[3:-1]
1129 else:
1130 main.log.error( "Error, intent ID not found" )
1131 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001132 except TypeError:
1133 main.log.exception( self.name + ": Object not as expected" )
1134 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001136 main.log.error( self.name + ": EOF exception found" )
1137 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001138 main.cleanup()
1139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001140 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001141 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001142 main.cleanup()
1143 main.exit()
1144
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001146 self,
shahshreyac2f97072015-03-19 17:04:29 -07001147 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001149 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001151 ethType="",
1152 ethSrc="",
1153 ethDst="",
1154 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001156 ipProto="",
1157 ipSrc="",
1158 ipDst="",
1159 tcpSrc="",
1160 tcpDst="",
1161 setEthSrc="",
1162 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001163 """
shahshreyad0c80432014-12-04 16:56:05 -08001164 Note:
shahshreya70622b12015-03-19 17:19:00 -07001165 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001166 is same. That is, all ingress devices include port numbers
1167 with a "/" or all ingress devices could specify device
1168 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001169 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001170 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001171 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001173 Optional:
1174 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001175 * ethSrc: specify ethSrc ( i.e. src mac addr )
1176 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001177 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001179 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001180 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001181 * ipSrc: specify ip source address
1182 * ipDst: specify ip destination address
1183 * tcpSrc: specify tcp source port
1184 * tcpDst: specify tcp destination port
1185 * setEthSrc: action to Rewrite Source MAC Address
1186 * setEthDst: action to Rewrite Destination MAC Address
1187 Description:
kelvin8ec71442015-01-15 16:57:00 -08001188 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001189 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001190 Returns:
1191 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001192
Jon Halle3f39ff2015-01-13 11:50:53 -08001193 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001194 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001195 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001196 """
shahshreyad0c80432014-12-04 16:56:05 -08001197 try:
kelvin8ec71442015-01-15 16:57:00 -08001198 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001199 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001201 and not ipProto and not ipSrc and not ipDst\
1202 and not tcpSrc and not tcpDst and not setEthSrc\
1203 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001204 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001205
1206 else:
1207 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001208
shahshreyad0c80432014-12-04 16:56:05 -08001209 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001210 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001211 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001212 cmd += " --ethSrc " + str( ethSrc )
1213 if ethDst:
1214 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001215 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001217 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001218 cmd += " --lambda "
1219 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001220 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001221 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001222 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001223 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001224 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001225 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001226 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001227 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001228 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001229 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001230 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001231 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001232 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001233
kelvin8ec71442015-01-15 16:57:00 -08001234 # Check whether the user appended the port
1235 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001236
1237 if portIngressList is None:
1238 for ingressDevice in ingressDeviceList:
1239 if "/" in ingressDevice:
1240 cmd += " " + str( ingressDevice )
1241 else:
1242 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001243 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001244 # TODO: perhaps more meaningful return
1245 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001246 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001247 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001248 for ingressDevice, portIngress in zip( ingressDeviceList,
1249 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001250 cmd += " " + \
1251 str( ingressDevice ) + "/" +\
1252 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001253 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001254 main.log.error( "Device list and port list does not " +
1255 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001256 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 if "/" in egressDevice:
1258 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001259 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001261 main.log.error( "You must specify " +
1262 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001263 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001264
kelvin8ec71442015-01-15 16:57:00 -08001265 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 str( egressDevice ) + "/" +\
1267 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001268 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001269 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001271 main.log.error( "Error in adding multipoint-to-singlepoint " +
1272 "intent" )
1273 return None
shahshreyad0c80432014-12-04 16:56:05 -08001274 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001275 match = re.search('id=0x([\da-f]+),', handle)
1276 if match:
1277 return match.group()[3:-1]
1278 else:
1279 main.log.error( "Error, intent ID not found" )
1280 return None
1281 except TypeError:
1282 main.log.exception( self.name + ": Object not as expected" )
1283 return None
1284 except pexpect.EOF:
1285 main.log.error( self.name + ": EOF exception found" )
1286 main.log.error( self.name + ": " + self.handle.before )
1287 main.cleanup()
1288 main.exit()
1289 except Exception:
1290 main.log.exception( self.name + ": Uncaught exception!" )
1291 main.cleanup()
1292 main.exit()
1293
1294 def addSinglepointToMultipointIntent(
1295 self,
1296 ingressDevice,
1297 egressDeviceList,
1298 portIngress="",
1299 portEgressList=None,
1300 ethType="",
1301 ethSrc="",
1302 ethDst="",
1303 bandwidth="",
1304 lambdaAlloc=False,
1305 ipProto="",
1306 ipSrc="",
1307 ipDst="",
1308 tcpSrc="",
1309 tcpDst="",
1310 setEthSrc="",
1311 setEthDst="" ):
1312 """
1313 Note:
1314 This function assumes the format of all egress devices
1315 is same. That is, all egress devices include port numbers
1316 with a "/" or all egress devices could specify device
1317 ids and port numbers seperately.
1318 Required:
1319 * EgressDeviceList: List of device ids of egress device
1320 ( Atleast 2 eress devices required in the list )
1321 * ingressDevice: device id of ingress device
1322 Optional:
1323 * ethType: specify ethType
1324 * ethSrc: specify ethSrc ( i.e. src mac addr )
1325 * ethDst: specify ethDst ( i.e. dst mac addr )
1326 * bandwidth: specify bandwidth capacity of link
1327 * lambdaAlloc: if True, intent will allocate lambda
1328 for the specified intent
1329 * ipProto: specify ip protocol
1330 * ipSrc: specify ip source address
1331 * ipDst: specify ip destination address
1332 * tcpSrc: specify tcp source port
1333 * tcpDst: specify tcp destination port
1334 * setEthSrc: action to Rewrite Source MAC Address
1335 * setEthDst: action to Rewrite Destination MAC Address
1336 Description:
1337 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1338 specifying device id's and optional fields
1339 Returns:
1340 A string of the intent id or None on error
1341
1342 NOTE: This function may change depending on the
1343 options developers provide for singlepoint-to-multipoint
1344 intent via cli
1345 """
1346 try:
1347 # If there are no optional arguments
1348 if not ethType and not ethSrc and not ethDst\
1349 and not bandwidth and not lambdaAlloc\
1350 and not ipProto and not ipSrc and not ipDst\
1351 and not tcpSrc and not tcpDst and not setEthSrc\
1352 and not setEthDst:
1353 cmd = "add-single-to-multi-intent"
1354
1355 else:
1356 cmd = "add-single-to-multi-intent"
1357
1358 if ethType:
1359 cmd += " --ethType " + str( ethType )
1360 if ethSrc:
1361 cmd += " --ethSrc " + str( ethSrc )
1362 if ethDst:
1363 cmd += " --ethDst " + str( ethDst )
1364 if bandwidth:
1365 cmd += " --bandwidth " + str( bandwidth )
1366 if lambdaAlloc:
1367 cmd += " --lambda "
1368 if ipProto:
1369 cmd += " --ipProto " + str( ipProto )
1370 if ipSrc:
1371 cmd += " --ipSrc " + str( ipSrc )
1372 if ipDst:
1373 cmd += " --ipDst " + str( ipDst )
1374 if tcpSrc:
1375 cmd += " --tcpSrc " + str( tcpSrc )
1376 if tcpDst:
1377 cmd += " --tcpDst " + str( tcpDst )
1378 if setEthSrc:
1379 cmd += " --setEthSrc " + str( setEthSrc )
1380 if setEthDst:
1381 cmd += " --setEthDst " + str( setEthDst )
1382
1383 # Check whether the user appended the port
1384 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001385
kelvin-onlabb9408212015-04-01 13:34:04 -07001386 if "/" in ingressDevice:
1387 cmd += " " + str( ingressDevice )
1388 else:
1389 if not portIngress:
1390 main.log.error( "You must specify " +
1391 "the Ingress port" )
1392 return main.FALSE
1393
1394 cmd += " " +\
1395 str( ingressDevice ) + "/" +\
1396 str( portIngress )
1397
1398 if portEgressList is None:
1399 for egressDevice in egressDeviceList:
1400 if "/" in egressDevice:
1401 cmd += " " + str( egressDevice )
1402 else:
1403 main.log.error( "You must specify " +
1404 "the egress port" )
1405 # TODO: perhaps more meaningful return
1406 return main.FALSE
1407 else:
1408 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001409 for egressDevice, portEgress in zip( egressDeviceList,
1410 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001411 cmd += " " + \
1412 str( egressDevice ) + "/" +\
1413 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001414 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001415 main.log.error( "Device list and port list does not " +
1416 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001417 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001418 handle = self.sendline( cmd )
1419 # If error, return error message
1420 if re.search( "Error", handle ):
1421 main.log.error( "Error in adding singlepoint-to-multipoint " +
1422 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001423 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001424 else:
1425 match = re.search('id=0x([\da-f]+),', handle)
1426 if match:
1427 return match.group()[3:-1]
1428 else:
1429 main.log.error( "Error, intent ID not found" )
1430 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001431 except TypeError:
1432 main.log.exception( self.name + ": Object not as expected" )
1433 return None
shahshreyad0c80432014-12-04 16:56:05 -08001434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001437 main.cleanup()
1438 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001439 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001440 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001441 main.cleanup()
1442 main.exit()
1443
Hari Krishna9e232602015-04-13 17:29:08 -07001444 def addMplsIntent(
1445 self,
1446 ingressDevice,
1447 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001448 ingressPort="",
1449 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001450 ethType="",
1451 ethSrc="",
1452 ethDst="",
1453 bandwidth="",
1454 lambdaAlloc=False,
1455 ipProto="",
1456 ipSrc="",
1457 ipDst="",
1458 tcpSrc="",
1459 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001460 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001461 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001462 priority=""):
1463 """
1464 Required:
1465 * ingressDevice: device id of ingress device
1466 * egressDevice: device id of egress device
1467 Optional:
1468 * ethType: specify ethType
1469 * ethSrc: specify ethSrc ( i.e. src mac addr )
1470 * ethDst: specify ethDst ( i.e. dst mac addr )
1471 * bandwidth: specify bandwidth capacity of link
1472 * lambdaAlloc: if True, intent will allocate lambda
1473 for the specified intent
1474 * ipProto: specify ip protocol
1475 * ipSrc: specify ip source address
1476 * ipDst: specify ip destination address
1477 * tcpSrc: specify tcp source port
1478 * tcpDst: specify tcp destination port
1479 * ingressLabel: Ingress MPLS label
1480 * egressLabel: Egress MPLS label
1481 Description:
1482 Adds MPLS intent by
1483 specifying device id's and optional fields
1484 Returns:
1485 A string of the intent id or None on error
1486
1487 NOTE: This function may change depending on the
1488 options developers provide for MPLS
1489 intent via cli
1490 """
1491 try:
1492 # If there are no optional arguments
1493 if not ethType and not ethSrc and not ethDst\
1494 and not bandwidth and not lambdaAlloc \
1495 and not ipProto and not ipSrc and not ipDst \
1496 and not tcpSrc and not tcpDst and not ingressLabel \
1497 and not egressLabel:
1498 cmd = "add-mpls-intent"
1499
1500 else:
1501 cmd = "add-mpls-intent"
1502
1503 if ethType:
1504 cmd += " --ethType " + str( ethType )
1505 if ethSrc:
1506 cmd += " --ethSrc " + str( ethSrc )
1507 if ethDst:
1508 cmd += " --ethDst " + str( ethDst )
1509 if bandwidth:
1510 cmd += " --bandwidth " + str( bandwidth )
1511 if lambdaAlloc:
1512 cmd += " --lambda "
1513 if ipProto:
1514 cmd += " --ipProto " + str( ipProto )
1515 if ipSrc:
1516 cmd += " --ipSrc " + str( ipSrc )
1517 if ipDst:
1518 cmd += " --ipDst " + str( ipDst )
1519 if tcpSrc:
1520 cmd += " --tcpSrc " + str( tcpSrc )
1521 if tcpDst:
1522 cmd += " --tcpDst " + str( tcpDst )
1523 if ingressLabel:
1524 cmd += " --ingressLabel " + str( ingressLabel )
1525 if egressLabel:
1526 cmd += " --egressLabel " + str( egressLabel )
1527 if priority:
1528 cmd += " --priority " + str( priority )
1529
1530 # Check whether the user appended the port
1531 # or provided it as an input
1532 if "/" in ingressDevice:
1533 cmd += " " + str( ingressDevice )
1534 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001535 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001536 main.log.error( "You must specify the ingress port" )
1537 return None
1538
1539 cmd += " " + \
1540 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001541 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001542
1543 if "/" in egressDevice:
1544 cmd += " " + str( egressDevice )
1545 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001546 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001547 main.log.error( "You must specify the egress port" )
1548 return None
1549
1550 cmd += " " +\
1551 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001552 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001553
1554 handle = self.sendline( cmd )
1555 # If error, return error message
1556 if re.search( "Error", handle ):
1557 main.log.error( "Error in adding mpls intent" )
1558 return None
1559 else:
1560 # TODO: print out all the options in this message?
1561 main.log.info( "MPLS intent installed between " +
1562 str( ingressDevice ) + " and " +
1563 str( egressDevice ) )
1564 match = re.search('id=0x([\da-f]+),', handle)
1565 if match:
1566 return match.group()[3:-1]
1567 else:
1568 main.log.error( "Error, intent ID not found" )
1569 return None
1570 except TypeError:
1571 main.log.exception( self.name + ": Object not as expected" )
1572 return None
1573 except pexpect.EOF:
1574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
1576 main.cleanup()
1577 main.exit()
1578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
1580 main.cleanup()
1581 main.exit()
1582
Jon Hallefbd9792015-03-05 16:11:36 -08001583 def removeIntent( self, intentId, app='org.onosproject.cli',
1584 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001585 """
shahshreya1c818fc2015-02-26 13:44:08 -08001586 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001587 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001588 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001589 -p or --purge: Purge the intent from the store after removal
1590
Jon Halle3f39ff2015-01-13 11:50:53 -08001591 Returns:
1592 main.False on error and
1593 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001594 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001595 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001596 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001597 if purge:
1598 cmdStr += " -p"
1599 if sync:
1600 cmdStr += " -s"
1601
1602 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001604 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001605 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001606 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001607 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001608 # TODO: Should this be main.TRUE
1609 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001610 except TypeError:
1611 main.log.exception( self.name + ": Object not as expected" )
1612 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001613 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001614 main.log.error( self.name + ": EOF exception found" )
1615 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001616 main.cleanup()
1617 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001618 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001619 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001620 main.cleanup()
1621 main.exit()
1622
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001624 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001625 NOTE: This method should be used after installing application:
1626 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001627 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001628 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001629 Description:
1630 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001631 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001632 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001633 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001635 cmdStr += " -j"
1636 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001637 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001638 except TypeError:
1639 main.log.exception( self.name + ": Object not as expected" )
1640 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001641 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001642 main.log.error( self.name + ": EOF exception found" )
1643 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001644 main.cleanup()
1645 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001646 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001647 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001648 main.cleanup()
1649 main.exit()
1650
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001652 """
andrewonlab377693f2014-10-21 16:00:30 -04001653 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001654 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001655 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001656 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001657 """
andrewonlabe6745342014-10-17 14:29:13 -04001658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001659 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001661 cmdStr += " -j"
1662 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001663 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001664 except TypeError:
1665 main.log.exception( self.name + ": Object not as expected" )
1666 return None
andrewonlabe6745342014-10-17 14:29:13 -04001667 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001668 main.log.error( self.name + ": EOF exception found" )
1669 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001670 main.cleanup()
1671 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001672 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001673 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001674 main.cleanup()
1675 main.exit()
1676
kelvin-onlab54400a92015-02-26 18:05:51 -08001677 def getIntentState(self, intentsId, intentsJson=None):
1678 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001679 Check intent state.
1680 Accepts a single intent ID (string type) or a list of intent IDs.
1681 Returns the state(string type) of the id if a single intent ID is
1682 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001683 Returns a dictionary with intent IDs as the key and its
1684 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001685 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001686 intentId: intent ID (string type)
1687 intentsJson: parsed json object from the onos:intents api
1688 Returns:
1689 state = An intent's state- INSTALL,WITHDRAWN etc.
1690 stateDict = Dictionary of intent's state. intent ID as the keys and
1691 state as the values.
1692 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001693 try:
1694 state = "State is Undefined"
1695 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001696 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001697 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001698 intentsJsonTemp = json.loads( intentsJson )
1699 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001700 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001701 if intentsId == intent[ 'id' ]:
1702 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001703 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001704 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1705 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001706 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001707 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001708 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001709 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001710 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001711 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001712 if intentsId[ i ] == intents[ 'id' ]:
1713 stateDict[ 'state' ] = intents[ 'state' ]
1714 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001715 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001716 break
Jon Hallefbd9792015-03-05 16:11:36 -08001717 if len( intentsId ) != len( dictList ):
1718 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001719 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001720 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001721 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001722 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001723 except TypeError:
1724 main.log.exception( self.name + ": Object not as expected" )
1725 return None
1726 except pexpect.EOF:
1727 main.log.error( self.name + ": EOF exception found" )
1728 main.log.error( self.name + ": " + self.handle.before )
1729 main.cleanup()
1730 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001731 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001732 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001733 main.cleanup()
1734 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001735
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001736 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1737 """
1738 Description:
1739 Check intents state
1740 Required:
1741 intentsId - List of intents ID to be checked
1742 Optional:
1743 expectedState - Check this expected state of each intents state
1744 in the list. Defaults to INSTALLED
1745 Return:
1746 Returns main.TRUE only if all intent are the same as expectedState,
1747 , otherwise,returns main.FALSE.
1748 """
1749 try:
1750 # Generating a dictionary: intent id as a key and state as value
1751 intentsDict = self.getIntentState( intentsId )
Jon Hall390696c2015-05-05 17:13:41 -07001752 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001753 if len( intentsId ) != len( intentsDict ):
1754 main.log.info( self.name + "There is something wrong " +
1755 "getting intents state" )
1756 return main.FALSE
1757 returnValue = main.TRUE
1758 for intents in intentsDict:
1759 if intents.get( 'state' ) != expectedState:
1760 main.log.info( self.name + " : " + intents.get( 'id' ) +
1761 " actual state = " + intents.get( 'state' )
1762 + " does not equal expected state = "
1763 + expectedState )
1764 returnValue = main.FALSE
1765 if returnValue == main.TRUE:
1766 main.log.info( self.name + ": All " +
1767 str( len( intentsDict ) ) +
1768 " intents are in " + expectedState + " state")
1769 return returnValue
1770 except TypeError:
1771 main.log.exception( self.name + ": Object not as expected" )
1772 return None
1773 except pexpect.EOF:
1774 main.log.error( self.name + ": EOF exception found" )
1775 main.log.error( self.name + ": " + self.handle.before )
1776 main.cleanup()
1777 main.exit()
1778 except Exception:
1779 main.log.exception( self.name + ": Uncaught exception!" )
1780 main.cleanup()
1781 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001782
kelvin-onlabd3b64892015-01-20 13:26:24 -08001783 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001784 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001785 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001787 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001788 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001789 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001790 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001791 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001793 cmdStr += " -j"
1794 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001795 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001796 main.log.error( self.name + ".flows() response: " +
1797 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001798 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001799 except TypeError:
1800 main.log.exception( self.name + ": Object not as expected" )
1801 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001802 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001803 main.log.error( self.name + ": EOF exception found" )
1804 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001805 main.cleanup()
1806 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001807 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001808 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001809 main.cleanup()
1810 main.exit()
1811
kelvin-onlab4df89f22015-04-13 18:10:23 -07001812 def checkFlowsState( self ):
1813 """
1814 Description:
1815 Check the if all the current flows are in ADDED state or
1816 PENDING_ADD state
1817 Return:
1818 returnValue - Returns main.TRUE only if all flows are in
1819 ADDED state or PENDING_ADD, return main.FALSE
1820 otherwise.
1821 """
1822 try:
1823 tempFlows = json.loads( self.flows() )
1824 returnValue = main.TRUE
1825 for device in tempFlows:
1826 for flow in device.get( 'flows' ):
1827 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1828 'PENDING_ADD':
1829 main.log.info( self.name + ": flow Id: " +
Jon Hallfeff3082015-05-19 10:23:26 -07001830 flow.get( 'id' ) +
kelvin-onlab4df89f22015-04-13 18:10:23 -07001831 " | state:" + flow.get( 'state' ) )
1832 returnValue = main.FALSE
1833 return returnValue
1834 except TypeError:
1835 main.log.exception( self.name + ": Object not as expected" )
1836 return None
1837 except pexpect.EOF:
1838 main.log.error( self.name + ": EOF exception found" )
1839 main.log.error( self.name + ": " + self.handle.before )
1840 main.cleanup()
1841 main.exit()
1842 except Exception:
1843 main.log.exception( self.name + ": Uncaught exception!" )
1844 main.cleanup()
1845 main.exit()
1846
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001848 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001849 """
andrewonlab87852b02014-11-19 18:44:19 -05001850 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001851 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001852 a specific point-to-point intent definition
1853 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001854 * dpidSrc: specify source dpid
1855 * dpidDst: specify destination dpid
1856 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001857 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001859 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001860 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001861 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001862 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001863 """
andrewonlab87852b02014-11-19 18:44:19 -05001864 try:
kelvin8ec71442015-01-15 16:57:00 -08001865 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001866 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1867 str( numIntents )
1868 if numMult:
1869 cmd += " " + str( numMult )
1870 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001871 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001872 if appId:
1873 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001874 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001875 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001876 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001877 main.log.info( handle )
1878 # Split result by newline
1879 newline = handle.split( "\r\r\n" )
1880 # Ignore the first object of list, which is empty
1881 newline = newline[ 1: ]
1882 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001883 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001884 result = result.split( ": " )
1885 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001886 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1887 main.log.info( latResult )
1888 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001889 else:
1890 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001891 except TypeError:
1892 main.log.exception( self.name + ": Object not as expected" )
1893 return None
andrewonlab87852b02014-11-19 18:44:19 -05001894 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001895 main.log.error( self.name + ": EOF exception found" )
1896 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001897 main.cleanup()
1898 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001899 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001900 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001901 main.cleanup()
1902 main.exit()
1903
kelvin-onlabd3b64892015-01-20 13:26:24 -08001904 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001905 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001906 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001907 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001908 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001909 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001910 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001911 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001912 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001913 cmdStr += " -j"
1914 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001915 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001916 except TypeError:
1917 main.log.exception( self.name + ": Object not as expected" )
1918 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001920 main.log.error( self.name + ": EOF exception found" )
1921 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001922 main.cleanup()
1923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001925 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001926 main.cleanup()
1927 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001928
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001930 """
1931 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001932 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001933 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001934 """
andrewonlab867212a2014-10-22 20:13:38 -04001935 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001936 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001937 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001938 cmdStr += " -j"
1939 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001940 if handle:
1941 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001942 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001943 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001944 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001945 else:
1946 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001947 except TypeError:
1948 main.log.exception( self.name + ": Object not as expected" )
1949 return None
andrewonlab867212a2014-10-22 20:13:38 -04001950 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001951 main.log.error( self.name + ": EOF exception found" )
1952 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001953 main.cleanup()
1954 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001955 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001956 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001957 main.cleanup()
1958 main.exit()
1959
kelvin8ec71442015-01-15 16:57:00 -08001960 # Wrapper functions ****************
1961 # Wrapper functions use existing driver
1962 # functions and extends their use case.
1963 # For example, we may use the output of
1964 # a normal driver function, and parse it
1965 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001966
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001968 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001969 Description:
1970 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001971 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001972 try:
kelvin8ec71442015-01-15 16:57:00 -08001973 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001974 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001975 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001976
kelvin8ec71442015-01-15 16:57:00 -08001977 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001978 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1979 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001980 match = re.search('id=0x([\da-f]+),', intents)
1981 if match:
1982 tmpId = match.group()[3:-1]
1983 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001985
Jon Halld4d4b372015-01-28 16:02:41 -08001986 except TypeError:
1987 main.log.exception( self.name + ": Object not as expected" )
1988 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001989 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001990 main.log.error( self.name + ": EOF exception found" )
1991 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001992 main.cleanup()
1993 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001994 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001995 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001996 main.cleanup()
1997 main.exit()
1998
Jon Hall30b82fa2015-03-04 17:15:43 -08001999 def FlowAddedCount( self, deviceId ):
2000 """
2001 Determine the number of flow rules for the given device id that are
2002 in the added state
2003 """
2004 try:
2005 cmdStr = "flows any " + str( deviceId ) + " | " +\
2006 "grep 'state=ADDED' | wc -l"
2007 handle = self.sendline( cmdStr )
2008 return handle
2009 except pexpect.EOF:
2010 main.log.error( self.name + ": EOF exception found" )
2011 main.log.error( self.name + ": " + self.handle.before )
2012 main.cleanup()
2013 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002014 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002015 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002016 main.cleanup()
2017 main.exit()
2018
kelvin-onlabd3b64892015-01-20 13:26:24 -08002019 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002020 """
andrewonlab95ce8322014-10-13 14:12:04 -04002021 Use 'devices' function to obtain list of all devices
2022 and parse the result to obtain a list of all device
2023 id's. Returns this list. Returns empty list if no
2024 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002025 List is ordered sequentially
2026
andrewonlab95ce8322014-10-13 14:12:04 -04002027 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002028 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002029 the ids. By obtaining the list of device ids on the fly,
2030 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002031 """
andrewonlab95ce8322014-10-13 14:12:04 -04002032 try:
kelvin8ec71442015-01-15 16:57:00 -08002033 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002034 devicesStr = self.devices( jsonFormat=False )
2035 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002036
kelvin-onlabd3b64892015-01-20 13:26:24 -08002037 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002038 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002039 return idList
kelvin8ec71442015-01-15 16:57:00 -08002040
2041 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002042 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002043 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002044 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002045 # Split list further into arguments before and after string
2046 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002047 # append to idList
2048 for arg in tempList:
2049 idList.append( arg.split( "id=" )[ 1 ] )
2050 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002051
Jon Halld4d4b372015-01-28 16:02:41 -08002052 except TypeError:
2053 main.log.exception( self.name + ": Object not as expected" )
2054 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002055 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002056 main.log.error( self.name + ": EOF exception found" )
2057 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002058 main.cleanup()
2059 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002060 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002061 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002062 main.cleanup()
2063 main.exit()
2064
kelvin-onlabd3b64892015-01-20 13:26:24 -08002065 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002066 """
andrewonlab7c211572014-10-15 16:45:20 -04002067 Uses 'nodes' function to obtain list of all nodes
2068 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002069 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002070 Returns:
2071 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002072 """
andrewonlab7c211572014-10-15 16:45:20 -04002073 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002074 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002075 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002076 # Sample nodesStr output
2077 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002078 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002079 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002080 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002081 nodesJson = json.loads( nodesStr )
2082 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002083 return idList
kelvin8ec71442015-01-15 16:57:00 -08002084
Jon Halld4d4b372015-01-28 16:02:41 -08002085 except TypeError:
2086 main.log.exception( self.name + ": Object not as expected" )
2087 return None
andrewonlab7c211572014-10-15 16:45:20 -04002088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002089 main.log.error( self.name + ": EOF exception found" )
2090 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002091 main.cleanup()
2092 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002093 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002094 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002095 main.cleanup()
2096 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002097
kelvin-onlabd3b64892015-01-20 13:26:24 -08002098 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002099 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002100 Return the first device from the devices api whose 'id' contains 'dpid'
2101 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002102 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002103 try:
kelvin8ec71442015-01-15 16:57:00 -08002104 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002105 return None
2106 else:
kelvin8ec71442015-01-15 16:57:00 -08002107 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002108 rawDevices = self.devices()
2109 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002110 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002112 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2113 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002114 return device
2115 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002116 except TypeError:
2117 main.log.exception( self.name + ": Object not as expected" )
2118 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002120 main.log.error( self.name + ": EOF exception found" )
2121 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002122 main.cleanup()
2123 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002124 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002125 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002126 main.cleanup()
2127 main.exit()
2128
kelvin-onlabd3b64892015-01-20 13:26:24 -08002129 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002130 """
Jon Hallefbd9792015-03-05 16:11:36 -08002131 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002132 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002133 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002134
Jon Hall42db6dc2014-10-24 19:03:48 -04002135 Params: ip = ip used for the onos cli
2136 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002137 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002138 logLevel = level to log to. Currently accepts
2139 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002140
2141
kelvin-onlabd3b64892015-01-20 13:26:24 -08002142 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002143
Jon Hallefbd9792015-03-05 16:11:36 -08002144 Returns: main.TRUE if the number of switches and links are correct,
2145 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002146 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002147 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002148 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002149 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002150 if topology == {}:
2151 return main.ERROR
2152 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002153 # Is the number of switches is what we expected
2154 devices = topology.get( 'devices', False )
2155 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002156 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002157 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002158 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002159 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 linkCheck = ( int( links ) == int( numolink ) )
2161 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002162 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002163 output += "The number of links and switches match " +\
2164 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002165 result = main.TRUE
2166 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002167 output += "The number of links and switches does not match " +\
2168 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002169 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002170 output = output + "\n ONOS sees %i devices (%i expected) \
2171 and %i links (%i expected)" % (
2172 int( devices ), int( numoswitch ), int( links ),
2173 int( numolink ) )
2174 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002175 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002176 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002177 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002178 else:
Jon Hall390696c2015-05-05 17:13:41 -07002179 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002180 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002181 except TypeError:
2182 main.log.exception( self.name + ": Object not as expected" )
2183 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002184 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002185 main.log.error( self.name + ": EOF exception found" )
2186 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002187 main.cleanup()
2188 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002189 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002190 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002191 main.cleanup()
2192 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002193
kelvin-onlabd3b64892015-01-20 13:26:24 -08002194 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002195 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002196 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002197 deviceId must be the id of a device as seen in the onos devices command
2198 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002199 role must be either master, standby, or none
2200
Jon Halle3f39ff2015-01-13 11:50:53 -08002201 Returns:
2202 main.TRUE or main.FALSE based on argument verification and
2203 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002204 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002205 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002206 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002207 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002208 cmdStr = "device-role " +\
2209 str( deviceId ) + " " +\
2210 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002211 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002212 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002213 if re.search( "Error", handle ):
2214 # end color output to escape any colours
2215 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002216 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002217 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002218 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002219 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002220 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002221 main.log.error( "Invalid 'role' given to device_role(). " +
2222 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002223 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002224 except TypeError:
2225 main.log.exception( self.name + ": Object not as expected" )
2226 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002227 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002228 main.log.error( self.name + ": EOF exception found" )
2229 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002230 main.cleanup()
2231 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002232 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002233 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002234 main.cleanup()
2235 main.exit()
2236
kelvin-onlabd3b64892015-01-20 13:26:24 -08002237 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002238 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002239 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002240 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002241 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002242 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002243 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002244 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002245 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002246 cmdStr += " -j"
2247 handle = self.sendline( cmdStr )
2248 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002249 except TypeError:
2250 main.log.exception( self.name + ": Object not as expected" )
2251 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002252 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002253 main.log.error( self.name + ": EOF exception found" )
2254 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002255 main.cleanup()
2256 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002257 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002258 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002259 main.cleanup()
2260 main.exit()
2261
kelvin-onlabd3b64892015-01-20 13:26:24 -08002262 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002263 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002264 CLI command to get the current leader for the Election test application
2265 NOTE: Requires installation of the onos-app-election feature
2266 Returns: Node IP of the leader if one exists
2267 None if none exists
2268 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002269 """
Jon Hall94fd0472014-12-08 11:52:42 -08002270 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002271 cmdStr = "election-test-leader"
2272 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002273 # Leader
2274 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002275 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 nodeSearch = re.search( leaderPattern, response )
2277 if nodeSearch:
2278 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002279 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002280 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002281 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002282 # no leader
2283 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002284 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 nullSearch = re.search( nullPattern, response )
2286 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002287 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002289 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002290 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002291 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002292 if re.search( errorPattern, response ):
2293 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002294 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002295 return main.FALSE
2296 else:
Jon Hall390696c2015-05-05 17:13:41 -07002297 main.log.error( "Error in electionTestLeader on " + self.name +
2298 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002299 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002300 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002301 except TypeError:
2302 main.log.exception( self.name + ": Object not as expected" )
2303 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002305 main.log.error( self.name + ": EOF exception found" )
2306 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002307 main.cleanup()
2308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002310 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002311 main.cleanup()
2312 main.exit()
2313
kelvin-onlabd3b64892015-01-20 13:26:24 -08002314 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002315 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002316 CLI command to run for leadership of the Election test application.
2317 NOTE: Requires installation of the onos-app-election feature
2318 Returns: Main.TRUE on success
2319 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002320 """
Jon Hall94fd0472014-12-08 11:52:42 -08002321 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 cmdStr = "election-test-run"
2323 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002324 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002325 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002326 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002327 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002328 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002329 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002330 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002331 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002332 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002333 errorPattern = "Command\snot\sfound"
2334 if re.search( errorPattern, response ):
2335 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002336 return main.FALSE
2337 else:
Jon Hall390696c2015-05-05 17:13:41 -07002338 main.log.error( "Error in electionTestRun on " + self.name +
2339 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002340 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002341 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002345 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002348 main.cleanup()
2349 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002350 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002351 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002352 main.cleanup()
2353 main.exit()
2354
kelvin-onlabd3b64892015-01-20 13:26:24 -08002355 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002356 """
Jon Hall94fd0472014-12-08 11:52:42 -08002357 * CLI command to withdraw the local node from leadership election for
2358 * the Election test application.
2359 #NOTE: Requires installation of the onos-app-election feature
2360 Returns: Main.TRUE on success
2361 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002362 """
Jon Hall94fd0472014-12-08 11:52:42 -08002363 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002364 cmdStr = "election-test-withdraw"
2365 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002366 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002367 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002368 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002369 if re.search( successPattern, response ):
2370 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002371 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002372 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002373 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002374 errorPattern = "Command\snot\sfound"
2375 if re.search( errorPattern, response ):
2376 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002377 return main.FALSE
2378 else:
Jon Hall390696c2015-05-05 17:13:41 -07002379 main.log.error( "Error in electionTestWithdraw on " +
2380 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002381 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002382 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002383 except TypeError:
2384 main.log.exception( self.name + ": Object not as expected" )
2385 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002386 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002387 main.log.error( self.name + ": EOF exception found" )
2388 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002389 main.cleanup()
2390 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002391 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002392 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002393 main.cleanup()
2394 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002395
kelvin8ec71442015-01-15 16:57:00 -08002396 def getDevicePortsEnabledCount( self, dpid ):
2397 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002398 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002399 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002400 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002401 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002402 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2403 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002404 if re.search( "No such device", output ):
2405 main.log.error( "Error in getting ports" )
2406 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002407 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002408 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002409 except TypeError:
2410 main.log.exception( self.name + ": Object not as expected" )
2411 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002412 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002413 main.log.error( self.name + ": EOF exception found" )
2414 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002415 main.cleanup()
2416 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002417 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002418 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002419 main.cleanup()
2420 main.exit()
2421
kelvin8ec71442015-01-15 16:57:00 -08002422 def getDeviceLinksActiveCount( self, dpid ):
2423 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002424 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002425 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002426 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002427 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002428 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2429 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002430 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002431 main.log.error( "Error in getting ports " )
2432 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002433 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002434 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002435 except TypeError:
2436 main.log.exception( self.name + ": Object not as expected" )
2437 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002439 main.log.error( self.name + ": EOF exception found" )
2440 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002441 main.cleanup()
2442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002444 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002445 main.cleanup()
2446 main.exit()
2447
kelvin8ec71442015-01-15 16:57:00 -08002448 def getAllIntentIds( self ):
2449 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002450 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002451 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002452 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002453 cmdStr = "onos:intents | grep id="
2454 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002455 if re.search( "Error", output ):
2456 main.log.error( "Error in getting ports" )
2457 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002458 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002459 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002460 except TypeError:
2461 main.log.exception( self.name + ": Object not as expected" )
2462 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002464 main.log.error( self.name + ": EOF exception found" )
2465 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002466 main.cleanup()
2467 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002468 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002469 main.log.exception( self.name + ": Uncaught exception!" )
2470 main.cleanup()
2471 main.exit()
2472
Jon Hall73509952015-02-24 16:42:56 -08002473 def intentSummary( self ):
2474 """
Jon Hallefbd9792015-03-05 16:11:36 -08002475 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002476 """
2477 try:
2478 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002479 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002480 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002481 states.append( intent.get( 'state', None ) )
2482 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002483 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002484 return dict( out )
2485 except TypeError:
2486 main.log.exception( self.name + ": Object not as expected" )
2487 return None
2488 except pexpect.EOF:
2489 main.log.error( self.name + ": EOF exception found" )
2490 main.log.error( self.name + ": " + self.handle.before )
2491 main.cleanup()
2492 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002493 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002494 main.log.exception( self.name + ": Uncaught exception!" )
2495 main.cleanup()
2496 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002497
Jon Hall61282e32015-03-19 11:34:11 -07002498 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002499 """
2500 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002501 Optional argument:
2502 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002503 """
2504 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002505 # Sample JSON
2506 # {
2507 # "electedTime": "13m ago",
2508 # "epoch": 4,
2509 # "leader": "10.128.30.17",
2510 # "topic": "intent-partition-3"
2511 # },
Jon Hall63604932015-02-26 17:09:50 -08002512 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002513 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002514 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002515 cmdStr += " -j"
2516 output = self.sendline( cmdStr )
2517 return output
Jon Hall63604932015-02-26 17:09:50 -08002518 except TypeError:
2519 main.log.exception( self.name + ": Object not as expected" )
2520 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002521 except pexpect.EOF:
2522 main.log.error( self.name + ": EOF exception found" )
2523 main.log.error( self.name + ": " + self.handle.before )
2524 main.cleanup()
2525 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002526 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002527 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002528 main.cleanup()
2529 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002530
Jon Hall61282e32015-03-19 11:34:11 -07002531 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002532 """
2533 Returns the output of the intent Pending map.
2534 """
Jon Hall63604932015-02-26 17:09:50 -08002535 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002536 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002537 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002538 cmdStr += " -j"
2539 output = self.sendline( cmdStr )
2540 return output
Jon Hall63604932015-02-26 17:09:50 -08002541 except TypeError:
2542 main.log.exception( self.name + ": Object not as expected" )
2543 return None
2544 except pexpect.EOF:
2545 main.log.error( self.name + ": EOF exception found" )
2546 main.log.error( self.name + ": " + self.handle.before )
2547 main.cleanup()
2548 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002549 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002550 main.log.exception( self.name + ": Uncaught exception!" )
2551 main.cleanup()
2552 main.exit()
2553
Jon Hall61282e32015-03-19 11:34:11 -07002554 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002555 """
2556 Returns the output of the raft partitions command for ONOS.
2557 """
Jon Hall61282e32015-03-19 11:34:11 -07002558 # Sample JSON
2559 # {
2560 # "leader": "tcp://10.128.30.11:7238",
2561 # "members": [
2562 # "tcp://10.128.30.11:7238",
2563 # "tcp://10.128.30.17:7238",
2564 # "tcp://10.128.30.13:7238",
2565 # ],
2566 # "name": "p1",
2567 # "term": 3
2568 # },
Jon Hall63604932015-02-26 17:09:50 -08002569 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002570 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002571 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002572 cmdStr += " -j"
2573 output = self.sendline( cmdStr )
2574 return output
Jon Hall63604932015-02-26 17:09:50 -08002575 except TypeError:
2576 main.log.exception( self.name + ": Object not as expected" )
2577 return None
2578 except pexpect.EOF:
2579 main.log.error( self.name + ": EOF exception found" )
2580 main.log.error( self.name + ": " + self.handle.before )
2581 main.cleanup()
2582 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002583 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002584 main.log.exception( self.name + ": Uncaught exception!" )
2585 main.cleanup()
2586 main.exit()
2587
Jon Hallbe379602015-03-24 13:39:32 -07002588 def apps( self, jsonFormat=True ):
2589 """
2590 Returns the output of the apps command for ONOS. This command lists
2591 information about installed ONOS applications
2592 """
2593 # Sample JSON object
2594 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2595 # "description":"ONOS OpenFlow protocol southbound providers",
2596 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2597 # "features":"[onos-openflow]","state":"ACTIVE"}]
2598 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002599 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002600 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002601 cmdStr += " -j"
2602 output = self.sendline( cmdStr )
2603 assert "Error executing command" not in output
2604 return output
Jon Hallbe379602015-03-24 13:39:32 -07002605 # FIXME: look at specific exceptions/Errors
2606 except AssertionError:
2607 main.log.error( "Error in processing onos:app command: " +
2608 str( output ) )
2609 return None
2610 except TypeError:
2611 main.log.exception( self.name + ": Object not as expected" )
2612 return None
2613 except pexpect.EOF:
2614 main.log.error( self.name + ": EOF exception found" )
2615 main.log.error( self.name + ": " + self.handle.before )
2616 main.cleanup()
2617 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002618 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002619 main.log.exception( self.name + ": Uncaught exception!" )
2620 main.cleanup()
2621 main.exit()
2622
Jon Hall146f1522015-03-24 15:33:24 -07002623 def appStatus( self, appName ):
2624 """
2625 Uses the onos:apps cli command to return the status of an application.
2626 Returns:
2627 "ACTIVE" - If app is installed and activated
2628 "INSTALLED" - If app is installed and deactivated
2629 "UNINSTALLED" - If app is not installed
2630 None - on error
2631 """
Jon Hall146f1522015-03-24 15:33:24 -07002632 try:
2633 if not isinstance( appName, types.StringType ):
2634 main.log.error( self.name + ".appStatus(): appName must be" +
2635 " a string" )
2636 return None
2637 output = self.apps( jsonFormat=True )
2638 appsJson = json.loads( output )
2639 state = None
2640 for app in appsJson:
2641 if appName == app.get('name'):
2642 state = app.get('state')
2643 break
2644 if state == "ACTIVE" or state == "INSTALLED":
2645 return state
2646 elif state is None:
2647 return "UNINSTALLED"
2648 elif state:
2649 main.log.error( "Unexpected state from 'onos:apps': " +
2650 str( state ) )
2651 return state
2652 except TypeError:
2653 main.log.exception( self.name + ": Object not as expected" )
2654 return None
2655 except pexpect.EOF:
2656 main.log.error( self.name + ": EOF exception found" )
2657 main.log.error( self.name + ": " + self.handle.before )
2658 main.cleanup()
2659 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002660 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002661 main.log.exception( self.name + ": Uncaught exception!" )
2662 main.cleanup()
2663 main.exit()
2664
Jon Hallbe379602015-03-24 13:39:32 -07002665 def app( self, appName, option ):
2666 """
2667 Interacts with the app command for ONOS. This command manages
2668 application inventory.
2669 """
Jon Hallbe379602015-03-24 13:39:32 -07002670 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002671 # Validate argument types
2672 valid = True
2673 if not isinstance( appName, types.StringType ):
2674 main.log.error( self.name + ".app(): appName must be a " +
2675 "string" )
2676 valid = False
2677 if not isinstance( option, types.StringType ):
2678 main.log.error( self.name + ".app(): option must be a string" )
2679 valid = False
2680 if not valid:
2681 return main.FALSE
2682 # Validate Option
2683 option = option.lower()
2684 # NOTE: Install may become a valid option
2685 if option == "activate":
2686 pass
2687 elif option == "deactivate":
2688 pass
2689 elif option == "uninstall":
2690 pass
2691 else:
2692 # Invalid option
2693 main.log.error( "The ONOS app command argument only takes " +
2694 "the values: (activate|deactivate|uninstall)" +
2695 "; was given '" + option + "'")
2696 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002697 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002698 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002699 if "Error executing command" in output:
2700 main.log.error( "Error in processing onos:app command: " +
2701 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002702 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002703 elif "No such application" in output:
2704 main.log.error( "The application '" + appName +
2705 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002706 return main.FALSE
2707 elif "Command not found:" in output:
2708 main.log.error( "Error in processing onos:app command: " +
2709 str( output ) )
2710 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002711 elif "Unsupported command:" in output:
2712 main.log.error( "Incorrect command given to 'app': " +
2713 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002714 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002715 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002716 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002717 return main.TRUE
2718 except TypeError:
2719 main.log.exception( self.name + ": Object not as expected" )
2720 return main.ERROR
2721 except pexpect.EOF:
2722 main.log.error( self.name + ": EOF exception found" )
2723 main.log.error( self.name + ": " + self.handle.before )
2724 main.cleanup()
2725 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002726 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002727 main.log.exception( self.name + ": Uncaught exception!" )
2728 main.cleanup()
2729 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002730
Jon Hallbd16b922015-03-26 17:53:15 -07002731 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002732 """
2733 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002734 appName is the hierarchical app name, not the feature name
2735 If check is True, method will check the status of the app after the
2736 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002737 Returns main.TRUE if the command was successfully sent
2738 main.FALSE if the cli responded with an error or given
2739 incorrect input
2740 """
2741 try:
2742 if not isinstance( appName, types.StringType ):
2743 main.log.error( self.name + ".activateApp(): appName must be" +
2744 " a string" )
2745 return main.FALSE
2746 status = self.appStatus( appName )
2747 if status == "INSTALLED":
2748 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002749 if check and response == main.TRUE:
2750 for i in range(10): # try 10 times then give up
2751 # TODO: Check with Thomas about this delay
2752 status = self.appStatus( appName )
2753 if status == "ACTIVE":
2754 return main.TRUE
2755 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002756 main.log.debug( "The state of application " +
2757 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002758 time.sleep( 1 )
2759 return main.FALSE
2760 else: # not 'check' or command didn't succeed
2761 return response
Jon Hall146f1522015-03-24 15:33:24 -07002762 elif status == "ACTIVE":
2763 return main.TRUE
2764 elif status == "UNINSTALLED":
2765 main.log.error( self.name + ": Tried to activate the " +
2766 "application '" + appName + "' which is not " +
2767 "installed." )
2768 else:
2769 main.log.error( "Unexpected return value from appStatus: " +
2770 str( status ) )
2771 return main.ERROR
2772 except TypeError:
2773 main.log.exception( self.name + ": Object not as expected" )
2774 return main.ERROR
2775 except pexpect.EOF:
2776 main.log.error( self.name + ": EOF exception found" )
2777 main.log.error( self.name + ": " + self.handle.before )
2778 main.cleanup()
2779 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002780 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002781 main.log.exception( self.name + ": Uncaught exception!" )
2782 main.cleanup()
2783 main.exit()
2784
Jon Hallbd16b922015-03-26 17:53:15 -07002785 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002786 """
2787 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002788 appName is the hierarchical app name, not the feature name
2789 If check is True, method will check the status of the app after the
2790 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002791 Returns main.TRUE if the command was successfully sent
2792 main.FALSE if the cli responded with an error or given
2793 incorrect input
2794 """
2795 try:
2796 if not isinstance( appName, types.StringType ):
2797 main.log.error( self.name + ".deactivateApp(): appName must " +
2798 "be a string" )
2799 return main.FALSE
2800 status = self.appStatus( appName )
2801 if status == "INSTALLED":
2802 return main.TRUE
2803 elif status == "ACTIVE":
2804 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002805 if check and response == main.TRUE:
2806 for i in range(10): # try 10 times then give up
2807 status = self.appStatus( appName )
2808 if status == "INSTALLED":
2809 return main.TRUE
2810 else:
2811 time.sleep( 1 )
2812 return main.FALSE
2813 else: # not check or command didn't succeed
2814 return response
Jon Hall146f1522015-03-24 15:33:24 -07002815 elif status == "UNINSTALLED":
2816 main.log.warn( self.name + ": Tried to deactivate the " +
2817 "application '" + appName + "' which is not " +
2818 "installed." )
2819 return main.TRUE
2820 else:
2821 main.log.error( "Unexpected return value from appStatus: " +
2822 str( status ) )
2823 return main.ERROR
2824 except TypeError:
2825 main.log.exception( self.name + ": Object not as expected" )
2826 return main.ERROR
2827 except pexpect.EOF:
2828 main.log.error( self.name + ": EOF exception found" )
2829 main.log.error( self.name + ": " + self.handle.before )
2830 main.cleanup()
2831 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002832 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002833 main.log.exception( self.name + ": Uncaught exception!" )
2834 main.cleanup()
2835 main.exit()
2836
Jon Hallbd16b922015-03-26 17:53:15 -07002837 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002838 """
2839 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002840 appName is the hierarchical app name, not the feature name
2841 If check is True, method will check the status of the app after the
2842 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002843 Returns main.TRUE if the command was successfully sent
2844 main.FALSE if the cli responded with an error or given
2845 incorrect input
2846 """
2847 # TODO: check with Thomas about the state machine for apps
2848 try:
2849 if not isinstance( appName, types.StringType ):
2850 main.log.error( self.name + ".uninstallApp(): appName must " +
2851 "be a string" )
2852 return main.FALSE
2853 status = self.appStatus( appName )
2854 if status == "INSTALLED":
2855 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002856 if check and response == main.TRUE:
2857 for i in range(10): # try 10 times then give up
2858 status = self.appStatus( appName )
2859 if status == "UNINSTALLED":
2860 return main.TRUE
2861 else:
2862 time.sleep( 1 )
2863 return main.FALSE
2864 else: # not check or command didn't succeed
2865 return response
Jon Hall146f1522015-03-24 15:33:24 -07002866 elif status == "ACTIVE":
2867 main.log.warn( self.name + ": Tried to uninstall the " +
2868 "application '" + appName + "' which is " +
2869 "currently active." )
2870 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002871 if check and response == main.TRUE:
2872 for i in range(10): # try 10 times then give up
2873 status = self.appStatus( appName )
2874 if status == "UNINSTALLED":
2875 return main.TRUE
2876 else:
2877 time.sleep( 1 )
2878 return main.FALSE
2879 else: # not check or command didn't succeed
2880 return response
Jon Hall146f1522015-03-24 15:33:24 -07002881 elif status == "UNINSTALLED":
2882 return main.TRUE
2883 else:
2884 main.log.error( "Unexpected return value from appStatus: " +
2885 str( status ) )
2886 return main.ERROR
2887 except TypeError:
2888 main.log.exception( self.name + ": Object not as expected" )
2889 return main.ERROR
2890 except pexpect.EOF:
2891 main.log.error( self.name + ": EOF exception found" )
2892 main.log.error( self.name + ": " + self.handle.before )
2893 main.cleanup()
2894 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002895 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002896 main.log.exception( self.name + ": Uncaught exception!" )
2897 main.cleanup()
2898 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002899
2900 def appIDs( self, jsonFormat=True ):
2901 """
2902 Show the mappings between app id and app names given by the 'app-ids'
2903 cli command
2904 """
2905 try:
2906 cmdStr = "app-ids"
2907 if jsonFormat:
2908 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002909 output = self.sendline( cmdStr )
2910 assert "Error executing command" not in output
2911 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002912 except AssertionError:
2913 main.log.error( "Error in processing onos:app-ids command: " +
2914 str( output ) )
2915 return None
2916 except TypeError:
2917 main.log.exception( self.name + ": Object not as expected" )
2918 return None
2919 except pexpect.EOF:
2920 main.log.error( self.name + ": EOF exception found" )
2921 main.log.error( self.name + ": " + self.handle.before )
2922 main.cleanup()
2923 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002924 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002925 main.log.exception( self.name + ": Uncaught exception!" )
2926 main.cleanup()
2927 main.exit()
2928
2929 def appToIDCheck( self ):
2930 """
2931 This method will check that each application's ID listed in 'apps' is
2932 the same as the ID listed in 'app-ids'. The check will also check that
2933 there are no duplicate IDs issued. Note that an app ID should be
2934 a globaly unique numerical identifier for app/app-like features. Once
2935 an ID is registered, the ID is never freed up so that if an app is
2936 reinstalled it will have the same ID.
2937
2938 Returns: main.TRUE if the check passes and
2939 main.FALSE if the check fails or
2940 main.ERROR if there is some error in processing the test
2941 """
2942 try:
Jon Hall390696c2015-05-05 17:13:41 -07002943 bail = False
2944 ids = self.appIDs( jsonFormat=True )
2945 if ids:
2946 ids = json.loads( ids )
2947 else:
2948 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2949 bail = True
2950 apps = self.apps( jsonFormat=True )
2951 if apps:
2952 apps = json.loads( apps )
2953 else:
2954 main.log.error( "apps returned nothing:" + repr( apps ) )
2955 bail = True
2956 if bail:
2957 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002958 result = main.TRUE
2959 for app in apps:
2960 appID = app.get( 'id' )
2961 if appID is None:
2962 main.log.error( "Error parsing app: " + str( app ) )
2963 result = main.FALSE
2964 appName = app.get( 'name' )
2965 if appName is None:
2966 main.log.error( "Error parsing app: " + str( app ) )
2967 result = main.FALSE
2968 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07002969 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07002970 # main.log.debug( "Comparing " + str( app ) + " to " +
2971 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002972 if not current: # if ids doesn't have this id
2973 result = main.FALSE
2974 main.log.error( "'app-ids' does not have the ID for " +
2975 str( appName ) + " that apps does." )
2976 elif len( current ) > 1:
2977 # there is more than one app with this ID
2978 result = main.FALSE
2979 # We will log this later in the method
2980 elif not current[0][ 'name' ] == appName:
2981 currentName = current[0][ 'name' ]
2982 result = main.FALSE
2983 main.log.error( "'app-ids' has " + str( currentName ) +
2984 " registered under id:" + str( appID ) +
2985 " but 'apps' has " + str( appName ) )
2986 else:
2987 pass # id and name match!
2988 # now make sure that app-ids has no duplicates
2989 idsList = []
2990 namesList = []
2991 for item in ids:
2992 idsList.append( item[ 'id' ] )
2993 namesList.append( item[ 'name' ] )
2994 if len( idsList ) != len( set( idsList ) ) or\
2995 len( namesList ) != len( set( namesList ) ):
2996 main.log.error( "'app-ids' has some duplicate entries: \n"
2997 + json.dumps( ids,
2998 sort_keys=True,
2999 indent=4,
3000 separators=( ',', ': ' ) ) )
3001 result = main.FALSE
3002 return result
3003 except ( ValueError, TypeError ):
3004 main.log.exception( self.name + ": Object not as expected" )
3005 return main.ERROR
3006 except pexpect.EOF:
3007 main.log.error( self.name + ": EOF exception found" )
3008 main.log.error( self.name + ": " + self.handle.before )
3009 main.cleanup()
3010 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003011 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003012 main.log.exception( self.name + ": Uncaught exception!" )
3013 main.cleanup()
3014 main.exit()
3015
Jon Hallfb760a02015-04-13 15:35:03 -07003016 def getCfg( self, component=None, propName=None, short=False,
3017 jsonFormat=True ):
3018 """
3019 Get configuration settings from onos cli
3020 Optional arguments:
3021 component - Optionally only list configurations for a specific
3022 component. If None, all components with configurations
3023 are displayed. Case Sensitive string.
3024 propName - If component is specified, propName option will show
3025 only this specific configuration from that component.
3026 Case Sensitive string.
3027 jsonFormat - Returns output as json. Note that this will override
3028 the short option
3029 short - Short, less verbose, version of configurations.
3030 This is overridden by the json option
3031 returns:
3032 Output from cli as a string or None on error
3033 """
3034 try:
3035 baseStr = "cfg"
3036 cmdStr = " get"
3037 componentStr = ""
3038 if component:
3039 componentStr += " " + component
3040 if propName:
3041 componentStr += " " + propName
3042 if jsonFormat:
3043 baseStr += " -j"
3044 elif short:
3045 baseStr += " -s"
3046 output = self.sendline( baseStr + cmdStr + componentStr )
3047 assert "Error executing command" not in output
3048 return output
3049 except AssertionError:
3050 main.log.error( "Error in processing 'cfg get' command: " +
3051 str( output ) )
3052 return None
3053 except TypeError:
3054 main.log.exception( self.name + ": Object not as expected" )
3055 return None
3056 except pexpect.EOF:
3057 main.log.error( self.name + ": EOF exception found" )
3058 main.log.error( self.name + ": " + self.handle.before )
3059 main.cleanup()
3060 main.exit()
3061 except Exception:
3062 main.log.exception( self.name + ": Uncaught exception!" )
3063 main.cleanup()
3064 main.exit()
3065
3066 def setCfg( self, component, propName, value=None, check=True ):
3067 """
3068 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003069 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003070 component - The case sensitive name of the component whose
3071 property is to be set
3072 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003073 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003074 value - The value to set the property to. If None, will unset the
3075 property and revert it to it's default value(if applicable)
3076 check - Boolean, Check whether the option was successfully set this
3077 only applies when a value is given.
3078 returns:
3079 main.TRUE on success or main.FALSE on failure. If check is False,
3080 will return main.TRUE unless there is an error
3081 """
3082 try:
3083 baseStr = "cfg"
3084 cmdStr = " set " + str( component ) + " " + str( propName )
3085 if value is not None:
3086 cmdStr += " " + str( value )
3087 output = self.sendline( baseStr + cmdStr )
3088 assert "Error executing command" not in output
3089 if value and check:
3090 results = self.getCfg( component=str( component ),
3091 propName=str( propName ),
3092 jsonFormat=True )
3093 # Check if current value is what we just set
3094 try:
3095 jsonOutput = json.loads( results )
3096 current = jsonOutput[ 'value' ]
3097 except ( ValueError, TypeError ):
3098 main.log.exception( "Error parsing cfg output" )
3099 main.log.error( "output:" + repr( results ) )
3100 return main.FALSE
3101 if current == str( value ):
3102 return main.TRUE
3103 return main.FALSE
3104 return main.TRUE
3105 except AssertionError:
3106 main.log.error( "Error in processing 'cfg set' command: " +
3107 str( output ) )
3108 return main.FALSE
3109 except TypeError:
3110 main.log.exception( self.name + ": Object not as expected" )
3111 return main.FALSE
3112 except pexpect.EOF:
3113 main.log.error( self.name + ": EOF exception found" )
3114 main.log.error( self.name + ": " + self.handle.before )
3115 main.cleanup()
3116 main.exit()
3117 except Exception:
3118 main.log.exception( self.name + ": Uncaught exception!" )
3119 main.cleanup()
3120 main.exit()
3121
Jon Hall390696c2015-05-05 17:13:41 -07003122 def setTestAdd( self, setName, values ):
3123 """
3124 CLI command to add elements to a distributed set.
3125 Arguments:
3126 setName - The name of the set to add to.
3127 values - The value(s) to add to the set, space seperated.
3128 Example usages:
3129 setTestAdd( "set1", "a b c" )
3130 setTestAdd( "set2", "1" )
3131 returns:
3132 main.TRUE on success OR
3133 main.FALSE if elements were already in the set OR
3134 main.ERROR on error
3135 """
3136 try:
3137 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3138 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003139 try:
3140 # TODO: Maybe make this less hardcoded
3141 # ConsistentMap Exceptions
3142 assert "org.onosproject.store.service" not in output
3143 # Node not leader
3144 assert "java.lang.IllegalStateException" not in output
3145 except AssertionError:
3146 main.log.error( "Error in processing 'set-test-add' " +
3147 "command: " + str( output ) )
3148 retryTime = 30 # Conservative time, given by Madan
3149 main.log.info( "Waiting " + str( retryTime ) +
3150 "seconds before retrying." )
3151 time.sleep( retryTime ) # Due to change in mastership
3152 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003153 assert "Error executing command" not in output
3154 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3155 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3156 main.log.info( self.name + ": " + output )
3157 if re.search( positiveMatch, output):
3158 return main.TRUE
3159 elif re.search( negativeMatch, output):
3160 return main.FALSE
3161 else:
3162 main.log.error( self.name + ": setTestAdd did not" +
3163 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003164 main.log.debug( self.name + " actual: " + repr( output ) )
3165 return main.ERROR
3166 except AssertionError:
3167 main.log.error( "Error in processing 'set-test-add' command: " +
3168 str( output ) )
3169 return main.ERROR
3170 except TypeError:
3171 main.log.exception( self.name + ": Object not as expected" )
3172 return main.ERROR
3173 except pexpect.EOF:
3174 main.log.error( self.name + ": EOF exception found" )
3175 main.log.error( self.name + ": " + self.handle.before )
3176 main.cleanup()
3177 main.exit()
3178 except Exception:
3179 main.log.exception( self.name + ": Uncaught exception!" )
3180 main.cleanup()
3181 main.exit()
3182
3183 def setTestRemove( self, setName, values, clear=False, retain=False ):
3184 """
3185 CLI command to remove elements from a distributed set.
3186 Required arguments:
3187 setName - The name of the set to remove from.
3188 values - The value(s) to remove from the set, space seperated.
3189 Optional arguments:
3190 clear - Clear all elements from the set
3191 retain - Retain only the given values. (intersection of the
3192 original set and the given set)
3193 returns:
3194 main.TRUE on success OR
3195 main.FALSE if the set was not changed OR
3196 main.ERROR on error
3197 """
3198 try:
3199 cmdStr = "set-test-remove "
3200 if clear:
3201 cmdStr += "-c " + str( setName )
3202 elif retain:
3203 cmdStr += "-r " + str( setName ) + " " + str( values )
3204 else:
3205 cmdStr += str( setName ) + " " + str( values )
3206 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003207 try:
3208 # TODO: Maybe make this less hardcoded
3209 # ConsistentMap Exceptions
3210 assert "org.onosproject.store.service" not in output
3211 # Node not leader
3212 assert "java.lang.IllegalStateException" not in output
3213 except AssertionError:
3214 main.log.error( "Error in processing 'set-test-add' " +
3215 "command: " + str( output ) )
3216 retryTime = 30 # Conservative time, given by Madan
3217 main.log.info( "Waiting " + str( retryTime ) +
3218 "seconds before retrying." )
3219 time.sleep( retryTime ) # Due to change in mastership
3220 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003221 assert "Error executing command" not in output
3222 main.log.info( self.name + ": " + output )
3223 if clear:
3224 pattern = "Set " + str( setName ) + " cleared"
3225 if re.search( pattern, output ):
3226 return main.TRUE
3227 elif retain:
3228 positivePattern = str( setName ) + " was pruned to contain " +\
3229 "only elements of set \[(.*)\]"
3230 negativePattern = str( setName ) + " was not changed by " +\
3231 "retaining only elements of the set " +\
3232 "\[(.*)\]"
3233 if re.search( positivePattern, output ):
3234 return main.TRUE
3235 elif re.search( negativePattern, output ):
3236 return main.FALSE
3237 else:
3238 positivePattern = "\[(.*)\] was removed from the set " +\
3239 str( setName )
3240 if ( len( values.split() ) == 1 ):
3241 negativePattern = "\[(.*)\] was not in set " +\
3242 str( setName )
3243 else:
3244 negativePattern = "No element of \[(.*)\] was in set " +\
3245 str( setName )
3246 if re.search( positivePattern, output ):
3247 return main.TRUE
3248 elif re.search( negativePattern, output ):
3249 return main.FALSE
3250 main.log.error( self.name + ": setTestRemove did not" +
3251 " match expected output" )
3252 main.log.debug( self.name + " expected: " + pattern )
3253 main.log.debug( self.name + " actual: " + repr( output ) )
3254 return main.ERROR
3255 except AssertionError:
3256 main.log.error( "Error in processing 'set-test-remove' command: " +
3257 str( output ) )
3258 return main.ERROR
3259 except TypeError:
3260 main.log.exception( self.name + ": Object not as expected" )
3261 return main.ERROR
3262 except pexpect.EOF:
3263 main.log.error( self.name + ": EOF exception found" )
3264 main.log.error( self.name + ": " + self.handle.before )
3265 main.cleanup()
3266 main.exit()
3267 except Exception:
3268 main.log.exception( self.name + ": Uncaught exception!" )
3269 main.cleanup()
3270 main.exit()
3271
3272 def setTestGet( self, setName, values="" ):
3273 """
3274 CLI command to get the elements in a distributed set.
3275 Required arguments:
3276 setName - The name of the set to remove from.
3277 Optional arguments:
3278 values - The value(s) to check if in the set, space seperated.
3279 returns:
3280 main.ERROR on error OR
3281 A list of elements in the set if no optional arguments are
3282 supplied OR
3283 A tuple containing the list then:
3284 main.FALSE if the given values are not in the set OR
3285 main.TRUE if the given values are in the set OR
3286 """
3287 try:
3288 values = str( values ).strip()
3289 setName = str( setName ).strip()
3290 length = len( values.split() )
3291 containsCheck = None
3292 # Patterns to match
3293 setPattern = "\[(.*)\]"
3294 pattern = "Items in set " + setName + ":\n" + setPattern
3295 containsTrue = "Set " + setName + " contains the value " + values
3296 containsFalse = "Set " + setName + " did not contain the value " +\
3297 values
3298 containsAllTrue = "Set " + setName + " contains the the subset " +\
3299 setPattern
3300 containsAllFalse = "Set " + setName + " did not contain the the" +\
3301 " subset " + setPattern
3302
3303 cmdStr = "set-test-get "
3304 cmdStr += setName + " " + values
3305 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003306 try:
3307 # TODO: Maybe make this less hardcoded
3308 # ConsistentMap Exceptions
3309 assert "org.onosproject.store.service" not in output
3310 # Node not leader
3311 assert "java.lang.IllegalStateException" not in output
3312 except AssertionError:
3313 main.log.error( "Error in processing 'set-test-add' " +
3314 "command: " + str( output ) )
3315 retryTime = 30 # Conservative time, given by Madan
3316 main.log.info( "Waiting " + str( retryTime ) +
3317 "seconds before retrying." )
3318 time.sleep( retryTime ) # Due to change in mastership
3319 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003320 assert "Error executing command" not in output
3321 main.log.info( self.name + ": " + output )
3322
3323 if length == 0:
3324 match = re.search( pattern, output )
3325 else: # if given values
3326 if length == 1: # Contains output
3327 patternTrue = pattern + "\n" + containsTrue
3328 patternFalse = pattern + "\n" + containsFalse
3329 else: # ContainsAll output
3330 patternTrue = pattern + "\n" + containsAllTrue
3331 patternFalse = pattern + "\n" + containsAllFalse
3332 matchTrue = re.search( patternTrue, output )
3333 matchFalse = re.search( patternFalse, output )
3334 if matchTrue:
3335 containsCheck = main.TRUE
3336 match = matchTrue
3337 elif matchFalse:
3338 containsCheck = main.FALSE
3339 match = matchFalse
3340 else:
3341 main.log.error( self.name + " setTestGet did not match " +\
3342 "expected output" )
3343 main.log.debug( self.name + " expected: " + pattern )
3344 main.log.debug( self.name + " actual: " + repr( output ) )
3345 match = None
3346 if match:
3347 setMatch = match.group( 1 )
3348 if setMatch == '':
3349 setList = []
3350 else:
3351 setList = setMatch.split( ", " )
3352 if length > 0:
3353 return ( setList, containsCheck )
3354 else:
3355 return setList
3356 else: # no match
3357 main.log.error( self.name + ": setTestGet did not" +
3358 " match expected output" )
3359 main.log.debug( self.name + " expected: " + pattern )
3360 main.log.debug( self.name + " actual: " + repr( output ) )
3361 return main.ERROR
3362 except AssertionError:
3363 main.log.error( "Error in processing 'set-test-get' command: " +
3364 str( output ) )
3365 return main.ERROR
3366 except TypeError:
3367 main.log.exception( self.name + ": Object not as expected" )
3368 return main.ERROR
3369 except pexpect.EOF:
3370 main.log.error( self.name + ": EOF exception found" )
3371 main.log.error( self.name + ": " + self.handle.before )
3372 main.cleanup()
3373 main.exit()
3374 except Exception:
3375 main.log.exception( self.name + ": Uncaught exception!" )
3376 main.cleanup()
3377 main.exit()
3378
3379 def setTestSize( self, setName ):
3380 """
3381 CLI command to get the elements in a distributed set.
3382 Required arguments:
3383 setName - The name of the set to remove from.
3384 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003385 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003386 None on error
3387 """
3388 try:
3389 # TODO: Should this check against the number of elements returned
3390 # and then return true/false based on that?
3391 setName = str( setName ).strip()
3392 # Patterns to match
3393 setPattern = "\[(.*)\]"
3394 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3395 setPattern
3396 cmdStr = "set-test-get -s "
3397 cmdStr += setName
3398 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003399 try:
3400 # TODO: Maybe make this less hardcoded
3401 # ConsistentMap Exceptions
3402 assert "org.onosproject.store.service" not in output
3403 # Node not leader
3404 assert "java.lang.IllegalStateException" not in output
3405 except AssertionError:
3406 main.log.error( "Error in processing 'set-test-add' " +
3407 "command: " + str( output ) )
3408 retryTime = 30 # Conservative time, given by Madan
3409 main.log.info( "Waiting " + str( retryTime ) +
3410 "seconds before retrying." )
3411 time.sleep( retryTime ) # Due to change in mastership
3412 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003413 assert "Error executing command" not in output
3414 main.log.info( self.name + ": " + output )
3415 match = re.search( pattern, output )
3416 if match:
3417 setSize = int( match.group( 1 ) )
3418 setMatch = match.group( 2 )
3419 if len( setMatch.split() ) == setSize:
3420 main.log.info( "The size returned by " + self.name +
3421 " matches the number of elements in " +
3422 "the returned set" )
3423 else:
3424 main.log.error( "The size returned by " + self.name +
3425 " does not match the number of " +
3426 "elements in the returned set." )
3427 return setSize
3428 else: # no match
3429 main.log.error( self.name + ": setTestGet did not" +
3430 " match expected output" )
3431 main.log.debug( self.name + " expected: " + pattern )
3432 main.log.debug( self.name + " actual: " + repr( output ) )
3433 return None
3434 except AssertionError:
3435 main.log.error( "Error in processing 'set-test-get' command: " +
3436 str( output ) )
3437 return None
3438 except TypeError:
3439 main.log.exception( self.name + ": Object not as expected" )
3440 return None
3441 except pexpect.EOF:
3442 main.log.error( self.name + ": EOF exception found" )
3443 main.log.error( self.name + ": " + self.handle.before )
3444 main.cleanup()
3445 main.exit()
3446 except Exception:
3447 main.log.exception( self.name + ": Uncaught exception!" )
3448 main.cleanup()
3449 main.exit()
3450
Jon Hall80daded2015-05-27 16:07:00 -07003451 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003452 """
3453 Command to list the various counters in the system.
3454 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003455 if jsonFormat, a string of the json object returned by the cli
3456 command
3457 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003458 None on error
3459 """
Jon Hall390696c2015-05-05 17:13:41 -07003460 try:
3461 counters = {}
3462 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003463 if jsonFormat:
3464 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003465 output = self.sendline( cmdStr )
3466 assert "Error executing command" not in output
3467 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003468 return output
Jon Hall390696c2015-05-05 17:13:41 -07003469 except AssertionError:
3470 main.log.error( "Error in processing 'counters' command: " +
3471 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003472 return None
Jon Hall390696c2015-05-05 17:13:41 -07003473 except TypeError:
3474 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003475 return None
Jon Hall390696c2015-05-05 17:13:41 -07003476 except pexpect.EOF:
3477 main.log.error( self.name + ": EOF exception found" )
3478 main.log.error( self.name + ": " + self.handle.before )
3479 main.cleanup()
3480 main.exit()
3481 except Exception:
3482 main.log.exception( self.name + ": Uncaught exception!" )
3483 main.cleanup()
3484 main.exit()
3485
3486 def counterTestIncrement( self, counter, inMemory=False ):
3487 """
3488 CLI command to increment and get a distributed counter.
3489 Required arguments:
3490 counter - The name of the counter to increment.
3491 Optional arguments:
3492 inMemory - use in memory map for the counter
3493 returns:
3494 integer value of the counter or
3495 None on Error
3496 """
3497 try:
3498 counter = str( counter )
3499 cmdStr = "counter-test-increment "
3500 if inMemory:
3501 cmdStr += "-i "
3502 cmdStr += counter
3503 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003504 try:
3505 # TODO: Maybe make this less hardcoded
3506 # ConsistentMap Exceptions
3507 assert "org.onosproject.store.service" not in output
3508 # Node not leader
3509 assert "java.lang.IllegalStateException" not in output
3510 except AssertionError:
3511 main.log.error( "Error in processing 'set-test-add' " +
3512 "command: " + str( output ) )
3513 retryTime = 30 # Conservative time, given by Madan
3514 main.log.info( "Waiting " + str( retryTime ) +
3515 "seconds before retrying." )
3516 time.sleep( retryTime ) # Due to change in mastership
3517 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003518 assert "Error executing command" not in output
3519 main.log.info( self.name + ": " + output )
3520 pattern = counter + " was incremented to (\d+)"
3521 match = re.search( pattern, output )
3522 if match:
3523 return int( match.group( 1 ) )
3524 else:
3525 main.log.error( self.name + ": counterTestIncrement did not" +
3526 " match expected output." )
3527 main.log.debug( self.name + " expected: " + pattern )
3528 main.log.debug( self.name + " actual: " + repr( output ) )
3529 return None
3530 except AssertionError:
3531 main.log.error( "Error in processing 'counter-test-increment'" +
3532 " command: " + str( output ) )
3533 return None
3534 except TypeError:
3535 main.log.exception( self.name + ": Object not as expected" )
3536 return None
3537 except pexpect.EOF:
3538 main.log.error( self.name + ": EOF exception found" )
3539 main.log.error( self.name + ": " + self.handle.before )
3540 main.cleanup()
3541 main.exit()
3542 except Exception:
3543 main.log.exception( self.name + ": Uncaught exception!" )
3544 main.cleanup()
3545 main.exit()
3546