blob: a203492af1b7c2ce5d4580bc321f411f43d6c81c [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import sys
andrewonlab95ce8322014-10-13 14:12:04 -040020import pexpect
21import re
Jon Hall30b82fa2015-03-04 17:15:43 -080022import json
23import types
Jon Hallbd16b922015-03-26 17:53:15 -070024import time
kelvin8ec71442015-01-15 16:57:00 -080025sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040026from drivers.common.clidriver import CLI
27
andrewonlab95ce8322014-10-13 14:12:04 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 self.name = None
36 self.home = None
37 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080038 super( CLI, self ).__init__()
39
40 def connect( self, **connectargs ):
41 """
andrewonlab95ce8322014-10-13 14:12:04 -040042 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080043 """
andrewonlab95ce8322014-10-13 14:12:04 -040044 try:
45 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080046 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070047 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040048 for key in self.options:
49 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080050 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040051 break
kelvin-onlabfb521662015-02-27 09:52:40 -080052 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054
kelvin8ec71442015-01-15 16:57:00 -080055 self.name = self.options[ 'name' ]
56 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 user_name=self.user_name,
58 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080059 port=self.port,
60 pwd=self.pwd,
61 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040062
kelvin8ec71442015-01-15 16:57:00 -080063 self.handle.sendline( "cd " + self.home )
64 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040065 if self.handle:
66 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080067 else:
68 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040069 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080070 except TypeError:
71 main.log.exception( self.name + ": Object not as expected" )
72 return None
andrewonlab95ce8322014-10-13 14:12:04 -040073 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080074 main.log.error( self.name + ": EOF exception found" )
75 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040076 main.cleanup()
77 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080078 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080079 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040080 main.cleanup()
81 main.exit()
82
kelvin8ec71442015-01-15 16:57:00 -080083 def disconnect( self ):
84 """
andrewonlab95ce8322014-10-13 14:12:04 -040085 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080086 """
Jon Halld61331b2015-02-17 16:35:47 -080087 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040088 try:
Jon Hall61282e32015-03-19 11:34:11 -070089 if self.handle:
90 i = self.logout()
91 if i == main.TRUE:
92 self.handle.sendline( "" )
93 self.handle.expect( "\$" )
94 self.handle.sendline( "exit" )
95 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080096 except TypeError:
97 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080098 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800100 main.log.error( self.name + ": EOF exception found" )
101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700102 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700103 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700104 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 response = main.FALSE
108 return response
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def logout( self ):
111 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500112 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700113 Returns main.TRUE if exited CLI and
114 main.FALSE on timeout (not guranteed you are disconnected)
115 None on TypeError
116 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800117 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500118 try:
Jon Hall61282e32015-03-19 11:34:11 -0700119 if self.handle:
120 self.handle.sendline( "" )
121 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
122 timeout=10 )
123 if i == 0: # In ONOS CLI
124 self.handle.sendline( "logout" )
125 self.handle.expect( "\$" )
126 return main.TRUE
127 elif i == 1: # not in CLI
128 return main.TRUE
129 elif i == 3: # Timeout
130 return main.FALSE
131 else:
andrewonlab9627f432014-11-14 12:45:10 -0500132 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800133 except TypeError:
134 main.log.exception( self.name + ": Object not as expected" )
135 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800137 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700138 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 main.cleanup()
140 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700141 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700142 main.log.error( self.name +
143 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800145 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500146 main.cleanup()
147 main.exit()
148
kelvin-onlabd3b64892015-01-20 13:26:24 -0800149 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800150 """
andrewonlab95ce8322014-10-13 14:12:04 -0400151 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800152
andrewonlab95ce8322014-10-13 14:12:04 -0400153 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800154 """
andrewonlab95ce8322014-10-13 14:12:04 -0400155 try:
156 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400158 main.cleanup()
159 main.exit()
160 else:
kelvin8ec71442015-01-15 16:57:00 -0800161 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800162 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800163 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400164 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800165 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800166 handleBefore = self.handle.before
167 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800168 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800169 self.handle.sendline("")
170 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800171 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400172
kelvin-onlabd3b64892015-01-20 13:26:24 -0800173 main.log.info( "Cell call returned: " + handleBefore +
174 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400175
176 return main.TRUE
177
Jon Halld4d4b372015-01-28 16:02:41 -0800178 except TypeError:
179 main.log.exception( self.name + ": Object not as expected" )
180 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400181 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800182 main.log.error( self.name + ": eof exception found" )
183 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400184 main.cleanup()
185 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800186 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800187 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400188 main.cleanup()
189 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800190
kelvin-onlabd3b64892015-01-20 13:26:24 -0800191 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800192 """
Jon Hallefbd9792015-03-05 16:11:36 -0800193 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800194 by user would be used to set the current karaf shell idle timeout.
195 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800196 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800197 Below is an example to start a session with 60 seconds idle timeout
198 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800199
Hari Krishna25d42f72015-01-05 15:08:28 -0800200 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800202
kelvin-onlabd3b64892015-01-20 13:26:24 -0800203 Note: karafTimeout is left as str so that this could be read
204 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800205 """
andrewonlab95ce8322014-10-13 14:12:04 -0400206 try:
kelvin8ec71442015-01-15 16:57:00 -0800207 self.handle.sendline( "" )
208 x = self.handle.expect( [
209 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500210
211 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800212 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500213 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400214
kelvin8ec71442015-01-15 16:57:00 -0800215 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800217 i = self.handle.expect( [
218 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800219 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400220
221 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800223 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800224 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800225 "config:property-set -p org.apache.karaf.shell\
226 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800227 karafTimeout )
228 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400231 return main.TRUE
232 else:
kelvin8ec71442015-01-15 16:57:00 -0800233 # If failed, send ctrl+c to process and try again
234 main.log.info( "Starting CLI failed. Retrying..." )
235 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800237 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
238 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400239 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800241 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800242 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800243 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 "config:property-set -p org.apache.karaf.shell\
245 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800246 karafTimeout )
247 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800249 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400250 return main.TRUE
251 else:
kelvin8ec71442015-01-15 16:57:00 -0800252 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400254 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400255
Jon Halld4d4b372015-01-28 16:02:41 -0800256 except TypeError:
257 main.log.exception( self.name + ": Object not as expected" )
258 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800260 main.log.error( self.name + ": EOF exception found" )
261 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400262 main.cleanup()
263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800265 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400266 main.cleanup()
267 main.exit()
268
Jon Hallefbd9792015-03-05 16:11:36 -0800269 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800270 """
271 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800272 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800273 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800274 Available level: DEBUG, TRACE, INFO, WARN, ERROR
275 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800276 """
277 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800278 lvlStr = ""
279 if level:
280 lvlStr = "--level=" + level
281
kelvin-onlab9f541032015-02-04 16:19:53 -0800282 self.handle.sendline( "" )
283 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800284 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700285 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800286 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800287
kelvin-onlab9f541032015-02-04 16:19:53 -0800288 response = self.handle.before
289 if re.search( "Error", response ):
290 return main.FALSE
291 return main.TRUE
292
293 except pexpect.EOF:
294 main.log.error( self.name + ": EOF exception found" )
295 main.log.error( self.name + ": " + self.handle.before )
296 main.cleanup()
297 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800298 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800299 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400300 main.cleanup()
301 main.exit()
302
Jon Hallc6358dd2015-04-10 12:44:28 -0700303 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800304 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800305 Send a completely user specified string to
306 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400307 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800308
andrewonlaba18f6bf2014-10-13 19:31:54 -0400309 Warning: There are no sanity checking to commands
310 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800311 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400312 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800313 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
314 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800316 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
317 response = self.handle.before
318 if i == 2:
319 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700320 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800321 response += self.handle.before
322 print response
323 try:
324 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700325 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800326 pass
327 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800328 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800329 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700330 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700331 main.log.debug( self.name + ": Raw output" )
332 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700333
334 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800335 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800336 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700337 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700338 main.log.debug( self.name + ": ansiEscape output" )
339 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700340
kelvin-onlabfb521662015-02-27 09:52:40 -0800341 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800342 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700343 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700344 main.log.debug( self.name + ": Removed extra returns " +
345 "from output" )
346 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700347
348 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800349 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700350 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700351 main.log.debug( self.name + ": parsed and stripped output" )
352 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700353
Jon Hall63604932015-02-26 17:09:50 -0800354 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700355 output = response.split( cmdStr.strip(), 1 )
356 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700357 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700358 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700359 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700360 return output[1].strip()
361 except IndexError:
362 main.log.exception( self.name + ": Object not as expected" )
363 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800364 except TypeError:
365 main.log.exception( self.name + ": Object not as expected" )
366 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400367 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800368 main.log.error( self.name + ": EOF exception found" )
369 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400370 main.cleanup()
371 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800372 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800373 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400374 main.cleanup()
375 main.exit()
376
kelvin8ec71442015-01-15 16:57:00 -0800377 # IMPORTANT NOTE:
378 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800379 # the cli command changing 'a:b' with 'aB'.
380 # Ex ) onos:topology > onosTopology
381 # onos:links > onosLinks
382 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800383
kelvin-onlabd3b64892015-01-20 13:26:24 -0800384 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800385 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400386 Adds a new cluster node by ID and address information.
387 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800388 * nodeId
389 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400390 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800392 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400393 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800394 cmdStr = "add-node " + str( nodeId ) + " " +\
395 str( ONOSIp ) + " " + str( tcpPort )
396 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800397 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800398 main.log.error( "Error in adding node" )
399 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800400 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400401 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400403 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800404 except TypeError:
405 main.log.exception( self.name + ": Object not as expected" )
406 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400407 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800408 main.log.error( self.name + ": EOF exception found" )
409 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400410 main.cleanup()
411 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800412 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800413 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400414 main.cleanup()
415 main.exit()
416
kelvin-onlabd3b64892015-01-20 13:26:24 -0800417 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800418 """
andrewonlab86dc3082014-10-13 18:18:38 -0400419 Removes a cluster by ID
420 Issues command: 'remove-node [<node-id>]'
421 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlab86dc3082014-10-13 18:18:38 -0400424 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400425
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700427 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700428 if re.search( "Error", handle ):
429 main.log.error( "Error in removing node" )
430 main.log.error( handle )
431 return main.FALSE
432 else:
433 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800434 except TypeError:
435 main.log.exception( self.name + ": Object not as expected" )
436 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400437 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800438 main.log.error( self.name + ": EOF exception found" )
439 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400440 main.cleanup()
441 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800442 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800443 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400444 main.cleanup()
445 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446
Jon Hall61282e32015-03-19 11:34:11 -0700447 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800448 """
andrewonlab7c211572014-10-15 16:45:20 -0400449 List the nodes currently visible
450 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700451 Optional argument:
452 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800453 """
andrewonlab7c211572014-10-15 16:45:20 -0400454 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700455 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700456 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700457 cmdStr += " -j"
458 output = self.sendline( cmdStr )
459 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800460 except TypeError:
461 main.log.exception( self.name + ": Object not as expected" )
462 return None
andrewonlab7c211572014-10-15 16:45:20 -0400463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800464 main.log.error( self.name + ": EOF exception found" )
465 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400466 main.cleanup()
467 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800468 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800469 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400470 main.cleanup()
471 main.exit()
472
kelvin8ec71442015-01-15 16:57:00 -0800473 def topology( self ):
474 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700475 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700476 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700477 Return:
478 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800479 """
andrewonlab95ce8322014-10-13 14:12:04 -0400480 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700481 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800482 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400484 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800485 except TypeError:
486 main.log.exception( self.name + ": Object not as expected" )
487 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800489 main.log.error( self.name + ": EOF exception found" )
490 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400491 main.cleanup()
492 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800493 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800494 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400495 main.cleanup()
496 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800497
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800499 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 Installs a specified feature by issuing command:
501 'feature:install <feature_str>'
502 NOTE: This is now deprecated, you should use the activateApp method
503 instead
kelvin8ec71442015-01-15 16:57:00 -0800504 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400505 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 handle = self.sendline( cmdStr )
508 if re.search( "Error", handle ):
509 main.log.error( "Error in installing feature" )
510 main.log.error( handle )
511 return main.FALSE
512 else:
513 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800514 except TypeError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400517 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800518 main.log.error( self.name + ": EOF exception found" )
519 main.log.error( self.name + ": " + self.handle.before )
520 main.log.report( "Failed to install feature" )
521 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400522 main.cleanup()
523 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800524 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800525 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800526 main.log.report( "Failed to install feature" )
527 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 main.cleanup()
529 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800530
kelvin-onlabd3b64892015-01-20 13:26:24 -0800531 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800532 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700533 Uninstalls a specified feature by issuing command:
534 'feature:uninstall <feature_str>'
535 NOTE: This is now deprecated, you should use the deactivateApp method
536 instead
kelvin8ec71442015-01-15 16:57:00 -0800537 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400538 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800539 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
540 handle = self.sendline( cmdStr )
541 if handle != '':
542 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800544 # TODO: Check for possible error responses from karaf
545 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800546 main.log.info( "Feature needs to be installed before " +
547 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700548 return main.TRUE
549 if re.search( "Error", output ):
550 main.log.error( "Error in uninstalling feature" )
551 main.log.error( output )
552 return main.FALSE
553 else:
554 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800555 except TypeError:
556 main.log.exception( self.name + ": Object not as expected" )
557 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400558 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800559 main.log.error( self.name + ": EOF exception found" )
560 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400561 main.cleanup()
562 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800563 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800564 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 main.cleanup()
566 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800567
jenkins7ead5a82015-03-13 10:28:21 -0700568 def deviceRemove( self, deviceId ):
569 """
570 Removes particular device from storage
571
572 TODO: refactor this function
573 """
574 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700575 cmdStr = "device-remove " + str( deviceId )
576 handle = self.sendline( cmdStr )
577 if re.search( "Error", handle ):
578 main.log.error( "Error in removing device" )
579 main.log.error( handle )
580 return main.FALSE
581 else:
582 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700583 except TypeError:
584 main.log.exception( self.name + ": Object not as expected" )
585 return None
586 except pexpect.EOF:
587 main.log.error( self.name + ": EOF exception found" )
588 main.log.error( self.name + ": " + self.handle.before )
589 main.cleanup()
590 main.exit()
591 except Exception:
592 main.log.exception( self.name + ": Uncaught exception!" )
593 main.cleanup()
594 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700595
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800597 """
Jon Hall7b02d952014-10-17 20:14:54 -0400598 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400599 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800600 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800601 """
andrewonlab86dc3082014-10-13 18:18:38 -0400602 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700605 cmdStr += " -j"
606 handle = self.sendline( cmdStr )
607 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800608 except TypeError:
609 main.log.exception( self.name + ": Object not as expected" )
610 return None
andrewonlab7c211572014-10-15 16:45:20 -0400611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800612 main.log.error( self.name + ": EOF exception found" )
613 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400614 main.cleanup()
615 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800617 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400618 main.cleanup()
619 main.exit()
620
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800622 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800623 This balances the devices across all controllers
624 by issuing command: 'onos> onos:balance-masters'
625 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800626 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800627 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 handle = self.sendline( cmdStr )
630 if re.search( "Error", handle ):
631 main.log.error( "Error in balancing masters" )
632 main.log.error( handle )
633 return main.FALSE
634 else:
635 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800646 main.cleanup()
647 main.exit()
648
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800650 """
Jon Halle8217482014-10-17 13:49:14 -0400651 Lists all core links
652 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800653 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800654 """
Jon Halle8217482014-10-17 13:49:14 -0400655 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700656 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800657 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700658 cmdStr += " -j"
659 handle = self.sendline( cmdStr )
660 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800661 except TypeError:
662 main.log.exception( self.name + ": Object not as expected" )
663 return None
Jon Halle8217482014-10-17 13:49:14 -0400664 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800665 main.log.error( self.name + ": EOF exception found" )
666 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400667 main.cleanup()
668 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800669 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800670 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400671 main.cleanup()
672 main.exit()
673
kelvin-onlabd3b64892015-01-20 13:26:24 -0800674 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800675 """
Jon Halle8217482014-10-17 13:49:14 -0400676 Lists all ports
677 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800679 """
Jon Halle8217482014-10-17 13:49:14 -0400680 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700681 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700683 cmdStr += " -j"
684 handle = self.sendline( cmdStr )
685 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800686 except TypeError:
687 main.log.exception( self.name + ": Object not as expected" )
688 return None
Jon Halle8217482014-10-17 13:49:14 -0400689 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800690 main.log.error( self.name + ": EOF exception found" )
691 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400692 main.cleanup()
693 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800694 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800695 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400696 main.cleanup()
697 main.exit()
698
kelvin-onlabd3b64892015-01-20 13:26:24 -0800699 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800700 """
Jon Hall983a1702014-10-28 18:44:22 -0400701 Lists all devices and the controllers with roles assigned to them
702 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800703 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800704 """
andrewonlab7c211572014-10-15 16:45:20 -0400705 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700708 cmdStr += " -j"
709 handle = self.sendline( cmdStr )
710 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800711 except TypeError:
712 main.log.exception( self.name + ": Object not as expected" )
713 return None
Jon Hall983a1702014-10-28 18:44:22 -0400714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400717 main.cleanup()
718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800720 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400721 main.cleanup()
722 main.exit()
723
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800725 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800726 Given the a string containing the json representation of the "roles"
727 cli command and a partial or whole device id, returns a json object
728 containing the roles output for the first device whose id contains
729 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400730
731 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800732 A dict of the role assignments for the given device or
733 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800734 """
Jon Hall983a1702014-10-28 18:44:22 -0400735 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400737 return None
738 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 rawRoles = self.roles()
740 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800741 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800743 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400745 return device
746 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800747 except TypeError:
748 main.log.exception( self.name + ": Object not as expected" )
749 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400753 main.cleanup()
754 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800755 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800756 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400757 main.cleanup()
758 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800759
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800761 """
Jon Hall94fd0472014-12-08 11:52:42 -0800762 Iterates through each device and checks if there is a master assigned
763 Returns: main.TRUE if each device has a master
764 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Jon Hall94fd0472014-12-08 11:52:42 -0800766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 rawRoles = self.roles()
768 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800769 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800771 # print device
772 if device[ 'master' ] == "none":
773 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800774 return main.FALSE
775 return main.TRUE
776
Jon Halld4d4b372015-01-28 16:02:41 -0800777 except TypeError:
778 main.log.exception( self.name + ": Object not as expected" )
779 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800780 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( self.name + ": EOF exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800783 main.cleanup()
784 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800786 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800787 main.cleanup()
788 main.exit()
789
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800791 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400792 Returns string of paths, and the cost.
793 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800794 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400795 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
797 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800798 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800799 main.log.error( "Error in getting paths" )
800 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400801 else:
kelvin8ec71442015-01-15 16:57:00 -0800802 path = handle.split( ";" )[ 0 ]
803 cost = handle.split( ";" )[ 1 ]
804 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800805 except TypeError:
806 main.log.exception( self.name + ": Object not as expected" )
807 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800809 main.log.error( self.name + ": EOF exception found" )
810 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400811 main.cleanup()
812 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800814 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400815 main.cleanup()
816 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800817
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800819 """
Jon Hallffb386d2014-11-21 13:43:38 -0800820 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400821 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800823 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400824 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700825 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800826 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700827 cmdStr += " -j"
828 handle = self.sendline( cmdStr )
829 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800830 except TypeError:
831 main.log.exception( self.name + ": Object not as expected" )
832 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400836 main.cleanup()
837 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800838 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800839 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400840 main.cleanup()
841 main.exit()
842
kelvin-onlabd3b64892015-01-20 13:26:24 -0800843 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800844 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400845 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800846
Jon Hallefbd9792015-03-05 16:11:36 -0800847 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800848 partial mac address
849
Jon Hall42db6dc2014-10-24 19:03:48 -0400850 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 try:
kelvin8ec71442015-01-15 16:57:00 -0800853 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400854 return None
855 else:
856 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 rawHosts = self.hosts()
858 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800859 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800861 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800862 if not host:
863 pass
864 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400865 return host
866 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800867 except TypeError:
868 main.log.exception( self.name + ": Object not as expected" )
869 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400870 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800871 main.log.error( self.name + ": EOF exception found" )
872 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400873 main.cleanup()
874 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800875 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800876 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400877 main.cleanup()
878 main.exit()
879
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800881 """
882 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400883 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800884
andrewonlab3f0a4af2014-10-17 12:25:14 -0400885 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800886 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400887 IMPORTANT:
888 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800889 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400890 Furthermore, it assumes that value of VLAN is '-1'
891 Description:
kelvin8ec71442015-01-15 16:57:00 -0800892 Converts mininet hosts ( h1, h2, h3... ) into
893 ONOS format ( 00:00:00:00:00:01/-1 , ... )
894 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400895 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400897
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800899 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 hostHex = hex( int( host ) ).zfill( 12 )
901 hostHex = str( hostHex ).replace( 'x', '0' )
902 i = iter( str( hostHex ) )
903 hostHex = ":".join( a + b for a, b in zip( i, i ) )
904 hostHex = hostHex + "/-1"
905 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908
Jon Halld4d4b372015-01-28 16:02:41 -0800909 except TypeError:
910 main.log.exception( self.name + ": Object not as expected" )
911 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800913 main.log.error( self.name + ": EOF exception found" )
914 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400915 main.cleanup()
916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800918 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400919 main.cleanup()
920 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400921
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800923 """
andrewonlabe6745342014-10-17 14:29:13 -0400924 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 * hostIdOne: ONOS host id for host1
926 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400927 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800928 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500929 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800930 Returns:
931 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800932 """
andrewonlabe6745342014-10-17 14:29:13 -0400933 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 cmdStr = "add-host-intent " + str( hostIdOne ) +\
935 " " + str( hostIdTwo )
936 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800937 if re.search( "Error", handle ):
938 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700939 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800940 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800941 else:
942 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800943 str( hostIdOne ) + " and " + str( hostIdTwo ) )
944 match = re.search('id=0x([\da-f]+),', handle)
945 if match:
946 return match.group()[3:-1]
947 else:
948 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700949 main.log.debug( "Response from ONOS was: " +
950 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800951 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800952 except TypeError:
953 main.log.exception( self.name + ": Object not as expected" )
954 return None
andrewonlabe6745342014-10-17 14:29:13 -0400955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400958 main.cleanup()
959 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800961 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400962 main.cleanup()
963 main.exit()
964
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800966 """
andrewonlab7b31d232014-10-24 13:31:47 -0400967 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 * ingressDevice: device id of ingress device
969 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400970 Optional:
971 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -0800972 Description:
973 Adds an optical intent by specifying an ingress and egress device
974 Returns:
975 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800976 """
andrewonlab7b31d232014-10-24 13:31:47 -0400977 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
979 " " + str( egressDevice )
980 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800981 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800982 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800983 main.log.error( "Error in adding Optical intent" )
984 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400985 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800986 main.log.info( "Optical intent installed between " +
987 str( ingressDevice ) + " and " +
988 str( egressDevice ) )
989 match = re.search('id=0x([\da-f]+),', handle)
990 if match:
991 return match.group()[3:-1]
992 else:
993 main.log.error( "Error, intent ID not found" )
994 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800995 except TypeError:
996 main.log.exception( self.name + ": Object not as expected" )
997 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400998 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800999 main.log.error( self.name + ": EOF exception found" )
1000 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001001 main.cleanup()
1002 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001003 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001004 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001005 main.cleanup()
1006 main.exit()
1007
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001009 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 ingressDevice,
1011 egressDevice,
1012 portIngress="",
1013 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001014 ethType="",
1015 ethSrc="",
1016 ethDst="",
1017 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001019 ipProto="",
1020 ipSrc="",
1021 ipDst="",
1022 tcpSrc="",
1023 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001024 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001025 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 * ingressDevice: device id of ingress device
1027 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001028 Optional:
1029 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001030 * ethSrc: specify ethSrc ( i.e. src mac addr )
1031 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001032 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001034 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001035 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001036 * ipSrc: specify ip source address
1037 * ipDst: specify ip destination address
1038 * tcpSrc: specify tcp source port
1039 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001040 Description:
kelvin8ec71442015-01-15 16:57:00 -08001041 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001042 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001043 Returns:
1044 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001045
Jon Halle3f39ff2015-01-13 11:50:53 -08001046 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001047 options developers provide for point-to-point
1048 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001049 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001050 try:
kelvin8ec71442015-01-15 16:57:00 -08001051 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001052 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001054 and not ipProto and not ipSrc and not ipDst \
1055 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001056 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001057
andrewonlab289e4b72014-10-21 21:24:18 -04001058 else:
andrewonlab36af3822014-11-18 17:48:18 -05001059 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001060
andrewonlab0c0a6772014-10-22 12:31:18 -04001061 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001062 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001063 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001064 cmd += " --ethSrc " + str( ethSrc )
1065 if ethDst:
1066 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001067 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001068 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001070 cmd += " --lambda "
1071 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001072 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001073 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001074 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001075 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001076 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001077 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001078 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001079 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001080 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001081
kelvin8ec71442015-01-15 16:57:00 -08001082 # Check whether the user appended the port
1083 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 if "/" in ingressDevice:
1085 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001086 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001088 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001089 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001090 # Would it make sense to throw an exception and exit
1091 # the test?
1092 return None
andrewonlab36af3822014-11-18 17:48:18 -05001093
kelvin8ec71442015-01-15 16:57:00 -08001094 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 str( ingressDevice ) + "/" +\
1096 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001097
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 if "/" in egressDevice:
1099 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001100 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001102 main.log.error( "You must specify the egress port" )
1103 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001104
kelvin8ec71442015-01-15 16:57:00 -08001105 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 str( egressDevice ) + "/" +\
1107 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001108
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001110 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001111 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001112 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001113 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001114 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001115 # TODO: print out all the options in this message?
1116 main.log.info( "Point-to-point intent installed between " +
1117 str( ingressDevice ) + " and " +
1118 str( egressDevice ) )
1119 match = re.search('id=0x([\da-f]+),', handle)
1120 if match:
1121 return match.group()[3:-1]
1122 else:
1123 main.log.error( "Error, intent ID not found" )
1124 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001125 except TypeError:
1126 main.log.exception( self.name + ": Object not as expected" )
1127 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001129 main.log.error( self.name + ": EOF exception found" )
1130 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001131 main.cleanup()
1132 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001134 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001135 main.cleanup()
1136 main.exit()
1137
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001139 self,
shahshreyac2f97072015-03-19 17:04:29 -07001140 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001142 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001144 ethType="",
1145 ethSrc="",
1146 ethDst="",
1147 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001149 ipProto="",
1150 ipSrc="",
1151 ipDst="",
1152 tcpSrc="",
1153 tcpDst="",
1154 setEthSrc="",
1155 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001156 """
shahshreyad0c80432014-12-04 16:56:05 -08001157 Note:
shahshreya70622b12015-03-19 17:19:00 -07001158 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001159 is same. That is, all ingress devices include port numbers
1160 with a "/" or all ingress devices could specify device
1161 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001162 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001163 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001164 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001166 Optional:
1167 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001168 * ethSrc: specify ethSrc ( i.e. src mac addr )
1169 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001170 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001172 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001173 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001174 * ipSrc: specify ip source address
1175 * ipDst: specify ip destination address
1176 * tcpSrc: specify tcp source port
1177 * tcpDst: specify tcp destination port
1178 * setEthSrc: action to Rewrite Source MAC Address
1179 * setEthDst: action to Rewrite Destination MAC Address
1180 Description:
kelvin8ec71442015-01-15 16:57:00 -08001181 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001182 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001183 Returns:
1184 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001185
Jon Halle3f39ff2015-01-13 11:50:53 -08001186 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001187 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001188 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001189 """
shahshreyad0c80432014-12-04 16:56:05 -08001190 try:
kelvin8ec71442015-01-15 16:57:00 -08001191 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001192 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001194 and not ipProto and not ipSrc and not ipDst\
1195 and not tcpSrc and not tcpDst and not setEthSrc\
1196 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001197 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001198
1199 else:
1200 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001201
shahshreyad0c80432014-12-04 16:56:05 -08001202 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001203 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001204 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " --ethSrc " + str( ethSrc )
1206 if ethDst:
1207 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001208 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001209 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001211 cmd += " --lambda "
1212 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001214 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001215 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001216 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001217 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001218 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001219 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001220 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001221 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001222 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001223 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001224 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001225 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001226
kelvin8ec71442015-01-15 16:57:00 -08001227 # Check whether the user appended the port
1228 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001229
1230 if portIngressList is None:
1231 for ingressDevice in ingressDeviceList:
1232 if "/" in ingressDevice:
1233 cmd += " " + str( ingressDevice )
1234 else:
1235 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001236 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001237 # TODO: perhaps more meaningful return
1238 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001239 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001240 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001241 for ingressDevice, portIngress in zip( ingressDeviceList,
1242 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001243 cmd += " " + \
1244 str( ingressDevice ) + "/" +\
1245 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001246 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001247 main.log.error( "Device list and port list does not " +
1248 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001249 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 if "/" in egressDevice:
1251 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001252 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( "You must specify " +
1255 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001256 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001257
kelvin8ec71442015-01-15 16:57:00 -08001258 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 str( egressDevice ) + "/" +\
1260 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001261 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001262 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001264 main.log.error( "Error in adding multipoint-to-singlepoint " +
1265 "intent" )
1266 return None
shahshreyad0c80432014-12-04 16:56:05 -08001267 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001268 match = re.search('id=0x([\da-f]+),', handle)
1269 if match:
1270 return match.group()[3:-1]
1271 else:
1272 main.log.error( "Error, intent ID not found" )
1273 return None
1274 except TypeError:
1275 main.log.exception( self.name + ": Object not as expected" )
1276 return None
1277 except pexpect.EOF:
1278 main.log.error( self.name + ": EOF exception found" )
1279 main.log.error( self.name + ": " + self.handle.before )
1280 main.cleanup()
1281 main.exit()
1282 except Exception:
1283 main.log.exception( self.name + ": Uncaught exception!" )
1284 main.cleanup()
1285 main.exit()
1286
1287 def addSinglepointToMultipointIntent(
1288 self,
1289 ingressDevice,
1290 egressDeviceList,
1291 portIngress="",
1292 portEgressList=None,
1293 ethType="",
1294 ethSrc="",
1295 ethDst="",
1296 bandwidth="",
1297 lambdaAlloc=False,
1298 ipProto="",
1299 ipSrc="",
1300 ipDst="",
1301 tcpSrc="",
1302 tcpDst="",
1303 setEthSrc="",
1304 setEthDst="" ):
1305 """
1306 Note:
1307 This function assumes the format of all egress devices
1308 is same. That is, all egress devices include port numbers
1309 with a "/" or all egress devices could specify device
1310 ids and port numbers seperately.
1311 Required:
1312 * EgressDeviceList: List of device ids of egress device
1313 ( Atleast 2 eress devices required in the list )
1314 * ingressDevice: device id of ingress device
1315 Optional:
1316 * ethType: specify ethType
1317 * ethSrc: specify ethSrc ( i.e. src mac addr )
1318 * ethDst: specify ethDst ( i.e. dst mac addr )
1319 * bandwidth: specify bandwidth capacity of link
1320 * lambdaAlloc: if True, intent will allocate lambda
1321 for the specified intent
1322 * ipProto: specify ip protocol
1323 * ipSrc: specify ip source address
1324 * ipDst: specify ip destination address
1325 * tcpSrc: specify tcp source port
1326 * tcpDst: specify tcp destination port
1327 * setEthSrc: action to Rewrite Source MAC Address
1328 * setEthDst: action to Rewrite Destination MAC Address
1329 Description:
1330 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1331 specifying device id's and optional fields
1332 Returns:
1333 A string of the intent id or None on error
1334
1335 NOTE: This function may change depending on the
1336 options developers provide for singlepoint-to-multipoint
1337 intent via cli
1338 """
1339 try:
1340 # If there are no optional arguments
1341 if not ethType and not ethSrc and not ethDst\
1342 and not bandwidth and not lambdaAlloc\
1343 and not ipProto and not ipSrc and not ipDst\
1344 and not tcpSrc and not tcpDst and not setEthSrc\
1345 and not setEthDst:
1346 cmd = "add-single-to-multi-intent"
1347
1348 else:
1349 cmd = "add-single-to-multi-intent"
1350
1351 if ethType:
1352 cmd += " --ethType " + str( ethType )
1353 if ethSrc:
1354 cmd += " --ethSrc " + str( ethSrc )
1355 if ethDst:
1356 cmd += " --ethDst " + str( ethDst )
1357 if bandwidth:
1358 cmd += " --bandwidth " + str( bandwidth )
1359 if lambdaAlloc:
1360 cmd += " --lambda "
1361 if ipProto:
1362 cmd += " --ipProto " + str( ipProto )
1363 if ipSrc:
1364 cmd += " --ipSrc " + str( ipSrc )
1365 if ipDst:
1366 cmd += " --ipDst " + str( ipDst )
1367 if tcpSrc:
1368 cmd += " --tcpSrc " + str( tcpSrc )
1369 if tcpDst:
1370 cmd += " --tcpDst " + str( tcpDst )
1371 if setEthSrc:
1372 cmd += " --setEthSrc " + str( setEthSrc )
1373 if setEthDst:
1374 cmd += " --setEthDst " + str( setEthDst )
1375
1376 # Check whether the user appended the port
1377 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001378
kelvin-onlabb9408212015-04-01 13:34:04 -07001379 if "/" in ingressDevice:
1380 cmd += " " + str( ingressDevice )
1381 else:
1382 if not portIngress:
1383 main.log.error( "You must specify " +
1384 "the Ingress port" )
1385 return main.FALSE
1386
1387 cmd += " " +\
1388 str( ingressDevice ) + "/" +\
1389 str( portIngress )
1390
1391 if portEgressList is None:
1392 for egressDevice in egressDeviceList:
1393 if "/" in egressDevice:
1394 cmd += " " + str( egressDevice )
1395 else:
1396 main.log.error( "You must specify " +
1397 "the egress port" )
1398 # TODO: perhaps more meaningful return
1399 return main.FALSE
1400 else:
1401 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001402 for egressDevice, portEgress in zip( egressDeviceList,
1403 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001404 cmd += " " + \
1405 str( egressDevice ) + "/" +\
1406 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001407 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001408 main.log.error( "Device list and port list does not " +
1409 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001410 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001411 handle = self.sendline( cmd )
1412 # If error, return error message
1413 if re.search( "Error", handle ):
1414 main.log.error( "Error in adding singlepoint-to-multipoint " +
1415 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001416 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001417 else:
1418 match = re.search('id=0x([\da-f]+),', handle)
1419 if match:
1420 return match.group()[3:-1]
1421 else:
1422 main.log.error( "Error, intent ID not found" )
1423 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001424 except TypeError:
1425 main.log.exception( self.name + ": Object not as expected" )
1426 return None
shahshreyad0c80432014-12-04 16:56:05 -08001427 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001428 main.log.error( self.name + ": EOF exception found" )
1429 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001430 main.cleanup()
1431 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001432 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001433 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001434 main.cleanup()
1435 main.exit()
1436
Hari Krishna9e232602015-04-13 17:29:08 -07001437 def addMplsIntent(
1438 self,
1439 ingressDevice,
1440 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001441 ingressPort="",
1442 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001443 ethType="",
1444 ethSrc="",
1445 ethDst="",
1446 bandwidth="",
1447 lambdaAlloc=False,
1448 ipProto="",
1449 ipSrc="",
1450 ipDst="",
1451 tcpSrc="",
1452 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001453 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001454 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001455 priority=""):
1456 """
1457 Required:
1458 * ingressDevice: device id of ingress device
1459 * egressDevice: device id of egress device
1460 Optional:
1461 * ethType: specify ethType
1462 * ethSrc: specify ethSrc ( i.e. src mac addr )
1463 * ethDst: specify ethDst ( i.e. dst mac addr )
1464 * bandwidth: specify bandwidth capacity of link
1465 * lambdaAlloc: if True, intent will allocate lambda
1466 for the specified intent
1467 * ipProto: specify ip protocol
1468 * ipSrc: specify ip source address
1469 * ipDst: specify ip destination address
1470 * tcpSrc: specify tcp source port
1471 * tcpDst: specify tcp destination port
1472 * ingressLabel: Ingress MPLS label
1473 * egressLabel: Egress MPLS label
1474 Description:
1475 Adds MPLS intent by
1476 specifying device id's and optional fields
1477 Returns:
1478 A string of the intent id or None on error
1479
1480 NOTE: This function may change depending on the
1481 options developers provide for MPLS
1482 intent via cli
1483 """
1484 try:
1485 # If there are no optional arguments
1486 if not ethType and not ethSrc and not ethDst\
1487 and not bandwidth and not lambdaAlloc \
1488 and not ipProto and not ipSrc and not ipDst \
1489 and not tcpSrc and not tcpDst and not ingressLabel \
1490 and not egressLabel:
1491 cmd = "add-mpls-intent"
1492
1493 else:
1494 cmd = "add-mpls-intent"
1495
1496 if ethType:
1497 cmd += " --ethType " + str( ethType )
1498 if ethSrc:
1499 cmd += " --ethSrc " + str( ethSrc )
1500 if ethDst:
1501 cmd += " --ethDst " + str( ethDst )
1502 if bandwidth:
1503 cmd += " --bandwidth " + str( bandwidth )
1504 if lambdaAlloc:
1505 cmd += " --lambda "
1506 if ipProto:
1507 cmd += " --ipProto " + str( ipProto )
1508 if ipSrc:
1509 cmd += " --ipSrc " + str( ipSrc )
1510 if ipDst:
1511 cmd += " --ipDst " + str( ipDst )
1512 if tcpSrc:
1513 cmd += " --tcpSrc " + str( tcpSrc )
1514 if tcpDst:
1515 cmd += " --tcpDst " + str( tcpDst )
1516 if ingressLabel:
1517 cmd += " --ingressLabel " + str( ingressLabel )
1518 if egressLabel:
1519 cmd += " --egressLabel " + str( egressLabel )
1520 if priority:
1521 cmd += " --priority " + str( priority )
1522
1523 # Check whether the user appended the port
1524 # or provided it as an input
1525 if "/" in ingressDevice:
1526 cmd += " " + str( ingressDevice )
1527 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001528 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001529 main.log.error( "You must specify the ingress port" )
1530 return None
1531
1532 cmd += " " + \
1533 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001534 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001535
1536 if "/" in egressDevice:
1537 cmd += " " + str( egressDevice )
1538 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001539 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001540 main.log.error( "You must specify the egress port" )
1541 return None
1542
1543 cmd += " " +\
1544 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001545 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001546
1547 handle = self.sendline( cmd )
1548 # If error, return error message
1549 if re.search( "Error", handle ):
1550 main.log.error( "Error in adding mpls intent" )
1551 return None
1552 else:
1553 # TODO: print out all the options in this message?
1554 main.log.info( "MPLS intent installed between " +
1555 str( ingressDevice ) + " and " +
1556 str( egressDevice ) )
1557 match = re.search('id=0x([\da-f]+),', handle)
1558 if match:
1559 return match.group()[3:-1]
1560 else:
1561 main.log.error( "Error, intent ID not found" )
1562 return None
1563 except TypeError:
1564 main.log.exception( self.name + ": Object not as expected" )
1565 return None
1566 except pexpect.EOF:
1567 main.log.error( self.name + ": EOF exception found" )
1568 main.log.error( self.name + ": " + self.handle.before )
1569 main.cleanup()
1570 main.exit()
1571 except Exception:
1572 main.log.exception( self.name + ": Uncaught exception!" )
1573 main.cleanup()
1574 main.exit()
1575
Jon Hallefbd9792015-03-05 16:11:36 -08001576 def removeIntent( self, intentId, app='org.onosproject.cli',
1577 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001578 """
shahshreya1c818fc2015-02-26 13:44:08 -08001579 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001580 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001581 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001582 -p or --purge: Purge the intent from the store after removal
1583
Jon Halle3f39ff2015-01-13 11:50:53 -08001584 Returns:
1585 main.False on error and
1586 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001587 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001588 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001589 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001590 if purge:
1591 cmdStr += " -p"
1592 if sync:
1593 cmdStr += " -s"
1594
1595 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001597 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001598 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001599 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001600 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001601 # TODO: Should this be main.TRUE
1602 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001603 except TypeError:
1604 main.log.exception( self.name + ": Object not as expected" )
1605 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001607 main.log.error( self.name + ": EOF exception found" )
1608 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001609 main.cleanup()
1610 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001611 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001612 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001613 main.cleanup()
1614 main.exit()
1615
kelvin-onlabd3b64892015-01-20 13:26:24 -08001616 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001617 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001618 NOTE: This method should be used after installing application:
1619 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001620 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001622 Description:
1623 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001624 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001625 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001626 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001628 cmdStr += " -j"
1629 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001630 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001631 except TypeError:
1632 main.log.exception( self.name + ": Object not as expected" )
1633 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001634 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001635 main.log.error( self.name + ": EOF exception found" )
1636 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001637 main.cleanup()
1638 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001639 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001640 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001641 main.cleanup()
1642 main.exit()
1643
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001645 """
andrewonlab377693f2014-10-21 16:00:30 -04001646 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001647 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001648 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001649 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001650 """
andrewonlabe6745342014-10-17 14:29:13 -04001651 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001652 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001654 cmdStr += " -j"
1655 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001656 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001657 except TypeError:
1658 main.log.exception( self.name + ": Object not as expected" )
1659 return None
andrewonlabe6745342014-10-17 14:29:13 -04001660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001661 main.log.error( self.name + ": EOF exception found" )
1662 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001663 main.cleanup()
1664 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001665 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001666 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001667 main.cleanup()
1668 main.exit()
1669
kelvin-onlab54400a92015-02-26 18:05:51 -08001670 def getIntentState(self, intentsId, intentsJson=None):
1671 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001672 Check intent state.
1673 Accepts a single intent ID (string type) or a list of intent IDs.
1674 Returns the state(string type) of the id if a single intent ID is
1675 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001676 Returns a dictionary with intent IDs as the key and its
1677 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001678 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001679 intentId: intent ID (string type)
1680 intentsJson: parsed json object from the onos:intents api
1681 Returns:
1682 state = An intent's state- INSTALL,WITHDRAWN etc.
1683 stateDict = Dictionary of intent's state. intent ID as the keys and
1684 state as the values.
1685 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001686 try:
1687 state = "State is Undefined"
1688 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001689 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001690 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001691 intentsJsonTemp = json.loads( intentsJson )
1692 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001693 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001694 if intentsId == intent[ 'id' ]:
1695 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001696 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001697 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1698 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001699 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001700 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001701 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001702 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001703 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001704 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001705 if intentsId[ i ] == intents[ 'id' ]:
1706 stateDict[ 'state' ] = intents[ 'state' ]
1707 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001708 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001709 break
Jon Hallefbd9792015-03-05 16:11:36 -08001710 if len( intentsId ) != len( dictList ):
1711 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001712 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001713 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001714 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001715 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001716 except TypeError:
1717 main.log.exception( self.name + ": Object not as expected" )
1718 return None
1719 except pexpect.EOF:
1720 main.log.error( self.name + ": EOF exception found" )
1721 main.log.error( self.name + ": " + self.handle.before )
1722 main.cleanup()
1723 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001724 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001725 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001726 main.cleanup()
1727 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001728
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001729 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1730 """
1731 Description:
1732 Check intents state
1733 Required:
1734 intentsId - List of intents ID to be checked
1735 Optional:
1736 expectedState - Check this expected state of each intents state
1737 in the list. Defaults to INSTALLED
1738 Return:
1739 Returns main.TRUE only if all intent are the same as expectedState,
1740 , otherwise,returns main.FALSE.
1741 """
1742 try:
1743 # Generating a dictionary: intent id as a key and state as value
1744 intentsDict = self.getIntentState( intentsId )
Jon Hall390696c2015-05-05 17:13:41 -07001745 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001746 if len( intentsId ) != len( intentsDict ):
1747 main.log.info( self.name + "There is something wrong " +
1748 "getting intents state" )
1749 return main.FALSE
1750 returnValue = main.TRUE
1751 for intents in intentsDict:
1752 if intents.get( 'state' ) != expectedState:
1753 main.log.info( self.name + " : " + intents.get( 'id' ) +
1754 " actual state = " + intents.get( 'state' )
1755 + " does not equal expected state = "
1756 + expectedState )
1757 returnValue = main.FALSE
1758 if returnValue == main.TRUE:
1759 main.log.info( self.name + ": All " +
1760 str( len( intentsDict ) ) +
1761 " intents are in " + expectedState + " state")
1762 return returnValue
1763 except TypeError:
1764 main.log.exception( self.name + ": Object not as expected" )
1765 return None
1766 except pexpect.EOF:
1767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
1769 main.cleanup()
1770 main.exit()
1771 except Exception:
1772 main.log.exception( self.name + ": Uncaught exception!" )
1773 main.cleanup()
1774 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001777 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001778 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001780 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001781 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001782 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001783 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001784 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001786 cmdStr += " -j"
1787 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001788 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001789 main.log.error( self.name + ".flows() response: " +
1790 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001791 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001792 except TypeError:
1793 main.log.exception( self.name + ": Object not as expected" )
1794 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001795 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001796 main.log.error( self.name + ": EOF exception found" )
1797 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001798 main.cleanup()
1799 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001800 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001801 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001802 main.cleanup()
1803 main.exit()
1804
kelvin-onlab4df89f22015-04-13 18:10:23 -07001805 def checkFlowsState( self ):
1806 """
1807 Description:
1808 Check the if all the current flows are in ADDED state or
1809 PENDING_ADD state
1810 Return:
1811 returnValue - Returns main.TRUE only if all flows are in
1812 ADDED state or PENDING_ADD, return main.FALSE
1813 otherwise.
1814 """
1815 try:
1816 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001817 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001818 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001819
kelvin-onlab4df89f22015-04-13 18:10:23 -07001820 for device in tempFlows:
1821 for flow in device.get( 'flows' ):
1822 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1823 'PENDING_ADD':
1824 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf0594d72015-05-19 17:25:12 -07001825 flow.get( 'groupId' ) +
kelvin-onlab4df89f22015-04-13 18:10:23 -07001826 " | state:" + flow.get( 'state' ) )
1827 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001828
kelvin-onlab4df89f22015-04-13 18:10:23 -07001829 return returnValue
1830 except TypeError:
1831 main.log.exception( self.name + ": Object not as expected" )
1832 return None
1833 except pexpect.EOF:
1834 main.log.error( self.name + ": EOF exception found" )
1835 main.log.error( self.name + ": " + self.handle.before )
1836 main.cleanup()
1837 main.exit()
1838 except Exception:
1839 main.log.exception( self.name + ": Uncaught exception!" )
1840 main.cleanup()
1841 main.exit()
1842
kelvin-onlabd3b64892015-01-20 13:26:24 -08001843 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001844 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001845 """
andrewonlab87852b02014-11-19 18:44:19 -05001846 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001847 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001848 a specific point-to-point intent definition
1849 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001850 * dpidSrc: specify source dpid
1851 * dpidDst: specify destination dpid
1852 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001853 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001854 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001855 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001857 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001858 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001859 """
andrewonlab87852b02014-11-19 18:44:19 -05001860 try:
kelvin8ec71442015-01-15 16:57:00 -08001861 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001862 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1863 str( numIntents )
1864 if numMult:
1865 cmd += " " + str( numMult )
1866 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001867 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001868 if appId:
1869 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001870 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001871 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001872 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.info( handle )
1874 # Split result by newline
1875 newline = handle.split( "\r\r\n" )
1876 # Ignore the first object of list, which is empty
1877 newline = newline[ 1: ]
1878 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001879 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001880 result = result.split( ": " )
1881 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001882 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1883 main.log.info( latResult )
1884 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001885 else:
1886 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001887 except TypeError:
1888 main.log.exception( self.name + ": Object not as expected" )
1889 return None
andrewonlab87852b02014-11-19 18:44:19 -05001890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001891 main.log.error( self.name + ": EOF exception found" )
1892 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001893 main.cleanup()
1894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001896 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001897 main.cleanup()
1898 main.exit()
1899
kelvin-onlabd3b64892015-01-20 13:26:24 -08001900 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001901 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001902 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001903 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001904 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001905 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001906 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001907 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001908 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001909 cmdStr += " -j"
1910 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001911 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001912 except TypeError:
1913 main.log.exception( self.name + ": Object not as expected" )
1914 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001915 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001916 main.log.error( self.name + ": EOF exception found" )
1917 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001918 main.cleanup()
1919 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001920 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001921 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001922 main.cleanup()
1923 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001924
kelvin-onlabd3b64892015-01-20 13:26:24 -08001925 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001926 """
1927 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001928 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001930 """
andrewonlab867212a2014-10-22 20:13:38 -04001931 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001932 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001933 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001934 cmdStr += " -j"
1935 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001936 if handle:
1937 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001938 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001939 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001940 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001941 else:
1942 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001943 except TypeError:
1944 main.log.exception( self.name + ": Object not as expected" )
1945 return None
andrewonlab867212a2014-10-22 20:13:38 -04001946 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001947 main.log.error( self.name + ": EOF exception found" )
1948 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001949 main.cleanup()
1950 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001951 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001952 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001953 main.cleanup()
1954 main.exit()
1955
kelvin8ec71442015-01-15 16:57:00 -08001956 # Wrapper functions ****************
1957 # Wrapper functions use existing driver
1958 # functions and extends their use case.
1959 # For example, we may use the output of
1960 # a normal driver function, and parse it
1961 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001962
kelvin-onlabd3b64892015-01-20 13:26:24 -08001963 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001964 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001965 Description:
1966 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001967 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001968 try:
kelvin8ec71442015-01-15 16:57:00 -08001969 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001970 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001971 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001972
kelvin8ec71442015-01-15 16:57:00 -08001973 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001974 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1975 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001976 match = re.search('id=0x([\da-f]+),', intents)
1977 if match:
1978 tmpId = match.group()[3:-1]
1979 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001980 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001981
Jon Halld4d4b372015-01-28 16:02:41 -08001982 except TypeError:
1983 main.log.exception( self.name + ": Object not as expected" )
1984 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001985 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001986 main.log.error( self.name + ": EOF exception found" )
1987 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001988 main.cleanup()
1989 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001990 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001991 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001992 main.cleanup()
1993 main.exit()
1994
Jon Hall30b82fa2015-03-04 17:15:43 -08001995 def FlowAddedCount( self, deviceId ):
1996 """
1997 Determine the number of flow rules for the given device id that are
1998 in the added state
1999 """
2000 try:
2001 cmdStr = "flows any " + str( deviceId ) + " | " +\
2002 "grep 'state=ADDED' | wc -l"
2003 handle = self.sendline( cmdStr )
2004 return handle
2005 except pexpect.EOF:
2006 main.log.error( self.name + ": EOF exception found" )
2007 main.log.error( self.name + ": " + self.handle.before )
2008 main.cleanup()
2009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002010 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002011 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002012 main.cleanup()
2013 main.exit()
2014
kelvin-onlabd3b64892015-01-20 13:26:24 -08002015 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002016 """
andrewonlab95ce8322014-10-13 14:12:04 -04002017 Use 'devices' function to obtain list of all devices
2018 and parse the result to obtain a list of all device
2019 id's. Returns this list. Returns empty list if no
2020 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002021 List is ordered sequentially
2022
andrewonlab95ce8322014-10-13 14:12:04 -04002023 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002024 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002025 the ids. By obtaining the list of device ids on the fly,
2026 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002027 """
andrewonlab95ce8322014-10-13 14:12:04 -04002028 try:
kelvin8ec71442015-01-15 16:57:00 -08002029 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002030 devicesStr = self.devices( jsonFormat=False )
2031 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002032
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002034 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 return idList
kelvin8ec71442015-01-15 16:57:00 -08002036
2037 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002038 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002039 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002040 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002041 # Split list further into arguments before and after string
2042 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002043 # append to idList
2044 for arg in tempList:
2045 idList.append( arg.split( "id=" )[ 1 ] )
2046 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002047
Jon Halld4d4b372015-01-28 16:02:41 -08002048 except TypeError:
2049 main.log.exception( self.name + ": Object not as expected" )
2050 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002051 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002052 main.log.error( self.name + ": EOF exception found" )
2053 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002054 main.cleanup()
2055 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002056 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002057 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002058 main.cleanup()
2059 main.exit()
2060
kelvin-onlabd3b64892015-01-20 13:26:24 -08002061 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002062 """
andrewonlab7c211572014-10-15 16:45:20 -04002063 Uses 'nodes' function to obtain list of all nodes
2064 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002065 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002066 Returns:
2067 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002068 """
andrewonlab7c211572014-10-15 16:45:20 -04002069 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002070 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002072 # Sample nodesStr output
2073 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002075 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002077 nodesJson = json.loads( nodesStr )
2078 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002079 return idList
kelvin8ec71442015-01-15 16:57:00 -08002080
Jon Halld4d4b372015-01-28 16:02:41 -08002081 except TypeError:
2082 main.log.exception( self.name + ": Object not as expected" )
2083 return None
andrewonlab7c211572014-10-15 16:45:20 -04002084 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002085 main.log.error( self.name + ": EOF exception found" )
2086 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002087 main.cleanup()
2088 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002089 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002090 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002091 main.cleanup()
2092 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002093
kelvin-onlabd3b64892015-01-20 13:26:24 -08002094 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002095 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002096 Return the first device from the devices api whose 'id' contains 'dpid'
2097 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002098 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002099 try:
kelvin8ec71442015-01-15 16:57:00 -08002100 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002101 return None
2102 else:
kelvin8ec71442015-01-15 16:57:00 -08002103 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 rawDevices = self.devices()
2105 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002106 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002107 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002108 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2109 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002110 return device
2111 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002112 except TypeError:
2113 main.log.exception( self.name + ": Object not as expected" )
2114 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002115 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002116 main.log.error( self.name + ": EOF exception found" )
2117 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002118 main.cleanup()
2119 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002120 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002121 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002122 main.cleanup()
2123 main.exit()
2124
kelvin-onlabd3b64892015-01-20 13:26:24 -08002125 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002126 """
Jon Hallefbd9792015-03-05 16:11:36 -08002127 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002128 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002129 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002130
Jon Hall42db6dc2014-10-24 19:03:48 -04002131 Params: ip = ip used for the onos cli
2132 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002133 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002134 logLevel = level to log to. Currently accepts
2135 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002136
2137
kelvin-onlabd3b64892015-01-20 13:26:24 -08002138 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002139
Jon Hallefbd9792015-03-05 16:11:36 -08002140 Returns: main.TRUE if the number of switches and links are correct,
2141 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002142 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002143 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002144 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002145 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002146 if topology == {}:
2147 return main.ERROR
2148 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002149 # Is the number of switches is what we expected
2150 devices = topology.get( 'devices', False )
2151 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002152 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002153 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002154 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002155 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002156 linkCheck = ( int( links ) == int( numolink ) )
2157 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002158 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002159 output += "The number of links and switches match " +\
2160 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002161 result = main.TRUE
2162 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002163 output += "The number of links and switches does not match " +\
2164 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002165 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002166 output = output + "\n ONOS sees %i devices (%i expected) \
2167 and %i links (%i expected)" % (
2168 int( devices ), int( numoswitch ), int( links ),
2169 int( numolink ) )
2170 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002171 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002172 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002173 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002174 else:
Jon Hall390696c2015-05-05 17:13:41 -07002175 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002176 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002177 except TypeError:
2178 main.log.exception( self.name + ": Object not as expected" )
2179 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002180 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002181 main.log.error( self.name + ": EOF exception found" )
2182 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002183 main.cleanup()
2184 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002185 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002186 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002187 main.cleanup()
2188 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002189
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002191 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002192 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002193 deviceId must be the id of a device as seen in the onos devices command
2194 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002195 role must be either master, standby, or none
2196
Jon Halle3f39ff2015-01-13 11:50:53 -08002197 Returns:
2198 main.TRUE or main.FALSE based on argument verification and
2199 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002200 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002201 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002202 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002203 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002204 cmdStr = "device-role " +\
2205 str( deviceId ) + " " +\
2206 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002207 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002208 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002209 if re.search( "Error", handle ):
2210 # end color output to escape any colours
2211 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002212 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002213 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002214 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002215 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002216 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002217 main.log.error( "Invalid 'role' given to device_role(). " +
2218 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002219 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002220 except TypeError:
2221 main.log.exception( self.name + ": Object not as expected" )
2222 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002224 main.log.error( self.name + ": EOF exception found" )
2225 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002226 main.cleanup()
2227 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002229 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002230 main.cleanup()
2231 main.exit()
2232
kelvin-onlabd3b64892015-01-20 13:26:24 -08002233 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002234 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002235 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002236 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002237 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002238 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002239 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002240 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002241 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002242 cmdStr += " -j"
2243 handle = self.sendline( cmdStr )
2244 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002245 except TypeError:
2246 main.log.exception( self.name + ": Object not as expected" )
2247 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002249 main.log.error( self.name + ": EOF exception found" )
2250 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002251 main.cleanup()
2252 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002254 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002255 main.cleanup()
2256 main.exit()
2257
kelvin-onlabd3b64892015-01-20 13:26:24 -08002258 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002259 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002260 CLI command to get the current leader for the Election test application
2261 NOTE: Requires installation of the onos-app-election feature
2262 Returns: Node IP of the leader if one exists
2263 None if none exists
2264 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002265 """
Jon Hall94fd0472014-12-08 11:52:42 -08002266 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002267 cmdStr = "election-test-leader"
2268 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002269 # Leader
2270 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002271 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002272 nodeSearch = re.search( leaderPattern, response )
2273 if nodeSearch:
2274 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002275 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002276 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002277 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002278 # no leader
2279 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002280 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002281 nullSearch = re.search( nullPattern, response )
2282 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002283 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002284 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002285 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002286 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002287 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 if re.search( errorPattern, response ):
2289 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002290 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002291 return main.FALSE
2292 else:
Jon Hall390696c2015-05-05 17:13:41 -07002293 main.log.error( "Error in electionTestLeader on " + self.name +
2294 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002295 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002296 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002297 except TypeError:
2298 main.log.exception( self.name + ": Object not as expected" )
2299 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002300 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002301 main.log.error( self.name + ": EOF exception found" )
2302 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002303 main.cleanup()
2304 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002305 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002306 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002307 main.cleanup()
2308 main.exit()
2309
kelvin-onlabd3b64892015-01-20 13:26:24 -08002310 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002311 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002312 CLI command to run for leadership of the Election test application.
2313 NOTE: Requires installation of the onos-app-election feature
2314 Returns: Main.TRUE on success
2315 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002316 """
Jon Hall94fd0472014-12-08 11:52:42 -08002317 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002318 cmdStr = "election-test-run"
2319 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002320 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002321 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002322 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002323 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002324 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002325 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002326 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002327 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002328 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002329 errorPattern = "Command\snot\sfound"
2330 if re.search( errorPattern, response ):
2331 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002332 return main.FALSE
2333 else:
Jon Hall390696c2015-05-05 17:13:41 -07002334 main.log.error( "Error in electionTestRun on " + self.name +
2335 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002336 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002337 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002338 except TypeError:
2339 main.log.exception( self.name + ": Object not as expected" )
2340 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002341 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002342 main.log.error( self.name + ": EOF exception found" )
2343 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002344 main.cleanup()
2345 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002346 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002347 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002348 main.cleanup()
2349 main.exit()
2350
kelvin-onlabd3b64892015-01-20 13:26:24 -08002351 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002352 """
Jon Hall94fd0472014-12-08 11:52:42 -08002353 * CLI command to withdraw the local node from leadership election for
2354 * the Election test application.
2355 #NOTE: Requires installation of the onos-app-election feature
2356 Returns: Main.TRUE on success
2357 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002358 """
Jon Hall94fd0472014-12-08 11:52:42 -08002359 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002360 cmdStr = "election-test-withdraw"
2361 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002362 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002363 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002364 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002365 if re.search( successPattern, response ):
2366 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002367 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002368 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002369 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002370 errorPattern = "Command\snot\sfound"
2371 if re.search( errorPattern, response ):
2372 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002373 return main.FALSE
2374 else:
Jon Hall390696c2015-05-05 17:13:41 -07002375 main.log.error( "Error in electionTestWithdraw on " +
2376 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002377 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002378 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002379 except TypeError:
2380 main.log.exception( self.name + ": Object not as expected" )
2381 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002382 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002383 main.log.error( self.name + ": EOF exception found" )
2384 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002385 main.cleanup()
2386 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002387 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002388 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002389 main.cleanup()
2390 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002391
kelvin8ec71442015-01-15 16:57:00 -08002392 def getDevicePortsEnabledCount( self, dpid ):
2393 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002394 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002395 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002396 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002397 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002398 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2399 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002400 if re.search( "No such device", output ):
2401 main.log.error( "Error in getting ports" )
2402 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002403 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002404 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002405 except TypeError:
2406 main.log.exception( self.name + ": Object not as expected" )
2407 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002408 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002409 main.log.error( self.name + ": EOF exception found" )
2410 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002411 main.cleanup()
2412 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002413 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002414 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002415 main.cleanup()
2416 main.exit()
2417
kelvin8ec71442015-01-15 16:57:00 -08002418 def getDeviceLinksActiveCount( self, dpid ):
2419 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002420 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002421 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002422 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002423 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002424 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2425 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002426 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002427 main.log.error( "Error in getting ports " )
2428 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002429 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002430 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002431 except TypeError:
2432 main.log.exception( self.name + ": Object not as expected" )
2433 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002435 main.log.error( self.name + ": EOF exception found" )
2436 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002437 main.cleanup()
2438 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002439 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002440 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002441 main.cleanup()
2442 main.exit()
2443
kelvin8ec71442015-01-15 16:57:00 -08002444 def getAllIntentIds( self ):
2445 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002446 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002447 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002448 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002449 cmdStr = "onos:intents | grep id="
2450 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002451 if re.search( "Error", output ):
2452 main.log.error( "Error in getting ports" )
2453 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002454 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002455 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002456 except TypeError:
2457 main.log.exception( self.name + ": Object not as expected" )
2458 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002459 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002460 main.log.error( self.name + ": EOF exception found" )
2461 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002462 main.cleanup()
2463 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002464 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002465 main.log.exception( self.name + ": Uncaught exception!" )
2466 main.cleanup()
2467 main.exit()
2468
Jon Hall73509952015-02-24 16:42:56 -08002469 def intentSummary( self ):
2470 """
Jon Hallefbd9792015-03-05 16:11:36 -08002471 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002472 """
2473 try:
2474 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002475 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002476 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002477 states.append( intent.get( 'state', None ) )
2478 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002479 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002480 return dict( out )
2481 except TypeError:
2482 main.log.exception( self.name + ": Object not as expected" )
2483 return None
2484 except pexpect.EOF:
2485 main.log.error( self.name + ": EOF exception found" )
2486 main.log.error( self.name + ": " + self.handle.before )
2487 main.cleanup()
2488 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002489 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002490 main.log.exception( self.name + ": Uncaught exception!" )
2491 main.cleanup()
2492 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002493
Jon Hall61282e32015-03-19 11:34:11 -07002494 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002495 """
2496 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002497 Optional argument:
2498 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002499 """
2500 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002501 # Sample JSON
2502 # {
2503 # "electedTime": "13m ago",
2504 # "epoch": 4,
2505 # "leader": "10.128.30.17",
2506 # "topic": "intent-partition-3"
2507 # },
Jon Hall63604932015-02-26 17:09:50 -08002508 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002509 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002510 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002511 cmdStr += " -j"
2512 output = self.sendline( cmdStr )
2513 return output
Jon Hall63604932015-02-26 17:09:50 -08002514 except TypeError:
2515 main.log.exception( self.name + ": Object not as expected" )
2516 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002517 except pexpect.EOF:
2518 main.log.error( self.name + ": EOF exception found" )
2519 main.log.error( self.name + ": " + self.handle.before )
2520 main.cleanup()
2521 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002522 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002523 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002524 main.cleanup()
2525 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002526
Jon Hall61282e32015-03-19 11:34:11 -07002527 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002528 """
2529 Returns the output of the intent Pending map.
2530 """
Jon Hall63604932015-02-26 17:09:50 -08002531 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002532 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002533 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002534 cmdStr += " -j"
2535 output = self.sendline( cmdStr )
2536 return output
Jon Hall63604932015-02-26 17:09:50 -08002537 except TypeError:
2538 main.log.exception( self.name + ": Object not as expected" )
2539 return None
2540 except pexpect.EOF:
2541 main.log.error( self.name + ": EOF exception found" )
2542 main.log.error( self.name + ": " + self.handle.before )
2543 main.cleanup()
2544 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002545 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002546 main.log.exception( self.name + ": Uncaught exception!" )
2547 main.cleanup()
2548 main.exit()
2549
Jon Hall61282e32015-03-19 11:34:11 -07002550 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002551 """
2552 Returns the output of the raft partitions command for ONOS.
2553 """
Jon Hall61282e32015-03-19 11:34:11 -07002554 # Sample JSON
2555 # {
2556 # "leader": "tcp://10.128.30.11:7238",
2557 # "members": [
2558 # "tcp://10.128.30.11:7238",
2559 # "tcp://10.128.30.17:7238",
2560 # "tcp://10.128.30.13:7238",
2561 # ],
2562 # "name": "p1",
2563 # "term": 3
2564 # },
Jon Hall63604932015-02-26 17:09:50 -08002565 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002566 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002567 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002568 cmdStr += " -j"
2569 output = self.sendline( cmdStr )
2570 return output
Jon Hall63604932015-02-26 17:09:50 -08002571 except TypeError:
2572 main.log.exception( self.name + ": Object not as expected" )
2573 return None
2574 except pexpect.EOF:
2575 main.log.error( self.name + ": EOF exception found" )
2576 main.log.error( self.name + ": " + self.handle.before )
2577 main.cleanup()
2578 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002579 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002580 main.log.exception( self.name + ": Uncaught exception!" )
2581 main.cleanup()
2582 main.exit()
2583
Jon Hallbe379602015-03-24 13:39:32 -07002584 def apps( self, jsonFormat=True ):
2585 """
2586 Returns the output of the apps command for ONOS. This command lists
2587 information about installed ONOS applications
2588 """
2589 # Sample JSON object
2590 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2591 # "description":"ONOS OpenFlow protocol southbound providers",
2592 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2593 # "features":"[onos-openflow]","state":"ACTIVE"}]
2594 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002595 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002596 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002597 cmdStr += " -j"
2598 output = self.sendline( cmdStr )
2599 assert "Error executing command" not in output
2600 return output
Jon Hallbe379602015-03-24 13:39:32 -07002601 # FIXME: look at specific exceptions/Errors
2602 except AssertionError:
2603 main.log.error( "Error in processing onos:app command: " +
2604 str( output ) )
2605 return None
2606 except TypeError:
2607 main.log.exception( self.name + ": Object not as expected" )
2608 return None
2609 except pexpect.EOF:
2610 main.log.error( self.name + ": EOF exception found" )
2611 main.log.error( self.name + ": " + self.handle.before )
2612 main.cleanup()
2613 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002614 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002615 main.log.exception( self.name + ": Uncaught exception!" )
2616 main.cleanup()
2617 main.exit()
2618
Jon Hall146f1522015-03-24 15:33:24 -07002619 def appStatus( self, appName ):
2620 """
2621 Uses the onos:apps cli command to return the status of an application.
2622 Returns:
2623 "ACTIVE" - If app is installed and activated
2624 "INSTALLED" - If app is installed and deactivated
2625 "UNINSTALLED" - If app is not installed
2626 None - on error
2627 """
Jon Hall146f1522015-03-24 15:33:24 -07002628 try:
2629 if not isinstance( appName, types.StringType ):
2630 main.log.error( self.name + ".appStatus(): appName must be" +
2631 " a string" )
2632 return None
2633 output = self.apps( jsonFormat=True )
2634 appsJson = json.loads( output )
2635 state = None
2636 for app in appsJson:
2637 if appName == app.get('name'):
2638 state = app.get('state')
2639 break
2640 if state == "ACTIVE" or state == "INSTALLED":
2641 return state
2642 elif state is None:
2643 return "UNINSTALLED"
2644 elif state:
2645 main.log.error( "Unexpected state from 'onos:apps': " +
2646 str( state ) )
2647 return state
2648 except TypeError:
2649 main.log.exception( self.name + ": Object not as expected" )
2650 return None
2651 except pexpect.EOF:
2652 main.log.error( self.name + ": EOF exception found" )
2653 main.log.error( self.name + ": " + self.handle.before )
2654 main.cleanup()
2655 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002656 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002657 main.log.exception( self.name + ": Uncaught exception!" )
2658 main.cleanup()
2659 main.exit()
2660
Jon Hallbe379602015-03-24 13:39:32 -07002661 def app( self, appName, option ):
2662 """
2663 Interacts with the app command for ONOS. This command manages
2664 application inventory.
2665 """
Jon Hallbe379602015-03-24 13:39:32 -07002666 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002667 # Validate argument types
2668 valid = True
2669 if not isinstance( appName, types.StringType ):
2670 main.log.error( self.name + ".app(): appName must be a " +
2671 "string" )
2672 valid = False
2673 if not isinstance( option, types.StringType ):
2674 main.log.error( self.name + ".app(): option must be a string" )
2675 valid = False
2676 if not valid:
2677 return main.FALSE
2678 # Validate Option
2679 option = option.lower()
2680 # NOTE: Install may become a valid option
2681 if option == "activate":
2682 pass
2683 elif option == "deactivate":
2684 pass
2685 elif option == "uninstall":
2686 pass
2687 else:
2688 # Invalid option
2689 main.log.error( "The ONOS app command argument only takes " +
2690 "the values: (activate|deactivate|uninstall)" +
2691 "; was given '" + option + "'")
2692 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002693 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002694 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002695 if "Error executing command" in output:
2696 main.log.error( "Error in processing onos:app command: " +
2697 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002698 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002699 elif "No such application" in output:
2700 main.log.error( "The application '" + appName +
2701 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002702 return main.FALSE
2703 elif "Command not found:" in output:
2704 main.log.error( "Error in processing onos:app command: " +
2705 str( output ) )
2706 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002707 elif "Unsupported command:" in output:
2708 main.log.error( "Incorrect command given to 'app': " +
2709 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002710 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002711 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002712 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002713 return main.TRUE
2714 except TypeError:
2715 main.log.exception( self.name + ": Object not as expected" )
2716 return main.ERROR
2717 except pexpect.EOF:
2718 main.log.error( self.name + ": EOF exception found" )
2719 main.log.error( self.name + ": " + self.handle.before )
2720 main.cleanup()
2721 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002722 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002723 main.log.exception( self.name + ": Uncaught exception!" )
2724 main.cleanup()
2725 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002726
Jon Hallbd16b922015-03-26 17:53:15 -07002727 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002728 """
2729 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002730 appName is the hierarchical app name, not the feature name
2731 If check is True, method will check the status of the app after the
2732 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002733 Returns main.TRUE if the command was successfully sent
2734 main.FALSE if the cli responded with an error or given
2735 incorrect input
2736 """
2737 try:
2738 if not isinstance( appName, types.StringType ):
2739 main.log.error( self.name + ".activateApp(): appName must be" +
2740 " a string" )
2741 return main.FALSE
2742 status = self.appStatus( appName )
2743 if status == "INSTALLED":
2744 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002745 if check and response == main.TRUE:
2746 for i in range(10): # try 10 times then give up
2747 # TODO: Check with Thomas about this delay
2748 status = self.appStatus( appName )
2749 if status == "ACTIVE":
2750 return main.TRUE
2751 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002752 main.log.debug( "The state of application " +
2753 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002754 time.sleep( 1 )
2755 return main.FALSE
2756 else: # not 'check' or command didn't succeed
2757 return response
Jon Hall146f1522015-03-24 15:33:24 -07002758 elif status == "ACTIVE":
2759 return main.TRUE
2760 elif status == "UNINSTALLED":
2761 main.log.error( self.name + ": Tried to activate the " +
2762 "application '" + appName + "' which is not " +
2763 "installed." )
2764 else:
2765 main.log.error( "Unexpected return value from appStatus: " +
2766 str( status ) )
2767 return main.ERROR
2768 except TypeError:
2769 main.log.exception( self.name + ": Object not as expected" )
2770 return main.ERROR
2771 except pexpect.EOF:
2772 main.log.error( self.name + ": EOF exception found" )
2773 main.log.error( self.name + ": " + self.handle.before )
2774 main.cleanup()
2775 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002776 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002777 main.log.exception( self.name + ": Uncaught exception!" )
2778 main.cleanup()
2779 main.exit()
2780
Jon Hallbd16b922015-03-26 17:53:15 -07002781 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002782 """
2783 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002784 appName is the hierarchical app name, not the feature name
2785 If check is True, method will check the status of the app after the
2786 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002787 Returns main.TRUE if the command was successfully sent
2788 main.FALSE if the cli responded with an error or given
2789 incorrect input
2790 """
2791 try:
2792 if not isinstance( appName, types.StringType ):
2793 main.log.error( self.name + ".deactivateApp(): appName must " +
2794 "be a string" )
2795 return main.FALSE
2796 status = self.appStatus( appName )
2797 if status == "INSTALLED":
2798 return main.TRUE
2799 elif status == "ACTIVE":
2800 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002801 if check and response == main.TRUE:
2802 for i in range(10): # try 10 times then give up
2803 status = self.appStatus( appName )
2804 if status == "INSTALLED":
2805 return main.TRUE
2806 else:
2807 time.sleep( 1 )
2808 return main.FALSE
2809 else: # not check or command didn't succeed
2810 return response
Jon Hall146f1522015-03-24 15:33:24 -07002811 elif status == "UNINSTALLED":
2812 main.log.warn( self.name + ": Tried to deactivate the " +
2813 "application '" + appName + "' which is not " +
2814 "installed." )
2815 return main.TRUE
2816 else:
2817 main.log.error( "Unexpected return value from appStatus: " +
2818 str( status ) )
2819 return main.ERROR
2820 except TypeError:
2821 main.log.exception( self.name + ": Object not as expected" )
2822 return main.ERROR
2823 except pexpect.EOF:
2824 main.log.error( self.name + ": EOF exception found" )
2825 main.log.error( self.name + ": " + self.handle.before )
2826 main.cleanup()
2827 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002828 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002829 main.log.exception( self.name + ": Uncaught exception!" )
2830 main.cleanup()
2831 main.exit()
2832
Jon Hallbd16b922015-03-26 17:53:15 -07002833 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002834 """
2835 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002836 appName is the hierarchical app name, not the feature name
2837 If check is True, method will check the status of the app after the
2838 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002839 Returns main.TRUE if the command was successfully sent
2840 main.FALSE if the cli responded with an error or given
2841 incorrect input
2842 """
2843 # TODO: check with Thomas about the state machine for apps
2844 try:
2845 if not isinstance( appName, types.StringType ):
2846 main.log.error( self.name + ".uninstallApp(): appName must " +
2847 "be a string" )
2848 return main.FALSE
2849 status = self.appStatus( appName )
2850 if status == "INSTALLED":
2851 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002852 if check and response == main.TRUE:
2853 for i in range(10): # try 10 times then give up
2854 status = self.appStatus( appName )
2855 if status == "UNINSTALLED":
2856 return main.TRUE
2857 else:
2858 time.sleep( 1 )
2859 return main.FALSE
2860 else: # not check or command didn't succeed
2861 return response
Jon Hall146f1522015-03-24 15:33:24 -07002862 elif status == "ACTIVE":
2863 main.log.warn( self.name + ": Tried to uninstall the " +
2864 "application '" + appName + "' which is " +
2865 "currently active." )
2866 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002867 if check and response == main.TRUE:
2868 for i in range(10): # try 10 times then give up
2869 status = self.appStatus( appName )
2870 if status == "UNINSTALLED":
2871 return main.TRUE
2872 else:
2873 time.sleep( 1 )
2874 return main.FALSE
2875 else: # not check or command didn't succeed
2876 return response
Jon Hall146f1522015-03-24 15:33:24 -07002877 elif status == "UNINSTALLED":
2878 return main.TRUE
2879 else:
2880 main.log.error( "Unexpected return value from appStatus: " +
2881 str( status ) )
2882 return main.ERROR
2883 except TypeError:
2884 main.log.exception( self.name + ": Object not as expected" )
2885 return main.ERROR
2886 except pexpect.EOF:
2887 main.log.error( self.name + ": EOF exception found" )
2888 main.log.error( self.name + ": " + self.handle.before )
2889 main.cleanup()
2890 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002891 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002892 main.log.exception( self.name + ": Uncaught exception!" )
2893 main.cleanup()
2894 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002895
2896 def appIDs( self, jsonFormat=True ):
2897 """
2898 Show the mappings between app id and app names given by the 'app-ids'
2899 cli command
2900 """
2901 try:
2902 cmdStr = "app-ids"
2903 if jsonFormat:
2904 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002905 output = self.sendline( cmdStr )
2906 assert "Error executing command" not in output
2907 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002908 except AssertionError:
2909 main.log.error( "Error in processing onos:app-ids command: " +
2910 str( output ) )
2911 return None
2912 except TypeError:
2913 main.log.exception( self.name + ": Object not as expected" )
2914 return None
2915 except pexpect.EOF:
2916 main.log.error( self.name + ": EOF exception found" )
2917 main.log.error( self.name + ": " + self.handle.before )
2918 main.cleanup()
2919 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002920 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002921 main.log.exception( self.name + ": Uncaught exception!" )
2922 main.cleanup()
2923 main.exit()
2924
2925 def appToIDCheck( self ):
2926 """
2927 This method will check that each application's ID listed in 'apps' is
2928 the same as the ID listed in 'app-ids'. The check will also check that
2929 there are no duplicate IDs issued. Note that an app ID should be
2930 a globaly unique numerical identifier for app/app-like features. Once
2931 an ID is registered, the ID is never freed up so that if an app is
2932 reinstalled it will have the same ID.
2933
2934 Returns: main.TRUE if the check passes and
2935 main.FALSE if the check fails or
2936 main.ERROR if there is some error in processing the test
2937 """
2938 try:
Jon Hall390696c2015-05-05 17:13:41 -07002939 bail = False
2940 ids = self.appIDs( jsonFormat=True )
2941 if ids:
2942 ids = json.loads( ids )
2943 else:
2944 main.log.error( "app-ids returned nothing:" + repr( ids ) )
2945 bail = True
2946 apps = self.apps( jsonFormat=True )
2947 if apps:
2948 apps = json.loads( apps )
2949 else:
2950 main.log.error( "apps returned nothing:" + repr( apps ) )
2951 bail = True
2952 if bail:
2953 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002954 result = main.TRUE
2955 for app in apps:
2956 appID = app.get( 'id' )
2957 if appID is None:
2958 main.log.error( "Error parsing app: " + str( app ) )
2959 result = main.FALSE
2960 appName = app.get( 'name' )
2961 if appName is None:
2962 main.log.error( "Error parsing app: " + str( app ) )
2963 result = main.FALSE
2964 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07002965 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07002966 # main.log.debug( "Comparing " + str( app ) + " to " +
2967 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002968 if not current: # if ids doesn't have this id
2969 result = main.FALSE
2970 main.log.error( "'app-ids' does not have the ID for " +
2971 str( appName ) + " that apps does." )
2972 elif len( current ) > 1:
2973 # there is more than one app with this ID
2974 result = main.FALSE
2975 # We will log this later in the method
2976 elif not current[0][ 'name' ] == appName:
2977 currentName = current[0][ 'name' ]
2978 result = main.FALSE
2979 main.log.error( "'app-ids' has " + str( currentName ) +
2980 " registered under id:" + str( appID ) +
2981 " but 'apps' has " + str( appName ) )
2982 else:
2983 pass # id and name match!
2984 # now make sure that app-ids has no duplicates
2985 idsList = []
2986 namesList = []
2987 for item in ids:
2988 idsList.append( item[ 'id' ] )
2989 namesList.append( item[ 'name' ] )
2990 if len( idsList ) != len( set( idsList ) ) or\
2991 len( namesList ) != len( set( namesList ) ):
2992 main.log.error( "'app-ids' has some duplicate entries: \n"
2993 + json.dumps( ids,
2994 sort_keys=True,
2995 indent=4,
2996 separators=( ',', ': ' ) ) )
2997 result = main.FALSE
2998 return result
2999 except ( ValueError, TypeError ):
3000 main.log.exception( self.name + ": Object not as expected" )
3001 return main.ERROR
3002 except pexpect.EOF:
3003 main.log.error( self.name + ": EOF exception found" )
3004 main.log.error( self.name + ": " + self.handle.before )
3005 main.cleanup()
3006 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003007 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003008 main.log.exception( self.name + ": Uncaught exception!" )
3009 main.cleanup()
3010 main.exit()
3011
Jon Hallfb760a02015-04-13 15:35:03 -07003012 def getCfg( self, component=None, propName=None, short=False,
3013 jsonFormat=True ):
3014 """
3015 Get configuration settings from onos cli
3016 Optional arguments:
3017 component - Optionally only list configurations for a specific
3018 component. If None, all components with configurations
3019 are displayed. Case Sensitive string.
3020 propName - If component is specified, propName option will show
3021 only this specific configuration from that component.
3022 Case Sensitive string.
3023 jsonFormat - Returns output as json. Note that this will override
3024 the short option
3025 short - Short, less verbose, version of configurations.
3026 This is overridden by the json option
3027 returns:
3028 Output from cli as a string or None on error
3029 """
3030 try:
3031 baseStr = "cfg"
3032 cmdStr = " get"
3033 componentStr = ""
3034 if component:
3035 componentStr += " " + component
3036 if propName:
3037 componentStr += " " + propName
3038 if jsonFormat:
3039 baseStr += " -j"
3040 elif short:
3041 baseStr += " -s"
3042 output = self.sendline( baseStr + cmdStr + componentStr )
3043 assert "Error executing command" not in output
3044 return output
3045 except AssertionError:
3046 main.log.error( "Error in processing 'cfg get' command: " +
3047 str( output ) )
3048 return None
3049 except TypeError:
3050 main.log.exception( self.name + ": Object not as expected" )
3051 return None
3052 except pexpect.EOF:
3053 main.log.error( self.name + ": EOF exception found" )
3054 main.log.error( self.name + ": " + self.handle.before )
3055 main.cleanup()
3056 main.exit()
3057 except Exception:
3058 main.log.exception( self.name + ": Uncaught exception!" )
3059 main.cleanup()
3060 main.exit()
3061
3062 def setCfg( self, component, propName, value=None, check=True ):
3063 """
3064 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003065 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003066 component - The case sensitive name of the component whose
3067 property is to be set
3068 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003069 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003070 value - The value to set the property to. If None, will unset the
3071 property and revert it to it's default value(if applicable)
3072 check - Boolean, Check whether the option was successfully set this
3073 only applies when a value is given.
3074 returns:
3075 main.TRUE on success or main.FALSE on failure. If check is False,
3076 will return main.TRUE unless there is an error
3077 """
3078 try:
3079 baseStr = "cfg"
3080 cmdStr = " set " + str( component ) + " " + str( propName )
3081 if value is not None:
3082 cmdStr += " " + str( value )
3083 output = self.sendline( baseStr + cmdStr )
3084 assert "Error executing command" not in output
3085 if value and check:
3086 results = self.getCfg( component=str( component ),
3087 propName=str( propName ),
3088 jsonFormat=True )
3089 # Check if current value is what we just set
3090 try:
3091 jsonOutput = json.loads( results )
3092 current = jsonOutput[ 'value' ]
3093 except ( ValueError, TypeError ):
3094 main.log.exception( "Error parsing cfg output" )
3095 main.log.error( "output:" + repr( results ) )
3096 return main.FALSE
3097 if current == str( value ):
3098 return main.TRUE
3099 return main.FALSE
3100 return main.TRUE
3101 except AssertionError:
3102 main.log.error( "Error in processing 'cfg set' command: " +
3103 str( output ) )
3104 return main.FALSE
3105 except TypeError:
3106 main.log.exception( self.name + ": Object not as expected" )
3107 return main.FALSE
3108 except pexpect.EOF:
3109 main.log.error( self.name + ": EOF exception found" )
3110 main.log.error( self.name + ": " + self.handle.before )
3111 main.cleanup()
3112 main.exit()
3113 except Exception:
3114 main.log.exception( self.name + ": Uncaught exception!" )
3115 main.cleanup()
3116 main.exit()
3117
Jon Hall390696c2015-05-05 17:13:41 -07003118 def setTestAdd( self, setName, values ):
3119 """
3120 CLI command to add elements to a distributed set.
3121 Arguments:
3122 setName - The name of the set to add to.
3123 values - The value(s) to add to the set, space seperated.
3124 Example usages:
3125 setTestAdd( "set1", "a b c" )
3126 setTestAdd( "set2", "1" )
3127 returns:
3128 main.TRUE on success OR
3129 main.FALSE if elements were already in the set OR
3130 main.ERROR on error
3131 """
3132 try:
3133 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3134 output = self.sendline( cmdStr )
3135 assert "Error executing command" not in output
3136 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3137 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3138 main.log.info( self.name + ": " + output )
3139 if re.search( positiveMatch, output):
3140 return main.TRUE
3141 elif re.search( negativeMatch, output):
3142 return main.FALSE
3143 else:
3144 main.log.error( self.name + ": setTestAdd did not" +
3145 " match expected output" )
3146 main.log.debug( self.name + " expected: " + pattern )
3147 main.log.debug( self.name + " actual: " + repr( output ) )
3148 return main.ERROR
3149 except AssertionError:
3150 main.log.error( "Error in processing 'set-test-add' command: " +
3151 str( output ) )
3152 return main.ERROR
3153 except TypeError:
3154 main.log.exception( self.name + ": Object not as expected" )
3155 return main.ERROR
3156 except pexpect.EOF:
3157 main.log.error( self.name + ": EOF exception found" )
3158 main.log.error( self.name + ": " + self.handle.before )
3159 main.cleanup()
3160 main.exit()
3161 except Exception:
3162 main.log.exception( self.name + ": Uncaught exception!" )
3163 main.cleanup()
3164 main.exit()
3165
3166 def setTestRemove( self, setName, values, clear=False, retain=False ):
3167 """
3168 CLI command to remove elements from a distributed set.
3169 Required arguments:
3170 setName - The name of the set to remove from.
3171 values - The value(s) to remove from the set, space seperated.
3172 Optional arguments:
3173 clear - Clear all elements from the set
3174 retain - Retain only the given values. (intersection of the
3175 original set and the given set)
3176 returns:
3177 main.TRUE on success OR
3178 main.FALSE if the set was not changed OR
3179 main.ERROR on error
3180 """
3181 try:
3182 cmdStr = "set-test-remove "
3183 if clear:
3184 cmdStr += "-c " + str( setName )
3185 elif retain:
3186 cmdStr += "-r " + str( setName ) + " " + str( values )
3187 else:
3188 cmdStr += str( setName ) + " " + str( values )
3189 output = self.sendline( cmdStr )
3190 assert "Error executing command" not in output
3191 main.log.info( self.name + ": " + output )
3192 if clear:
3193 pattern = "Set " + str( setName ) + " cleared"
3194 if re.search( pattern, output ):
3195 return main.TRUE
3196 elif retain:
3197 positivePattern = str( setName ) + " was pruned to contain " +\
3198 "only elements of set \[(.*)\]"
3199 negativePattern = str( setName ) + " was not changed by " +\
3200 "retaining only elements of the set " +\
3201 "\[(.*)\]"
3202 if re.search( positivePattern, output ):
3203 return main.TRUE
3204 elif re.search( negativePattern, output ):
3205 return main.FALSE
3206 else:
3207 positivePattern = "\[(.*)\] was removed from the set " +\
3208 str( setName )
3209 if ( len( values.split() ) == 1 ):
3210 negativePattern = "\[(.*)\] was not in set " +\
3211 str( setName )
3212 else:
3213 negativePattern = "No element of \[(.*)\] was in set " +\
3214 str( setName )
3215 if re.search( positivePattern, output ):
3216 return main.TRUE
3217 elif re.search( negativePattern, output ):
3218 return main.FALSE
3219 main.log.error( self.name + ": setTestRemove did not" +
3220 " match expected output" )
3221 main.log.debug( self.name + " expected: " + pattern )
3222 main.log.debug( self.name + " actual: " + repr( output ) )
3223 return main.ERROR
3224 except AssertionError:
3225 main.log.error( "Error in processing 'set-test-remove' command: " +
3226 str( output ) )
3227 return main.ERROR
3228 except TypeError:
3229 main.log.exception( self.name + ": Object not as expected" )
3230 return main.ERROR
3231 except pexpect.EOF:
3232 main.log.error( self.name + ": EOF exception found" )
3233 main.log.error( self.name + ": " + self.handle.before )
3234 main.cleanup()
3235 main.exit()
3236 except Exception:
3237 main.log.exception( self.name + ": Uncaught exception!" )
3238 main.cleanup()
3239 main.exit()
3240
3241 def setTestGet( self, setName, values="" ):
3242 """
3243 CLI command to get the elements in a distributed set.
3244 Required arguments:
3245 setName - The name of the set to remove from.
3246 Optional arguments:
3247 values - The value(s) to check if in the set, space seperated.
3248 returns:
3249 main.ERROR on error OR
3250 A list of elements in the set if no optional arguments are
3251 supplied OR
3252 A tuple containing the list then:
3253 main.FALSE if the given values are not in the set OR
3254 main.TRUE if the given values are in the set OR
3255 """
3256 try:
3257 values = str( values ).strip()
3258 setName = str( setName ).strip()
3259 length = len( values.split() )
3260 containsCheck = None
3261 # Patterns to match
3262 setPattern = "\[(.*)\]"
3263 pattern = "Items in set " + setName + ":\n" + setPattern
3264 containsTrue = "Set " + setName + " contains the value " + values
3265 containsFalse = "Set " + setName + " did not contain the value " +\
3266 values
3267 containsAllTrue = "Set " + setName + " contains the the subset " +\
3268 setPattern
3269 containsAllFalse = "Set " + setName + " did not contain the the" +\
3270 " subset " + setPattern
3271
3272 cmdStr = "set-test-get "
3273 cmdStr += setName + " " + values
3274 output = self.sendline( cmdStr )
3275 assert "Error executing command" not in output
3276 main.log.info( self.name + ": " + output )
3277
3278 if length == 0:
3279 match = re.search( pattern, output )
3280 else: # if given values
3281 if length == 1: # Contains output
3282 patternTrue = pattern + "\n" + containsTrue
3283 patternFalse = pattern + "\n" + containsFalse
3284 else: # ContainsAll output
3285 patternTrue = pattern + "\n" + containsAllTrue
3286 patternFalse = pattern + "\n" + containsAllFalse
3287 matchTrue = re.search( patternTrue, output )
3288 matchFalse = re.search( patternFalse, output )
3289 if matchTrue:
3290 containsCheck = main.TRUE
3291 match = matchTrue
3292 elif matchFalse:
3293 containsCheck = main.FALSE
3294 match = matchFalse
3295 else:
3296 main.log.error( self.name + " setTestGet did not match " +\
3297 "expected output" )
3298 main.log.debug( self.name + " expected: " + pattern )
3299 main.log.debug( self.name + " actual: " + repr( output ) )
3300 match = None
3301 if match:
3302 setMatch = match.group( 1 )
3303 if setMatch == '':
3304 setList = []
3305 else:
3306 setList = setMatch.split( ", " )
3307 if length > 0:
3308 return ( setList, containsCheck )
3309 else:
3310 return setList
3311 else: # no match
3312 main.log.error( self.name + ": setTestGet did not" +
3313 " match expected output" )
3314 main.log.debug( self.name + " expected: " + pattern )
3315 main.log.debug( self.name + " actual: " + repr( output ) )
3316 return main.ERROR
3317 except AssertionError:
3318 main.log.error( "Error in processing 'set-test-get' command: " +
3319 str( output ) )
3320 return main.ERROR
3321 except TypeError:
3322 main.log.exception( self.name + ": Object not as expected" )
3323 return main.ERROR
3324 except pexpect.EOF:
3325 main.log.error( self.name + ": EOF exception found" )
3326 main.log.error( self.name + ": " + self.handle.before )
3327 main.cleanup()
3328 main.exit()
3329 except Exception:
3330 main.log.exception( self.name + ": Uncaught exception!" )
3331 main.cleanup()
3332 main.exit()
3333
3334 def setTestSize( self, setName ):
3335 """
3336 CLI command to get the elements in a distributed set.
3337 Required arguments:
3338 setName - The name of the set to remove from.
3339 returns:
3340 The integer value of the size returned or
3341 None on error
3342 """
3343 try:
3344 # TODO: Should this check against the number of elements returned
3345 # and then return true/false based on that?
3346 setName = str( setName ).strip()
3347 # Patterns to match
3348 setPattern = "\[(.*)\]"
3349 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3350 setPattern
3351 cmdStr = "set-test-get -s "
3352 cmdStr += setName
3353 output = self.sendline( cmdStr )
3354 assert "Error executing command" not in output
3355 main.log.info( self.name + ": " + output )
3356 match = re.search( pattern, output )
3357 if match:
3358 setSize = int( match.group( 1 ) )
3359 setMatch = match.group( 2 )
3360 if len( setMatch.split() ) == setSize:
3361 main.log.info( "The size returned by " + self.name +
3362 " matches the number of elements in " +
3363 "the returned set" )
3364 else:
3365 main.log.error( "The size returned by " + self.name +
3366 " does not match the number of " +
3367 "elements in the returned set." )
3368 return setSize
3369 else: # no match
3370 main.log.error( self.name + ": setTestGet did not" +
3371 " match expected output" )
3372 main.log.debug( self.name + " expected: " + pattern )
3373 main.log.debug( self.name + " actual: " + repr( output ) )
3374 return None
3375 except AssertionError:
3376 main.log.error( "Error in processing 'set-test-get' command: " +
3377 str( output ) )
3378 return None
3379 except TypeError:
3380 main.log.exception( self.name + ": Object not as expected" )
3381 return None
3382 except pexpect.EOF:
3383 main.log.error( self.name + ": EOF exception found" )
3384 main.log.error( self.name + ": " + self.handle.before )
3385 main.cleanup()
3386 main.exit()
3387 except Exception:
3388 main.log.exception( self.name + ": Uncaught exception!" )
3389 main.cleanup()
3390 main.exit()
3391
3392 def counters( self ):
3393 """
3394 Command to list the various counters in the system.
3395 returns:
3396 A dict containing the counters in the system with the counter
3397 names being the keys and the value of the counters being the
3398 values OR
3399 None on error
3400 """
3401 #FIXME: JSON FORMAT
3402 try:
3403 counters = {}
3404 cmdStr = "counters"
3405 output = self.sendline( cmdStr )
3406 assert "Error executing command" not in output
3407 main.log.info( self.name + ": " + output )
3408 for line in output.splitlines():
3409 match = re.search( "name=(\S+) value=(\d+)", line )
3410 if match:
3411 key = match.group( 1 )
3412 value = int( match.group( 2 ) )
3413 counters[key] = value
3414 else:
3415 main.log.error( self.name + ": counters did not match " +
3416 "expected output" )
3417 main.log.debug( self.name + " expected: " + pattern )
3418 main.log.debug( self.name + " actual: " + repr( output ) )
3419 return None
3420 return counters
3421 except AssertionError:
3422 main.log.error( "Error in processing 'counters' command: " +
3423 str( output ) )
3424 return main.ERROR
3425 except TypeError:
3426 main.log.exception( self.name + ": Object not as expected" )
3427 return main.ERROR
3428 except pexpect.EOF:
3429 main.log.error( self.name + ": EOF exception found" )
3430 main.log.error( self.name + ": " + self.handle.before )
3431 main.cleanup()
3432 main.exit()
3433 except Exception:
3434 main.log.exception( self.name + ": Uncaught exception!" )
3435 main.cleanup()
3436 main.exit()
3437
3438 def counterTestIncrement( self, counter, inMemory=False ):
3439 """
3440 CLI command to increment and get a distributed counter.
3441 Required arguments:
3442 counter - The name of the counter to increment.
3443 Optional arguments:
3444 inMemory - use in memory map for the counter
3445 returns:
3446 integer value of the counter or
3447 None on Error
3448 """
3449 try:
3450 counter = str( counter )
3451 cmdStr = "counter-test-increment "
3452 if inMemory:
3453 cmdStr += "-i "
3454 cmdStr += counter
3455 output = self.sendline( cmdStr )
3456 assert "Error executing command" not in output
3457 main.log.info( self.name + ": " + output )
3458 pattern = counter + " was incremented to (\d+)"
3459 match = re.search( pattern, output )
3460 if match:
3461 return int( match.group( 1 ) )
3462 else:
3463 main.log.error( self.name + ": counterTestIncrement did not" +
3464 " match expected output." )
3465 main.log.debug( self.name + " expected: " + pattern )
3466 main.log.debug( self.name + " actual: " + repr( output ) )
3467 return None
3468 except AssertionError:
3469 main.log.error( "Error in processing 'counter-test-increment'" +
3470 " command: " + str( output ) )
3471 return None
3472 except TypeError:
3473 main.log.exception( self.name + ": Object not as expected" )
3474 return None
3475 except pexpect.EOF:
3476 main.log.error( self.name + ": EOF exception found" )
3477 main.log.error( self.name + ": " + self.handle.before )
3478 main.cleanup()
3479 main.exit()
3480 except Exception:
3481 main.log.exception( self.name + ": Uncaught exception!" )
3482 main.cleanup()
3483 main.exit()
3484