blob: c4e2e4238f87de37aec9e1c23124fe4e837be824 [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:
1753 main.log.info( self.name + " : " + intents.get( 'id' ) +
1754 " actual state = " + intents.get( 'state' )
1755 + " does not equal expected state = "
1756 + expectedState )
1757 returnValue = main.FALSE
1758 if returnValue == main.TRUE:
1759 main.log.info( self.name + ": All " +
1760 str( len( intentsDict ) ) +
1761 " intents are in " + expectedState + " state")
1762 return returnValue
1763 except TypeError:
1764 main.log.exception( self.name + ": Object not as expected" )
1765 return None
1766 except pexpect.EOF:
1767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
1769 main.cleanup()
1770 main.exit()
1771 except Exception:
1772 main.log.exception( self.name + ": Uncaught exception!" )
1773 main.cleanup()
1774 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001777 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001778 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001780 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001781 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001782 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001783 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001784 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001786 cmdStr += " -j"
1787 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001788 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001789 main.log.error( self.name + ".flows() response: " +
1790 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001791 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001792 except TypeError:
1793 main.log.exception( self.name + ": Object not as expected" )
1794 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001795 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001796 main.log.error( self.name + ": EOF exception found" )
1797 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001798 main.cleanup()
1799 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001800 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001801 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001802 main.cleanup()
1803 main.exit()
1804
kelvin-onlab4df89f22015-04-13 18:10:23 -07001805 def checkFlowsState( self ):
1806 """
1807 Description:
1808 Check the if all the current flows are in ADDED state or
1809 PENDING_ADD state
1810 Return:
1811 returnValue - Returns main.TRUE only if all flows are in
1812 ADDED state or PENDING_ADD, return main.FALSE
1813 otherwise.
1814 """
1815 try:
1816 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001817 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001818 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001819
kelvin-onlab4df89f22015-04-13 18:10:23 -07001820 for device in tempFlows:
1821 for flow in device.get( 'flows' ):
1822 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1823 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001824
kelvin-onlab4df89f22015-04-13 18:10:23 -07001825 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001826 str( flow.get( 'groupId' ) ) +
1827 " | state:" +
1828 str( flow.get( 'state' ) ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07001829 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001830
kelvin-onlab4df89f22015-04-13 18:10:23 -07001831 return returnValue
1832 except TypeError:
1833 main.log.exception( self.name + ": Object not as expected" )
1834 return None
1835 except pexpect.EOF:
1836 main.log.error( self.name + ": EOF exception found" )
1837 main.log.error( self.name + ": " + self.handle.before )
1838 main.cleanup()
1839 main.exit()
1840 except Exception:
1841 main.log.exception( self.name + ": Uncaught exception!" )
1842 main.cleanup()
1843 main.exit()
1844
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001846 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001847 """
andrewonlab87852b02014-11-19 18:44:19 -05001848 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001849 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001850 a specific point-to-point intent definition
1851 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001852 * dpidSrc: specify source dpid
1853 * dpidDst: specify destination dpid
1854 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001855 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001857 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001859 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001860 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001861 """
andrewonlab87852b02014-11-19 18:44:19 -05001862 try:
kelvin8ec71442015-01-15 16:57:00 -08001863 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001864 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1865 str( numIntents )
1866 if numMult:
1867 cmd += " " + str( numMult )
1868 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001869 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001870 if appId:
1871 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001872 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001873 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001874 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001875 main.log.info( handle )
1876 # Split result by newline
1877 newline = handle.split( "\r\r\n" )
1878 # Ignore the first object of list, which is empty
1879 newline = newline[ 1: ]
1880 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001881 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001882 result = result.split( ": " )
1883 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001884 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1885 main.log.info( latResult )
1886 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001887 else:
1888 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001889 except TypeError:
1890 main.log.exception( self.name + ": Object not as expected" )
1891 return None
andrewonlab87852b02014-11-19 18:44:19 -05001892 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001893 main.log.error( self.name + ": EOF exception found" )
1894 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001895 main.cleanup()
1896 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001897 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001898 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001899 main.cleanup()
1900 main.exit()
1901
kelvin-onlabd3b64892015-01-20 13:26:24 -08001902 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001903 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001904 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001905 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001906 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001907 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001908 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001909 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001910 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001911 cmdStr += " -j"
1912 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001913 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001914 except TypeError:
1915 main.log.exception( self.name + ": Object not as expected" )
1916 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001918 main.log.error( self.name + ": EOF exception found" )
1919 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001920 main.cleanup()
1921 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001922 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001923 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001924 main.cleanup()
1925 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001926
kelvin-onlabd3b64892015-01-20 13:26:24 -08001927 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001928 """
1929 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001930 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001931 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001932 """
andrewonlab867212a2014-10-22 20:13:38 -04001933 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001934 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001936 cmdStr += " -j"
1937 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001938 if handle:
1939 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001940 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001941 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001942 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001943 else:
1944 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001945 except TypeError:
1946 main.log.exception( self.name + ": Object not as expected" )
1947 return None
andrewonlab867212a2014-10-22 20:13:38 -04001948 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001949 main.log.error( self.name + ": EOF exception found" )
1950 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001951 main.cleanup()
1952 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001953 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001954 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001955 main.cleanup()
1956 main.exit()
1957
kelvin8ec71442015-01-15 16:57:00 -08001958 # Wrapper functions ****************
1959 # Wrapper functions use existing driver
1960 # functions and extends their use case.
1961 # For example, we may use the output of
1962 # a normal driver function, and parse it
1963 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001964
kelvin-onlabd3b64892015-01-20 13:26:24 -08001965 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001966 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001967 Description:
1968 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001969 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001970 try:
kelvin8ec71442015-01-15 16:57:00 -08001971 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001972 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001973 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001974
kelvin8ec71442015-01-15 16:57:00 -08001975 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001976 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1977 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001978 match = re.search('id=0x([\da-f]+),', intents)
1979 if match:
1980 tmpId = match.group()[3:-1]
1981 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001983
Jon Halld4d4b372015-01-28 16:02:41 -08001984 except TypeError:
1985 main.log.exception( self.name + ": Object not as expected" )
1986 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001988 main.log.error( self.name + ": EOF exception found" )
1989 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001990 main.cleanup()
1991 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001992 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001993 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001994 main.cleanup()
1995 main.exit()
1996
Jon Hall30b82fa2015-03-04 17:15:43 -08001997 def FlowAddedCount( self, deviceId ):
1998 """
1999 Determine the number of flow rules for the given device id that are
2000 in the added state
2001 """
2002 try:
2003 cmdStr = "flows any " + str( deviceId ) + " | " +\
2004 "grep 'state=ADDED' | wc -l"
2005 handle = self.sendline( cmdStr )
2006 return handle
2007 except pexpect.EOF:
2008 main.log.error( self.name + ": EOF exception found" )
2009 main.log.error( self.name + ": " + self.handle.before )
2010 main.cleanup()
2011 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002012 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002013 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002014 main.cleanup()
2015 main.exit()
2016
kelvin-onlabd3b64892015-01-20 13:26:24 -08002017 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002018 """
andrewonlab95ce8322014-10-13 14:12:04 -04002019 Use 'devices' function to obtain list of all devices
2020 and parse the result to obtain a list of all device
2021 id's. Returns this list. Returns empty list if no
2022 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002023 List is ordered sequentially
2024
andrewonlab95ce8322014-10-13 14:12:04 -04002025 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002026 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002027 the ids. By obtaining the list of device ids on the fly,
2028 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002029 """
andrewonlab95ce8322014-10-13 14:12:04 -04002030 try:
kelvin8ec71442015-01-15 16:57:00 -08002031 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002032 devicesStr = self.devices( jsonFormat=False )
2033 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002034
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002036 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002037 return idList
kelvin8ec71442015-01-15 16:57:00 -08002038
2039 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002040 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002041 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002042 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002043 # Split list further into arguments before and after string
2044 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002045 # append to idList
2046 for arg in tempList:
2047 idList.append( arg.split( "id=" )[ 1 ] )
2048 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002049
Jon Halld4d4b372015-01-28 16:02:41 -08002050 except TypeError:
2051 main.log.exception( self.name + ": Object not as expected" )
2052 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002056 main.cleanup()
2057 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002058 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002059 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002060 main.cleanup()
2061 main.exit()
2062
kelvin-onlabd3b64892015-01-20 13:26:24 -08002063 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002064 """
andrewonlab7c211572014-10-15 16:45:20 -04002065 Uses 'nodes' function to obtain list of all nodes
2066 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002067 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002068 Returns:
2069 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002070 """
andrewonlab7c211572014-10-15 16:45:20 -04002071 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002072 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002073 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002074 # Sample nodesStr output
2075 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002077 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002078 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002079 nodesJson = json.loads( nodesStr )
2080 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002081 return idList
kelvin8ec71442015-01-15 16:57:00 -08002082
Jon Halld4d4b372015-01-28 16:02:41 -08002083 except TypeError:
2084 main.log.exception( self.name + ": Object not as expected" )
2085 return None
andrewonlab7c211572014-10-15 16:45:20 -04002086 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002087 main.log.error( self.name + ": EOF exception found" )
2088 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002089 main.cleanup()
2090 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002091 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002092 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002093 main.cleanup()
2094 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002095
kelvin-onlabd3b64892015-01-20 13:26:24 -08002096 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002097 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002098 Return the first device from the devices api whose 'id' contains 'dpid'
2099 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002100 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002101 try:
kelvin8ec71442015-01-15 16:57:00 -08002102 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002103 return None
2104 else:
kelvin8ec71442015-01-15 16:57:00 -08002105 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002106 rawDevices = self.devices()
2107 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002108 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002109 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002110 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2111 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002112 return device
2113 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002114 except TypeError:
2115 main.log.exception( self.name + ": Object not as expected" )
2116 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002118 main.log.error( self.name + ": EOF exception found" )
2119 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002120 main.cleanup()
2121 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002122 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002123 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002124 main.cleanup()
2125 main.exit()
2126
kelvin-onlabd3b64892015-01-20 13:26:24 -08002127 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002128 """
Jon Hallefbd9792015-03-05 16:11:36 -08002129 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002130 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002131 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002132
Jon Hall42db6dc2014-10-24 19:03:48 -04002133 Params: ip = ip used for the onos cli
2134 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002135 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002136 logLevel = level to log to. Currently accepts
2137 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002138
2139
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002141
Jon Hallefbd9792015-03-05 16:11:36 -08002142 Returns: main.TRUE if the number of switches and links are correct,
2143 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002144 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002145 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002146 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002147 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002148 if topology == {}:
2149 return main.ERROR
2150 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002151 # Is the number of switches is what we expected
2152 devices = topology.get( 'devices', False )
2153 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002154 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002155 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002156 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002157 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002158 linkCheck = ( int( links ) == int( numolink ) )
2159 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002160 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002161 output += "The number of links and switches match " +\
2162 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002163 result = main.TRUE
2164 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002165 output += "The number of links and switches does not match " +\
2166 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002167 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002168 output = output + "\n ONOS sees %i devices (%i expected) \
2169 and %i links (%i expected)" % (
2170 int( devices ), int( numoswitch ), int( links ),
2171 int( numolink ) )
2172 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002173 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002175 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002176 else:
Jon Hall390696c2015-05-05 17:13:41 -07002177 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002178 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002179 except TypeError:
2180 main.log.exception( self.name + ": Object not as expected" )
2181 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002182 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002183 main.log.error( self.name + ": EOF exception found" )
2184 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002185 main.cleanup()
2186 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002188 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002189 main.cleanup()
2190 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002191
kelvin-onlabd3b64892015-01-20 13:26:24 -08002192 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002193 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002194 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 deviceId must be the id of a device as seen in the onos devices command
2196 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002197 role must be either master, standby, or none
2198
Jon Halle3f39ff2015-01-13 11:50:53 -08002199 Returns:
2200 main.TRUE or main.FALSE based on argument verification and
2201 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002202 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002203 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002204 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002205 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002206 cmdStr = "device-role " +\
2207 str( deviceId ) + " " +\
2208 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002209 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002210 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002211 if re.search( "Error", handle ):
2212 # end color output to escape any colours
2213 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002214 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002215 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002216 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002217 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002218 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002219 main.log.error( "Invalid 'role' given to device_role(). " +
2220 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002221 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002222 except TypeError:
2223 main.log.exception( self.name + ": Object not as expected" )
2224 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002225 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002226 main.log.error( self.name + ": EOF exception found" )
2227 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002228 main.cleanup()
2229 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002230 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002231 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002232 main.cleanup()
2233 main.exit()
2234
kelvin-onlabd3b64892015-01-20 13:26:24 -08002235 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002236 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002237 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002238 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002239 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002240 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002241 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002242 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002244 cmdStr += " -j"
2245 handle = self.sendline( cmdStr )
2246 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002247 except TypeError:
2248 main.log.exception( self.name + ": Object not as expected" )
2249 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002251 main.log.error( self.name + ": EOF exception found" )
2252 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002253 main.cleanup()
2254 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002255 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002256 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002257 main.cleanup()
2258 main.exit()
2259
kelvin-onlabd3b64892015-01-20 13:26:24 -08002260 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002261 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002262 CLI command to get the current leader for the Election test application
2263 NOTE: Requires installation of the onos-app-election feature
2264 Returns: Node IP of the leader if one exists
2265 None if none exists
2266 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002267 """
Jon Hall94fd0472014-12-08 11:52:42 -08002268 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002269 cmdStr = "election-test-leader"
2270 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002271 # Leader
2272 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002273 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002274 nodeSearch = re.search( leaderPattern, response )
2275 if nodeSearch:
2276 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002277 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002278 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002279 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002280 # no leader
2281 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002282 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 nullSearch = re.search( nullPattern, response )
2284 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002285 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002286 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002287 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002289 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002290 if re.search( errorPattern, response ):
2291 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002292 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002293 return main.FALSE
2294 else:
Jon Hall390696c2015-05-05 17:13:41 -07002295 main.log.error( "Error in electionTestLeader on " + self.name +
2296 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002297 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002298 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002299 except TypeError:
2300 main.log.exception( self.name + ": Object not as expected" )
2301 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002302 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002303 main.log.error( self.name + ": EOF exception found" )
2304 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002305 main.cleanup()
2306 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002307 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002308 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002309 main.cleanup()
2310 main.exit()
2311
kelvin-onlabd3b64892015-01-20 13:26:24 -08002312 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002313 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002314 CLI command to run for leadership of the Election test application.
2315 NOTE: Requires installation of the onos-app-election feature
2316 Returns: Main.TRUE on success
2317 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002318 """
Jon Hall94fd0472014-12-08 11:52:42 -08002319 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002320 cmdStr = "election-test-run"
2321 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002322 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002323 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002324 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002325 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002326 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002327 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002328 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002329 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002330 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002331 errorPattern = "Command\snot\sfound"
2332 if re.search( errorPattern, response ):
2333 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002334 return main.FALSE
2335 else:
Jon Hall390696c2015-05-05 17:13:41 -07002336 main.log.error( "Error in electionTestRun on " + self.name +
2337 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002338 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002339 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002340 except TypeError:
2341 main.log.exception( self.name + ": Object not as expected" )
2342 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002343 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002344 main.log.error( self.name + ": EOF exception found" )
2345 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002346 main.cleanup()
2347 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002348 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002349 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002350 main.cleanup()
2351 main.exit()
2352
kelvin-onlabd3b64892015-01-20 13:26:24 -08002353 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002354 """
Jon Hall94fd0472014-12-08 11:52:42 -08002355 * CLI command to withdraw the local node from leadership election for
2356 * the Election test application.
2357 #NOTE: Requires installation of the onos-app-election feature
2358 Returns: Main.TRUE on success
2359 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002360 """
Jon Hall94fd0472014-12-08 11:52:42 -08002361 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002362 cmdStr = "election-test-withdraw"
2363 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002364 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002365 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002366 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002367 if re.search( successPattern, response ):
2368 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002369 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002370 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002371 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002372 errorPattern = "Command\snot\sfound"
2373 if re.search( errorPattern, response ):
2374 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002375 return main.FALSE
2376 else:
Jon Hall390696c2015-05-05 17:13:41 -07002377 main.log.error( "Error in electionTestWithdraw on " +
2378 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002379 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002380 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002381 except TypeError:
2382 main.log.exception( self.name + ": Object not as expected" )
2383 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002384 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002385 main.log.error( self.name + ": EOF exception found" )
2386 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002387 main.cleanup()
2388 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002389 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002390 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002391 main.cleanup()
2392 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002393
kelvin8ec71442015-01-15 16:57:00 -08002394 def getDevicePortsEnabledCount( self, dpid ):
2395 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002396 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002397 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002398 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002399 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002400 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2401 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002402 if re.search( "No such device", output ):
2403 main.log.error( "Error in getting ports" )
2404 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002405 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002406 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002407 except TypeError:
2408 main.log.exception( self.name + ": Object not as expected" )
2409 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002410 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002411 main.log.error( self.name + ": EOF exception found" )
2412 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002413 main.cleanup()
2414 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002415 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002416 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002417 main.cleanup()
2418 main.exit()
2419
kelvin8ec71442015-01-15 16:57:00 -08002420 def getDeviceLinksActiveCount( self, dpid ):
2421 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002422 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002423 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002424 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002425 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002426 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2427 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002428 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002429 main.log.error( "Error in getting ports " )
2430 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002431 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002432 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002433 except TypeError:
2434 main.log.exception( self.name + ": Object not as expected" )
2435 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002436 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002437 main.log.error( self.name + ": EOF exception found" )
2438 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002439 main.cleanup()
2440 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002441 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002442 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002443 main.cleanup()
2444 main.exit()
2445
kelvin8ec71442015-01-15 16:57:00 -08002446 def getAllIntentIds( self ):
2447 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002448 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002449 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002450 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002451 cmdStr = "onos:intents | grep id="
2452 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002453 if re.search( "Error", output ):
2454 main.log.error( "Error in getting ports" )
2455 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002456 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002457 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002458 except TypeError:
2459 main.log.exception( self.name + ": Object not as expected" )
2460 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002461 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002462 main.log.error( self.name + ": EOF exception found" )
2463 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002464 main.cleanup()
2465 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002466 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002467 main.log.exception( self.name + ": Uncaught exception!" )
2468 main.cleanup()
2469 main.exit()
2470
Jon Hall73509952015-02-24 16:42:56 -08002471 def intentSummary( self ):
2472 """
Jon Hallefbd9792015-03-05 16:11:36 -08002473 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002474 """
2475 try:
2476 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002477 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002478 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002479 states.append( intent.get( 'state', None ) )
2480 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002481 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002482 return dict( out )
2483 except TypeError:
2484 main.log.exception( self.name + ": Object not as expected" )
2485 return None
2486 except pexpect.EOF:
2487 main.log.error( self.name + ": EOF exception found" )
2488 main.log.error( self.name + ": " + self.handle.before )
2489 main.cleanup()
2490 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002491 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002492 main.log.exception( self.name + ": Uncaught exception!" )
2493 main.cleanup()
2494 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002495
Jon Hall61282e32015-03-19 11:34:11 -07002496 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002497 """
2498 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002499 Optional argument:
2500 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002501 """
2502 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002503 # Sample JSON
2504 # {
2505 # "electedTime": "13m ago",
2506 # "epoch": 4,
2507 # "leader": "10.128.30.17",
2508 # "topic": "intent-partition-3"
2509 # },
Jon Hall63604932015-02-26 17:09:50 -08002510 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002511 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002512 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002513 cmdStr += " -j"
2514 output = self.sendline( cmdStr )
2515 return output
Jon Hall63604932015-02-26 17:09:50 -08002516 except TypeError:
2517 main.log.exception( self.name + ": Object not as expected" )
2518 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002519 except pexpect.EOF:
2520 main.log.error( self.name + ": EOF exception found" )
2521 main.log.error( self.name + ": " + self.handle.before )
2522 main.cleanup()
2523 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002524 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002525 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002526 main.cleanup()
2527 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002528
Jon Hall61282e32015-03-19 11:34:11 -07002529 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002530 """
2531 Returns the output of the intent Pending map.
2532 """
Jon Hall63604932015-02-26 17:09:50 -08002533 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002534 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002535 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002536 cmdStr += " -j"
2537 output = self.sendline( cmdStr )
2538 return output
Jon Hall63604932015-02-26 17:09:50 -08002539 except TypeError:
2540 main.log.exception( self.name + ": Object not as expected" )
2541 return None
2542 except pexpect.EOF:
2543 main.log.error( self.name + ": EOF exception found" )
2544 main.log.error( self.name + ": " + self.handle.before )
2545 main.cleanup()
2546 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002547 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002548 main.log.exception( self.name + ": Uncaught exception!" )
2549 main.cleanup()
2550 main.exit()
2551
Jon Hall61282e32015-03-19 11:34:11 -07002552 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002553 """
2554 Returns the output of the raft partitions command for ONOS.
2555 """
Jon Hall61282e32015-03-19 11:34:11 -07002556 # Sample JSON
2557 # {
2558 # "leader": "tcp://10.128.30.11:7238",
2559 # "members": [
2560 # "tcp://10.128.30.11:7238",
2561 # "tcp://10.128.30.17:7238",
2562 # "tcp://10.128.30.13:7238",
2563 # ],
2564 # "name": "p1",
2565 # "term": 3
2566 # },
Jon Hall63604932015-02-26 17:09:50 -08002567 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002568 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002569 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002570 cmdStr += " -j"
2571 output = self.sendline( cmdStr )
2572 return output
Jon Hall63604932015-02-26 17:09:50 -08002573 except TypeError:
2574 main.log.exception( self.name + ": Object not as expected" )
2575 return None
2576 except pexpect.EOF:
2577 main.log.error( self.name + ": EOF exception found" )
2578 main.log.error( self.name + ": " + self.handle.before )
2579 main.cleanup()
2580 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002581 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002582 main.log.exception( self.name + ": Uncaught exception!" )
2583 main.cleanup()
2584 main.exit()
2585
Jon Hallbe379602015-03-24 13:39:32 -07002586 def apps( self, jsonFormat=True ):
2587 """
2588 Returns the output of the apps command for ONOS. This command lists
2589 information about installed ONOS applications
2590 """
2591 # Sample JSON object
2592 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2593 # "description":"ONOS OpenFlow protocol southbound providers",
2594 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2595 # "features":"[onos-openflow]","state":"ACTIVE"}]
2596 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002597 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002598 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002599 cmdStr += " -j"
2600 output = self.sendline( cmdStr )
2601 assert "Error executing command" not in output
2602 return output
Jon Hallbe379602015-03-24 13:39:32 -07002603 # FIXME: look at specific exceptions/Errors
2604 except AssertionError:
2605 main.log.error( "Error in processing onos:app command: " +
2606 str( output ) )
2607 return None
2608 except TypeError:
2609 main.log.exception( self.name + ": Object not as expected" )
2610 return None
2611 except pexpect.EOF:
2612 main.log.error( self.name + ": EOF exception found" )
2613 main.log.error( self.name + ": " + self.handle.before )
2614 main.cleanup()
2615 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002616 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002617 main.log.exception( self.name + ": Uncaught exception!" )
2618 main.cleanup()
2619 main.exit()
2620
Jon Hall146f1522015-03-24 15:33:24 -07002621 def appStatus( self, appName ):
2622 """
2623 Uses the onos:apps cli command to return the status of an application.
2624 Returns:
2625 "ACTIVE" - If app is installed and activated
2626 "INSTALLED" - If app is installed and deactivated
2627 "UNINSTALLED" - If app is not installed
2628 None - on error
2629 """
Jon Hall146f1522015-03-24 15:33:24 -07002630 try:
2631 if not isinstance( appName, types.StringType ):
2632 main.log.error( self.name + ".appStatus(): appName must be" +
2633 " a string" )
2634 return None
2635 output = self.apps( jsonFormat=True )
2636 appsJson = json.loads( output )
2637 state = None
2638 for app in appsJson:
2639 if appName == app.get('name'):
2640 state = app.get('state')
2641 break
2642 if state == "ACTIVE" or state == "INSTALLED":
2643 return state
2644 elif state is None:
2645 return "UNINSTALLED"
2646 elif state:
2647 main.log.error( "Unexpected state from 'onos:apps': " +
2648 str( state ) )
2649 return state
2650 except TypeError:
2651 main.log.exception( self.name + ": Object not as expected" )
2652 return None
2653 except pexpect.EOF:
2654 main.log.error( self.name + ": EOF exception found" )
2655 main.log.error( self.name + ": " + self.handle.before )
2656 main.cleanup()
2657 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002658 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002659 main.log.exception( self.name + ": Uncaught exception!" )
2660 main.cleanup()
2661 main.exit()
2662
Jon Hallbe379602015-03-24 13:39:32 -07002663 def app( self, appName, option ):
2664 """
2665 Interacts with the app command for ONOS. This command manages
2666 application inventory.
2667 """
Jon Hallbe379602015-03-24 13:39:32 -07002668 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002669 # Validate argument types
2670 valid = True
2671 if not isinstance( appName, types.StringType ):
2672 main.log.error( self.name + ".app(): appName must be a " +
2673 "string" )
2674 valid = False
2675 if not isinstance( option, types.StringType ):
2676 main.log.error( self.name + ".app(): option must be a string" )
2677 valid = False
2678 if not valid:
2679 return main.FALSE
2680 # Validate Option
2681 option = option.lower()
2682 # NOTE: Install may become a valid option
2683 if option == "activate":
2684 pass
2685 elif option == "deactivate":
2686 pass
2687 elif option == "uninstall":
2688 pass
2689 else:
2690 # Invalid option
2691 main.log.error( "The ONOS app command argument only takes " +
2692 "the values: (activate|deactivate|uninstall)" +
2693 "; was given '" + option + "'")
2694 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002695 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002696 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002697 if "Error executing command" in output:
2698 main.log.error( "Error in processing onos:app command: " +
2699 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002700 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002701 elif "No such application" in output:
2702 main.log.error( "The application '" + appName +
2703 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002704 return main.FALSE
2705 elif "Command not found:" in output:
2706 main.log.error( "Error in processing onos:app command: " +
2707 str( output ) )
2708 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002709 elif "Unsupported command:" in output:
2710 main.log.error( "Incorrect command given to 'app': " +
2711 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002712 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002713 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002714 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002715 return main.TRUE
2716 except TypeError:
2717 main.log.exception( self.name + ": Object not as expected" )
2718 return main.ERROR
2719 except pexpect.EOF:
2720 main.log.error( self.name + ": EOF exception found" )
2721 main.log.error( self.name + ": " + self.handle.before )
2722 main.cleanup()
2723 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002724 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002725 main.log.exception( self.name + ": Uncaught exception!" )
2726 main.cleanup()
2727 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002728
Jon Hallbd16b922015-03-26 17:53:15 -07002729 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002730 """
2731 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002732 appName is the hierarchical app name, not the feature name
2733 If check is True, method will check the status of the app after the
2734 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002735 Returns main.TRUE if the command was successfully sent
2736 main.FALSE if the cli responded with an error or given
2737 incorrect input
2738 """
2739 try:
2740 if not isinstance( appName, types.StringType ):
2741 main.log.error( self.name + ".activateApp(): appName must be" +
2742 " a string" )
2743 return main.FALSE
2744 status = self.appStatus( appName )
2745 if status == "INSTALLED":
2746 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002747 if check and response == main.TRUE:
2748 for i in range(10): # try 10 times then give up
2749 # TODO: Check with Thomas about this delay
2750 status = self.appStatus( appName )
2751 if status == "ACTIVE":
2752 return main.TRUE
2753 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002754 main.log.debug( "The state of application " +
2755 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002756 time.sleep( 1 )
2757 return main.FALSE
2758 else: # not 'check' or command didn't succeed
2759 return response
Jon Hall146f1522015-03-24 15:33:24 -07002760 elif status == "ACTIVE":
2761 return main.TRUE
2762 elif status == "UNINSTALLED":
2763 main.log.error( self.name + ": Tried to activate the " +
2764 "application '" + appName + "' which is not " +
2765 "installed." )
2766 else:
2767 main.log.error( "Unexpected return value from appStatus: " +
2768 str( status ) )
2769 return main.ERROR
2770 except TypeError:
2771 main.log.exception( self.name + ": Object not as expected" )
2772 return main.ERROR
2773 except pexpect.EOF:
2774 main.log.error( self.name + ": EOF exception found" )
2775 main.log.error( self.name + ": " + self.handle.before )
2776 main.cleanup()
2777 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002778 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002779 main.log.exception( self.name + ": Uncaught exception!" )
2780 main.cleanup()
2781 main.exit()
2782
Jon Hallbd16b922015-03-26 17:53:15 -07002783 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002784 """
2785 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002786 appName is the hierarchical app name, not the feature name
2787 If check is True, method will check the status of the app after the
2788 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002789 Returns main.TRUE if the command was successfully sent
2790 main.FALSE if the cli responded with an error or given
2791 incorrect input
2792 """
2793 try:
2794 if not isinstance( appName, types.StringType ):
2795 main.log.error( self.name + ".deactivateApp(): appName must " +
2796 "be a string" )
2797 return main.FALSE
2798 status = self.appStatus( appName )
2799 if status == "INSTALLED":
2800 return main.TRUE
2801 elif status == "ACTIVE":
2802 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002803 if check and response == main.TRUE:
2804 for i in range(10): # try 10 times then give up
2805 status = self.appStatus( appName )
2806 if status == "INSTALLED":
2807 return main.TRUE
2808 else:
2809 time.sleep( 1 )
2810 return main.FALSE
2811 else: # not check or command didn't succeed
2812 return response
Jon Hall146f1522015-03-24 15:33:24 -07002813 elif status == "UNINSTALLED":
2814 main.log.warn( self.name + ": Tried to deactivate the " +
2815 "application '" + appName + "' which is not " +
2816 "installed." )
2817 return main.TRUE
2818 else:
2819 main.log.error( "Unexpected return value from appStatus: " +
2820 str( status ) )
2821 return main.ERROR
2822 except TypeError:
2823 main.log.exception( self.name + ": Object not as expected" )
2824 return main.ERROR
2825 except pexpect.EOF:
2826 main.log.error( self.name + ": EOF exception found" )
2827 main.log.error( self.name + ": " + self.handle.before )
2828 main.cleanup()
2829 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002830 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002831 main.log.exception( self.name + ": Uncaught exception!" )
2832 main.cleanup()
2833 main.exit()
2834
Jon Hallbd16b922015-03-26 17:53:15 -07002835 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002836 """
2837 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002838 appName is the hierarchical app name, not the feature name
2839 If check is True, method will check the status of the app after the
2840 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002841 Returns main.TRUE if the command was successfully sent
2842 main.FALSE if the cli responded with an error or given
2843 incorrect input
2844 """
2845 # TODO: check with Thomas about the state machine for apps
2846 try:
2847 if not isinstance( appName, types.StringType ):
2848 main.log.error( self.name + ".uninstallApp(): appName must " +
2849 "be a string" )
2850 return main.FALSE
2851 status = self.appStatus( appName )
2852 if status == "INSTALLED":
2853 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002854 if check and response == main.TRUE:
2855 for i in range(10): # try 10 times then give up
2856 status = self.appStatus( appName )
2857 if status == "UNINSTALLED":
2858 return main.TRUE
2859 else:
2860 time.sleep( 1 )
2861 return main.FALSE
2862 else: # not check or command didn't succeed
2863 return response
Jon Hall146f1522015-03-24 15:33:24 -07002864 elif status == "ACTIVE":
2865 main.log.warn( self.name + ": Tried to uninstall the " +
2866 "application '" + appName + "' which is " +
2867 "currently active." )
2868 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002869 if check and response == main.TRUE:
2870 for i in range(10): # try 10 times then give up
2871 status = self.appStatus( appName )
2872 if status == "UNINSTALLED":
2873 return main.TRUE
2874 else:
2875 time.sleep( 1 )
2876 return main.FALSE
2877 else: # not check or command didn't succeed
2878 return response
Jon Hall146f1522015-03-24 15:33:24 -07002879 elif status == "UNINSTALLED":
2880 return main.TRUE
2881 else:
2882 main.log.error( "Unexpected return value from appStatus: " +
2883 str( status ) )
2884 return main.ERROR
2885 except TypeError:
2886 main.log.exception( self.name + ": Object not as expected" )
2887 return main.ERROR
2888 except pexpect.EOF:
2889 main.log.error( self.name + ": EOF exception found" )
2890 main.log.error( self.name + ": " + self.handle.before )
2891 main.cleanup()
2892 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002893 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002894 main.log.exception( self.name + ": Uncaught exception!" )
2895 main.cleanup()
2896 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002897
2898 def appIDs( self, jsonFormat=True ):
2899 """
2900 Show the mappings between app id and app names given by the 'app-ids'
2901 cli command
2902 """
2903 try:
2904 cmdStr = "app-ids"
2905 if jsonFormat:
2906 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002907 output = self.sendline( cmdStr )
2908 assert "Error executing command" not in output
2909 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002910 except AssertionError:
2911 main.log.error( "Error in processing onos:app-ids command: " +
2912 str( output ) )
2913 return None
2914 except TypeError:
2915 main.log.exception( self.name + ": Object not as expected" )
2916 return None
2917 except pexpect.EOF:
2918 main.log.error( self.name + ": EOF exception found" )
2919 main.log.error( self.name + ": " + self.handle.before )
2920 main.cleanup()
2921 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002922 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002923 main.log.exception( self.name + ": Uncaught exception!" )
2924 main.cleanup()
2925 main.exit()
2926
2927 def appToIDCheck( self ):
2928 """
2929 This method will check that each application's ID listed in 'apps' is
2930 the same as the ID listed in 'app-ids'. The check will also check that
2931 there are no duplicate IDs issued. Note that an app ID should be
2932 a globaly unique numerical identifier for app/app-like features. Once
2933 an ID is registered, the ID is never freed up so that if an app is
2934 reinstalled it will have the same ID.
2935
2936 Returns: main.TRUE if the check passes and
2937 main.FALSE if the check fails or
2938 main.ERROR if there is some error in processing the test
2939 """
2940 try:
Jon Hall390696c2015-05-05 17:13:41 -07002941 bail = False
2942 ids = self.appIDs( jsonFormat=True )
2943 if ids:
2944 ids = json.loads( ids )
2945 else:
2946 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2947 bail = True
2948 apps = self.apps( jsonFormat=True )
2949 if apps:
2950 apps = json.loads( apps )
2951 else:
2952 main.log.error( "apps returned nothing:" + repr( apps ) )
2953 bail = True
2954 if bail:
2955 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002956 result = main.TRUE
2957 for app in apps:
2958 appID = app.get( 'id' )
2959 if appID is None:
2960 main.log.error( "Error parsing app: " + str( app ) )
2961 result = main.FALSE
2962 appName = app.get( 'name' )
2963 if appName is None:
2964 main.log.error( "Error parsing app: " + str( app ) )
2965 result = main.FALSE
2966 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07002967 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07002968 # main.log.debug( "Comparing " + str( app ) + " to " +
2969 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002970 if not current: # if ids doesn't have this id
2971 result = main.FALSE
2972 main.log.error( "'app-ids' does not have the ID for " +
2973 str( appName ) + " that apps does." )
2974 elif len( current ) > 1:
2975 # there is more than one app with this ID
2976 result = main.FALSE
2977 # We will log this later in the method
2978 elif not current[0][ 'name' ] == appName:
2979 currentName = current[0][ 'name' ]
2980 result = main.FALSE
2981 main.log.error( "'app-ids' has " + str( currentName ) +
2982 " registered under id:" + str( appID ) +
2983 " but 'apps' has " + str( appName ) )
2984 else:
2985 pass # id and name match!
2986 # now make sure that app-ids has no duplicates
2987 idsList = []
2988 namesList = []
2989 for item in ids:
2990 idsList.append( item[ 'id' ] )
2991 namesList.append( item[ 'name' ] )
2992 if len( idsList ) != len( set( idsList ) ) or\
2993 len( namesList ) != len( set( namesList ) ):
2994 main.log.error( "'app-ids' has some duplicate entries: \n"
2995 + json.dumps( ids,
2996 sort_keys=True,
2997 indent=4,
2998 separators=( ',', ': ' ) ) )
2999 result = main.FALSE
3000 return result
3001 except ( ValueError, TypeError ):
3002 main.log.exception( self.name + ": Object not as expected" )
3003 return main.ERROR
3004 except pexpect.EOF:
3005 main.log.error( self.name + ": EOF exception found" )
3006 main.log.error( self.name + ": " + self.handle.before )
3007 main.cleanup()
3008 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003009 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003010 main.log.exception( self.name + ": Uncaught exception!" )
3011 main.cleanup()
3012 main.exit()
3013
Jon Hallfb760a02015-04-13 15:35:03 -07003014 def getCfg( self, component=None, propName=None, short=False,
3015 jsonFormat=True ):
3016 """
3017 Get configuration settings from onos cli
3018 Optional arguments:
3019 component - Optionally only list configurations for a specific
3020 component. If None, all components with configurations
3021 are displayed. Case Sensitive string.
3022 propName - If component is specified, propName option will show
3023 only this specific configuration from that component.
3024 Case Sensitive string.
3025 jsonFormat - Returns output as json. Note that this will override
3026 the short option
3027 short - Short, less verbose, version of configurations.
3028 This is overridden by the json option
3029 returns:
3030 Output from cli as a string or None on error
3031 """
3032 try:
3033 baseStr = "cfg"
3034 cmdStr = " get"
3035 componentStr = ""
3036 if component:
3037 componentStr += " " + component
3038 if propName:
3039 componentStr += " " + propName
3040 if jsonFormat:
3041 baseStr += " -j"
3042 elif short:
3043 baseStr += " -s"
3044 output = self.sendline( baseStr + cmdStr + componentStr )
3045 assert "Error executing command" not in output
3046 return output
3047 except AssertionError:
3048 main.log.error( "Error in processing 'cfg get' command: " +
3049 str( output ) )
3050 return None
3051 except TypeError:
3052 main.log.exception( self.name + ": Object not as expected" )
3053 return None
3054 except pexpect.EOF:
3055 main.log.error( self.name + ": EOF exception found" )
3056 main.log.error( self.name + ": " + self.handle.before )
3057 main.cleanup()
3058 main.exit()
3059 except Exception:
3060 main.log.exception( self.name + ": Uncaught exception!" )
3061 main.cleanup()
3062 main.exit()
3063
3064 def setCfg( self, component, propName, value=None, check=True ):
3065 """
3066 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003067 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003068 component - The case sensitive name of the component whose
3069 property is to be set
3070 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003071 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003072 value - The value to set the property to. If None, will unset the
3073 property and revert it to it's default value(if applicable)
3074 check - Boolean, Check whether the option was successfully set this
3075 only applies when a value is given.
3076 returns:
3077 main.TRUE on success or main.FALSE on failure. If check is False,
3078 will return main.TRUE unless there is an error
3079 """
3080 try:
3081 baseStr = "cfg"
3082 cmdStr = " set " + str( component ) + " " + str( propName )
3083 if value is not None:
3084 cmdStr += " " + str( value )
3085 output = self.sendline( baseStr + cmdStr )
3086 assert "Error executing command" not in output
3087 if value and check:
3088 results = self.getCfg( component=str( component ),
3089 propName=str( propName ),
3090 jsonFormat=True )
3091 # Check if current value is what we just set
3092 try:
3093 jsonOutput = json.loads( results )
3094 current = jsonOutput[ 'value' ]
3095 except ( ValueError, TypeError ):
3096 main.log.exception( "Error parsing cfg output" )
3097 main.log.error( "output:" + repr( results ) )
3098 return main.FALSE
3099 if current == str( value ):
3100 return main.TRUE
3101 return main.FALSE
3102 return main.TRUE
3103 except AssertionError:
3104 main.log.error( "Error in processing 'cfg set' command: " +
3105 str( output ) )
3106 return main.FALSE
3107 except TypeError:
3108 main.log.exception( self.name + ": Object not as expected" )
3109 return main.FALSE
3110 except pexpect.EOF:
3111 main.log.error( self.name + ": EOF exception found" )
3112 main.log.error( self.name + ": " + self.handle.before )
3113 main.cleanup()
3114 main.exit()
3115 except Exception:
3116 main.log.exception( self.name + ": Uncaught exception!" )
3117 main.cleanup()
3118 main.exit()
3119
Jon Hall390696c2015-05-05 17:13:41 -07003120 def setTestAdd( self, setName, values ):
3121 """
3122 CLI command to add elements to a distributed set.
3123 Arguments:
3124 setName - The name of the set to add to.
3125 values - The value(s) to add to the set, space seperated.
3126 Example usages:
3127 setTestAdd( "set1", "a b c" )
3128 setTestAdd( "set2", "1" )
3129 returns:
3130 main.TRUE on success OR
3131 main.FALSE if elements were already in the set OR
3132 main.ERROR on error
3133 """
3134 try:
3135 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3136 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003137 try:
3138 # TODO: Maybe make this less hardcoded
3139 # ConsistentMap Exceptions
3140 assert "org.onosproject.store.service" not in output
3141 # Node not leader
3142 assert "java.lang.IllegalStateException" not in output
3143 except AssertionError:
3144 main.log.error( "Error in processing 'set-test-add' " +
3145 "command: " + str( output ) )
3146 retryTime = 30 # Conservative time, given by Madan
3147 main.log.info( "Waiting " + str( retryTime ) +
3148 "seconds before retrying." )
3149 time.sleep( retryTime ) # Due to change in mastership
3150 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003151 assert "Error executing command" not in output
3152 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3153 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3154 main.log.info( self.name + ": " + output )
3155 if re.search( positiveMatch, output):
3156 return main.TRUE
3157 elif re.search( negativeMatch, output):
3158 return main.FALSE
3159 else:
3160 main.log.error( self.name + ": setTestAdd did not" +
3161 " match expected output" )
3162 main.log.debug( self.name + " expected: " + pattern )
3163 main.log.debug( self.name + " actual: " + repr( output ) )
3164 return main.ERROR
3165 except AssertionError:
3166 main.log.error( "Error in processing 'set-test-add' command: " +
3167 str( output ) )
3168 return main.ERROR
3169 except TypeError:
3170 main.log.exception( self.name + ": Object not as expected" )
3171 return main.ERROR
3172 except pexpect.EOF:
3173 main.log.error( self.name + ": EOF exception found" )
3174 main.log.error( self.name + ": " + self.handle.before )
3175 main.cleanup()
3176 main.exit()
3177 except Exception:
3178 main.log.exception( self.name + ": Uncaught exception!" )
3179 main.cleanup()
3180 main.exit()
3181
3182 def setTestRemove( self, setName, values, clear=False, retain=False ):
3183 """
3184 CLI command to remove elements from a distributed set.
3185 Required arguments:
3186 setName - The name of the set to remove from.
3187 values - The value(s) to remove from the set, space seperated.
3188 Optional arguments:
3189 clear - Clear all elements from the set
3190 retain - Retain only the given values. (intersection of the
3191 original set and the given set)
3192 returns:
3193 main.TRUE on success OR
3194 main.FALSE if the set was not changed OR
3195 main.ERROR on error
3196 """
3197 try:
3198 cmdStr = "set-test-remove "
3199 if clear:
3200 cmdStr += "-c " + str( setName )
3201 elif retain:
3202 cmdStr += "-r " + str( setName ) + " " + str( values )
3203 else:
3204 cmdStr += str( setName ) + " " + str( values )
3205 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003206 try:
3207 # TODO: Maybe make this less hardcoded
3208 # ConsistentMap Exceptions
3209 assert "org.onosproject.store.service" not in output
3210 # Node not leader
3211 assert "java.lang.IllegalStateException" not in output
3212 except AssertionError:
3213 main.log.error( "Error in processing 'set-test-add' " +
3214 "command: " + str( output ) )
3215 retryTime = 30 # Conservative time, given by Madan
3216 main.log.info( "Waiting " + str( retryTime ) +
3217 "seconds before retrying." )
3218 time.sleep( retryTime ) # Due to change in mastership
3219 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003220 assert "Error executing command" not in output
3221 main.log.info( self.name + ": " + output )
3222 if clear:
3223 pattern = "Set " + str( setName ) + " cleared"
3224 if re.search( pattern, output ):
3225 return main.TRUE
3226 elif retain:
3227 positivePattern = str( setName ) + " was pruned to contain " +\
3228 "only elements of set \[(.*)\]"
3229 negativePattern = str( setName ) + " was not changed by " +\
3230 "retaining only elements of the set " +\
3231 "\[(.*)\]"
3232 if re.search( positivePattern, output ):
3233 return main.TRUE
3234 elif re.search( negativePattern, output ):
3235 return main.FALSE
3236 else:
3237 positivePattern = "\[(.*)\] was removed from the set " +\
3238 str( setName )
3239 if ( len( values.split() ) == 1 ):
3240 negativePattern = "\[(.*)\] was not in set " +\
3241 str( setName )
3242 else:
3243 negativePattern = "No element of \[(.*)\] was in set " +\
3244 str( setName )
3245 if re.search( positivePattern, output ):
3246 return main.TRUE
3247 elif re.search( negativePattern, output ):
3248 return main.FALSE
3249 main.log.error( self.name + ": setTestRemove did not" +
3250 " match expected output" )
3251 main.log.debug( self.name + " expected: " + pattern )
3252 main.log.debug( self.name + " actual: " + repr( output ) )
3253 return main.ERROR
3254 except AssertionError:
3255 main.log.error( "Error in processing 'set-test-remove' command: " +
3256 str( output ) )
3257 return main.ERROR
3258 except TypeError:
3259 main.log.exception( self.name + ": Object not as expected" )
3260 return main.ERROR
3261 except pexpect.EOF:
3262 main.log.error( self.name + ": EOF exception found" )
3263 main.log.error( self.name + ": " + self.handle.before )
3264 main.cleanup()
3265 main.exit()
3266 except Exception:
3267 main.log.exception( self.name + ": Uncaught exception!" )
3268 main.cleanup()
3269 main.exit()
3270
3271 def setTestGet( self, setName, values="" ):
3272 """
3273 CLI command to get the elements in a distributed set.
3274 Required arguments:
3275 setName - The name of the set to remove from.
3276 Optional arguments:
3277 values - The value(s) to check if in the set, space seperated.
3278 returns:
3279 main.ERROR on error OR
3280 A list of elements in the set if no optional arguments are
3281 supplied OR
3282 A tuple containing the list then:
3283 main.FALSE if the given values are not in the set OR
3284 main.TRUE if the given values are in the set OR
3285 """
3286 try:
3287 values = str( values ).strip()
3288 setName = str( setName ).strip()
3289 length = len( values.split() )
3290 containsCheck = None
3291 # Patterns to match
3292 setPattern = "\[(.*)\]"
3293 pattern = "Items in set " + setName + ":\n" + setPattern
3294 containsTrue = "Set " + setName + " contains the value " + values
3295 containsFalse = "Set " + setName + " did not contain the value " +\
3296 values
3297 containsAllTrue = "Set " + setName + " contains the the subset " +\
3298 setPattern
3299 containsAllFalse = "Set " + setName + " did not contain the the" +\
3300 " subset " + setPattern
3301
3302 cmdStr = "set-test-get "
3303 cmdStr += setName + " " + values
3304 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003305 try:
3306 # TODO: Maybe make this less hardcoded
3307 # ConsistentMap Exceptions
3308 assert "org.onosproject.store.service" not in output
3309 # Node not leader
3310 assert "java.lang.IllegalStateException" not in output
3311 except AssertionError:
3312 main.log.error( "Error in processing 'set-test-add' " +
3313 "command: " + str( output ) )
3314 retryTime = 30 # Conservative time, given by Madan
3315 main.log.info( "Waiting " + str( retryTime ) +
3316 "seconds before retrying." )
3317 time.sleep( retryTime ) # Due to change in mastership
3318 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003319 assert "Error executing command" not in output
3320 main.log.info( self.name + ": " + output )
3321
3322 if length == 0:
3323 match = re.search( pattern, output )
3324 else: # if given values
3325 if length == 1: # Contains output
3326 patternTrue = pattern + "\n" + containsTrue
3327 patternFalse = pattern + "\n" + containsFalse
3328 else: # ContainsAll output
3329 patternTrue = pattern + "\n" + containsAllTrue
3330 patternFalse = pattern + "\n" + containsAllFalse
3331 matchTrue = re.search( patternTrue, output )
3332 matchFalse = re.search( patternFalse, output )
3333 if matchTrue:
3334 containsCheck = main.TRUE
3335 match = matchTrue
3336 elif matchFalse:
3337 containsCheck = main.FALSE
3338 match = matchFalse
3339 else:
3340 main.log.error( self.name + " setTestGet did not match " +\
3341 "expected output" )
3342 main.log.debug( self.name + " expected: " + pattern )
3343 main.log.debug( self.name + " actual: " + repr( output ) )
3344 match = None
3345 if match:
3346 setMatch = match.group( 1 )
3347 if setMatch == '':
3348 setList = []
3349 else:
3350 setList = setMatch.split( ", " )
3351 if length > 0:
3352 return ( setList, containsCheck )
3353 else:
3354 return setList
3355 else: # no match
3356 main.log.error( self.name + ": setTestGet did not" +
3357 " match expected output" )
3358 main.log.debug( self.name + " expected: " + pattern )
3359 main.log.debug( self.name + " actual: " + repr( output ) )
3360 return main.ERROR
3361 except AssertionError:
3362 main.log.error( "Error in processing 'set-test-get' command: " +
3363 str( output ) )
3364 return main.ERROR
3365 except TypeError:
3366 main.log.exception( self.name + ": Object not as expected" )
3367 return main.ERROR
3368 except pexpect.EOF:
3369 main.log.error( self.name + ": EOF exception found" )
3370 main.log.error( self.name + ": " + self.handle.before )
3371 main.cleanup()
3372 main.exit()
3373 except Exception:
3374 main.log.exception( self.name + ": Uncaught exception!" )
3375 main.cleanup()
3376 main.exit()
3377
3378 def setTestSize( self, setName ):
3379 """
3380 CLI command to get the elements in a distributed set.
3381 Required arguments:
3382 setName - The name of the set to remove from.
3383 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003384 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003385 None on error
3386 """
3387 try:
3388 # TODO: Should this check against the number of elements returned
3389 # and then return true/false based on that?
3390 setName = str( setName ).strip()
3391 # Patterns to match
3392 setPattern = "\[(.*)\]"
3393 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3394 setPattern
3395 cmdStr = "set-test-get -s "
3396 cmdStr += setName
3397 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003398 try:
3399 # TODO: Maybe make this less hardcoded
3400 # ConsistentMap Exceptions
3401 assert "org.onosproject.store.service" not in output
3402 # Node not leader
3403 assert "java.lang.IllegalStateException" not in output
3404 except AssertionError:
3405 main.log.error( "Error in processing 'set-test-add' " +
3406 "command: " + str( output ) )
3407 retryTime = 30 # Conservative time, given by Madan
3408 main.log.info( "Waiting " + str( retryTime ) +
3409 "seconds before retrying." )
3410 time.sleep( retryTime ) # Due to change in mastership
3411 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003412 assert "Error executing command" not in output
3413 main.log.info( self.name + ": " + output )
3414 match = re.search( pattern, output )
3415 if match:
3416 setSize = int( match.group( 1 ) )
3417 setMatch = match.group( 2 )
3418 if len( setMatch.split() ) == setSize:
3419 main.log.info( "The size returned by " + self.name +
3420 " matches the number of elements in " +
3421 "the returned set" )
3422 else:
3423 main.log.error( "The size returned by " + self.name +
3424 " does not match the number of " +
3425 "elements in the returned set." )
3426 return setSize
3427 else: # no match
3428 main.log.error( self.name + ": setTestGet did not" +
3429 " match expected output" )
3430 main.log.debug( self.name + " expected: " + pattern )
3431 main.log.debug( self.name + " actual: " + repr( output ) )
3432 return None
3433 except AssertionError:
3434 main.log.error( "Error in processing 'set-test-get' command: " +
3435 str( output ) )
3436 return None
3437 except TypeError:
3438 main.log.exception( self.name + ": Object not as expected" )
3439 return None
3440 except pexpect.EOF:
3441 main.log.error( self.name + ": EOF exception found" )
3442 main.log.error( self.name + ": " + self.handle.before )
3443 main.cleanup()
3444 main.exit()
3445 except Exception:
3446 main.log.exception( self.name + ": Uncaught exception!" )
3447 main.cleanup()
3448 main.exit()
3449
3450 def counters( self ):
3451 """
3452 Command to list the various counters in the system.
3453 returns:
3454 A dict containing the counters in the system with the counter
3455 names being the keys and the value of the counters being the
3456 values OR
3457 None on error
3458 """
3459 #FIXME: JSON FORMAT
3460 try:
3461 counters = {}
3462 cmdStr = "counters"
3463 output = self.sendline( cmdStr )
3464 assert "Error executing command" not in output
3465 main.log.info( self.name + ": " + output )
3466 for line in output.splitlines():
3467 match = re.search( "name=(\S+) value=(\d+)", line )
3468 if match:
3469 key = match.group( 1 )
3470 value = int( match.group( 2 ) )
3471 counters[key] = value
3472 else:
3473 main.log.error( self.name + ": counters did not match " +
3474 "expected output" )
3475 main.log.debug( self.name + " expected: " + pattern )
3476 main.log.debug( self.name + " actual: " + repr( output ) )
3477 return None
3478 return counters
3479 except AssertionError:
3480 main.log.error( "Error in processing 'counters' command: " +
3481 str( output ) )
3482 return main.ERROR
3483 except TypeError:
3484 main.log.exception( self.name + ": Object not as expected" )
3485 return main.ERROR
3486 except pexpect.EOF:
3487 main.log.error( self.name + ": EOF exception found" )
3488 main.log.error( self.name + ": " + self.handle.before )
3489 main.cleanup()
3490 main.exit()
3491 except Exception:
3492 main.log.exception( self.name + ": Uncaught exception!" )
3493 main.cleanup()
3494 main.exit()
3495
3496 def counterTestIncrement( self, counter, inMemory=False ):
3497 """
3498 CLI command to increment and get a distributed counter.
3499 Required arguments:
3500 counter - The name of the counter to increment.
3501 Optional arguments:
3502 inMemory - use in memory map for the counter
3503 returns:
3504 integer value of the counter or
3505 None on Error
3506 """
3507 try:
3508 counter = str( counter )
3509 cmdStr = "counter-test-increment "
3510 if inMemory:
3511 cmdStr += "-i "
3512 cmdStr += counter
3513 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003514 try:
3515 # TODO: Maybe make this less hardcoded
3516 # ConsistentMap Exceptions
3517 assert "org.onosproject.store.service" not in output
3518 # Node not leader
3519 assert "java.lang.IllegalStateException" not in output
3520 except AssertionError:
3521 main.log.error( "Error in processing 'set-test-add' " +
3522 "command: " + str( output ) )
3523 retryTime = 30 # Conservative time, given by Madan
3524 main.log.info( "Waiting " + str( retryTime ) +
3525 "seconds before retrying." )
3526 time.sleep( retryTime ) # Due to change in mastership
3527 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003528 assert "Error executing command" not in output
3529 main.log.info( self.name + ": " + output )
3530 pattern = counter + " was incremented to (\d+)"
3531 match = re.search( pattern, output )
3532 if match:
3533 return int( match.group( 1 ) )
3534 else:
3535 main.log.error( self.name + ": counterTestIncrement did not" +
3536 " match expected output." )
3537 main.log.debug( self.name + " expected: " + pattern )
3538 main.log.debug( self.name + " actual: " + repr( output ) )
3539 return None
3540 except AssertionError:
3541 main.log.error( "Error in processing 'counter-test-increment'" +
3542 " command: " + str( output ) )
3543 return None
3544 except TypeError:
3545 main.log.exception( self.name + ": Object not as expected" )
3546 return None
3547 except pexpect.EOF:
3548 main.log.error( self.name + ": EOF exception found" )
3549 main.log.error( self.name + ": " + self.handle.before )
3550 main.cleanup()
3551 main.exit()
3552 except Exception:
3553 main.log.exception( self.name + ": Uncaught exception!" )
3554 main.cleanup()
3555 main.exit()
3556