blob: c7e25e064e46e84d91215219edc1623f8b3f30d4 [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() )
1817 returnValue = main.TRUE
1818 for device in tempFlows:
1819 for flow in device.get( 'flows' ):
1820 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1821 'PENDING_ADD':
1822 main.log.info( self.name + ": flow Id: " +
Jon Hallfeff3082015-05-19 10:23:26 -07001823 flow.get( 'id' ) +
kelvin-onlab4df89f22015-04-13 18:10:23 -07001824 " | state:" + flow.get( 'state' ) )
1825 returnValue = main.FALSE
1826 return returnValue
1827 except TypeError:
1828 main.log.exception( self.name + ": Object not as expected" )
1829 return None
1830 except pexpect.EOF:
1831 main.log.error( self.name + ": EOF exception found" )
1832 main.log.error( self.name + ": " + self.handle.before )
1833 main.cleanup()
1834 main.exit()
1835 except Exception:
1836 main.log.exception( self.name + ": Uncaught exception!" )
1837 main.cleanup()
1838 main.exit()
1839
kelvin-onlabd3b64892015-01-20 13:26:24 -08001840 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001841 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001842 """
andrewonlab87852b02014-11-19 18:44:19 -05001843 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001844 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001845 a specific point-to-point intent definition
1846 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 * dpidSrc: specify source dpid
1848 * dpidDst: specify destination dpid
1849 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001850 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001852 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001854 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001855 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001856 """
andrewonlab87852b02014-11-19 18:44:19 -05001857 try:
kelvin8ec71442015-01-15 16:57:00 -08001858 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001859 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1860 str( numIntents )
1861 if numMult:
1862 cmd += " " + str( numMult )
1863 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001864 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 if appId:
1866 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001867 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001868 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001869 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001870 main.log.info( handle )
1871 # Split result by newline
1872 newline = handle.split( "\r\r\n" )
1873 # Ignore the first object of list, which is empty
1874 newline = newline[ 1: ]
1875 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001876 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001877 result = result.split( ": " )
1878 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1880 main.log.info( latResult )
1881 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001882 else:
1883 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001884 except TypeError:
1885 main.log.exception( self.name + ": Object not as expected" )
1886 return None
andrewonlab87852b02014-11-19 18:44:19 -05001887 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001888 main.log.error( self.name + ": EOF exception found" )
1889 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001890 main.cleanup()
1891 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001892 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001893 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001894 main.cleanup()
1895 main.exit()
1896
kelvin-onlabd3b64892015-01-20 13:26:24 -08001897 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001898 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001899 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001900 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001901 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001902 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001903 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001904 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001905 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001906 cmdStr += " -j"
1907 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001908 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001909 except TypeError:
1910 main.log.exception( self.name + ": Object not as expected" )
1911 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001913 main.log.error( self.name + ": EOF exception found" )
1914 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001915 main.cleanup()
1916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001918 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001919 main.cleanup()
1920 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001921
kelvin-onlabd3b64892015-01-20 13:26:24 -08001922 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001923 """
1924 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001925 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001926 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001927 """
andrewonlab867212a2014-10-22 20:13:38 -04001928 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001929 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001930 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001931 cmdStr += " -j"
1932 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001933 if handle:
1934 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001935 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001936 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001937 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001938 else:
1939 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001940 except TypeError:
1941 main.log.exception( self.name + ": Object not as expected" )
1942 return None
andrewonlab867212a2014-10-22 20:13:38 -04001943 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001944 main.log.error( self.name + ": EOF exception found" )
1945 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001946 main.cleanup()
1947 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001949 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001950 main.cleanup()
1951 main.exit()
1952
kelvin8ec71442015-01-15 16:57:00 -08001953 # Wrapper functions ****************
1954 # Wrapper functions use existing driver
1955 # functions and extends their use case.
1956 # For example, we may use the output of
1957 # a normal driver function, and parse it
1958 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001959
kelvin-onlabd3b64892015-01-20 13:26:24 -08001960 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001961 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001962 Description:
1963 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001964 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001965 try:
kelvin8ec71442015-01-15 16:57:00 -08001966 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001967 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001968 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001969
kelvin8ec71442015-01-15 16:57:00 -08001970 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001971 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1972 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001973 match = re.search('id=0x([\da-f]+),', intents)
1974 if match:
1975 tmpId = match.group()[3:-1]
1976 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001977 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001978
Jon Halld4d4b372015-01-28 16:02:41 -08001979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001985 main.cleanup()
1986 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001987 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001988 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001989 main.cleanup()
1990 main.exit()
1991
Jon Hall30b82fa2015-03-04 17:15:43 -08001992 def FlowAddedCount( self, deviceId ):
1993 """
1994 Determine the number of flow rules for the given device id that are
1995 in the added state
1996 """
1997 try:
1998 cmdStr = "flows any " + str( deviceId ) + " | " +\
1999 "grep 'state=ADDED' | wc -l"
2000 handle = self.sendline( cmdStr )
2001 return handle
2002 except pexpect.EOF:
2003 main.log.error( self.name + ": EOF exception found" )
2004 main.log.error( self.name + ": " + self.handle.before )
2005 main.cleanup()
2006 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002007 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002008 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002009 main.cleanup()
2010 main.exit()
2011
kelvin-onlabd3b64892015-01-20 13:26:24 -08002012 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002013 """
andrewonlab95ce8322014-10-13 14:12:04 -04002014 Use 'devices' function to obtain list of all devices
2015 and parse the result to obtain a list of all device
2016 id's. Returns this list. Returns empty list if no
2017 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002018 List is ordered sequentially
2019
andrewonlab95ce8322014-10-13 14:12:04 -04002020 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002021 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002022 the ids. By obtaining the list of device ids on the fly,
2023 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002024 """
andrewonlab95ce8322014-10-13 14:12:04 -04002025 try:
kelvin8ec71442015-01-15 16:57:00 -08002026 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002027 devicesStr = self.devices( jsonFormat=False )
2028 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002029
kelvin-onlabd3b64892015-01-20 13:26:24 -08002030 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002031 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002032 return idList
kelvin8ec71442015-01-15 16:57:00 -08002033
2034 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002036 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002037 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002038 # Split list further into arguments before and after string
2039 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002040 # append to idList
2041 for arg in tempList:
2042 idList.append( arg.split( "id=" )[ 1 ] )
2043 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002044
Jon Halld4d4b372015-01-28 16:02:41 -08002045 except TypeError:
2046 main.log.exception( self.name + ": Object not as expected" )
2047 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002051 main.cleanup()
2052 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002054 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002055 main.cleanup()
2056 main.exit()
2057
kelvin-onlabd3b64892015-01-20 13:26:24 -08002058 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002059 """
andrewonlab7c211572014-10-15 16:45:20 -04002060 Uses 'nodes' function to obtain list of all nodes
2061 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002062 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002063 Returns:
2064 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002065 """
andrewonlab7c211572014-10-15 16:45:20 -04002066 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002067 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002068 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002069 # Sample nodesStr output
2070 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002072 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002073 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002074 nodesJson = json.loads( nodesStr )
2075 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 return idList
kelvin8ec71442015-01-15 16:57:00 -08002077
Jon Halld4d4b372015-01-28 16:02:41 -08002078 except TypeError:
2079 main.log.exception( self.name + ": Object not as expected" )
2080 return None
andrewonlab7c211572014-10-15 16:45:20 -04002081 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002082 main.log.error( self.name + ": EOF exception found" )
2083 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002084 main.cleanup()
2085 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002086 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002087 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002088 main.cleanup()
2089 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002090
kelvin-onlabd3b64892015-01-20 13:26:24 -08002091 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002092 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002093 Return the first device from the devices api whose 'id' contains 'dpid'
2094 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002095 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002096 try:
kelvin8ec71442015-01-15 16:57:00 -08002097 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002098 return None
2099 else:
kelvin8ec71442015-01-15 16:57:00 -08002100 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002101 rawDevices = self.devices()
2102 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002103 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002105 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2106 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002107 return device
2108 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002109 except TypeError:
2110 main.log.exception( self.name + ": Object not as expected" )
2111 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002115 main.cleanup()
2116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002117 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002118 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002119 main.cleanup()
2120 main.exit()
2121
kelvin-onlabd3b64892015-01-20 13:26:24 -08002122 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002123 """
Jon Hallefbd9792015-03-05 16:11:36 -08002124 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002125 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002126 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002127
Jon Hall42db6dc2014-10-24 19:03:48 -04002128 Params: ip = ip used for the onos cli
2129 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002130 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002131 logLevel = level to log to. Currently accepts
2132 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002133
2134
kelvin-onlabd3b64892015-01-20 13:26:24 -08002135 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002136
Jon Hallefbd9792015-03-05 16:11:36 -08002137 Returns: main.TRUE if the number of switches and links are correct,
2138 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002139 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002140 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002141 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002142 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002143 if topology == {}:
2144 return main.ERROR
2145 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002146 # Is the number of switches is what we expected
2147 devices = topology.get( 'devices', False )
2148 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002149 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002150 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002151 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002152 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002153 linkCheck = ( int( links ) == int( numolink ) )
2154 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002155 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002156 output += "The number of links and switches match " +\
2157 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002158 result = main.TRUE
2159 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002160 output += "The number of links and switches does not match " +\
2161 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002162 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002163 output = output + "\n ONOS sees %i devices (%i expected) \
2164 and %i links (%i expected)" % (
2165 int( devices ), int( numoswitch ), int( links ),
2166 int( numolink ) )
2167 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002168 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002169 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002170 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002171 else:
Jon Hall390696c2015-05-05 17:13:41 -07002172 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002173 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002174 except TypeError:
2175 main.log.exception( self.name + ": Object not as expected" )
2176 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002178 main.log.error( self.name + ": EOF exception found" )
2179 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002180 main.cleanup()
2181 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002182 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002183 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002184 main.cleanup()
2185 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002186
kelvin-onlabd3b64892015-01-20 13:26:24 -08002187 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002188 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002189 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 deviceId must be the id of a device as seen in the onos devices command
2191 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002192 role must be either master, standby, or none
2193
Jon Halle3f39ff2015-01-13 11:50:53 -08002194 Returns:
2195 main.TRUE or main.FALSE based on argument verification and
2196 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002197 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002198 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002199 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002200 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002201 cmdStr = "device-role " +\
2202 str( deviceId ) + " " +\
2203 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002204 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002205 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002206 if re.search( "Error", handle ):
2207 # end color output to escape any colours
2208 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002209 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002210 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002211 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002212 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002213 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002214 main.log.error( "Invalid 'role' given to device_role(). " +
2215 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002216 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002217 except TypeError:
2218 main.log.exception( self.name + ": Object not as expected" )
2219 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002220 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002221 main.log.error( self.name + ": EOF exception found" )
2222 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002223 main.cleanup()
2224 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002225 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002226 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002227 main.cleanup()
2228 main.exit()
2229
kelvin-onlabd3b64892015-01-20 13:26:24 -08002230 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002231 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002232 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002233 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002234 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002235 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002236 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002237 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002238 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002239 cmdStr += " -j"
2240 handle = self.sendline( cmdStr )
2241 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002242 except TypeError:
2243 main.log.exception( self.name + ": Object not as expected" )
2244 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002245 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002246 main.log.error( self.name + ": EOF exception found" )
2247 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002248 main.cleanup()
2249 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002250 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002251 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002252 main.cleanup()
2253 main.exit()
2254
kelvin-onlabd3b64892015-01-20 13:26:24 -08002255 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002256 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002257 CLI command to get the current leader for the Election test application
2258 NOTE: Requires installation of the onos-app-election feature
2259 Returns: Node IP of the leader if one exists
2260 None if none exists
2261 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002262 """
Jon Hall94fd0472014-12-08 11:52:42 -08002263 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002264 cmdStr = "election-test-leader"
2265 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002266 # Leader
2267 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002268 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002269 nodeSearch = re.search( leaderPattern, response )
2270 if nodeSearch:
2271 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002272 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002273 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002274 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002275 # no leader
2276 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002277 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002278 nullSearch = re.search( nullPattern, response )
2279 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002280 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002281 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002282 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002283 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002284 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002285 if re.search( errorPattern, response ):
2286 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002287 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002288 return main.FALSE
2289 else:
Jon Hall390696c2015-05-05 17:13:41 -07002290 main.log.error( "Error in electionTestLeader on " + self.name +
2291 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002292 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002293 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002294 except TypeError:
2295 main.log.exception( self.name + ": Object not as expected" )
2296 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002298 main.log.error( self.name + ": EOF exception found" )
2299 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002300 main.cleanup()
2301 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002303 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002304 main.cleanup()
2305 main.exit()
2306
kelvin-onlabd3b64892015-01-20 13:26:24 -08002307 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002308 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002309 CLI command to run for leadership of the Election test application.
2310 NOTE: Requires installation of the onos-app-election feature
2311 Returns: Main.TRUE on success
2312 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002313 """
Jon Hall94fd0472014-12-08 11:52:42 -08002314 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002315 cmdStr = "election-test-run"
2316 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002317 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002318 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002319 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002320 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002321 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002322 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002323 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002324 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002325 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002326 errorPattern = "Command\snot\sfound"
2327 if re.search( errorPattern, response ):
2328 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002329 return main.FALSE
2330 else:
Jon Hall390696c2015-05-05 17:13:41 -07002331 main.log.error( "Error in electionTestRun on " + self.name +
2332 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002333 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002334 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002335 except TypeError:
2336 main.log.exception( self.name + ": Object not as expected" )
2337 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002338 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002339 main.log.error( self.name + ": EOF exception found" )
2340 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002341 main.cleanup()
2342 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002343 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002344 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002345 main.cleanup()
2346 main.exit()
2347
kelvin-onlabd3b64892015-01-20 13:26:24 -08002348 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002349 """
Jon Hall94fd0472014-12-08 11:52:42 -08002350 * CLI command to withdraw the local node from leadership election for
2351 * the Election test application.
2352 #NOTE: Requires installation of the onos-app-election feature
2353 Returns: Main.TRUE on success
2354 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002355 """
Jon Hall94fd0472014-12-08 11:52:42 -08002356 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002357 cmdStr = "election-test-withdraw"
2358 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002359 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002360 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002361 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002362 if re.search( successPattern, response ):
2363 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002364 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002365 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002366 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002367 errorPattern = "Command\snot\sfound"
2368 if re.search( errorPattern, response ):
2369 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002370 return main.FALSE
2371 else:
Jon Hall390696c2015-05-05 17:13:41 -07002372 main.log.error( "Error in electionTestWithdraw on " +
2373 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002374 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002375 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002376 except TypeError:
2377 main.log.exception( self.name + ": Object not as expected" )
2378 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002379 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002380 main.log.error( self.name + ": EOF exception found" )
2381 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002382 main.cleanup()
2383 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002384 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002385 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002386 main.cleanup()
2387 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002388
kelvin8ec71442015-01-15 16:57:00 -08002389 def getDevicePortsEnabledCount( self, dpid ):
2390 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002391 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002392 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002393 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002394 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002395 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2396 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002397 if re.search( "No such device", output ):
2398 main.log.error( "Error in getting ports" )
2399 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002400 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002401 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002402 except TypeError:
2403 main.log.exception( self.name + ": Object not as expected" )
2404 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002405 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002406 main.log.error( self.name + ": EOF exception found" )
2407 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002408 main.cleanup()
2409 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002410 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002411 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002412 main.cleanup()
2413 main.exit()
2414
kelvin8ec71442015-01-15 16:57:00 -08002415 def getDeviceLinksActiveCount( self, dpid ):
2416 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002417 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002418 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002419 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002420 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002421 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2422 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002423 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002424 main.log.error( "Error in getting ports " )
2425 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002426 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002427 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002428 except TypeError:
2429 main.log.exception( self.name + ": Object not as expected" )
2430 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002431 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002432 main.log.error( self.name + ": EOF exception found" )
2433 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002434 main.cleanup()
2435 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002436 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002437 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002438 main.cleanup()
2439 main.exit()
2440
kelvin8ec71442015-01-15 16:57:00 -08002441 def getAllIntentIds( self ):
2442 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002443 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002444 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002445 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002446 cmdStr = "onos:intents | grep id="
2447 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002448 if re.search( "Error", output ):
2449 main.log.error( "Error in getting ports" )
2450 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002451 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002452 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002453 except TypeError:
2454 main.log.exception( self.name + ": Object not as expected" )
2455 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002456 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002457 main.log.error( self.name + ": EOF exception found" )
2458 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002459 main.cleanup()
2460 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002461 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002462 main.log.exception( self.name + ": Uncaught exception!" )
2463 main.cleanup()
2464 main.exit()
2465
Jon Hall73509952015-02-24 16:42:56 -08002466 def intentSummary( self ):
2467 """
Jon Hallefbd9792015-03-05 16:11:36 -08002468 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002469 """
2470 try:
2471 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002472 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002473 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002474 states.append( intent.get( 'state', None ) )
2475 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002476 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002477 return dict( out )
2478 except TypeError:
2479 main.log.exception( self.name + ": Object not as expected" )
2480 return None
2481 except pexpect.EOF:
2482 main.log.error( self.name + ": EOF exception found" )
2483 main.log.error( self.name + ": " + self.handle.before )
2484 main.cleanup()
2485 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002486 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002487 main.log.exception( self.name + ": Uncaught exception!" )
2488 main.cleanup()
2489 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002490
Jon Hall61282e32015-03-19 11:34:11 -07002491 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002492 """
2493 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002494 Optional argument:
2495 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002496 """
2497 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002498 # Sample JSON
2499 # {
2500 # "electedTime": "13m ago",
2501 # "epoch": 4,
2502 # "leader": "10.128.30.17",
2503 # "topic": "intent-partition-3"
2504 # },
Jon Hall63604932015-02-26 17:09:50 -08002505 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002506 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002507 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002508 cmdStr += " -j"
2509 output = self.sendline( cmdStr )
2510 return output
Jon Hall63604932015-02-26 17:09:50 -08002511 except TypeError:
2512 main.log.exception( self.name + ": Object not as expected" )
2513 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002514 except pexpect.EOF:
2515 main.log.error( self.name + ": EOF exception found" )
2516 main.log.error( self.name + ": " + self.handle.before )
2517 main.cleanup()
2518 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002519 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002520 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002521 main.cleanup()
2522 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002523
Jon Hall61282e32015-03-19 11:34:11 -07002524 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002525 """
2526 Returns the output of the intent Pending map.
2527 """
Jon Hall63604932015-02-26 17:09:50 -08002528 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002529 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002530 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002531 cmdStr += " -j"
2532 output = self.sendline( cmdStr )
2533 return output
Jon Hall63604932015-02-26 17:09:50 -08002534 except TypeError:
2535 main.log.exception( self.name + ": Object not as expected" )
2536 return None
2537 except pexpect.EOF:
2538 main.log.error( self.name + ": EOF exception found" )
2539 main.log.error( self.name + ": " + self.handle.before )
2540 main.cleanup()
2541 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002542 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002543 main.log.exception( self.name + ": Uncaught exception!" )
2544 main.cleanup()
2545 main.exit()
2546
Jon Hall61282e32015-03-19 11:34:11 -07002547 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002548 """
2549 Returns the output of the raft partitions command for ONOS.
2550 """
Jon Hall61282e32015-03-19 11:34:11 -07002551 # Sample JSON
2552 # {
2553 # "leader": "tcp://10.128.30.11:7238",
2554 # "members": [
2555 # "tcp://10.128.30.11:7238",
2556 # "tcp://10.128.30.17:7238",
2557 # "tcp://10.128.30.13:7238",
2558 # ],
2559 # "name": "p1",
2560 # "term": 3
2561 # },
Jon Hall63604932015-02-26 17:09:50 -08002562 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002563 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002564 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002565 cmdStr += " -j"
2566 output = self.sendline( cmdStr )
2567 return output
Jon Hall63604932015-02-26 17:09:50 -08002568 except TypeError:
2569 main.log.exception( self.name + ": Object not as expected" )
2570 return None
2571 except pexpect.EOF:
2572 main.log.error( self.name + ": EOF exception found" )
2573 main.log.error( self.name + ": " + self.handle.before )
2574 main.cleanup()
2575 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002576 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002577 main.log.exception( self.name + ": Uncaught exception!" )
2578 main.cleanup()
2579 main.exit()
2580
Jon Hallbe379602015-03-24 13:39:32 -07002581 def apps( self, jsonFormat=True ):
2582 """
2583 Returns the output of the apps command for ONOS. This command lists
2584 information about installed ONOS applications
2585 """
2586 # Sample JSON object
2587 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2588 # "description":"ONOS OpenFlow protocol southbound providers",
2589 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2590 # "features":"[onos-openflow]","state":"ACTIVE"}]
2591 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002592 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002593 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002594 cmdStr += " -j"
2595 output = self.sendline( cmdStr )
2596 assert "Error executing command" not in output
2597 return output
Jon Hallbe379602015-03-24 13:39:32 -07002598 # FIXME: look at specific exceptions/Errors
2599 except AssertionError:
2600 main.log.error( "Error in processing onos:app command: " +
2601 str( output ) )
2602 return None
2603 except TypeError:
2604 main.log.exception( self.name + ": Object not as expected" )
2605 return None
2606 except pexpect.EOF:
2607 main.log.error( self.name + ": EOF exception found" )
2608 main.log.error( self.name + ": " + self.handle.before )
2609 main.cleanup()
2610 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002611 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002612 main.log.exception( self.name + ": Uncaught exception!" )
2613 main.cleanup()
2614 main.exit()
2615
Jon Hall146f1522015-03-24 15:33:24 -07002616 def appStatus( self, appName ):
2617 """
2618 Uses the onos:apps cli command to return the status of an application.
2619 Returns:
2620 "ACTIVE" - If app is installed and activated
2621 "INSTALLED" - If app is installed and deactivated
2622 "UNINSTALLED" - If app is not installed
2623 None - on error
2624 """
Jon Hall146f1522015-03-24 15:33:24 -07002625 try:
2626 if not isinstance( appName, types.StringType ):
2627 main.log.error( self.name + ".appStatus(): appName must be" +
2628 " a string" )
2629 return None
2630 output = self.apps( jsonFormat=True )
2631 appsJson = json.loads( output )
2632 state = None
2633 for app in appsJson:
2634 if appName == app.get('name'):
2635 state = app.get('state')
2636 break
2637 if state == "ACTIVE" or state == "INSTALLED":
2638 return state
2639 elif state is None:
2640 return "UNINSTALLED"
2641 elif state:
2642 main.log.error( "Unexpected state from 'onos:apps': " +
2643 str( state ) )
2644 return state
2645 except TypeError:
2646 main.log.exception( self.name + ": Object not as expected" )
2647 return None
2648 except pexpect.EOF:
2649 main.log.error( self.name + ": EOF exception found" )
2650 main.log.error( self.name + ": " + self.handle.before )
2651 main.cleanup()
2652 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002653 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002654 main.log.exception( self.name + ": Uncaught exception!" )
2655 main.cleanup()
2656 main.exit()
2657
Jon Hallbe379602015-03-24 13:39:32 -07002658 def app( self, appName, option ):
2659 """
2660 Interacts with the app command for ONOS. This command manages
2661 application inventory.
2662 """
Jon Hallbe379602015-03-24 13:39:32 -07002663 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002664 # Validate argument types
2665 valid = True
2666 if not isinstance( appName, types.StringType ):
2667 main.log.error( self.name + ".app(): appName must be a " +
2668 "string" )
2669 valid = False
2670 if not isinstance( option, types.StringType ):
2671 main.log.error( self.name + ".app(): option must be a string" )
2672 valid = False
2673 if not valid:
2674 return main.FALSE
2675 # Validate Option
2676 option = option.lower()
2677 # NOTE: Install may become a valid option
2678 if option == "activate":
2679 pass
2680 elif option == "deactivate":
2681 pass
2682 elif option == "uninstall":
2683 pass
2684 else:
2685 # Invalid option
2686 main.log.error( "The ONOS app command argument only takes " +
2687 "the values: (activate|deactivate|uninstall)" +
2688 "; was given '" + option + "'")
2689 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002690 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002691 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002692 if "Error executing command" in output:
2693 main.log.error( "Error in processing onos:app command: " +
2694 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002695 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002696 elif "No such application" in output:
2697 main.log.error( "The application '" + appName +
2698 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002699 return main.FALSE
2700 elif "Command not found:" in output:
2701 main.log.error( "Error in processing onos:app command: " +
2702 str( output ) )
2703 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002704 elif "Unsupported command:" in output:
2705 main.log.error( "Incorrect command given to 'app': " +
2706 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002707 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002708 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002709 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002710 return main.TRUE
2711 except TypeError:
2712 main.log.exception( self.name + ": Object not as expected" )
2713 return main.ERROR
2714 except pexpect.EOF:
2715 main.log.error( self.name + ": EOF exception found" )
2716 main.log.error( self.name + ": " + self.handle.before )
2717 main.cleanup()
2718 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002719 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002720 main.log.exception( self.name + ": Uncaught exception!" )
2721 main.cleanup()
2722 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002723
Jon Hallbd16b922015-03-26 17:53:15 -07002724 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002725 """
2726 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002727 appName is the hierarchical app name, not the feature name
2728 If check is True, method will check the status of the app after the
2729 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002730 Returns main.TRUE if the command was successfully sent
2731 main.FALSE if the cli responded with an error or given
2732 incorrect input
2733 """
2734 try:
2735 if not isinstance( appName, types.StringType ):
2736 main.log.error( self.name + ".activateApp(): appName must be" +
2737 " a string" )
2738 return main.FALSE
2739 status = self.appStatus( appName )
2740 if status == "INSTALLED":
2741 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002742 if check and response == main.TRUE:
2743 for i in range(10): # try 10 times then give up
2744 # TODO: Check with Thomas about this delay
2745 status = self.appStatus( appName )
2746 if status == "ACTIVE":
2747 return main.TRUE
2748 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002749 main.log.debug( "The state of application " +
2750 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002751 time.sleep( 1 )
2752 return main.FALSE
2753 else: # not 'check' or command didn't succeed
2754 return response
Jon Hall146f1522015-03-24 15:33:24 -07002755 elif status == "ACTIVE":
2756 return main.TRUE
2757 elif status == "UNINSTALLED":
2758 main.log.error( self.name + ": Tried to activate the " +
2759 "application '" + appName + "' which is not " +
2760 "installed." )
2761 else:
2762 main.log.error( "Unexpected return value from appStatus: " +
2763 str( status ) )
2764 return main.ERROR
2765 except TypeError:
2766 main.log.exception( self.name + ": Object not as expected" )
2767 return main.ERROR
2768 except pexpect.EOF:
2769 main.log.error( self.name + ": EOF exception found" )
2770 main.log.error( self.name + ": " + self.handle.before )
2771 main.cleanup()
2772 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002773 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002774 main.log.exception( self.name + ": Uncaught exception!" )
2775 main.cleanup()
2776 main.exit()
2777
Jon Hallbd16b922015-03-26 17:53:15 -07002778 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002779 """
2780 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002781 appName is the hierarchical app name, not the feature name
2782 If check is True, method will check the status of the app after the
2783 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002784 Returns main.TRUE if the command was successfully sent
2785 main.FALSE if the cli responded with an error or given
2786 incorrect input
2787 """
2788 try:
2789 if not isinstance( appName, types.StringType ):
2790 main.log.error( self.name + ".deactivateApp(): appName must " +
2791 "be a string" )
2792 return main.FALSE
2793 status = self.appStatus( appName )
2794 if status == "INSTALLED":
2795 return main.TRUE
2796 elif status == "ACTIVE":
2797 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002798 if check and response == main.TRUE:
2799 for i in range(10): # try 10 times then give up
2800 status = self.appStatus( appName )
2801 if status == "INSTALLED":
2802 return main.TRUE
2803 else:
2804 time.sleep( 1 )
2805 return main.FALSE
2806 else: # not check or command didn't succeed
2807 return response
Jon Hall146f1522015-03-24 15:33:24 -07002808 elif status == "UNINSTALLED":
2809 main.log.warn( self.name + ": Tried to deactivate the " +
2810 "application '" + appName + "' which is not " +
2811 "installed." )
2812 return main.TRUE
2813 else:
2814 main.log.error( "Unexpected return value from appStatus: " +
2815 str( status ) )
2816 return main.ERROR
2817 except TypeError:
2818 main.log.exception( self.name + ": Object not as expected" )
2819 return main.ERROR
2820 except pexpect.EOF:
2821 main.log.error( self.name + ": EOF exception found" )
2822 main.log.error( self.name + ": " + self.handle.before )
2823 main.cleanup()
2824 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002825 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002826 main.log.exception( self.name + ": Uncaught exception!" )
2827 main.cleanup()
2828 main.exit()
2829
Jon Hallbd16b922015-03-26 17:53:15 -07002830 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002831 """
2832 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002833 appName is the hierarchical app name, not the feature name
2834 If check is True, method will check the status of the app after the
2835 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002836 Returns main.TRUE if the command was successfully sent
2837 main.FALSE if the cli responded with an error or given
2838 incorrect input
2839 """
2840 # TODO: check with Thomas about the state machine for apps
2841 try:
2842 if not isinstance( appName, types.StringType ):
2843 main.log.error( self.name + ".uninstallApp(): appName must " +
2844 "be a string" )
2845 return main.FALSE
2846 status = self.appStatus( appName )
2847 if status == "INSTALLED":
2848 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002849 if check and response == main.TRUE:
2850 for i in range(10): # try 10 times then give up
2851 status = self.appStatus( appName )
2852 if status == "UNINSTALLED":
2853 return main.TRUE
2854 else:
2855 time.sleep( 1 )
2856 return main.FALSE
2857 else: # not check or command didn't succeed
2858 return response
Jon Hall146f1522015-03-24 15:33:24 -07002859 elif status == "ACTIVE":
2860 main.log.warn( self.name + ": Tried to uninstall the " +
2861 "application '" + appName + "' which is " +
2862 "currently active." )
2863 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002864 if check and response == main.TRUE:
2865 for i in range(10): # try 10 times then give up
2866 status = self.appStatus( appName )
2867 if status == "UNINSTALLED":
2868 return main.TRUE
2869 else:
2870 time.sleep( 1 )
2871 return main.FALSE
2872 else: # not check or command didn't succeed
2873 return response
Jon Hall146f1522015-03-24 15:33:24 -07002874 elif status == "UNINSTALLED":
2875 return main.TRUE
2876 else:
2877 main.log.error( "Unexpected return value from appStatus: " +
2878 str( status ) )
2879 return main.ERROR
2880 except TypeError:
2881 main.log.exception( self.name + ": Object not as expected" )
2882 return main.ERROR
2883 except pexpect.EOF:
2884 main.log.error( self.name + ": EOF exception found" )
2885 main.log.error( self.name + ": " + self.handle.before )
2886 main.cleanup()
2887 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002888 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002889 main.log.exception( self.name + ": Uncaught exception!" )
2890 main.cleanup()
2891 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002892
2893 def appIDs( self, jsonFormat=True ):
2894 """
2895 Show the mappings between app id and app names given by the 'app-ids'
2896 cli command
2897 """
2898 try:
2899 cmdStr = "app-ids"
2900 if jsonFormat:
2901 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002902 output = self.sendline( cmdStr )
2903 assert "Error executing command" not in output
2904 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002905 except AssertionError:
2906 main.log.error( "Error in processing onos:app-ids command: " +
2907 str( output ) )
2908 return None
2909 except TypeError:
2910 main.log.exception( self.name + ": Object not as expected" )
2911 return None
2912 except pexpect.EOF:
2913 main.log.error( self.name + ": EOF exception found" )
2914 main.log.error( self.name + ": " + self.handle.before )
2915 main.cleanup()
2916 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002917 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002918 main.log.exception( self.name + ": Uncaught exception!" )
2919 main.cleanup()
2920 main.exit()
2921
2922 def appToIDCheck( self ):
2923 """
2924 This method will check that each application's ID listed in 'apps' is
2925 the same as the ID listed in 'app-ids'. The check will also check that
2926 there are no duplicate IDs issued. Note that an app ID should be
2927 a globaly unique numerical identifier for app/app-like features. Once
2928 an ID is registered, the ID is never freed up so that if an app is
2929 reinstalled it will have the same ID.
2930
2931 Returns: main.TRUE if the check passes and
2932 main.FALSE if the check fails or
2933 main.ERROR if there is some error in processing the test
2934 """
2935 try:
Jon Hall390696c2015-05-05 17:13:41 -07002936 bail = False
2937 ids = self.appIDs( jsonFormat=True )
2938 if ids:
2939 ids = json.loads( ids )
2940 else:
2941 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2942 bail = True
2943 apps = self.apps( jsonFormat=True )
2944 if apps:
2945 apps = json.loads( apps )
2946 else:
2947 main.log.error( "apps returned nothing:" + repr( apps ) )
2948 bail = True
2949 if bail:
2950 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002951 result = main.TRUE
2952 for app in apps:
2953 appID = app.get( 'id' )
2954 if appID is None:
2955 main.log.error( "Error parsing app: " + str( app ) )
2956 result = main.FALSE
2957 appName = app.get( 'name' )
2958 if appName is None:
2959 main.log.error( "Error parsing app: " + str( app ) )
2960 result = main.FALSE
2961 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07002962 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07002963 # main.log.debug( "Comparing " + str( app ) + " to " +
2964 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002965 if not current: # if ids doesn't have this id
2966 result = main.FALSE
2967 main.log.error( "'app-ids' does not have the ID for " +
2968 str( appName ) + " that apps does." )
2969 elif len( current ) > 1:
2970 # there is more than one app with this ID
2971 result = main.FALSE
2972 # We will log this later in the method
2973 elif not current[0][ 'name' ] == appName:
2974 currentName = current[0][ 'name' ]
2975 result = main.FALSE
2976 main.log.error( "'app-ids' has " + str( currentName ) +
2977 " registered under id:" + str( appID ) +
2978 " but 'apps' has " + str( appName ) )
2979 else:
2980 pass # id and name match!
2981 # now make sure that app-ids has no duplicates
2982 idsList = []
2983 namesList = []
2984 for item in ids:
2985 idsList.append( item[ 'id' ] )
2986 namesList.append( item[ 'name' ] )
2987 if len( idsList ) != len( set( idsList ) ) or\
2988 len( namesList ) != len( set( namesList ) ):
2989 main.log.error( "'app-ids' has some duplicate entries: \n"
2990 + json.dumps( ids,
2991 sort_keys=True,
2992 indent=4,
2993 separators=( ',', ': ' ) ) )
2994 result = main.FALSE
2995 return result
2996 except ( ValueError, TypeError ):
2997 main.log.exception( self.name + ": Object not as expected" )
2998 return main.ERROR
2999 except pexpect.EOF:
3000 main.log.error( self.name + ": EOF exception found" )
3001 main.log.error( self.name + ": " + self.handle.before )
3002 main.cleanup()
3003 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003004 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003005 main.log.exception( self.name + ": Uncaught exception!" )
3006 main.cleanup()
3007 main.exit()
3008
Jon Hallfb760a02015-04-13 15:35:03 -07003009 def getCfg( self, component=None, propName=None, short=False,
3010 jsonFormat=True ):
3011 """
3012 Get configuration settings from onos cli
3013 Optional arguments:
3014 component - Optionally only list configurations for a specific
3015 component. If None, all components with configurations
3016 are displayed. Case Sensitive string.
3017 propName - If component is specified, propName option will show
3018 only this specific configuration from that component.
3019 Case Sensitive string.
3020 jsonFormat - Returns output as json. Note that this will override
3021 the short option
3022 short - Short, less verbose, version of configurations.
3023 This is overridden by the json option
3024 returns:
3025 Output from cli as a string or None on error
3026 """
3027 try:
3028 baseStr = "cfg"
3029 cmdStr = " get"
3030 componentStr = ""
3031 if component:
3032 componentStr += " " + component
3033 if propName:
3034 componentStr += " " + propName
3035 if jsonFormat:
3036 baseStr += " -j"
3037 elif short:
3038 baseStr += " -s"
3039 output = self.sendline( baseStr + cmdStr + componentStr )
3040 assert "Error executing command" not in output
3041 return output
3042 except AssertionError:
3043 main.log.error( "Error in processing 'cfg get' command: " +
3044 str( output ) )
3045 return None
3046 except TypeError:
3047 main.log.exception( self.name + ": Object not as expected" )
3048 return None
3049 except pexpect.EOF:
3050 main.log.error( self.name + ": EOF exception found" )
3051 main.log.error( self.name + ": " + self.handle.before )
3052 main.cleanup()
3053 main.exit()
3054 except Exception:
3055 main.log.exception( self.name + ": Uncaught exception!" )
3056 main.cleanup()
3057 main.exit()
3058
3059 def setCfg( self, component, propName, value=None, check=True ):
3060 """
3061 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003062 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003063 component - The case sensitive name of the component whose
3064 property is to be set
3065 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003066 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003067 value - The value to set the property to. If None, will unset the
3068 property and revert it to it's default value(if applicable)
3069 check - Boolean, Check whether the option was successfully set this
3070 only applies when a value is given.
3071 returns:
3072 main.TRUE on success or main.FALSE on failure. If check is False,
3073 will return main.TRUE unless there is an error
3074 """
3075 try:
3076 baseStr = "cfg"
3077 cmdStr = " set " + str( component ) + " " + str( propName )
3078 if value is not None:
3079 cmdStr += " " + str( value )
3080 output = self.sendline( baseStr + cmdStr )
3081 assert "Error executing command" not in output
3082 if value and check:
3083 results = self.getCfg( component=str( component ),
3084 propName=str( propName ),
3085 jsonFormat=True )
3086 # Check if current value is what we just set
3087 try:
3088 jsonOutput = json.loads( results )
3089 current = jsonOutput[ 'value' ]
3090 except ( ValueError, TypeError ):
3091 main.log.exception( "Error parsing cfg output" )
3092 main.log.error( "output:" + repr( results ) )
3093 return main.FALSE
3094 if current == str( value ):
3095 return main.TRUE
3096 return main.FALSE
3097 return main.TRUE
3098 except AssertionError:
3099 main.log.error( "Error in processing 'cfg set' command: " +
3100 str( output ) )
3101 return main.FALSE
3102 except TypeError:
3103 main.log.exception( self.name + ": Object not as expected" )
3104 return main.FALSE
3105 except pexpect.EOF:
3106 main.log.error( self.name + ": EOF exception found" )
3107 main.log.error( self.name + ": " + self.handle.before )
3108 main.cleanup()
3109 main.exit()
3110 except Exception:
3111 main.log.exception( self.name + ": Uncaught exception!" )
3112 main.cleanup()
3113 main.exit()
3114
Jon Hall390696c2015-05-05 17:13:41 -07003115 def setTestAdd( self, setName, values ):
3116 """
3117 CLI command to add elements to a distributed set.
3118 Arguments:
3119 setName - The name of the set to add to.
3120 values - The value(s) to add to the set, space seperated.
3121 Example usages:
3122 setTestAdd( "set1", "a b c" )
3123 setTestAdd( "set2", "1" )
3124 returns:
3125 main.TRUE on success OR
3126 main.FALSE if elements were already in the set OR
3127 main.ERROR on error
3128 """
3129 try:
3130 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3131 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003132 try:
3133 # TODO: Maybe make this less hardcoded
3134 # ConsistentMap Exceptions
3135 assert "org.onosproject.store.service" not in output
3136 # Node not leader
3137 assert "java.lang.IllegalStateException" not in output
3138 except AssertionError:
3139 main.log.error( "Error in processing 'set-test-add' " +
3140 "command: " + str( output ) )
3141 retryTime = 30 # Conservative time, given by Madan
3142 main.log.info( "Waiting " + str( retryTime ) +
3143 "seconds before retrying." )
3144 time.sleep( retryTime ) # Due to change in mastership
3145 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003146 assert "Error executing command" not in output
3147 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3148 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3149 main.log.info( self.name + ": " + output )
3150 if re.search( positiveMatch, output):
3151 return main.TRUE
3152 elif re.search( negativeMatch, output):
3153 return main.FALSE
3154 else:
3155 main.log.error( self.name + ": setTestAdd did not" +
3156 " match expected output" )
3157 main.log.debug( self.name + " expected: " + pattern )
3158 main.log.debug( self.name + " actual: " + repr( output ) )
3159 return main.ERROR
3160 except AssertionError:
3161 main.log.error( "Error in processing 'set-test-add' command: " +
3162 str( output ) )
3163 return main.ERROR
3164 except TypeError:
3165 main.log.exception( self.name + ": Object not as expected" )
3166 return main.ERROR
3167 except pexpect.EOF:
3168 main.log.error( self.name + ": EOF exception found" )
3169 main.log.error( self.name + ": " + self.handle.before )
3170 main.cleanup()
3171 main.exit()
3172 except Exception:
3173 main.log.exception( self.name + ": Uncaught exception!" )
3174 main.cleanup()
3175 main.exit()
3176
3177 def setTestRemove( self, setName, values, clear=False, retain=False ):
3178 """
3179 CLI command to remove elements from a distributed set.
3180 Required arguments:
3181 setName - The name of the set to remove from.
3182 values - The value(s) to remove from the set, space seperated.
3183 Optional arguments:
3184 clear - Clear all elements from the set
3185 retain - Retain only the given values. (intersection of the
3186 original set and the given set)
3187 returns:
3188 main.TRUE on success OR
3189 main.FALSE if the set was not changed OR
3190 main.ERROR on error
3191 """
3192 try:
3193 cmdStr = "set-test-remove "
3194 if clear:
3195 cmdStr += "-c " + str( setName )
3196 elif retain:
3197 cmdStr += "-r " + str( setName ) + " " + str( values )
3198 else:
3199 cmdStr += str( setName ) + " " + str( values )
3200 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003201 try:
3202 # TODO: Maybe make this less hardcoded
3203 # ConsistentMap Exceptions
3204 assert "org.onosproject.store.service" not in output
3205 # Node not leader
3206 assert "java.lang.IllegalStateException" not in output
3207 except AssertionError:
3208 main.log.error( "Error in processing 'set-test-add' " +
3209 "command: " + str( output ) )
3210 retryTime = 30 # Conservative time, given by Madan
3211 main.log.info( "Waiting " + str( retryTime ) +
3212 "seconds before retrying." )
3213 time.sleep( retryTime ) # Due to change in mastership
3214 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003215 assert "Error executing command" not in output
3216 main.log.info( self.name + ": " + output )
3217 if clear:
3218 pattern = "Set " + str( setName ) + " cleared"
3219 if re.search( pattern, output ):
3220 return main.TRUE
3221 elif retain:
3222 positivePattern = str( setName ) + " was pruned to contain " +\
3223 "only elements of set \[(.*)\]"
3224 negativePattern = str( setName ) + " was not changed by " +\
3225 "retaining only elements of the set " +\
3226 "\[(.*)\]"
3227 if re.search( positivePattern, output ):
3228 return main.TRUE
3229 elif re.search( negativePattern, output ):
3230 return main.FALSE
3231 else:
3232 positivePattern = "\[(.*)\] was removed from the set " +\
3233 str( setName )
3234 if ( len( values.split() ) == 1 ):
3235 negativePattern = "\[(.*)\] was not in set " +\
3236 str( setName )
3237 else:
3238 negativePattern = "No element of \[(.*)\] was in set " +\
3239 str( setName )
3240 if re.search( positivePattern, output ):
3241 return main.TRUE
3242 elif re.search( negativePattern, output ):
3243 return main.FALSE
3244 main.log.error( self.name + ": setTestRemove did not" +
3245 " match expected output" )
3246 main.log.debug( self.name + " expected: " + pattern )
3247 main.log.debug( self.name + " actual: " + repr( output ) )
3248 return main.ERROR
3249 except AssertionError:
3250 main.log.error( "Error in processing 'set-test-remove' command: " +
3251 str( output ) )
3252 return main.ERROR
3253 except TypeError:
3254 main.log.exception( self.name + ": Object not as expected" )
3255 return main.ERROR
3256 except pexpect.EOF:
3257 main.log.error( self.name + ": EOF exception found" )
3258 main.log.error( self.name + ": " + self.handle.before )
3259 main.cleanup()
3260 main.exit()
3261 except Exception:
3262 main.log.exception( self.name + ": Uncaught exception!" )
3263 main.cleanup()
3264 main.exit()
3265
3266 def setTestGet( self, setName, values="" ):
3267 """
3268 CLI command to get the elements in a distributed set.
3269 Required arguments:
3270 setName - The name of the set to remove from.
3271 Optional arguments:
3272 values - The value(s) to check if in the set, space seperated.
3273 returns:
3274 main.ERROR on error OR
3275 A list of elements in the set if no optional arguments are
3276 supplied OR
3277 A tuple containing the list then:
3278 main.FALSE if the given values are not in the set OR
3279 main.TRUE if the given values are in the set OR
3280 """
3281 try:
3282 values = str( values ).strip()
3283 setName = str( setName ).strip()
3284 length = len( values.split() )
3285 containsCheck = None
3286 # Patterns to match
3287 setPattern = "\[(.*)\]"
3288 pattern = "Items in set " + setName + ":\n" + setPattern
3289 containsTrue = "Set " + setName + " contains the value " + values
3290 containsFalse = "Set " + setName + " did not contain the value " +\
3291 values
3292 containsAllTrue = "Set " + setName + " contains the the subset " +\
3293 setPattern
3294 containsAllFalse = "Set " + setName + " did not contain the the" +\
3295 " subset " + setPattern
3296
3297 cmdStr = "set-test-get "
3298 cmdStr += setName + " " + values
3299 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003300 try:
3301 # TODO: Maybe make this less hardcoded
3302 # ConsistentMap Exceptions
3303 assert "org.onosproject.store.service" not in output
3304 # Node not leader
3305 assert "java.lang.IllegalStateException" not in output
3306 except AssertionError:
3307 main.log.error( "Error in processing 'set-test-add' " +
3308 "command: " + str( output ) )
3309 retryTime = 30 # Conservative time, given by Madan
3310 main.log.info( "Waiting " + str( retryTime ) +
3311 "seconds before retrying." )
3312 time.sleep( retryTime ) # Due to change in mastership
3313 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003314 assert "Error executing command" not in output
3315 main.log.info( self.name + ": " + output )
3316
3317 if length == 0:
3318 match = re.search( pattern, output )
3319 else: # if given values
3320 if length == 1: # Contains output
3321 patternTrue = pattern + "\n" + containsTrue
3322 patternFalse = pattern + "\n" + containsFalse
3323 else: # ContainsAll output
3324 patternTrue = pattern + "\n" + containsAllTrue
3325 patternFalse = pattern + "\n" + containsAllFalse
3326 matchTrue = re.search( patternTrue, output )
3327 matchFalse = re.search( patternFalse, output )
3328 if matchTrue:
3329 containsCheck = main.TRUE
3330 match = matchTrue
3331 elif matchFalse:
3332 containsCheck = main.FALSE
3333 match = matchFalse
3334 else:
3335 main.log.error( self.name + " setTestGet did not match " +\
3336 "expected output" )
3337 main.log.debug( self.name + " expected: " + pattern )
3338 main.log.debug( self.name + " actual: " + repr( output ) )
3339 match = None
3340 if match:
3341 setMatch = match.group( 1 )
3342 if setMatch == '':
3343 setList = []
3344 else:
3345 setList = setMatch.split( ", " )
3346 if length > 0:
3347 return ( setList, containsCheck )
3348 else:
3349 return setList
3350 else: # no match
3351 main.log.error( self.name + ": setTestGet did not" +
3352 " match expected output" )
3353 main.log.debug( self.name + " expected: " + pattern )
3354 main.log.debug( self.name + " actual: " + repr( output ) )
3355 return main.ERROR
3356 except AssertionError:
3357 main.log.error( "Error in processing 'set-test-get' command: " +
3358 str( output ) )
3359 return main.ERROR
3360 except TypeError:
3361 main.log.exception( self.name + ": Object not as expected" )
3362 return main.ERROR
3363 except pexpect.EOF:
3364 main.log.error( self.name + ": EOF exception found" )
3365 main.log.error( self.name + ": " + self.handle.before )
3366 main.cleanup()
3367 main.exit()
3368 except Exception:
3369 main.log.exception( self.name + ": Uncaught exception!" )
3370 main.cleanup()
3371 main.exit()
3372
3373 def setTestSize( self, setName ):
3374 """
3375 CLI command to get the elements in a distributed set.
3376 Required arguments:
3377 setName - The name of the set to remove from.
3378 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003379 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003380 None on error
3381 """
3382 try:
3383 # TODO: Should this check against the number of elements returned
3384 # and then return true/false based on that?
3385 setName = str( setName ).strip()
3386 # Patterns to match
3387 setPattern = "\[(.*)\]"
3388 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3389 setPattern
3390 cmdStr = "set-test-get -s "
3391 cmdStr += setName
3392 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003393 try:
3394 # TODO: Maybe make this less hardcoded
3395 # ConsistentMap Exceptions
3396 assert "org.onosproject.store.service" not in output
3397 # Node not leader
3398 assert "java.lang.IllegalStateException" not in output
3399 except AssertionError:
3400 main.log.error( "Error in processing 'set-test-add' " +
3401 "command: " + str( output ) )
3402 retryTime = 30 # Conservative time, given by Madan
3403 main.log.info( "Waiting " + str( retryTime ) +
3404 "seconds before retrying." )
3405 time.sleep( retryTime ) # Due to change in mastership
3406 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003407 assert "Error executing command" not in output
3408 main.log.info( self.name + ": " + output )
3409 match = re.search( pattern, output )
3410 if match:
3411 setSize = int( match.group( 1 ) )
3412 setMatch = match.group( 2 )
3413 if len( setMatch.split() ) == setSize:
3414 main.log.info( "The size returned by " + self.name +
3415 " matches the number of elements in " +
3416 "the returned set" )
3417 else:
3418 main.log.error( "The size returned by " + self.name +
3419 " does not match the number of " +
3420 "elements in the returned set." )
3421 return setSize
3422 else: # no match
3423 main.log.error( self.name + ": setTestGet did not" +
3424 " match expected output" )
3425 main.log.debug( self.name + " expected: " + pattern )
3426 main.log.debug( self.name + " actual: " + repr( output ) )
3427 return None
3428 except AssertionError:
3429 main.log.error( "Error in processing 'set-test-get' command: " +
3430 str( output ) )
3431 return None
3432 except TypeError:
3433 main.log.exception( self.name + ": Object not as expected" )
3434 return None
3435 except pexpect.EOF:
3436 main.log.error( self.name + ": EOF exception found" )
3437 main.log.error( self.name + ": " + self.handle.before )
3438 main.cleanup()
3439 main.exit()
3440 except Exception:
3441 main.log.exception( self.name + ": Uncaught exception!" )
3442 main.cleanup()
3443 main.exit()
3444
3445 def counters( self ):
3446 """
3447 Command to list the various counters in the system.
3448 returns:
3449 A dict containing the counters in the system with the counter
3450 names being the keys and the value of the counters being the
3451 values OR
3452 None on error
3453 """
3454 #FIXME: JSON FORMAT
3455 try:
3456 counters = {}
3457 cmdStr = "counters"
3458 output = self.sendline( cmdStr )
3459 assert "Error executing command" not in output
3460 main.log.info( self.name + ": " + output )
3461 for line in output.splitlines():
3462 match = re.search( "name=(\S+) value=(\d+)", line )
3463 if match:
3464 key = match.group( 1 )
3465 value = int( match.group( 2 ) )
3466 counters[key] = value
3467 else:
3468 main.log.error( self.name + ": counters did not match " +
3469 "expected output" )
3470 main.log.debug( self.name + " expected: " + pattern )
3471 main.log.debug( self.name + " actual: " + repr( output ) )
3472 return None
3473 return counters
3474 except AssertionError:
3475 main.log.error( "Error in processing 'counters' command: " +
3476 str( output ) )
3477 return main.ERROR
3478 except TypeError:
3479 main.log.exception( self.name + ": Object not as expected" )
3480 return main.ERROR
3481 except pexpect.EOF:
3482 main.log.error( self.name + ": EOF exception found" )
3483 main.log.error( self.name + ": " + self.handle.before )
3484 main.cleanup()
3485 main.exit()
3486 except Exception:
3487 main.log.exception( self.name + ": Uncaught exception!" )
3488 main.cleanup()
3489 main.exit()
3490
3491 def counterTestIncrement( self, counter, inMemory=False ):
3492 """
3493 CLI command to increment and get a distributed counter.
3494 Required arguments:
3495 counter - The name of the counter to increment.
3496 Optional arguments:
3497 inMemory - use in memory map for the counter
3498 returns:
3499 integer value of the counter or
3500 None on Error
3501 """
3502 try:
3503 counter = str( counter )
3504 cmdStr = "counter-test-increment "
3505 if inMemory:
3506 cmdStr += "-i "
3507 cmdStr += counter
3508 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003509 try:
3510 # TODO: Maybe make this less hardcoded
3511 # ConsistentMap Exceptions
3512 assert "org.onosproject.store.service" not in output
3513 # Node not leader
3514 assert "java.lang.IllegalStateException" not in output
3515 except AssertionError:
3516 main.log.error( "Error in processing 'set-test-add' " +
3517 "command: " + str( output ) )
3518 retryTime = 30 # Conservative time, given by Madan
3519 main.log.info( "Waiting " + str( retryTime ) +
3520 "seconds before retrying." )
3521 time.sleep( retryTime ) # Due to change in mastership
3522 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003523 assert "Error executing command" not in output
3524 main.log.info( self.name + ": " + output )
3525 pattern = counter + " was incremented to (\d+)"
3526 match = re.search( pattern, output )
3527 if match:
3528 return int( match.group( 1 ) )
3529 else:
3530 main.log.error( self.name + ": counterTestIncrement did not" +
3531 " match expected output." )
3532 main.log.debug( self.name + " expected: " + pattern )
3533 main.log.debug( self.name + " actual: " + repr( output ) )
3534 return None
3535 except AssertionError:
3536 main.log.error( "Error in processing 'counter-test-increment'" +
3537 " command: " + str( output ) )
3538 return None
3539 except TypeError:
3540 main.log.exception( self.name + ": Object not as expected" )
3541 return None
3542 except pexpect.EOF:
3543 main.log.error( self.name + ": EOF exception found" )
3544 main.log.error( self.name + ": " + self.handle.before )
3545 main.cleanup()
3546 main.exit()
3547 except Exception:
3548 main.log.exception( self.name + ": Uncaught exception!" )
3549 main.cleanup()
3550 main.exit()
3551