blob: b6f931e3d881e3c9a94dc99a74ba10c0447393a0 [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( "" )
283 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800284 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700285 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800286 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800287
kelvin-onlab9f541032015-02-04 16:19:53 -0800288 response = self.handle.before
289 if re.search( "Error", response ):
290 return main.FALSE
291 return main.TRUE
292
293 except pexpect.EOF:
294 main.log.error( self.name + ": EOF exception found" )
295 main.log.error( self.name + ": " + self.handle.before )
296 main.cleanup()
297 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800298 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800299 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400300 main.cleanup()
301 main.exit()
302
Jon Hallc6358dd2015-04-10 12:44:28 -0700303 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800304 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800305 Send a completely user specified string to
306 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400307 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800308
andrewonlaba18f6bf2014-10-13 19:31:54 -0400309 Warning: There are no sanity checking to commands
310 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800311 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400312 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800313 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
314 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800316 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
317 response = self.handle.before
318 if i == 2:
319 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700320 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800321 response += self.handle.before
322 print response
323 try:
324 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700325 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800326 pass
327 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800328 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800329 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700330 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700331 main.log.debug( self.name + ": Raw output" )
332 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700333
334 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800335 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800336 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700337 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700338 main.log.debug( self.name + ": ansiEscape output" )
339 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700340
kelvin-onlabfb521662015-02-27 09:52:40 -0800341 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800342 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700343 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700344 main.log.debug( self.name + ": Removed extra returns " +
345 "from output" )
346 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700347
348 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800349 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700350 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700351 main.log.debug( self.name + ": parsed and stripped output" )
352 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700353
Jon Hall63604932015-02-26 17:09:50 -0800354 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700355 output = response.split( cmdStr.strip(), 1 )
356 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700357 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700358 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700359 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700360 return output[1].strip()
361 except IndexError:
362 main.log.exception( self.name + ": Object not as expected" )
363 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800364 except TypeError:
365 main.log.exception( self.name + ": Object not as expected" )
366 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400367 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800368 main.log.error( self.name + ": EOF exception found" )
369 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400370 main.cleanup()
371 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800372 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800373 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400374 main.cleanup()
375 main.exit()
376
kelvin8ec71442015-01-15 16:57:00 -0800377 # IMPORTANT NOTE:
378 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800379 # the cli command changing 'a:b' with 'aB'.
380 # Ex ) onos:topology > onosTopology
381 # onos:links > onosLinks
382 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800383
kelvin-onlabd3b64892015-01-20 13:26:24 -0800384 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800385 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400386 Adds a new cluster node by ID and address information.
387 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800388 * nodeId
389 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400390 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800392 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400393 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800394 cmdStr = "add-node " + str( nodeId ) + " " +\
395 str( ONOSIp ) + " " + str( tcpPort )
396 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800397 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800398 main.log.error( "Error in adding node" )
399 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800400 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400401 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400403 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800404 except TypeError:
405 main.log.exception( self.name + ": Object not as expected" )
406 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400407 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800408 main.log.error( self.name + ": EOF exception found" )
409 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400410 main.cleanup()
411 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800412 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800413 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400414 main.cleanup()
415 main.exit()
416
kelvin-onlabd3b64892015-01-20 13:26:24 -0800417 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800418 """
andrewonlab86dc3082014-10-13 18:18:38 -0400419 Removes a cluster by ID
420 Issues command: 'remove-node [<node-id>]'
421 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlab86dc3082014-10-13 18:18:38 -0400424 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400425
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700427 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700428 if re.search( "Error", handle ):
429 main.log.error( "Error in removing node" )
430 main.log.error( handle )
431 return main.FALSE
432 else:
433 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800434 except TypeError:
435 main.log.exception( self.name + ": Object not as expected" )
436 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400437 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800438 main.log.error( self.name + ": EOF exception found" )
439 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400440 main.cleanup()
441 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800442 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800443 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400444 main.cleanup()
445 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446
Jon Hall61282e32015-03-19 11:34:11 -0700447 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800448 """
andrewonlab7c211572014-10-15 16:45:20 -0400449 List the nodes currently visible
450 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700451 Optional argument:
452 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800453 """
andrewonlab7c211572014-10-15 16:45:20 -0400454 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700455 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700456 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700457 cmdStr += " -j"
458 output = self.sendline( cmdStr )
459 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800460 except TypeError:
461 main.log.exception( self.name + ": Object not as expected" )
462 return None
andrewonlab7c211572014-10-15 16:45:20 -0400463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800464 main.log.error( self.name + ": EOF exception found" )
465 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400466 main.cleanup()
467 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800468 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800469 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400470 main.cleanup()
471 main.exit()
472
kelvin8ec71442015-01-15 16:57:00 -0800473 def topology( self ):
474 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700475 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700476 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700477 Return:
478 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800479 """
andrewonlab95ce8322014-10-13 14:12:04 -0400480 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700481 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800482 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400484 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800485 except TypeError:
486 main.log.exception( self.name + ": Object not as expected" )
487 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800489 main.log.error( self.name + ": EOF exception found" )
490 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400491 main.cleanup()
492 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800493 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800494 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400495 main.cleanup()
496 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800497
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800499 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 Installs a specified feature by issuing command:
501 'feature:install <feature_str>'
502 NOTE: This is now deprecated, you should use the activateApp method
503 instead
kelvin8ec71442015-01-15 16:57:00 -0800504 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400505 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 handle = self.sendline( cmdStr )
508 if re.search( "Error", handle ):
509 main.log.error( "Error in installing feature" )
510 main.log.error( handle )
511 return main.FALSE
512 else:
513 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800514 except TypeError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400517 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800518 main.log.error( self.name + ": EOF exception found" )
519 main.log.error( self.name + ": " + self.handle.before )
520 main.log.report( "Failed to install feature" )
521 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400522 main.cleanup()
523 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800524 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800525 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800526 main.log.report( "Failed to install feature" )
527 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 main.cleanup()
529 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800530
kelvin-onlabd3b64892015-01-20 13:26:24 -0800531 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800532 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700533 Uninstalls a specified feature by issuing command:
534 'feature:uninstall <feature_str>'
535 NOTE: This is now deprecated, you should use the deactivateApp method
536 instead
kelvin8ec71442015-01-15 16:57:00 -0800537 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400538 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800539 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
540 handle = self.sendline( cmdStr )
541 if handle != '':
542 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800544 # TODO: Check for possible error responses from karaf
545 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800546 main.log.info( "Feature needs to be installed before " +
547 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700548 return main.TRUE
549 if re.search( "Error", output ):
550 main.log.error( "Error in uninstalling feature" )
551 main.log.error( output )
552 return main.FALSE
553 else:
554 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800555 except TypeError:
556 main.log.exception( self.name + ": Object not as expected" )
557 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400558 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800559 main.log.error( self.name + ": EOF exception found" )
560 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400561 main.cleanup()
562 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800563 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800564 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 main.cleanup()
566 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800567
jenkins7ead5a82015-03-13 10:28:21 -0700568 def deviceRemove( self, deviceId ):
569 """
570 Removes particular device from storage
571
572 TODO: refactor this function
573 """
574 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700575 cmdStr = "device-remove " + str( deviceId )
576 handle = self.sendline( cmdStr )
577 if re.search( "Error", handle ):
578 main.log.error( "Error in removing device" )
579 main.log.error( handle )
580 return main.FALSE
581 else:
582 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700583 except TypeError:
584 main.log.exception( self.name + ": Object not as expected" )
585 return None
586 except pexpect.EOF:
587 main.log.error( self.name + ": EOF exception found" )
588 main.log.error( self.name + ": " + self.handle.before )
589 main.cleanup()
590 main.exit()
591 except Exception:
592 main.log.exception( self.name + ": Uncaught exception!" )
593 main.cleanup()
594 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700595
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800597 """
Jon Hall7b02d952014-10-17 20:14:54 -0400598 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400599 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800600 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800601 """
andrewonlab86dc3082014-10-13 18:18:38 -0400602 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700605 cmdStr += " -j"
606 handle = self.sendline( cmdStr )
607 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800608 except TypeError:
609 main.log.exception( self.name + ": Object not as expected" )
610 return None
andrewonlab7c211572014-10-15 16:45:20 -0400611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800612 main.log.error( self.name + ": EOF exception found" )
613 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400614 main.cleanup()
615 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800617 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400618 main.cleanup()
619 main.exit()
620
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800622 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800623 This balances the devices across all controllers
624 by issuing command: 'onos> onos:balance-masters'
625 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800626 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800627 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 handle = self.sendline( cmdStr )
630 if re.search( "Error", handle ):
631 main.log.error( "Error in balancing masters" )
632 main.log.error( handle )
633 return main.FALSE
634 else:
635 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800646 main.cleanup()
647 main.exit()
648
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800650 """
Jon Halle8217482014-10-17 13:49:14 -0400651 Lists all core links
652 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800653 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800654 """
Jon Halle8217482014-10-17 13:49:14 -0400655 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700656 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800657 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700658 cmdStr += " -j"
659 handle = self.sendline( cmdStr )
660 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800661 except TypeError:
662 main.log.exception( self.name + ": Object not as expected" )
663 return None
Jon Halle8217482014-10-17 13:49:14 -0400664 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800665 main.log.error( self.name + ": EOF exception found" )
666 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400667 main.cleanup()
668 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800669 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800670 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400671 main.cleanup()
672 main.exit()
673
kelvin-onlabd3b64892015-01-20 13:26:24 -0800674 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800675 """
Jon Halle8217482014-10-17 13:49:14 -0400676 Lists all ports
677 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800679 """
Jon Halle8217482014-10-17 13:49:14 -0400680 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700681 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700683 cmdStr += " -j"
684 handle = self.sendline( cmdStr )
685 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800686 except TypeError:
687 main.log.exception( self.name + ": Object not as expected" )
688 return None
Jon Halle8217482014-10-17 13:49:14 -0400689 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800690 main.log.error( self.name + ": EOF exception found" )
691 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400692 main.cleanup()
693 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800694 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800695 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400696 main.cleanup()
697 main.exit()
698
kelvin-onlabd3b64892015-01-20 13:26:24 -0800699 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800700 """
Jon Hall983a1702014-10-28 18:44:22 -0400701 Lists all devices and the controllers with roles assigned to them
702 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800703 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800704 """
andrewonlab7c211572014-10-15 16:45:20 -0400705 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700708 cmdStr += " -j"
709 handle = self.sendline( cmdStr )
710 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800711 except TypeError:
712 main.log.exception( self.name + ": Object not as expected" )
713 return None
Jon Hall983a1702014-10-28 18:44:22 -0400714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400717 main.cleanup()
718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800720 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400721 main.cleanup()
722 main.exit()
723
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800725 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800726 Given the a string containing the json representation of the "roles"
727 cli command and a partial or whole device id, returns a json object
728 containing the roles output for the first device whose id contains
729 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400730
731 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800732 A dict of the role assignments for the given device or
733 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800734 """
Jon Hall983a1702014-10-28 18:44:22 -0400735 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400737 return None
738 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 rawRoles = self.roles()
740 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800741 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800743 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400745 return device
746 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800747 except TypeError:
748 main.log.exception( self.name + ": Object not as expected" )
749 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400753 main.cleanup()
754 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800755 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800756 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400757 main.cleanup()
758 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800759
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800761 """
Jon Hall94fd0472014-12-08 11:52:42 -0800762 Iterates through each device and checks if there is a master assigned
763 Returns: main.TRUE if each device has a master
764 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Jon Hall94fd0472014-12-08 11:52:42 -0800766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 rawRoles = self.roles()
768 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800769 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800771 # print device
772 if device[ 'master' ] == "none":
773 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800774 return main.FALSE
775 return main.TRUE
776
Jon Halld4d4b372015-01-28 16:02:41 -0800777 except TypeError:
778 main.log.exception( self.name + ": Object not as expected" )
779 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800780 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( self.name + ": EOF exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800783 main.cleanup()
784 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800786 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800787 main.cleanup()
788 main.exit()
789
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800791 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400792 Returns string of paths, and the cost.
793 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800794 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400795 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
797 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800798 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800799 main.log.error( "Error in getting paths" )
800 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400801 else:
kelvin8ec71442015-01-15 16:57:00 -0800802 path = handle.split( ";" )[ 0 ]
803 cost = handle.split( ";" )[ 1 ]
804 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800805 except TypeError:
806 main.log.exception( self.name + ": Object not as expected" )
807 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800809 main.log.error( self.name + ": EOF exception found" )
810 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400811 main.cleanup()
812 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800814 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400815 main.cleanup()
816 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800817
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800819 """
Jon Hallffb386d2014-11-21 13:43:38 -0800820 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400821 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800823 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400824 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700825 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800826 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700827 cmdStr += " -j"
828 handle = self.sendline( cmdStr )
829 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800830 except TypeError:
831 main.log.exception( self.name + ": Object not as expected" )
832 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400836 main.cleanup()
837 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800838 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800839 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400840 main.cleanup()
841 main.exit()
842
kelvin-onlabd3b64892015-01-20 13:26:24 -0800843 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800844 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400845 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800846
Jon Hallefbd9792015-03-05 16:11:36 -0800847 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800848 partial mac address
849
Jon Hall42db6dc2014-10-24 19:03:48 -0400850 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 try:
kelvin8ec71442015-01-15 16:57:00 -0800853 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400854 return None
855 else:
856 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 rawHosts = self.hosts()
858 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800859 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800861 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800862 if not host:
863 pass
864 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400865 return host
866 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800867 except TypeError:
868 main.log.exception( self.name + ": Object not as expected" )
869 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400870 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800871 main.log.error( self.name + ": EOF exception found" )
872 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400873 main.cleanup()
874 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800875 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800876 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400877 main.cleanup()
878 main.exit()
879
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800881 """
882 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400883 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800884
andrewonlab3f0a4af2014-10-17 12:25:14 -0400885 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800886 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400887 IMPORTANT:
888 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800889 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400890 Furthermore, it assumes that value of VLAN is '-1'
891 Description:
kelvin8ec71442015-01-15 16:57:00 -0800892 Converts mininet hosts ( h1, h2, h3... ) into
893 ONOS format ( 00:00:00:00:00:01/-1 , ... )
894 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400895 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400897
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800899 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 hostHex = hex( int( host ) ).zfill( 12 )
901 hostHex = str( hostHex ).replace( 'x', '0' )
902 i = iter( str( hostHex ) )
903 hostHex = ":".join( a + b for a, b in zip( i, i ) )
904 hostHex = hostHex + "/-1"
905 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908
Jon Halld4d4b372015-01-28 16:02:41 -0800909 except TypeError:
910 main.log.exception( self.name + ": Object not as expected" )
911 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800913 main.log.error( self.name + ": EOF exception found" )
914 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400915 main.cleanup()
916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800918 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400919 main.cleanup()
920 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400921
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800923 """
andrewonlabe6745342014-10-17 14:29:13 -0400924 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 * hostIdOne: ONOS host id for host1
926 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400927 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800928 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500929 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800930 Returns:
931 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800932 """
andrewonlabe6745342014-10-17 14:29:13 -0400933 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 cmdStr = "add-host-intent " + str( hostIdOne ) +\
935 " " + str( hostIdTwo )
936 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800937 if re.search( "Error", handle ):
938 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700939 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800940 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800941 else:
942 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800943 str( hostIdOne ) + " and " + str( hostIdTwo ) )
944 match = re.search('id=0x([\da-f]+),', handle)
945 if match:
946 return match.group()[3:-1]
947 else:
948 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700949 main.log.debug( "Response from ONOS was: " +
950 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800951 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800952 except TypeError:
953 main.log.exception( self.name + ": Object not as expected" )
954 return None
andrewonlabe6745342014-10-17 14:29:13 -0400955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400958 main.cleanup()
959 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800961 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400962 main.cleanup()
963 main.exit()
964
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800966 """
andrewonlab7b31d232014-10-24 13:31:47 -0400967 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 * ingressDevice: device id of ingress device
969 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400970 Optional:
971 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -0800972 Description:
973 Adds an optical intent by specifying an ingress and egress device
974 Returns:
975 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800976 """
andrewonlab7b31d232014-10-24 13:31:47 -0400977 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
979 " " + str( egressDevice )
980 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800981 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800982 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800983 main.log.error( "Error in adding Optical intent" )
984 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400985 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800986 main.log.info( "Optical intent installed between " +
987 str( ingressDevice ) + " and " +
988 str( egressDevice ) )
989 match = re.search('id=0x([\da-f]+),', handle)
990 if match:
991 return match.group()[3:-1]
992 else:
993 main.log.error( "Error, intent ID not found" )
994 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800995 except TypeError:
996 main.log.exception( self.name + ": Object not as expected" )
997 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400998 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800999 main.log.error( self.name + ": EOF exception found" )
1000 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001001 main.cleanup()
1002 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001003 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001004 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001005 main.cleanup()
1006 main.exit()
1007
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001009 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 ingressDevice,
1011 egressDevice,
1012 portIngress="",
1013 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001014 ethType="",
1015 ethSrc="",
1016 ethDst="",
1017 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001019 ipProto="",
1020 ipSrc="",
1021 ipDst="",
1022 tcpSrc="",
1023 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001024 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001025 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 * ingressDevice: device id of ingress device
1027 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001028 Optional:
1029 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001030 * ethSrc: specify ethSrc ( i.e. src mac addr )
1031 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001032 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001034 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001035 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001036 * ipSrc: specify ip source address
1037 * ipDst: specify ip destination address
1038 * tcpSrc: specify tcp source port
1039 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001040 Description:
kelvin8ec71442015-01-15 16:57:00 -08001041 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001042 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001043 Returns:
1044 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001045
Jon Halle3f39ff2015-01-13 11:50:53 -08001046 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001047 options developers provide for point-to-point
1048 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001049 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001050 try:
kelvin8ec71442015-01-15 16:57:00 -08001051 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001052 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001054 and not ipProto and not ipSrc and not ipDst \
1055 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001056 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001057
andrewonlab289e4b72014-10-21 21:24:18 -04001058 else:
andrewonlab36af3822014-11-18 17:48:18 -05001059 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001060
andrewonlab0c0a6772014-10-22 12:31:18 -04001061 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001062 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001063 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001064 cmd += " --ethSrc " + str( ethSrc )
1065 if ethDst:
1066 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001067 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001068 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001070 cmd += " --lambda "
1071 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001072 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001073 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001074 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001075 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001076 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001077 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001078 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001079 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001080 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001081
kelvin8ec71442015-01-15 16:57:00 -08001082 # Check whether the user appended the port
1083 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 if "/" in ingressDevice:
1085 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001086 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001088 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001089 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001090 # Would it make sense to throw an exception and exit
1091 # the test?
1092 return None
andrewonlab36af3822014-11-18 17:48:18 -05001093
kelvin8ec71442015-01-15 16:57:00 -08001094 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 str( ingressDevice ) + "/" +\
1096 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001097
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 if "/" in egressDevice:
1099 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001100 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001102 main.log.error( "You must specify the egress port" )
1103 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001104
kelvin8ec71442015-01-15 16:57:00 -08001105 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 str( egressDevice ) + "/" +\
1107 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001108
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001110 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001111 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001112 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001113 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001114 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001115 # TODO: print out all the options in this message?
1116 main.log.info( "Point-to-point intent installed between " +
1117 str( ingressDevice ) + " and " +
1118 str( egressDevice ) )
1119 match = re.search('id=0x([\da-f]+),', handle)
1120 if match:
1121 return match.group()[3:-1]
1122 else:
1123 main.log.error( "Error, intent ID not found" )
1124 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001125 except TypeError:
1126 main.log.exception( self.name + ": Object not as expected" )
1127 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001129 main.log.error( self.name + ": EOF exception found" )
1130 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001131 main.cleanup()
1132 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001134 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001135 main.cleanup()
1136 main.exit()
1137
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001139 self,
shahshreyac2f97072015-03-19 17:04:29 -07001140 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001142 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001144 ethType="",
1145 ethSrc="",
1146 ethDst="",
1147 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001149 ipProto="",
1150 ipSrc="",
1151 ipDst="",
1152 tcpSrc="",
1153 tcpDst="",
1154 setEthSrc="",
1155 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001156 """
shahshreyad0c80432014-12-04 16:56:05 -08001157 Note:
shahshreya70622b12015-03-19 17:19:00 -07001158 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001159 is same. That is, all ingress devices include port numbers
1160 with a "/" or all ingress devices could specify device
1161 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001162 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001163 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001164 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001166 Optional:
1167 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001168 * ethSrc: specify ethSrc ( i.e. src mac addr )
1169 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001170 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001172 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001173 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001174 * ipSrc: specify ip source address
1175 * ipDst: specify ip destination address
1176 * tcpSrc: specify tcp source port
1177 * tcpDst: specify tcp destination port
1178 * setEthSrc: action to Rewrite Source MAC Address
1179 * setEthDst: action to Rewrite Destination MAC Address
1180 Description:
kelvin8ec71442015-01-15 16:57:00 -08001181 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001182 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001183 Returns:
1184 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001185
Jon Halle3f39ff2015-01-13 11:50:53 -08001186 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001187 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001188 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001189 """
shahshreyad0c80432014-12-04 16:56:05 -08001190 try:
kelvin8ec71442015-01-15 16:57:00 -08001191 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001192 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001194 and not ipProto and not ipSrc and not ipDst\
1195 and not tcpSrc and not tcpDst and not setEthSrc\
1196 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001197 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001198
1199 else:
1200 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001201
shahshreyad0c80432014-12-04 16:56:05 -08001202 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001203 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001204 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " --ethSrc " + str( ethSrc )
1206 if ethDst:
1207 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001208 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001209 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001211 cmd += " --lambda "
1212 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001214 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001215 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001216 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001217 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001218 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001219 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001220 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001221 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001222 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001223 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001224 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001225 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001226
kelvin8ec71442015-01-15 16:57:00 -08001227 # Check whether the user appended the port
1228 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001229
1230 if portIngressList is None:
1231 for ingressDevice in ingressDeviceList:
1232 if "/" in ingressDevice:
1233 cmd += " " + str( ingressDevice )
1234 else:
1235 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001236 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001237 # TODO: perhaps more meaningful return
1238 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001239 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001240 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001241 for ingressDevice, portIngress in zip( ingressDeviceList,
1242 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001243 cmd += " " + \
1244 str( ingressDevice ) + "/" +\
1245 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001246 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001247 main.log.error( "Device list and port list does not " +
1248 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001249 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 if "/" in egressDevice:
1251 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001252 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( "You must specify " +
1255 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001256 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001257
kelvin8ec71442015-01-15 16:57:00 -08001258 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 str( egressDevice ) + "/" +\
1260 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001261 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001262 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001264 main.log.error( "Error in adding multipoint-to-singlepoint " +
1265 "intent" )
1266 return None
shahshreyad0c80432014-12-04 16:56:05 -08001267 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001268 match = re.search('id=0x([\da-f]+),', handle)
1269 if match:
1270 return match.group()[3:-1]
1271 else:
1272 main.log.error( "Error, intent ID not found" )
1273 return None
1274 except TypeError:
1275 main.log.exception( self.name + ": Object not as expected" )
1276 return None
1277 except pexpect.EOF:
1278 main.log.error( self.name + ": EOF exception found" )
1279 main.log.error( self.name + ": " + self.handle.before )
1280 main.cleanup()
1281 main.exit()
1282 except Exception:
1283 main.log.exception( self.name + ": Uncaught exception!" )
1284 main.cleanup()
1285 main.exit()
1286
1287 def addSinglepointToMultipointIntent(
1288 self,
1289 ingressDevice,
1290 egressDeviceList,
1291 portIngress="",
1292 portEgressList=None,
1293 ethType="",
1294 ethSrc="",
1295 ethDst="",
1296 bandwidth="",
1297 lambdaAlloc=False,
1298 ipProto="",
1299 ipSrc="",
1300 ipDst="",
1301 tcpSrc="",
1302 tcpDst="",
1303 setEthSrc="",
1304 setEthDst="" ):
1305 """
1306 Note:
1307 This function assumes the format of all egress devices
1308 is same. That is, all egress devices include port numbers
1309 with a "/" or all egress devices could specify device
1310 ids and port numbers seperately.
1311 Required:
1312 * EgressDeviceList: List of device ids of egress device
1313 ( Atleast 2 eress devices required in the list )
1314 * ingressDevice: device id of ingress device
1315 Optional:
1316 * ethType: specify ethType
1317 * ethSrc: specify ethSrc ( i.e. src mac addr )
1318 * ethDst: specify ethDst ( i.e. dst mac addr )
1319 * bandwidth: specify bandwidth capacity of link
1320 * lambdaAlloc: if True, intent will allocate lambda
1321 for the specified intent
1322 * ipProto: specify ip protocol
1323 * ipSrc: specify ip source address
1324 * ipDst: specify ip destination address
1325 * tcpSrc: specify tcp source port
1326 * tcpDst: specify tcp destination port
1327 * setEthSrc: action to Rewrite Source MAC Address
1328 * setEthDst: action to Rewrite Destination MAC Address
1329 Description:
1330 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1331 specifying device id's and optional fields
1332 Returns:
1333 A string of the intent id or None on error
1334
1335 NOTE: This function may change depending on the
1336 options developers provide for singlepoint-to-multipoint
1337 intent via cli
1338 """
1339 try:
1340 # If there are no optional arguments
1341 if not ethType and not ethSrc and not ethDst\
1342 and not bandwidth and not lambdaAlloc\
1343 and not ipProto and not ipSrc and not ipDst\
1344 and not tcpSrc and not tcpDst and not setEthSrc\
1345 and not setEthDst:
1346 cmd = "add-single-to-multi-intent"
1347
1348 else:
1349 cmd = "add-single-to-multi-intent"
1350
1351 if ethType:
1352 cmd += " --ethType " + str( ethType )
1353 if ethSrc:
1354 cmd += " --ethSrc " + str( ethSrc )
1355 if ethDst:
1356 cmd += " --ethDst " + str( ethDst )
1357 if bandwidth:
1358 cmd += " --bandwidth " + str( bandwidth )
1359 if lambdaAlloc:
1360 cmd += " --lambda "
1361 if ipProto:
1362 cmd += " --ipProto " + str( ipProto )
1363 if ipSrc:
1364 cmd += " --ipSrc " + str( ipSrc )
1365 if ipDst:
1366 cmd += " --ipDst " + str( ipDst )
1367 if tcpSrc:
1368 cmd += " --tcpSrc " + str( tcpSrc )
1369 if tcpDst:
1370 cmd += " --tcpDst " + str( tcpDst )
1371 if setEthSrc:
1372 cmd += " --setEthSrc " + str( setEthSrc )
1373 if setEthDst:
1374 cmd += " --setEthDst " + str( setEthDst )
1375
1376 # Check whether the user appended the port
1377 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001378
kelvin-onlabb9408212015-04-01 13:34:04 -07001379 if "/" in ingressDevice:
1380 cmd += " " + str( ingressDevice )
1381 else:
1382 if not portIngress:
1383 main.log.error( "You must specify " +
1384 "the Ingress port" )
1385 return main.FALSE
1386
1387 cmd += " " +\
1388 str( ingressDevice ) + "/" +\
1389 str( portIngress )
1390
1391 if portEgressList is None:
1392 for egressDevice in egressDeviceList:
1393 if "/" in egressDevice:
1394 cmd += " " + str( egressDevice )
1395 else:
1396 main.log.error( "You must specify " +
1397 "the egress port" )
1398 # TODO: perhaps more meaningful return
1399 return main.FALSE
1400 else:
1401 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001402 for egressDevice, portEgress in zip( egressDeviceList,
1403 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001404 cmd += " " + \
1405 str( egressDevice ) + "/" +\
1406 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001407 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001408 main.log.error( "Device list and port list does not " +
1409 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001410 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001411 handle = self.sendline( cmd )
1412 # If error, return error message
1413 if re.search( "Error", handle ):
1414 main.log.error( "Error in adding singlepoint-to-multipoint " +
1415 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001416 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001417 else:
1418 match = re.search('id=0x([\da-f]+),', handle)
1419 if match:
1420 return match.group()[3:-1]
1421 else:
1422 main.log.error( "Error, intent ID not found" )
1423 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001424 except TypeError:
1425 main.log.exception( self.name + ": Object not as expected" )
1426 return None
shahshreyad0c80432014-12-04 16:56:05 -08001427 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001428 main.log.error( self.name + ": EOF exception found" )
1429 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001430 main.cleanup()
1431 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001432 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001433 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001434 main.cleanup()
1435 main.exit()
1436
Hari Krishna9e232602015-04-13 17:29:08 -07001437 def addMplsIntent(
1438 self,
1439 ingressDevice,
1440 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001441 ingressPort="",
1442 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001443 ethType="",
1444 ethSrc="",
1445 ethDst="",
1446 bandwidth="",
1447 lambdaAlloc=False,
1448 ipProto="",
1449 ipSrc="",
1450 ipDst="",
1451 tcpSrc="",
1452 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001453 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001454 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001455 priority=""):
1456 """
1457 Required:
1458 * ingressDevice: device id of ingress device
1459 * egressDevice: device id of egress device
1460 Optional:
1461 * ethType: specify ethType
1462 * ethSrc: specify ethSrc ( i.e. src mac addr )
1463 * ethDst: specify ethDst ( i.e. dst mac addr )
1464 * bandwidth: specify bandwidth capacity of link
1465 * lambdaAlloc: if True, intent will allocate lambda
1466 for the specified intent
1467 * ipProto: specify ip protocol
1468 * ipSrc: specify ip source address
1469 * ipDst: specify ip destination address
1470 * tcpSrc: specify tcp source port
1471 * tcpDst: specify tcp destination port
1472 * ingressLabel: Ingress MPLS label
1473 * egressLabel: Egress MPLS label
1474 Description:
1475 Adds MPLS intent by
1476 specifying device id's and optional fields
1477 Returns:
1478 A string of the intent id or None on error
1479
1480 NOTE: This function may change depending on the
1481 options developers provide for MPLS
1482 intent via cli
1483 """
1484 try:
1485 # If there are no optional arguments
1486 if not ethType and not ethSrc and not ethDst\
1487 and not bandwidth and not lambdaAlloc \
1488 and not ipProto and not ipSrc and not ipDst \
1489 and not tcpSrc and not tcpDst and not ingressLabel \
1490 and not egressLabel:
1491 cmd = "add-mpls-intent"
1492
1493 else:
1494 cmd = "add-mpls-intent"
1495
1496 if ethType:
1497 cmd += " --ethType " + str( ethType )
1498 if ethSrc:
1499 cmd += " --ethSrc " + str( ethSrc )
1500 if ethDst:
1501 cmd += " --ethDst " + str( ethDst )
1502 if bandwidth:
1503 cmd += " --bandwidth " + str( bandwidth )
1504 if lambdaAlloc:
1505 cmd += " --lambda "
1506 if ipProto:
1507 cmd += " --ipProto " + str( ipProto )
1508 if ipSrc:
1509 cmd += " --ipSrc " + str( ipSrc )
1510 if ipDst:
1511 cmd += " --ipDst " + str( ipDst )
1512 if tcpSrc:
1513 cmd += " --tcpSrc " + str( tcpSrc )
1514 if tcpDst:
1515 cmd += " --tcpDst " + str( tcpDst )
1516 if ingressLabel:
1517 cmd += " --ingressLabel " + str( ingressLabel )
1518 if egressLabel:
1519 cmd += " --egressLabel " + str( egressLabel )
1520 if priority:
1521 cmd += " --priority " + str( priority )
1522
1523 # Check whether the user appended the port
1524 # or provided it as an input
1525 if "/" in ingressDevice:
1526 cmd += " " + str( ingressDevice )
1527 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001528 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001529 main.log.error( "You must specify the ingress port" )
1530 return None
1531
1532 cmd += " " + \
1533 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001534 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001535
1536 if "/" in egressDevice:
1537 cmd += " " + str( egressDevice )
1538 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001539 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001540 main.log.error( "You must specify the egress port" )
1541 return None
1542
1543 cmd += " " +\
1544 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001545 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001546
1547 handle = self.sendline( cmd )
1548 # If error, return error message
1549 if re.search( "Error", handle ):
1550 main.log.error( "Error in adding mpls intent" )
1551 return None
1552 else:
1553 # TODO: print out all the options in this message?
1554 main.log.info( "MPLS intent installed between " +
1555 str( ingressDevice ) + " and " +
1556 str( egressDevice ) )
1557 match = re.search('id=0x([\da-f]+),', handle)
1558 if match:
1559 return match.group()[3:-1]
1560 else:
1561 main.log.error( "Error, intent ID not found" )
1562 return None
1563 except TypeError:
1564 main.log.exception( self.name + ": Object not as expected" )
1565 return None
1566 except pexpect.EOF:
1567 main.log.error( self.name + ": EOF exception found" )
1568 main.log.error( self.name + ": " + self.handle.before )
1569 main.cleanup()
1570 main.exit()
1571 except Exception:
1572 main.log.exception( self.name + ": Uncaught exception!" )
1573 main.cleanup()
1574 main.exit()
1575
Jon Hallefbd9792015-03-05 16:11:36 -08001576 def removeIntent( self, intentId, app='org.onosproject.cli',
1577 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001578 """
shahshreya1c818fc2015-02-26 13:44:08 -08001579 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001580 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001581 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001582 -p or --purge: Purge the intent from the store after removal
1583
Jon Halle3f39ff2015-01-13 11:50:53 -08001584 Returns:
1585 main.False on error and
1586 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001587 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001588 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001589 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001590 if purge:
1591 cmdStr += " -p"
1592 if sync:
1593 cmdStr += " -s"
1594
1595 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001597 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001598 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001599 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001600 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001601 # TODO: Should this be main.TRUE
1602 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001603 except TypeError:
1604 main.log.exception( self.name + ": Object not as expected" )
1605 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001607 main.log.error( self.name + ": EOF exception found" )
1608 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001609 main.cleanup()
1610 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001611 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001612 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001613 main.cleanup()
1614 main.exit()
1615
kelvin-onlabd3b64892015-01-20 13:26:24 -08001616 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001617 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001618 NOTE: This method should be used after installing application:
1619 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001620 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001622 Description:
1623 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001624 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001625 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001626 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001628 cmdStr += " -j"
1629 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001630 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001631 except TypeError:
1632 main.log.exception( self.name + ": Object not as expected" )
1633 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001634 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001635 main.log.error( self.name + ": EOF exception found" )
1636 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001637 main.cleanup()
1638 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001639 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001640 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001641 main.cleanup()
1642 main.exit()
1643
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001645 """
andrewonlab377693f2014-10-21 16:00:30 -04001646 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001647 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001648 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001649 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001650 """
andrewonlabe6745342014-10-17 14:29:13 -04001651 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001652 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001654 cmdStr += " -j"
1655 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001656 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001657 except TypeError:
1658 main.log.exception( self.name + ": Object not as expected" )
1659 return None
andrewonlabe6745342014-10-17 14:29:13 -04001660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001661 main.log.error( self.name + ": EOF exception found" )
1662 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001663 main.cleanup()
1664 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001665 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001666 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001667 main.cleanup()
1668 main.exit()
1669
kelvin-onlab54400a92015-02-26 18:05:51 -08001670 def getIntentState(self, intentsId, intentsJson=None):
1671 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001672 Check intent state.
1673 Accepts a single intent ID (string type) or a list of intent IDs.
1674 Returns the state(string type) of the id if a single intent ID is
1675 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001676 Returns a dictionary with intent IDs as the key and its
1677 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001678 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001679 intentId: intent ID (string type)
1680 intentsJson: parsed json object from the onos:intents api
1681 Returns:
1682 state = An intent's state- INSTALL,WITHDRAWN etc.
1683 stateDict = Dictionary of intent's state. intent ID as the keys and
1684 state as the values.
1685 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001686 try:
1687 state = "State is Undefined"
1688 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001689 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001690 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001691 intentsJsonTemp = json.loads( intentsJson )
1692 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001693 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001694 if intentsId == intent[ 'id' ]:
1695 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001696 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001697 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1698 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001699 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001700 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001701 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001702 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001703 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001704 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001705 if intentsId[ i ] == intents[ 'id' ]:
1706 stateDict[ 'state' ] = intents[ 'state' ]
1707 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001708 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001709 break
Jon Hallefbd9792015-03-05 16:11:36 -08001710 if len( intentsId ) != len( dictList ):
1711 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001712 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001713 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001714 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001715 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001716 except TypeError:
1717 main.log.exception( self.name + ": Object not as expected" )
1718 return None
1719 except pexpect.EOF:
1720 main.log.error( self.name + ": EOF exception found" )
1721 main.log.error( self.name + ": " + self.handle.before )
1722 main.cleanup()
1723 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001724 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001725 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001726 main.cleanup()
1727 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001728
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001729 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1730 """
1731 Description:
1732 Check intents state
1733 Required:
1734 intentsId - List of intents ID to be checked
1735 Optional:
1736 expectedState - Check this expected state of each intents state
1737 in the list. Defaults to INSTALLED
1738 Return:
1739 Returns main.TRUE only if all intent are the same as expectedState,
1740 , otherwise,returns main.FALSE.
1741 """
1742 try:
1743 # Generating a dictionary: intent id as a key and state as value
1744 intentsDict = self.getIntentState( intentsId )
Jon Hall390696c2015-05-05 17:13:41 -07001745 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001746 if len( intentsId ) != len( intentsDict ):
1747 main.log.info( self.name + "There is something wrong " +
1748 "getting intents state" )
1749 return main.FALSE
1750 returnValue = main.TRUE
1751 for intents in intentsDict:
1752 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001753 if intents.get( 'state' ) == "INSTALLING":
1754 main.log.debug( self.name + " : Intent ID - " +
1755 intents.get( 'id' ) +
1756 " is in INSTALLING state" )
1757 returnValue = main.TRUE
1758 else:
1759 main.log.info( self.name + " : Intent ID - " +
1760 intents.get( 'id' ) +
1761 " actual state = " +
1762 intents.get( 'state' )
1763 + " does not equal expected state = "
1764 + expectedState )
1765 returnValue = main.FALSE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001766 if returnValue == main.TRUE:
1767 main.log.info( self.name + ": All " +
1768 str( len( intentsDict ) ) +
1769 " intents are in " + expectedState + " state")
1770 return returnValue
1771 except TypeError:
1772 main.log.exception( self.name + ": Object not as expected" )
1773 return None
1774 except pexpect.EOF:
1775 main.log.error( self.name + ": EOF exception found" )
1776 main.log.error( self.name + ": " + self.handle.before )
1777 main.cleanup()
1778 main.exit()
1779 except Exception:
1780 main.log.exception( self.name + ": Uncaught exception!" )
1781 main.cleanup()
1782 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001783
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001785 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001786 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001788 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001789 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001790 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001791 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001792 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001794 cmdStr += " -j"
1795 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001796 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001797 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001798 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001799 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001800 except TypeError:
1801 main.log.exception( self.name + ": Object not as expected" )
1802 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001803 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001804 main.log.error( self.name + ": EOF exception found" )
1805 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001806 main.cleanup()
1807 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001808 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001809 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001810 main.cleanup()
1811 main.exit()
1812
kelvin-onlab4df89f22015-04-13 18:10:23 -07001813 def checkFlowsState( self ):
1814 """
1815 Description:
1816 Check the if all the current flows are in ADDED state or
1817 PENDING_ADD state
1818 Return:
1819 returnValue - Returns main.TRUE only if all flows are in
1820 ADDED state or PENDING_ADD, return main.FALSE
1821 otherwise.
1822 """
1823 try:
1824 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001825 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001826 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001827
kelvin-onlab4df89f22015-04-13 18:10:23 -07001828 for device in tempFlows:
1829 for flow in device.get( 'flows' ):
1830 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1831 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001832
kelvin-onlab4df89f22015-04-13 18:10:23 -07001833 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001834 str( flow.get( 'groupId' ) ) +
1835 " | state:" +
1836 str( flow.get( 'state' ) ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07001837 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001838
kelvin-onlab4df89f22015-04-13 18:10:23 -07001839 return returnValue
1840 except TypeError:
1841 main.log.exception( self.name + ": Object not as expected" )
1842 return None
1843 except pexpect.EOF:
1844 main.log.error( self.name + ": EOF exception found" )
1845 main.log.error( self.name + ": " + self.handle.before )
1846 main.cleanup()
1847 main.exit()
1848 except Exception:
1849 main.log.exception( self.name + ": Uncaught exception!" )
1850 main.cleanup()
1851 main.exit()
1852
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001854 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001855 """
andrewonlab87852b02014-11-19 18:44:19 -05001856 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001858 a specific point-to-point intent definition
1859 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001860 * dpidSrc: specify source dpid
1861 * dpidDst: specify destination dpid
1862 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001863 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001864 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001865 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001866 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001867 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001868 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001869 """
andrewonlab87852b02014-11-19 18:44:19 -05001870 try:
kelvin8ec71442015-01-15 16:57:00 -08001871 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001872 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1873 str( numIntents )
1874 if numMult:
1875 cmd += " " + str( numMult )
1876 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001877 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 if appId:
1879 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001880 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001881 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001882 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001883 main.log.info( handle )
1884 # Split result by newline
1885 newline = handle.split( "\r\r\n" )
1886 # Ignore the first object of list, which is empty
1887 newline = newline[ 1: ]
1888 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001889 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001890 result = result.split( ": " )
1891 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001892 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1893 main.log.info( latResult )
1894 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001895 else:
1896 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001897 except TypeError:
1898 main.log.exception( self.name + ": Object not as expected" )
1899 return None
andrewonlab87852b02014-11-19 18:44:19 -05001900 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001901 main.log.error( self.name + ": EOF exception found" )
1902 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001903 main.cleanup()
1904 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001905 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001906 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001907 main.cleanup()
1908 main.exit()
1909
kelvin-onlabd3b64892015-01-20 13:26:24 -08001910 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001911 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001912 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001913 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001914 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001915 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001916 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001917 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001918 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001919 cmdStr += " -j"
1920 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001921 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001922 except TypeError:
1923 main.log.exception( self.name + ": Object not as expected" )
1924 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001925 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001926 main.log.error( self.name + ": EOF exception found" )
1927 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001928 main.cleanup()
1929 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001930 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001931 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001932 main.cleanup()
1933 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001934
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001936 """
1937 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001938 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001939 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001940 """
andrewonlab867212a2014-10-22 20:13:38 -04001941 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001942 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001943 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001944 cmdStr += " -j"
1945 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001946 if handle:
1947 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001948 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001949 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001950 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001951 else:
1952 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001953 except TypeError:
1954 main.log.exception( self.name + ": Object not as expected" )
1955 return None
andrewonlab867212a2014-10-22 20:13:38 -04001956 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001957 main.log.error( self.name + ": EOF exception found" )
1958 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001959 main.cleanup()
1960 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001961 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001962 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001963 main.cleanup()
1964 main.exit()
1965
kelvin8ec71442015-01-15 16:57:00 -08001966 # Wrapper functions ****************
1967 # Wrapper functions use existing driver
1968 # functions and extends their use case.
1969 # For example, we may use the output of
1970 # a normal driver function, and parse it
1971 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001972
kelvin-onlabd3b64892015-01-20 13:26:24 -08001973 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001974 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001975 Description:
1976 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001977 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001978 try:
kelvin8ec71442015-01-15 16:57:00 -08001979 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001980 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001981 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001982
kelvin8ec71442015-01-15 16:57:00 -08001983 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1985 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001986 match = re.search('id=0x([\da-f]+),', intents)
1987 if match:
1988 tmpId = match.group()[3:-1]
1989 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001990 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001991
Jon Halld4d4b372015-01-28 16:02:41 -08001992 except TypeError:
1993 main.log.exception( self.name + ": Object not as expected" )
1994 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001995 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001996 main.log.error( self.name + ": EOF exception found" )
1997 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001998 main.cleanup()
1999 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002000 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002001 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002002 main.cleanup()
2003 main.exit()
2004
Jon Hall30b82fa2015-03-04 17:15:43 -08002005 def FlowAddedCount( self, deviceId ):
2006 """
2007 Determine the number of flow rules for the given device id that are
2008 in the added state
2009 """
2010 try:
2011 cmdStr = "flows any " + str( deviceId ) + " | " +\
2012 "grep 'state=ADDED' | wc -l"
2013 handle = self.sendline( cmdStr )
2014 return handle
2015 except pexpect.EOF:
2016 main.log.error( self.name + ": EOF exception found" )
2017 main.log.error( self.name + ": " + self.handle.before )
2018 main.cleanup()
2019 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002020 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002021 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002022 main.cleanup()
2023 main.exit()
2024
kelvin-onlabd3b64892015-01-20 13:26:24 -08002025 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002026 """
andrewonlab95ce8322014-10-13 14:12:04 -04002027 Use 'devices' function to obtain list of all devices
2028 and parse the result to obtain a list of all device
2029 id's. Returns this list. Returns empty list if no
2030 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002031 List is ordered sequentially
2032
andrewonlab95ce8322014-10-13 14:12:04 -04002033 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002034 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002035 the ids. By obtaining the list of device ids on the fly,
2036 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002037 """
andrewonlab95ce8322014-10-13 14:12:04 -04002038 try:
kelvin8ec71442015-01-15 16:57:00 -08002039 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002040 devicesStr = self.devices( jsonFormat=False )
2041 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002042
kelvin-onlabd3b64892015-01-20 13:26:24 -08002043 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002044 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002045 return idList
kelvin8ec71442015-01-15 16:57:00 -08002046
2047 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002048 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002049 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002050 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002051 # Split list further into arguments before and after string
2052 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002053 # append to idList
2054 for arg in tempList:
2055 idList.append( arg.split( "id=" )[ 1 ] )
2056 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002057
Jon Halld4d4b372015-01-28 16:02:41 -08002058 except TypeError:
2059 main.log.exception( self.name + ": Object not as expected" )
2060 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002061 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002062 main.log.error( self.name + ": EOF exception found" )
2063 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002064 main.cleanup()
2065 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002066 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002067 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002068 main.cleanup()
2069 main.exit()
2070
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002072 """
andrewonlab7c211572014-10-15 16:45:20 -04002073 Uses 'nodes' function to obtain list of all nodes
2074 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002075 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002076 Returns:
2077 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002078 """
andrewonlab7c211572014-10-15 16:45:20 -04002079 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002080 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002081 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002082 # Sample nodesStr output
2083 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002084 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002085 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002086 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002087 nodesJson = json.loads( nodesStr )
2088 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002089 return idList
kelvin8ec71442015-01-15 16:57:00 -08002090
Jon Halld4d4b372015-01-28 16:02:41 -08002091 except TypeError:
2092 main.log.exception( self.name + ": Object not as expected" )
2093 return None
andrewonlab7c211572014-10-15 16:45:20 -04002094 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002095 main.log.error( self.name + ": EOF exception found" )
2096 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002097 main.cleanup()
2098 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002099 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002100 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002101 main.cleanup()
2102 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002103
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002105 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002106 Return the first device from the devices api whose 'id' contains 'dpid'
2107 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002108 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002109 try:
kelvin8ec71442015-01-15 16:57:00 -08002110 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002111 return None
2112 else:
kelvin8ec71442015-01-15 16:57:00 -08002113 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002114 rawDevices = self.devices()
2115 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002116 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002118 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2119 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002120 return device
2121 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002122 except TypeError:
2123 main.log.exception( self.name + ": Object not as expected" )
2124 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002125 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002126 main.log.error( self.name + ": EOF exception found" )
2127 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002128 main.cleanup()
2129 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002131 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002132 main.cleanup()
2133 main.exit()
2134
kelvin-onlabd3b64892015-01-20 13:26:24 -08002135 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002136 """
Jon Hallefbd9792015-03-05 16:11:36 -08002137 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002138 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002139 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002140
Jon Hall42db6dc2014-10-24 19:03:48 -04002141 Params: ip = ip used for the onos cli
2142 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002143 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002144 logLevel = level to log to. Currently accepts
2145 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002146
2147
kelvin-onlabd3b64892015-01-20 13:26:24 -08002148 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002149
Jon Hallefbd9792015-03-05 16:11:36 -08002150 Returns: main.TRUE if the number of switches and links are correct,
2151 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002152 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002153 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002154 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002156 if topology == {}:
2157 return main.ERROR
2158 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002159 # Is the number of switches is what we expected
2160 devices = topology.get( 'devices', False )
2161 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002162 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002163 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002164 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002165 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002166 linkCheck = ( int( links ) == int( numolink ) )
2167 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002168 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002169 output += "The number of links and switches match " +\
2170 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002171 result = main.TRUE
2172 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002173 output += "The number of links and switches does not match " +\
2174 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002175 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002176 output = output + "\n ONOS sees %i devices (%i expected) \
2177 and %i links (%i expected)" % (
2178 int( devices ), int( numoswitch ), int( links ),
2179 int( numolink ) )
2180 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002181 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002182 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002183 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002184 else:
Jon Hall390696c2015-05-05 17:13:41 -07002185 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002186 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002187 except TypeError:
2188 main.log.exception( self.name + ": Object not as expected" )
2189 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002190 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002191 main.log.error( self.name + ": EOF exception found" )
2192 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002193 main.cleanup()
2194 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002196 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002197 main.cleanup()
2198 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002199
kelvin-onlabd3b64892015-01-20 13:26:24 -08002200 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002201 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002202 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002203 deviceId must be the id of a device as seen in the onos devices command
2204 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002205 role must be either master, standby, or none
2206
Jon Halle3f39ff2015-01-13 11:50:53 -08002207 Returns:
2208 main.TRUE or main.FALSE based on argument verification and
2209 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002210 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002211 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002212 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002213 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002214 cmdStr = "device-role " +\
2215 str( deviceId ) + " " +\
2216 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002217 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002218 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002219 if re.search( "Error", handle ):
2220 # end color output to escape any colours
2221 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002222 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002223 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002224 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002225 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002226 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002227 main.log.error( "Invalid 'role' given to device_role(). " +
2228 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002229 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002230 except TypeError:
2231 main.log.exception( self.name + ": Object not as expected" )
2232 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002233 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002234 main.log.error( self.name + ": EOF exception found" )
2235 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002236 main.cleanup()
2237 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002238 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002239 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002240 main.cleanup()
2241 main.exit()
2242
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002244 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002245 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002246 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002247 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002248 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002249 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002250 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002251 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002252 cmdStr += " -j"
2253 handle = self.sendline( cmdStr )
2254 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002255 except TypeError:
2256 main.log.exception( self.name + ": Object not as expected" )
2257 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002258 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002259 main.log.error( self.name + ": EOF exception found" )
2260 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002261 main.cleanup()
2262 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002263 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002264 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002265 main.cleanup()
2266 main.exit()
2267
kelvin-onlabd3b64892015-01-20 13:26:24 -08002268 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002269 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002270 CLI command to get the current leader for the Election test application
2271 NOTE: Requires installation of the onos-app-election feature
2272 Returns: Node IP of the leader if one exists
2273 None if none exists
2274 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002275 """
Jon Hall94fd0472014-12-08 11:52:42 -08002276 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002277 cmdStr = "election-test-leader"
2278 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002279 # Leader
2280 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002281 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002282 nodeSearch = re.search( leaderPattern, response )
2283 if nodeSearch:
2284 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002285 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002286 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002287 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002288 # no leader
2289 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002290 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002291 nullSearch = re.search( nullPattern, response )
2292 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002293 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002294 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002295 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002296 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002297 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002298 if re.search( errorPattern, response ):
2299 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002300 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002301 return main.FALSE
2302 else:
Jon Hall390696c2015-05-05 17:13:41 -07002303 main.log.error( "Error in electionTestLeader on " + self.name +
2304 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002305 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002306 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002307 except TypeError:
2308 main.log.exception( self.name + ": Object not as expected" )
2309 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002310 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002311 main.log.error( self.name + ": EOF exception found" )
2312 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002313 main.cleanup()
2314 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002315 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002316 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002317 main.cleanup()
2318 main.exit()
2319
kelvin-onlabd3b64892015-01-20 13:26:24 -08002320 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002321 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002322 CLI command to run for leadership of the Election test application.
2323 NOTE: Requires installation of the onos-app-election feature
2324 Returns: Main.TRUE on success
2325 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002326 """
Jon Hall94fd0472014-12-08 11:52:42 -08002327 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002328 cmdStr = "election-test-run"
2329 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002330 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002331 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002332 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002333 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002334 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002335 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002336 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002337 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002338 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002339 errorPattern = "Command\snot\sfound"
2340 if re.search( errorPattern, response ):
2341 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002342 return main.FALSE
2343 else:
Jon Hall390696c2015-05-05 17:13:41 -07002344 main.log.error( "Error in electionTestRun on " + self.name +
2345 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002346 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002347 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002348 except TypeError:
2349 main.log.exception( self.name + ": Object not as expected" )
2350 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002351 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002352 main.log.error( self.name + ": EOF exception found" )
2353 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002354 main.cleanup()
2355 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002356 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002357 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002358 main.cleanup()
2359 main.exit()
2360
kelvin-onlabd3b64892015-01-20 13:26:24 -08002361 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002362 """
Jon Hall94fd0472014-12-08 11:52:42 -08002363 * CLI command to withdraw the local node from leadership election for
2364 * the Election test application.
2365 #NOTE: Requires installation of the onos-app-election feature
2366 Returns: Main.TRUE on success
2367 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002368 """
Jon Hall94fd0472014-12-08 11:52:42 -08002369 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002370 cmdStr = "election-test-withdraw"
2371 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002372 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002373 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002374 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002375 if re.search( successPattern, response ):
2376 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002377 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002378 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002379 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002380 errorPattern = "Command\snot\sfound"
2381 if re.search( errorPattern, response ):
2382 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002383 return main.FALSE
2384 else:
Jon Hall390696c2015-05-05 17:13:41 -07002385 main.log.error( "Error in electionTestWithdraw on " +
2386 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002387 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002388 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002389 except TypeError:
2390 main.log.exception( self.name + ": Object not as expected" )
2391 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002392 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002393 main.log.error( self.name + ": EOF exception found" )
2394 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002395 main.cleanup()
2396 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002397 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002398 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002399 main.cleanup()
2400 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002401
kelvin8ec71442015-01-15 16:57:00 -08002402 def getDevicePortsEnabledCount( self, dpid ):
2403 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002404 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002405 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002406 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002407 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002408 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2409 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002410 if re.search( "No such device", output ):
2411 main.log.error( "Error in getting ports" )
2412 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002413 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002414 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002415 except TypeError:
2416 main.log.exception( self.name + ": Object not as expected" )
2417 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002419 main.log.error( self.name + ": EOF exception found" )
2420 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002421 main.cleanup()
2422 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002423 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002424 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002425 main.cleanup()
2426 main.exit()
2427
kelvin8ec71442015-01-15 16:57:00 -08002428 def getDeviceLinksActiveCount( self, dpid ):
2429 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002430 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002431 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002432 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002433 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002434 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2435 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002436 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002437 main.log.error( "Error in getting ports " )
2438 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002439 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002440 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002441 except TypeError:
2442 main.log.exception( self.name + ": Object not as expected" )
2443 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002444 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002445 main.log.error( self.name + ": EOF exception found" )
2446 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002447 main.cleanup()
2448 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002449 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002450 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002451 main.cleanup()
2452 main.exit()
2453
kelvin8ec71442015-01-15 16:57:00 -08002454 def getAllIntentIds( self ):
2455 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002456 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002457 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002458 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002459 cmdStr = "onos:intents | grep id="
2460 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002461 if re.search( "Error", output ):
2462 main.log.error( "Error in getting ports" )
2463 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002464 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002465 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002466 except TypeError:
2467 main.log.exception( self.name + ": Object not as expected" )
2468 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002469 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002470 main.log.error( self.name + ": EOF exception found" )
2471 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002472 main.cleanup()
2473 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002474 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002475 main.log.exception( self.name + ": Uncaught exception!" )
2476 main.cleanup()
2477 main.exit()
2478
Jon Hall73509952015-02-24 16:42:56 -08002479 def intentSummary( self ):
2480 """
Jon Hallefbd9792015-03-05 16:11:36 -08002481 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002482 """
2483 try:
2484 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002485 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002486 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002487 states.append( intent.get( 'state', None ) )
2488 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002489 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002490 return dict( out )
2491 except TypeError:
2492 main.log.exception( self.name + ": Object not as expected" )
2493 return None
2494 except pexpect.EOF:
2495 main.log.error( self.name + ": EOF exception found" )
2496 main.log.error( self.name + ": " + self.handle.before )
2497 main.cleanup()
2498 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002499 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002500 main.log.exception( self.name + ": Uncaught exception!" )
2501 main.cleanup()
2502 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002503
Jon Hall61282e32015-03-19 11:34:11 -07002504 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002505 """
2506 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002507 Optional argument:
2508 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002509 """
2510 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002511 # Sample JSON
2512 # {
2513 # "electedTime": "13m ago",
2514 # "epoch": 4,
2515 # "leader": "10.128.30.17",
2516 # "topic": "intent-partition-3"
2517 # },
Jon Hall63604932015-02-26 17:09:50 -08002518 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002519 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002520 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002521 cmdStr += " -j"
2522 output = self.sendline( cmdStr )
2523 return output
Jon Hall63604932015-02-26 17:09:50 -08002524 except TypeError:
2525 main.log.exception( self.name + ": Object not as expected" )
2526 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002527 except pexpect.EOF:
2528 main.log.error( self.name + ": EOF exception found" )
2529 main.log.error( self.name + ": " + self.handle.before )
2530 main.cleanup()
2531 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002532 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002533 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002534 main.cleanup()
2535 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002536
Jon Hall61282e32015-03-19 11:34:11 -07002537 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002538 """
2539 Returns the output of the intent Pending map.
2540 """
Jon Hall63604932015-02-26 17:09:50 -08002541 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002542 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002543 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002544 cmdStr += " -j"
2545 output = self.sendline( cmdStr )
2546 return output
Jon Hall63604932015-02-26 17:09:50 -08002547 except TypeError:
2548 main.log.exception( self.name + ": Object not as expected" )
2549 return None
2550 except pexpect.EOF:
2551 main.log.error( self.name + ": EOF exception found" )
2552 main.log.error( self.name + ": " + self.handle.before )
2553 main.cleanup()
2554 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002555 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002556 main.log.exception( self.name + ": Uncaught exception!" )
2557 main.cleanup()
2558 main.exit()
2559
Jon Hall61282e32015-03-19 11:34:11 -07002560 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002561 """
2562 Returns the output of the raft partitions command for ONOS.
2563 """
Jon Hall61282e32015-03-19 11:34:11 -07002564 # Sample JSON
2565 # {
2566 # "leader": "tcp://10.128.30.11:7238",
2567 # "members": [
2568 # "tcp://10.128.30.11:7238",
2569 # "tcp://10.128.30.17:7238",
2570 # "tcp://10.128.30.13:7238",
2571 # ],
2572 # "name": "p1",
2573 # "term": 3
2574 # },
Jon Hall63604932015-02-26 17:09:50 -08002575 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002576 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002577 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002578 cmdStr += " -j"
2579 output = self.sendline( cmdStr )
2580 return output
Jon Hall63604932015-02-26 17:09:50 -08002581 except TypeError:
2582 main.log.exception( self.name + ": Object not as expected" )
2583 return None
2584 except pexpect.EOF:
2585 main.log.error( self.name + ": EOF exception found" )
2586 main.log.error( self.name + ": " + self.handle.before )
2587 main.cleanup()
2588 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002589 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002590 main.log.exception( self.name + ": Uncaught exception!" )
2591 main.cleanup()
2592 main.exit()
2593
Jon Hallbe379602015-03-24 13:39:32 -07002594 def apps( self, jsonFormat=True ):
2595 """
2596 Returns the output of the apps command for ONOS. This command lists
2597 information about installed ONOS applications
2598 """
2599 # Sample JSON object
2600 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2601 # "description":"ONOS OpenFlow protocol southbound providers",
2602 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2603 # "features":"[onos-openflow]","state":"ACTIVE"}]
2604 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002605 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002606 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002607 cmdStr += " -j"
2608 output = self.sendline( cmdStr )
2609 assert "Error executing command" not in output
2610 return output
Jon Hallbe379602015-03-24 13:39:32 -07002611 # FIXME: look at specific exceptions/Errors
2612 except AssertionError:
2613 main.log.error( "Error in processing onos:app command: " +
2614 str( output ) )
2615 return None
2616 except TypeError:
2617 main.log.exception( self.name + ": Object not as expected" )
2618 return None
2619 except pexpect.EOF:
2620 main.log.error( self.name + ": EOF exception found" )
2621 main.log.error( self.name + ": " + self.handle.before )
2622 main.cleanup()
2623 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002624 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002625 main.log.exception( self.name + ": Uncaught exception!" )
2626 main.cleanup()
2627 main.exit()
2628
Jon Hall146f1522015-03-24 15:33:24 -07002629 def appStatus( self, appName ):
2630 """
2631 Uses the onos:apps cli command to return the status of an application.
2632 Returns:
2633 "ACTIVE" - If app is installed and activated
2634 "INSTALLED" - If app is installed and deactivated
2635 "UNINSTALLED" - If app is not installed
2636 None - on error
2637 """
Jon Hall146f1522015-03-24 15:33:24 -07002638 try:
2639 if not isinstance( appName, types.StringType ):
2640 main.log.error( self.name + ".appStatus(): appName must be" +
2641 " a string" )
2642 return None
2643 output = self.apps( jsonFormat=True )
2644 appsJson = json.loads( output )
2645 state = None
2646 for app in appsJson:
2647 if appName == app.get('name'):
2648 state = app.get('state')
2649 break
2650 if state == "ACTIVE" or state == "INSTALLED":
2651 return state
2652 elif state is None:
2653 return "UNINSTALLED"
2654 elif state:
2655 main.log.error( "Unexpected state from 'onos:apps': " +
2656 str( state ) )
2657 return state
2658 except TypeError:
2659 main.log.exception( self.name + ": Object not as expected" )
2660 return None
2661 except pexpect.EOF:
2662 main.log.error( self.name + ": EOF exception found" )
2663 main.log.error( self.name + ": " + self.handle.before )
2664 main.cleanup()
2665 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002666 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002667 main.log.exception( self.name + ": Uncaught exception!" )
2668 main.cleanup()
2669 main.exit()
2670
Jon Hallbe379602015-03-24 13:39:32 -07002671 def app( self, appName, option ):
2672 """
2673 Interacts with the app command for ONOS. This command manages
2674 application inventory.
2675 """
Jon Hallbe379602015-03-24 13:39:32 -07002676 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002677 # Validate argument types
2678 valid = True
2679 if not isinstance( appName, types.StringType ):
2680 main.log.error( self.name + ".app(): appName must be a " +
2681 "string" )
2682 valid = False
2683 if not isinstance( option, types.StringType ):
2684 main.log.error( self.name + ".app(): option must be a string" )
2685 valid = False
2686 if not valid:
2687 return main.FALSE
2688 # Validate Option
2689 option = option.lower()
2690 # NOTE: Install may become a valid option
2691 if option == "activate":
2692 pass
2693 elif option == "deactivate":
2694 pass
2695 elif option == "uninstall":
2696 pass
2697 else:
2698 # Invalid option
2699 main.log.error( "The ONOS app command argument only takes " +
2700 "the values: (activate|deactivate|uninstall)" +
2701 "; was given '" + option + "'")
2702 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002703 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002704 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002705 if "Error executing command" in output:
2706 main.log.error( "Error in processing onos:app command: " +
2707 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002708 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002709 elif "No such application" in output:
2710 main.log.error( "The application '" + appName +
2711 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002712 return main.FALSE
2713 elif "Command not found:" in output:
2714 main.log.error( "Error in processing onos:app command: " +
2715 str( output ) )
2716 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002717 elif "Unsupported command:" in output:
2718 main.log.error( "Incorrect command given to 'app': " +
2719 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002720 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002721 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002722 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002723 return main.TRUE
2724 except TypeError:
2725 main.log.exception( self.name + ": Object not as expected" )
2726 return main.ERROR
2727 except pexpect.EOF:
2728 main.log.error( self.name + ": EOF exception found" )
2729 main.log.error( self.name + ": " + self.handle.before )
2730 main.cleanup()
2731 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002732 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002733 main.log.exception( self.name + ": Uncaught exception!" )
2734 main.cleanup()
2735 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002736
Jon Hallbd16b922015-03-26 17:53:15 -07002737 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002738 """
2739 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002740 appName is the hierarchical app name, not the feature name
2741 If check is True, method will check the status of the app after the
2742 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002743 Returns main.TRUE if the command was successfully sent
2744 main.FALSE if the cli responded with an error or given
2745 incorrect input
2746 """
2747 try:
2748 if not isinstance( appName, types.StringType ):
2749 main.log.error( self.name + ".activateApp(): appName must be" +
2750 " a string" )
2751 return main.FALSE
2752 status = self.appStatus( appName )
2753 if status == "INSTALLED":
2754 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002755 if check and response == main.TRUE:
2756 for i in range(10): # try 10 times then give up
2757 # TODO: Check with Thomas about this delay
2758 status = self.appStatus( appName )
2759 if status == "ACTIVE":
2760 return main.TRUE
2761 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002762 main.log.debug( "The state of application " +
2763 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002764 time.sleep( 1 )
2765 return main.FALSE
2766 else: # not 'check' or command didn't succeed
2767 return response
Jon Hall146f1522015-03-24 15:33:24 -07002768 elif status == "ACTIVE":
2769 return main.TRUE
2770 elif status == "UNINSTALLED":
2771 main.log.error( self.name + ": Tried to activate the " +
2772 "application '" + appName + "' which is not " +
2773 "installed." )
2774 else:
2775 main.log.error( "Unexpected return value from appStatus: " +
2776 str( status ) )
2777 return main.ERROR
2778 except TypeError:
2779 main.log.exception( self.name + ": Object not as expected" )
2780 return main.ERROR
2781 except pexpect.EOF:
2782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
2784 main.cleanup()
2785 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002786 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002787 main.log.exception( self.name + ": Uncaught exception!" )
2788 main.cleanup()
2789 main.exit()
2790
Jon Hallbd16b922015-03-26 17:53:15 -07002791 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002792 """
2793 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002794 appName is the hierarchical app name, not the feature name
2795 If check is True, method will check the status of the app after the
2796 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002797 Returns main.TRUE if the command was successfully sent
2798 main.FALSE if the cli responded with an error or given
2799 incorrect input
2800 """
2801 try:
2802 if not isinstance( appName, types.StringType ):
2803 main.log.error( self.name + ".deactivateApp(): appName must " +
2804 "be a string" )
2805 return main.FALSE
2806 status = self.appStatus( appName )
2807 if status == "INSTALLED":
2808 return main.TRUE
2809 elif status == "ACTIVE":
2810 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002811 if check and response == main.TRUE:
2812 for i in range(10): # try 10 times then give up
2813 status = self.appStatus( appName )
2814 if status == "INSTALLED":
2815 return main.TRUE
2816 else:
2817 time.sleep( 1 )
2818 return main.FALSE
2819 else: # not check or command didn't succeed
2820 return response
Jon Hall146f1522015-03-24 15:33:24 -07002821 elif status == "UNINSTALLED":
2822 main.log.warn( self.name + ": Tried to deactivate the " +
2823 "application '" + appName + "' which is not " +
2824 "installed." )
2825 return main.TRUE
2826 else:
2827 main.log.error( "Unexpected return value from appStatus: " +
2828 str( status ) )
2829 return main.ERROR
2830 except TypeError:
2831 main.log.exception( self.name + ": Object not as expected" )
2832 return main.ERROR
2833 except pexpect.EOF:
2834 main.log.error( self.name + ": EOF exception found" )
2835 main.log.error( self.name + ": " + self.handle.before )
2836 main.cleanup()
2837 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002838 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002839 main.log.exception( self.name + ": Uncaught exception!" )
2840 main.cleanup()
2841 main.exit()
2842
Jon Hallbd16b922015-03-26 17:53:15 -07002843 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002844 """
2845 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002846 appName is the hierarchical app name, not the feature name
2847 If check is True, method will check the status of the app after the
2848 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002849 Returns main.TRUE if the command was successfully sent
2850 main.FALSE if the cli responded with an error or given
2851 incorrect input
2852 """
2853 # TODO: check with Thomas about the state machine for apps
2854 try:
2855 if not isinstance( appName, types.StringType ):
2856 main.log.error( self.name + ".uninstallApp(): appName must " +
2857 "be a string" )
2858 return main.FALSE
2859 status = self.appStatus( appName )
2860 if status == "INSTALLED":
2861 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002862 if check and response == main.TRUE:
2863 for i in range(10): # try 10 times then give up
2864 status = self.appStatus( appName )
2865 if status == "UNINSTALLED":
2866 return main.TRUE
2867 else:
2868 time.sleep( 1 )
2869 return main.FALSE
2870 else: # not check or command didn't succeed
2871 return response
Jon Hall146f1522015-03-24 15:33:24 -07002872 elif status == "ACTIVE":
2873 main.log.warn( self.name + ": Tried to uninstall the " +
2874 "application '" + appName + "' which is " +
2875 "currently active." )
2876 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002877 if check and response == main.TRUE:
2878 for i in range(10): # try 10 times then give up
2879 status = self.appStatus( appName )
2880 if status == "UNINSTALLED":
2881 return main.TRUE
2882 else:
2883 time.sleep( 1 )
2884 return main.FALSE
2885 else: # not check or command didn't succeed
2886 return response
Jon Hall146f1522015-03-24 15:33:24 -07002887 elif status == "UNINSTALLED":
2888 return main.TRUE
2889 else:
2890 main.log.error( "Unexpected return value from appStatus: " +
2891 str( status ) )
2892 return main.ERROR
2893 except TypeError:
2894 main.log.exception( self.name + ": Object not as expected" )
2895 return main.ERROR
2896 except pexpect.EOF:
2897 main.log.error( self.name + ": EOF exception found" )
2898 main.log.error( self.name + ": " + self.handle.before )
2899 main.cleanup()
2900 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002901 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002902 main.log.exception( self.name + ": Uncaught exception!" )
2903 main.cleanup()
2904 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002905
2906 def appIDs( self, jsonFormat=True ):
2907 """
2908 Show the mappings between app id and app names given by the 'app-ids'
2909 cli command
2910 """
2911 try:
2912 cmdStr = "app-ids"
2913 if jsonFormat:
2914 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002915 output = self.sendline( cmdStr )
2916 assert "Error executing command" not in output
2917 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002918 except AssertionError:
2919 main.log.error( "Error in processing onos:app-ids command: " +
2920 str( output ) )
2921 return None
2922 except TypeError:
2923 main.log.exception( self.name + ": Object not as expected" )
2924 return None
2925 except pexpect.EOF:
2926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
2928 main.cleanup()
2929 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002930 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002931 main.log.exception( self.name + ": Uncaught exception!" )
2932 main.cleanup()
2933 main.exit()
2934
2935 def appToIDCheck( self ):
2936 """
2937 This method will check that each application's ID listed in 'apps' is
2938 the same as the ID listed in 'app-ids'. The check will also check that
2939 there are no duplicate IDs issued. Note that an app ID should be
2940 a globaly unique numerical identifier for app/app-like features. Once
2941 an ID is registered, the ID is never freed up so that if an app is
2942 reinstalled it will have the same ID.
2943
2944 Returns: main.TRUE if the check passes and
2945 main.FALSE if the check fails or
2946 main.ERROR if there is some error in processing the test
2947 """
2948 try:
Jon Hall390696c2015-05-05 17:13:41 -07002949 bail = False
2950 ids = self.appIDs( jsonFormat=True )
2951 if ids:
2952 ids = json.loads( ids )
2953 else:
2954 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2955 bail = True
2956 apps = self.apps( jsonFormat=True )
2957 if apps:
2958 apps = json.loads( apps )
2959 else:
2960 main.log.error( "apps returned nothing:" + repr( apps ) )
2961 bail = True
2962 if bail:
2963 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002964 result = main.TRUE
2965 for app in apps:
2966 appID = app.get( 'id' )
2967 if appID is None:
2968 main.log.error( "Error parsing app: " + str( app ) )
2969 result = main.FALSE
2970 appName = app.get( 'name' )
2971 if appName is None:
2972 main.log.error( "Error parsing app: " + str( app ) )
2973 result = main.FALSE
2974 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07002975 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07002976 # main.log.debug( "Comparing " + str( app ) + " to " +
2977 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002978 if not current: # if ids doesn't have this id
2979 result = main.FALSE
2980 main.log.error( "'app-ids' does not have the ID for " +
2981 str( appName ) + " that apps does." )
2982 elif len( current ) > 1:
2983 # there is more than one app with this ID
2984 result = main.FALSE
2985 # We will log this later in the method
2986 elif not current[0][ 'name' ] == appName:
2987 currentName = current[0][ 'name' ]
2988 result = main.FALSE
2989 main.log.error( "'app-ids' has " + str( currentName ) +
2990 " registered under id:" + str( appID ) +
2991 " but 'apps' has " + str( appName ) )
2992 else:
2993 pass # id and name match!
2994 # now make sure that app-ids has no duplicates
2995 idsList = []
2996 namesList = []
2997 for item in ids:
2998 idsList.append( item[ 'id' ] )
2999 namesList.append( item[ 'name' ] )
3000 if len( idsList ) != len( set( idsList ) ) or\
3001 len( namesList ) != len( set( namesList ) ):
3002 main.log.error( "'app-ids' has some duplicate entries: \n"
3003 + json.dumps( ids,
3004 sort_keys=True,
3005 indent=4,
3006 separators=( ',', ': ' ) ) )
3007 result = main.FALSE
3008 return result
3009 except ( ValueError, TypeError ):
3010 main.log.exception( self.name + ": Object not as expected" )
3011 return main.ERROR
3012 except pexpect.EOF:
3013 main.log.error( self.name + ": EOF exception found" )
3014 main.log.error( self.name + ": " + self.handle.before )
3015 main.cleanup()
3016 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003017 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003018 main.log.exception( self.name + ": Uncaught exception!" )
3019 main.cleanup()
3020 main.exit()
3021
Jon Hallfb760a02015-04-13 15:35:03 -07003022 def getCfg( self, component=None, propName=None, short=False,
3023 jsonFormat=True ):
3024 """
3025 Get configuration settings from onos cli
3026 Optional arguments:
3027 component - Optionally only list configurations for a specific
3028 component. If None, all components with configurations
3029 are displayed. Case Sensitive string.
3030 propName - If component is specified, propName option will show
3031 only this specific configuration from that component.
3032 Case Sensitive string.
3033 jsonFormat - Returns output as json. Note that this will override
3034 the short option
3035 short - Short, less verbose, version of configurations.
3036 This is overridden by the json option
3037 returns:
3038 Output from cli as a string or None on error
3039 """
3040 try:
3041 baseStr = "cfg"
3042 cmdStr = " get"
3043 componentStr = ""
3044 if component:
3045 componentStr += " " + component
3046 if propName:
3047 componentStr += " " + propName
3048 if jsonFormat:
3049 baseStr += " -j"
3050 elif short:
3051 baseStr += " -s"
3052 output = self.sendline( baseStr + cmdStr + componentStr )
3053 assert "Error executing command" not in output
3054 return output
3055 except AssertionError:
3056 main.log.error( "Error in processing 'cfg get' command: " +
3057 str( output ) )
3058 return None
3059 except TypeError:
3060 main.log.exception( self.name + ": Object not as expected" )
3061 return None
3062 except pexpect.EOF:
3063 main.log.error( self.name + ": EOF exception found" )
3064 main.log.error( self.name + ": " + self.handle.before )
3065 main.cleanup()
3066 main.exit()
3067 except Exception:
3068 main.log.exception( self.name + ": Uncaught exception!" )
3069 main.cleanup()
3070 main.exit()
3071
3072 def setCfg( self, component, propName, value=None, check=True ):
3073 """
3074 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003075 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003076 component - The case sensitive name of the component whose
3077 property is to be set
3078 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003079 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003080 value - The value to set the property to. If None, will unset the
3081 property and revert it to it's default value(if applicable)
3082 check - Boolean, Check whether the option was successfully set this
3083 only applies when a value is given.
3084 returns:
3085 main.TRUE on success or main.FALSE on failure. If check is False,
3086 will return main.TRUE unless there is an error
3087 """
3088 try:
3089 baseStr = "cfg"
3090 cmdStr = " set " + str( component ) + " " + str( propName )
3091 if value is not None:
3092 cmdStr += " " + str( value )
3093 output = self.sendline( baseStr + cmdStr )
3094 assert "Error executing command" not in output
3095 if value and check:
3096 results = self.getCfg( component=str( component ),
3097 propName=str( propName ),
3098 jsonFormat=True )
3099 # Check if current value is what we just set
3100 try:
3101 jsonOutput = json.loads( results )
3102 current = jsonOutput[ 'value' ]
3103 except ( ValueError, TypeError ):
3104 main.log.exception( "Error parsing cfg output" )
3105 main.log.error( "output:" + repr( results ) )
3106 return main.FALSE
3107 if current == str( value ):
3108 return main.TRUE
3109 return main.FALSE
3110 return main.TRUE
3111 except AssertionError:
3112 main.log.error( "Error in processing 'cfg set' command: " +
3113 str( output ) )
3114 return main.FALSE
3115 except TypeError:
3116 main.log.exception( self.name + ": Object not as expected" )
3117 return main.FALSE
3118 except pexpect.EOF:
3119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
3121 main.cleanup()
3122 main.exit()
3123 except Exception:
3124 main.log.exception( self.name + ": Uncaught exception!" )
3125 main.cleanup()
3126 main.exit()
3127
Jon Hall390696c2015-05-05 17:13:41 -07003128 def setTestAdd( self, setName, values ):
3129 """
3130 CLI command to add elements to a distributed set.
3131 Arguments:
3132 setName - The name of the set to add to.
3133 values - The value(s) to add to the set, space seperated.
3134 Example usages:
3135 setTestAdd( "set1", "a b c" )
3136 setTestAdd( "set2", "1" )
3137 returns:
3138 main.TRUE on success OR
3139 main.FALSE if elements were already in the set OR
3140 main.ERROR on error
3141 """
3142 try:
3143 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3144 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003145 try:
3146 # TODO: Maybe make this less hardcoded
3147 # ConsistentMap Exceptions
3148 assert "org.onosproject.store.service" not in output
3149 # Node not leader
3150 assert "java.lang.IllegalStateException" not in output
3151 except AssertionError:
3152 main.log.error( "Error in processing 'set-test-add' " +
3153 "command: " + str( output ) )
3154 retryTime = 30 # Conservative time, given by Madan
3155 main.log.info( "Waiting " + str( retryTime ) +
3156 "seconds before retrying." )
3157 time.sleep( retryTime ) # Due to change in mastership
3158 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003159 assert "Error executing command" not in output
3160 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3161 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3162 main.log.info( self.name + ": " + output )
3163 if re.search( positiveMatch, output):
3164 return main.TRUE
3165 elif re.search( negativeMatch, output):
3166 return main.FALSE
3167 else:
3168 main.log.error( self.name + ": setTestAdd did not" +
3169 " match expected output" )
3170 main.log.debug( self.name + " expected: " + pattern )
3171 main.log.debug( self.name + " actual: " + repr( output ) )
3172 return main.ERROR
3173 except AssertionError:
3174 main.log.error( "Error in processing 'set-test-add' command: " +
3175 str( output ) )
3176 return main.ERROR
3177 except TypeError:
3178 main.log.exception( self.name + ": Object not as expected" )
3179 return main.ERROR
3180 except pexpect.EOF:
3181 main.log.error( self.name + ": EOF exception found" )
3182 main.log.error( self.name + ": " + self.handle.before )
3183 main.cleanup()
3184 main.exit()
3185 except Exception:
3186 main.log.exception( self.name + ": Uncaught exception!" )
3187 main.cleanup()
3188 main.exit()
3189
3190 def setTestRemove( self, setName, values, clear=False, retain=False ):
3191 """
3192 CLI command to remove elements from a distributed set.
3193 Required arguments:
3194 setName - The name of the set to remove from.
3195 values - The value(s) to remove from the set, space seperated.
3196 Optional arguments:
3197 clear - Clear all elements from the set
3198 retain - Retain only the given values. (intersection of the
3199 original set and the given set)
3200 returns:
3201 main.TRUE on success OR
3202 main.FALSE if the set was not changed OR
3203 main.ERROR on error
3204 """
3205 try:
3206 cmdStr = "set-test-remove "
3207 if clear:
3208 cmdStr += "-c " + str( setName )
3209 elif retain:
3210 cmdStr += "-r " + str( setName ) + " " + str( values )
3211 else:
3212 cmdStr += str( setName ) + " " + str( values )
3213 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003214 try:
3215 # TODO: Maybe make this less hardcoded
3216 # ConsistentMap Exceptions
3217 assert "org.onosproject.store.service" not in output
3218 # Node not leader
3219 assert "java.lang.IllegalStateException" not in output
3220 except AssertionError:
3221 main.log.error( "Error in processing 'set-test-add' " +
3222 "command: " + str( output ) )
3223 retryTime = 30 # Conservative time, given by Madan
3224 main.log.info( "Waiting " + str( retryTime ) +
3225 "seconds before retrying." )
3226 time.sleep( retryTime ) # Due to change in mastership
3227 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003228 assert "Error executing command" not in output
3229 main.log.info( self.name + ": " + output )
3230 if clear:
3231 pattern = "Set " + str( setName ) + " cleared"
3232 if re.search( pattern, output ):
3233 return main.TRUE
3234 elif retain:
3235 positivePattern = str( setName ) + " was pruned to contain " +\
3236 "only elements of set \[(.*)\]"
3237 negativePattern = str( setName ) + " was not changed by " +\
3238 "retaining only elements of the set " +\
3239 "\[(.*)\]"
3240 if re.search( positivePattern, output ):
3241 return main.TRUE
3242 elif re.search( negativePattern, output ):
3243 return main.FALSE
3244 else:
3245 positivePattern = "\[(.*)\] was removed from the set " +\
3246 str( setName )
3247 if ( len( values.split() ) == 1 ):
3248 negativePattern = "\[(.*)\] was not in set " +\
3249 str( setName )
3250 else:
3251 negativePattern = "No element of \[(.*)\] was in set " +\
3252 str( setName )
3253 if re.search( positivePattern, output ):
3254 return main.TRUE
3255 elif re.search( negativePattern, output ):
3256 return main.FALSE
3257 main.log.error( self.name + ": setTestRemove did not" +
3258 " match expected output" )
3259 main.log.debug( self.name + " expected: " + pattern )
3260 main.log.debug( self.name + " actual: " + repr( output ) )
3261 return main.ERROR
3262 except AssertionError:
3263 main.log.error( "Error in processing 'set-test-remove' command: " +
3264 str( output ) )
3265 return main.ERROR
3266 except TypeError:
3267 main.log.exception( self.name + ": Object not as expected" )
3268 return main.ERROR
3269 except pexpect.EOF:
3270 main.log.error( self.name + ": EOF exception found" )
3271 main.log.error( self.name + ": " + self.handle.before )
3272 main.cleanup()
3273 main.exit()
3274 except Exception:
3275 main.log.exception( self.name + ": Uncaught exception!" )
3276 main.cleanup()
3277 main.exit()
3278
3279 def setTestGet( self, setName, values="" ):
3280 """
3281 CLI command to get the elements in a distributed set.
3282 Required arguments:
3283 setName - The name of the set to remove from.
3284 Optional arguments:
3285 values - The value(s) to check if in the set, space seperated.
3286 returns:
3287 main.ERROR on error OR
3288 A list of elements in the set if no optional arguments are
3289 supplied OR
3290 A tuple containing the list then:
3291 main.FALSE if the given values are not in the set OR
3292 main.TRUE if the given values are in the set OR
3293 """
3294 try:
3295 values = str( values ).strip()
3296 setName = str( setName ).strip()
3297 length = len( values.split() )
3298 containsCheck = None
3299 # Patterns to match
3300 setPattern = "\[(.*)\]"
3301 pattern = "Items in set " + setName + ":\n" + setPattern
3302 containsTrue = "Set " + setName + " contains the value " + values
3303 containsFalse = "Set " + setName + " did not contain the value " +\
3304 values
3305 containsAllTrue = "Set " + setName + " contains the the subset " +\
3306 setPattern
3307 containsAllFalse = "Set " + setName + " did not contain the the" +\
3308 " subset " + setPattern
3309
3310 cmdStr = "set-test-get "
3311 cmdStr += setName + " " + values
3312 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003313 try:
3314 # TODO: Maybe make this less hardcoded
3315 # ConsistentMap Exceptions
3316 assert "org.onosproject.store.service" not in output
3317 # Node not leader
3318 assert "java.lang.IllegalStateException" not in output
3319 except AssertionError:
3320 main.log.error( "Error in processing 'set-test-add' " +
3321 "command: " + str( output ) )
3322 retryTime = 30 # Conservative time, given by Madan
3323 main.log.info( "Waiting " + str( retryTime ) +
3324 "seconds before retrying." )
3325 time.sleep( retryTime ) # Due to change in mastership
3326 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003327 assert "Error executing command" not in output
3328 main.log.info( self.name + ": " + output )
3329
3330 if length == 0:
3331 match = re.search( pattern, output )
3332 else: # if given values
3333 if length == 1: # Contains output
3334 patternTrue = pattern + "\n" + containsTrue
3335 patternFalse = pattern + "\n" + containsFalse
3336 else: # ContainsAll output
3337 patternTrue = pattern + "\n" + containsAllTrue
3338 patternFalse = pattern + "\n" + containsAllFalse
3339 matchTrue = re.search( patternTrue, output )
3340 matchFalse = re.search( patternFalse, output )
3341 if matchTrue:
3342 containsCheck = main.TRUE
3343 match = matchTrue
3344 elif matchFalse:
3345 containsCheck = main.FALSE
3346 match = matchFalse
3347 else:
3348 main.log.error( self.name + " setTestGet did not match " +\
3349 "expected output" )
3350 main.log.debug( self.name + " expected: " + pattern )
3351 main.log.debug( self.name + " actual: " + repr( output ) )
3352 match = None
3353 if match:
3354 setMatch = match.group( 1 )
3355 if setMatch == '':
3356 setList = []
3357 else:
3358 setList = setMatch.split( ", " )
3359 if length > 0:
3360 return ( setList, containsCheck )
3361 else:
3362 return setList
3363 else: # no match
3364 main.log.error( self.name + ": setTestGet did not" +
3365 " match expected output" )
3366 main.log.debug( self.name + " expected: " + pattern )
3367 main.log.debug( self.name + " actual: " + repr( output ) )
3368 return main.ERROR
3369 except AssertionError:
3370 main.log.error( "Error in processing 'set-test-get' command: " +
3371 str( output ) )
3372 return main.ERROR
3373 except TypeError:
3374 main.log.exception( self.name + ": Object not as expected" )
3375 return main.ERROR
3376 except pexpect.EOF:
3377 main.log.error( self.name + ": EOF exception found" )
3378 main.log.error( self.name + ": " + self.handle.before )
3379 main.cleanup()
3380 main.exit()
3381 except Exception:
3382 main.log.exception( self.name + ": Uncaught exception!" )
3383 main.cleanup()
3384 main.exit()
3385
3386 def setTestSize( self, setName ):
3387 """
3388 CLI command to get the elements in a distributed set.
3389 Required arguments:
3390 setName - The name of the set to remove from.
3391 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003392 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003393 None on error
3394 """
3395 try:
3396 # TODO: Should this check against the number of elements returned
3397 # and then return true/false based on that?
3398 setName = str( setName ).strip()
3399 # Patterns to match
3400 setPattern = "\[(.*)\]"
3401 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3402 setPattern
3403 cmdStr = "set-test-get -s "
3404 cmdStr += setName
3405 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003406 try:
3407 # TODO: Maybe make this less hardcoded
3408 # ConsistentMap Exceptions
3409 assert "org.onosproject.store.service" not in output
3410 # Node not leader
3411 assert "java.lang.IllegalStateException" not in output
3412 except AssertionError:
3413 main.log.error( "Error in processing 'set-test-add' " +
3414 "command: " + str( output ) )
3415 retryTime = 30 # Conservative time, given by Madan
3416 main.log.info( "Waiting " + str( retryTime ) +
3417 "seconds before retrying." )
3418 time.sleep( retryTime ) # Due to change in mastership
3419 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003420 assert "Error executing command" not in output
3421 main.log.info( self.name + ": " + output )
3422 match = re.search( pattern, output )
3423 if match:
3424 setSize = int( match.group( 1 ) )
3425 setMatch = match.group( 2 )
3426 if len( setMatch.split() ) == setSize:
3427 main.log.info( "The size returned by " + self.name +
3428 " matches the number of elements in " +
3429 "the returned set" )
3430 else:
3431 main.log.error( "The size returned by " + self.name +
3432 " does not match the number of " +
3433 "elements in the returned set." )
3434 return setSize
3435 else: # no match
3436 main.log.error( self.name + ": setTestGet did not" +
3437 " match expected output" )
3438 main.log.debug( self.name + " expected: " + pattern )
3439 main.log.debug( self.name + " actual: " + repr( output ) )
3440 return None
3441 except AssertionError:
3442 main.log.error( "Error in processing 'set-test-get' command: " +
3443 str( output ) )
3444 return None
3445 except TypeError:
3446 main.log.exception( self.name + ": Object not as expected" )
3447 return None
3448 except pexpect.EOF:
3449 main.log.error( self.name + ": EOF exception found" )
3450 main.log.error( self.name + ": " + self.handle.before )
3451 main.cleanup()
3452 main.exit()
3453 except Exception:
3454 main.log.exception( self.name + ": Uncaught exception!" )
3455 main.cleanup()
3456 main.exit()
3457
3458 def counters( self ):
3459 """
3460 Command to list the various counters in the system.
3461 returns:
3462 A dict containing the counters in the system with the counter
3463 names being the keys and the value of the counters being the
3464 values OR
3465 None on error
3466 """
3467 #FIXME: JSON FORMAT
3468 try:
3469 counters = {}
3470 cmdStr = "counters"
3471 output = self.sendline( cmdStr )
3472 assert "Error executing command" not in output
3473 main.log.info( self.name + ": " + output )
3474 for line in output.splitlines():
3475 match = re.search( "name=(\S+) value=(\d+)", line )
3476 if match:
3477 key = match.group( 1 )
3478 value = int( match.group( 2 ) )
3479 counters[key] = value
3480 else:
3481 main.log.error( self.name + ": counters did not match " +
3482 "expected output" )
3483 main.log.debug( self.name + " expected: " + pattern )
3484 main.log.debug( self.name + " actual: " + repr( output ) )
3485 return None
3486 return counters
3487 except AssertionError:
3488 main.log.error( "Error in processing 'counters' command: " +
3489 str( output ) )
3490 return main.ERROR
3491 except TypeError:
3492 main.log.exception( self.name + ": Object not as expected" )
3493 return main.ERROR
3494 except pexpect.EOF:
3495 main.log.error( self.name + ": EOF exception found" )
3496 main.log.error( self.name + ": " + self.handle.before )
3497 main.cleanup()
3498 main.exit()
3499 except Exception:
3500 main.log.exception( self.name + ": Uncaught exception!" )
3501 main.cleanup()
3502 main.exit()
3503
3504 def counterTestIncrement( self, counter, inMemory=False ):
3505 """
3506 CLI command to increment and get a distributed counter.
3507 Required arguments:
3508 counter - The name of the counter to increment.
3509 Optional arguments:
3510 inMemory - use in memory map for the counter
3511 returns:
3512 integer value of the counter or
3513 None on Error
3514 """
3515 try:
3516 counter = str( counter )
3517 cmdStr = "counter-test-increment "
3518 if inMemory:
3519 cmdStr += "-i "
3520 cmdStr += counter
3521 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003522 try:
3523 # TODO: Maybe make this less hardcoded
3524 # ConsistentMap Exceptions
3525 assert "org.onosproject.store.service" not in output
3526 # Node not leader
3527 assert "java.lang.IllegalStateException" not in output
3528 except AssertionError:
3529 main.log.error( "Error in processing 'set-test-add' " +
3530 "command: " + str( output ) )
3531 retryTime = 30 # Conservative time, given by Madan
3532 main.log.info( "Waiting " + str( retryTime ) +
3533 "seconds before retrying." )
3534 time.sleep( retryTime ) # Due to change in mastership
3535 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003536 assert "Error executing command" not in output
3537 main.log.info( self.name + ": " + output )
3538 pattern = counter + " was incremented to (\d+)"
3539 match = re.search( pattern, output )
3540 if match:
3541 return int( match.group( 1 ) )
3542 else:
3543 main.log.error( self.name + ": counterTestIncrement did not" +
3544 " match expected output." )
3545 main.log.debug( self.name + " expected: " + pattern )
3546 main.log.debug( self.name + " actual: " + repr( output ) )
3547 return None
3548 except AssertionError:
3549 main.log.error( "Error in processing 'counter-test-increment'" +
3550 " command: " + str( output ) )
3551 return None
3552 except TypeError:
3553 main.log.exception( self.name + ": Object not as expected" )
3554 return None
3555 except pexpect.EOF:
3556 main.log.error( self.name + ": EOF exception found" )
3557 main.log.error( self.name + ": " + self.handle.before )
3558 main.cleanup()
3559 main.exit()
3560 except Exception:
3561 main.log.exception( self.name + ": Uncaught exception!" )
3562 main.cleanup()
3563 main.exit()
3564
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003565 def summary( self, jsonFormat=True ):
3566 """
3567 Description: Execute summary command in onos
3568 Returns: json object ( summary -j ), returns main.FALSE if there is
3569 no output
3570
3571 """
3572 try:
3573 cmdStr = "summary"
3574 if jsonFormat:
3575 cmdStr += " -j"
3576 handle = self.sendline( cmdStr )
3577
3578 if re.search( "Error:", handle ):
3579 main.log.error( self.name + ": summary() response: " +
3580 str( handle ) )
3581 if not handle:
3582 main.log.error( self.name + ": There is no output in " +
3583 "summary command" )
3584 return main.FALSE
3585 return handle
3586 except TypeError:
3587 main.log.exception( self.name + ": Object not as expected" )
3588 return None
3589 except pexpect.EOF:
3590 main.log.error( self.name + ": EOF exception found" )
3591 main.log.error( self.name + ": " + self.handle.before )
3592 main.cleanup()
3593 main.exit()
3594 except Exception:
3595 main.log.exception( self.name + ": Uncaught exception!" )
3596 main.cleanup()
3597 main.exit()