blob: fca8f2262700a71dbf95d91a178873c21b91758e [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
pingping-lin57a56ce2015-05-20 16:43:48 -0700191 def startOnosCli( self, ONOSIp, karafTimeout="",
192 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800193 """
Jon Hallefbd9792015-03-05 16:11:36 -0800194 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 by user would be used to set the current karaf shell idle timeout.
196 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800197 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 Below is an example to start a session with 60 seconds idle timeout
199 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800200
Hari Krishna25d42f72015-01-05 15:08:28 -0800201 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800202 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800203
kelvin-onlabd3b64892015-01-20 13:26:24 -0800204 Note: karafTimeout is left as str so that this could be read
205 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800206 """
andrewonlab95ce8322014-10-13 14:12:04 -0400207 try:
kelvin8ec71442015-01-15 16:57:00 -0800208 self.handle.sendline( "" )
209 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700210 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500211
212 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800213 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500214 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400215
kelvin8ec71442015-01-15 16:57:00 -0800216 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800218 i = self.handle.expect( [
219 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700220 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400221
222 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800224 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800225 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800226 "config:property-set -p org.apache.karaf.shell\
227 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800228 karafTimeout )
229 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800230 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800231 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400232 return main.TRUE
233 else:
kelvin8ec71442015-01-15 16:57:00 -0800234 # If failed, send ctrl+c to process and try again
235 main.log.info( "Starting CLI failed. Retrying..." )
236 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800238 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
239 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400240 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800242 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800243 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800244 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 "config:property-set -p org.apache.karaf.shell\
246 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800247 karafTimeout )
248 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800250 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400251 return main.TRUE
252 else:
kelvin8ec71442015-01-15 16:57:00 -0800253 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400255 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400256
Jon Halld4d4b372015-01-28 16:02:41 -0800257 except TypeError:
258 main.log.exception( self.name + ": Object not as expected" )
259 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400260 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800261 main.log.error( self.name + ": EOF exception found" )
262 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400263 main.cleanup()
264 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800265 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800266 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400267 main.cleanup()
268 main.exit()
269
Jon Hallefbd9792015-03-05 16:11:36 -0800270 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800271 """
272 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800273 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800274 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800275 Available level: DEBUG, TRACE, INFO, WARN, ERROR
276 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800277 """
278 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800279 lvlStr = ""
280 if level:
281 lvlStr = "--level=" + level
282
kelvin-onlab9f541032015-02-04 16:19:53 -0800283 self.handle.sendline( "" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700284 i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700285 if i == 1:
Jon Hallc9eabec2015-06-10 14:33:14 -0700286 main.log.error( self.name + ": onos cli session closed." )
287 main.cleanup()
288 main.exit()
289 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700290 self.handle.sendline( "" )
291 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800292 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700293 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800294 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800295
kelvin-onlab9f541032015-02-04 16:19:53 -0800296 response = self.handle.before
297 if re.search( "Error", response ):
298 return main.FALSE
299 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700300 except pexpect.TIMEOUT:
301 main.log.exception( self.name + ": TIMEOUT exception found" )
302 main.cleanup()
303 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800304 except pexpect.EOF:
305 main.log.error( self.name + ": EOF exception found" )
306 main.log.error( self.name + ": " + self.handle.before )
307 main.cleanup()
308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800309 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800310 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400311 main.cleanup()
312 main.exit()
313
Jon Hallc6358dd2015-04-10 12:44:28 -0700314 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800315 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800316 Send a completely user specified string to
317 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400318 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800319
andrewonlaba18f6bf2014-10-13 19:31:54 -0400320 Warning: There are no sanity checking to commands
321 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800322 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400323 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800324 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
325 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800327 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
328 response = self.handle.before
329 if i == 2:
330 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700331 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800332 response += self.handle.before
333 print response
334 try:
335 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700336 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800337 pass
338 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800339 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800340 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700341 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700342 main.log.debug( self.name + ": Raw output" )
343 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700344
345 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800346 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800347 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700348 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700349 main.log.debug( self.name + ": ansiEscape output" )
350 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700351
kelvin-onlabfb521662015-02-27 09:52:40 -0800352 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800353 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700354 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700355 main.log.debug( self.name + ": Removed extra returns " +
356 "from output" )
357 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700358
359 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800360 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700361 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700362 main.log.debug( self.name + ": parsed and stripped output" )
363 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700364
Jon Hall63604932015-02-26 17:09:50 -0800365 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700366 output = response.split( cmdStr.strip(), 1 )
367 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700368 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700369 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700370 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700371 return output[1].strip()
372 except IndexError:
373 main.log.exception( self.name + ": Object not as expected" )
374 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800375 except TypeError:
376 main.log.exception( self.name + ": Object not as expected" )
377 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400378 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800379 main.log.error( self.name + ": EOF exception found" )
380 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400381 main.cleanup()
382 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800383 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800384 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400385 main.cleanup()
386 main.exit()
387
kelvin8ec71442015-01-15 16:57:00 -0800388 # IMPORTANT NOTE:
389 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800390 # the cli command changing 'a:b' with 'aB'.
391 # Ex ) onos:topology > onosTopology
392 # onos:links > onosLinks
393 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800394
kelvin-onlabd3b64892015-01-20 13:26:24 -0800395 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800396 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400397 Adds a new cluster node by ID and address information.
398 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800399 * nodeId
400 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400401 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800403 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400404 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800405 cmdStr = "add-node " + str( nodeId ) + " " +\
406 str( ONOSIp ) + " " + str( tcpPort )
407 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800408 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800409 main.log.error( "Error in adding node" )
410 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800411 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400412 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800413 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400414 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800415 except TypeError:
416 main.log.exception( self.name + ": Object not as expected" )
417 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 main.cleanup()
422 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800423 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800424 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400425 main.cleanup()
426 main.exit()
427
kelvin-onlabd3b64892015-01-20 13:26:24 -0800428 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800429 """
andrewonlab86dc3082014-10-13 18:18:38 -0400430 Removes a cluster by ID
431 Issues command: 'remove-node [<node-id>]'
432 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800434 """
andrewonlab86dc3082014-10-13 18:18:38 -0400435 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400436
kelvin-onlabd3b64892015-01-20 13:26:24 -0800437 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700438 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700439 if re.search( "Error", handle ):
440 main.log.error( "Error in removing node" )
441 main.log.error( handle )
442 return main.FALSE
443 else:
444 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800445 except TypeError:
446 main.log.exception( self.name + ": Object not as expected" )
447 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800449 main.log.error( self.name + ": EOF exception found" )
450 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400451 main.cleanup()
452 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800453 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800454 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400455 main.cleanup()
456 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400457
Jon Hall61282e32015-03-19 11:34:11 -0700458 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800459 """
andrewonlab7c211572014-10-15 16:45:20 -0400460 List the nodes currently visible
461 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700462 Optional argument:
463 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800464 """
andrewonlab7c211572014-10-15 16:45:20 -0400465 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700466 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700467 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700468 cmdStr += " -j"
469 output = self.sendline( cmdStr )
470 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800471 except TypeError:
472 main.log.exception( self.name + ": Object not as expected" )
473 return None
andrewonlab7c211572014-10-15 16:45:20 -0400474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800475 main.log.error( self.name + ": EOF exception found" )
476 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400477 main.cleanup()
478 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800479 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800480 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400481 main.cleanup()
482 main.exit()
483
kelvin8ec71442015-01-15 16:57:00 -0800484 def topology( self ):
485 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700486 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700487 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700488 Return:
489 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800490 """
andrewonlab95ce8322014-10-13 14:12:04 -0400491 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700492 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800493 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700494 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400495 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800496 except TypeError:
497 main.log.exception( self.name + ": Object not as expected" )
498 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800500 main.log.error( self.name + ": EOF exception found" )
501 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400502 main.cleanup()
503 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800504 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800505 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400506 main.cleanup()
507 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800508
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800510 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700511 Installs a specified feature by issuing command:
512 'feature:install <feature_str>'
513 NOTE: This is now deprecated, you should use the activateApp method
514 instead
kelvin8ec71442015-01-15 16:57:00 -0800515 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400516 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518 handle = self.sendline( cmdStr )
519 if re.search( "Error", handle ):
520 main.log.error( "Error in installing feature" )
521 main.log.error( handle )
522 return main.FALSE
523 else:
524 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800525 except TypeError:
526 main.log.exception( self.name + ": Object not as expected" )
527 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800529 main.log.error( self.name + ": EOF exception found" )
530 main.log.error( self.name + ": " + self.handle.before )
531 main.log.report( "Failed to install feature" )
532 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400533 main.cleanup()
534 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800536 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800537 main.log.report( "Failed to install feature" )
538 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400539 main.cleanup()
540 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800541
kelvin-onlabd3b64892015-01-20 13:26:24 -0800542 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800543 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700544 Uninstalls a specified feature by issuing command:
545 'feature:uninstall <feature_str>'
546 NOTE: This is now deprecated, you should use the deactivateApp method
547 instead
kelvin8ec71442015-01-15 16:57:00 -0800548 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800550 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
551 handle = self.sendline( cmdStr )
552 if handle != '':
553 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800555 # TODO: Check for possible error responses from karaf
556 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800557 main.log.info( "Feature needs to be installed before " +
558 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700559 return main.TRUE
560 if re.search( "Error", output ):
561 main.log.error( "Error in uninstalling feature" )
562 main.log.error( output )
563 return main.FALSE
564 else:
565 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800566 except TypeError:
567 main.log.exception( self.name + ": Object not as expected" )
568 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800570 main.log.error( self.name + ": EOF exception found" )
571 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 main.cleanup()
573 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800574 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800575 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400576 main.cleanup()
577 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800578
jenkins7ead5a82015-03-13 10:28:21 -0700579 def deviceRemove( self, deviceId ):
580 """
581 Removes particular device from storage
582
583 TODO: refactor this function
584 """
585 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700586 cmdStr = "device-remove " + str( deviceId )
587 handle = self.sendline( cmdStr )
588 if re.search( "Error", handle ):
589 main.log.error( "Error in removing device" )
590 main.log.error( handle )
591 return main.FALSE
592 else:
593 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700594 except TypeError:
595 main.log.exception( self.name + ": Object not as expected" )
596 return None
597 except pexpect.EOF:
598 main.log.error( self.name + ": EOF exception found" )
599 main.log.error( self.name + ": " + self.handle.before )
600 main.cleanup()
601 main.exit()
602 except Exception:
603 main.log.exception( self.name + ": Uncaught exception!" )
604 main.cleanup()
605 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700606
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800608 """
Jon Hall7b02d952014-10-17 20:14:54 -0400609 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400610 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800612 """
andrewonlab86dc3082014-10-13 18:18:38 -0400613 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700614 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700616 cmdStr += " -j"
617 handle = self.sendline( cmdStr )
618 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800619 except TypeError:
620 main.log.exception( self.name + ": Object not as expected" )
621 return None
andrewonlab7c211572014-10-15 16:45:20 -0400622 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800623 main.log.error( self.name + ": EOF exception found" )
624 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400625 main.cleanup()
626 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800627 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800628 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400629 main.cleanup()
630 main.exit()
631
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800633 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800634 This balances the devices across all controllers
635 by issuing command: 'onos> onos:balance-masters'
636 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800637 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800638 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700640 handle = self.sendline( cmdStr )
641 if re.search( "Error", handle ):
642 main.log.error( "Error in balancing masters" )
643 main.log.error( handle )
644 return main.FALSE
645 else:
646 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800647 except TypeError:
648 main.log.exception( self.name + ": Object not as expected" )
649 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800650 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800651 main.log.error( self.name + ": EOF exception found" )
652 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800653 main.cleanup()
654 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800655 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800656 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800657 main.cleanup()
658 main.exit()
659
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800661 """
Jon Halle8217482014-10-17 13:49:14 -0400662 Lists all core links
663 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800665 """
Jon Halle8217482014-10-17 13:49:14 -0400666 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700667 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700669 cmdStr += " -j"
670 handle = self.sendline( cmdStr )
671 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800672 except TypeError:
673 main.log.exception( self.name + ": Object not as expected" )
674 return None
Jon Halle8217482014-10-17 13:49:14 -0400675 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800676 main.log.error( self.name + ": EOF exception found" )
677 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400678 main.cleanup()
679 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800680 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800681 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400682 main.cleanup()
683 main.exit()
684
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800686 """
Jon Halle8217482014-10-17 13:49:14 -0400687 Lists all ports
688 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800690 """
Jon Halle8217482014-10-17 13:49:14 -0400691 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700692 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700694 cmdStr += " -j"
695 handle = self.sendline( cmdStr )
696 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
Jon Halle8217482014-10-17 13:49:14 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400703 main.cleanup()
704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800705 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800706 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400707 main.cleanup()
708 main.exit()
709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800711 """
Jon Hall983a1702014-10-28 18:44:22 -0400712 Lists all devices and the controllers with roles assigned to them
713 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800715 """
andrewonlab7c211572014-10-15 16:45:20 -0400716 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700717 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 cmdStr += " -j"
720 handle = self.sendline( cmdStr )
721 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800722 except TypeError:
723 main.log.exception( self.name + ": Object not as expected" )
724 return None
Jon Hall983a1702014-10-28 18:44:22 -0400725 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800726 main.log.error( self.name + ": EOF exception found" )
727 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400728 main.cleanup()
729 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800730 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800731 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400732 main.cleanup()
733 main.exit()
734
kelvin-onlabd3b64892015-01-20 13:26:24 -0800735 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800736 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800737 Given the a string containing the json representation of the "roles"
738 cli command and a partial or whole device id, returns a json object
739 containing the roles output for the first device whose id contains
740 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400741
742 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800743 A dict of the role assignments for the given device or
744 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800745 """
Jon Hall983a1702014-10-28 18:44:22 -0400746 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400748 return None
749 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 rawRoles = self.roles()
751 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800752 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800754 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400756 return device
757 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800758 except TypeError:
759 main.log.exception( self.name + ": Object not as expected" )
760 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400764 main.cleanup()
765 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800766 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800767 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400768 main.cleanup()
769 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800770
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Jon Hall94fd0472014-12-08 11:52:42 -0800773 Iterates through each device and checks if there is a master assigned
774 Returns: main.TRUE if each device has a master
775 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800776 """
Jon Hall94fd0472014-12-08 11:52:42 -0800777 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 rawRoles = self.roles()
779 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800780 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800782 # print device
783 if device[ 'master' ] == "none":
784 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800785 return main.FALSE
786 return main.TRUE
787
Jon Halld4d4b372015-01-28 16:02:41 -0800788 except TypeError:
789 main.log.exception( self.name + ": Object not as expected" )
790 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800792 main.log.error( self.name + ": EOF exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800794 main.cleanup()
795 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800796 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800797 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800798 main.cleanup()
799 main.exit()
800
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400803 Returns string of paths, and the cost.
804 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800805 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400806 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
808 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800809 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800810 main.log.error( "Error in getting paths" )
811 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400812 else:
kelvin8ec71442015-01-15 16:57:00 -0800813 path = handle.split( ";" )[ 0 ]
814 cost = handle.split( ";" )[ 1 ]
815 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800816 except TypeError:
817 main.log.exception( self.name + ": Object not as expected" )
818 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400819 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800820 main.log.error( self.name + ": EOF exception found" )
821 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400822 main.cleanup()
823 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800824 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800825 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400826 main.cleanup()
827 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800828
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800830 """
Jon Hallffb386d2014-11-21 13:43:38 -0800831 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400832 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800833 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800834 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400835 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700836 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700838 cmdStr += " -j"
839 handle = self.sendline( cmdStr )
840 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800841 except TypeError:
842 main.log.exception( self.name + ": Object not as expected" )
843 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400844 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800845 main.log.error( self.name + ": EOF exception found" )
846 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400847 main.cleanup()
848 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800849 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800850 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400851 main.cleanup()
852 main.exit()
853
kelvin-onlabd3b64892015-01-20 13:26:24 -0800854 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800855 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400856 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800857
Jon Hallefbd9792015-03-05 16:11:36 -0800858 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800859 partial mac address
860
Jon Hall42db6dc2014-10-24 19:03:48 -0400861 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800862 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400863 try:
kelvin8ec71442015-01-15 16:57:00 -0800864 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400865 return None
866 else:
867 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 rawHosts = self.hosts()
869 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800870 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800872 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800873 if not host:
874 pass
875 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400876 return host
877 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800878 except TypeError:
879 main.log.exception( self.name + ": Object not as expected" )
880 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400881 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800882 main.log.error( self.name + ": EOF exception found" )
883 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400884 main.cleanup()
885 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800886 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800887 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400888 main.cleanup()
889 main.exit()
890
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800892 """
893 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400894 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800895
andrewonlab3f0a4af2014-10-17 12:25:14 -0400896 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400898 IMPORTANT:
899 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800900 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400901 Furthermore, it assumes that value of VLAN is '-1'
902 Description:
kelvin8ec71442015-01-15 16:57:00 -0800903 Converts mininet hosts ( h1, h2, h3... ) into
904 ONOS format ( 00:00:00:00:00:01/-1 , ... )
905 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400906 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800910 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 hostHex = hex( int( host ) ).zfill( 12 )
912 hostHex = str( hostHex ).replace( 'x', '0' )
913 i = iter( str( hostHex ) )
914 hostHex = ":".join( a + b for a, b in zip( i, i ) )
915 hostHex = hostHex + "/-1"
916 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400917
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400919
Jon Halld4d4b372015-01-28 16:02:41 -0800920 except TypeError:
921 main.log.exception( self.name + ": Object not as expected" )
922 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400923 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800924 main.log.error( self.name + ": EOF exception found" )
925 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400926 main.cleanup()
927 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800928 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800929 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400930 main.cleanup()
931 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400932
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800934 """
andrewonlabe6745342014-10-17 14:29:13 -0400935 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800936 * hostIdOne: ONOS host id for host1
937 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400938 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800939 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500940 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800941 Returns:
942 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800943 """
andrewonlabe6745342014-10-17 14:29:13 -0400944 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800945 cmdStr = "add-host-intent " + str( hostIdOne ) +\
946 " " + str( hostIdTwo )
947 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800948 if re.search( "Error", handle ):
949 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700950 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800951 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800952 else:
953 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800954 str( hostIdOne ) + " and " + str( hostIdTwo ) )
955 match = re.search('id=0x([\da-f]+),', handle)
956 if match:
957 return match.group()[3:-1]
958 else:
959 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700960 main.log.debug( "Response from ONOS was: " +
961 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800962 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800963 except TypeError:
964 main.log.exception( self.name + ": Object not as expected" )
965 return None
andrewonlabe6745342014-10-17 14:29:13 -0400966 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800967 main.log.error( self.name + ": EOF exception found" )
968 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400969 main.cleanup()
970 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800971 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800972 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400973 main.cleanup()
974 main.exit()
975
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800977 """
andrewonlab7b31d232014-10-24 13:31:47 -0400978 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 * ingressDevice: device id of ingress device
980 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400981 Optional:
982 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -0800983 Description:
984 Adds an optical intent by specifying an ingress and egress device
985 Returns:
986 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800987 """
andrewonlab7b31d232014-10-24 13:31:47 -0400988 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
990 " " + str( egressDevice )
991 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800992 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800993 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800994 main.log.error( "Error in adding Optical intent" )
995 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400996 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800997 main.log.info( "Optical intent installed between " +
998 str( ingressDevice ) + " and " +
999 str( egressDevice ) )
1000 match = re.search('id=0x([\da-f]+),', handle)
1001 if match:
1002 return match.group()[3:-1]
1003 else:
1004 main.log.error( "Error, intent ID not found" )
1005 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001006 except TypeError:
1007 main.log.exception( self.name + ": Object not as expected" )
1008 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001012 main.cleanup()
1013 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001014 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001015 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001016 main.cleanup()
1017 main.exit()
1018
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001020 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 ingressDevice,
1022 egressDevice,
1023 portIngress="",
1024 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001025 ethType="",
1026 ethSrc="",
1027 ethDst="",
1028 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001030 ipProto="",
1031 ipSrc="",
1032 ipDst="",
1033 tcpSrc="",
1034 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001036 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 * ingressDevice: device id of ingress device
1038 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001039 Optional:
1040 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001041 * ethSrc: specify ethSrc ( i.e. src mac addr )
1042 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001043 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001045 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001046 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001047 * ipSrc: specify ip source address
1048 * ipDst: specify ip destination address
1049 * tcpSrc: specify tcp source port
1050 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001051 Description:
kelvin8ec71442015-01-15 16:57:00 -08001052 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001053 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001054 Returns:
1055 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001056
Jon Halle3f39ff2015-01-13 11:50:53 -08001057 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001058 options developers provide for point-to-point
1059 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001060 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001061 try:
kelvin8ec71442015-01-15 16:57:00 -08001062 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001063 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001065 and not ipProto and not ipSrc and not ipDst \
1066 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001067 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001068
andrewonlab289e4b72014-10-21 21:24:18 -04001069 else:
andrewonlab36af3822014-11-18 17:48:18 -05001070 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001071
andrewonlab0c0a6772014-10-22 12:31:18 -04001072 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001073 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001074 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001075 cmd += " --ethSrc " + str( ethSrc )
1076 if ethDst:
1077 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001078 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001079 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001081 cmd += " --lambda "
1082 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001083 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001084 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001085 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001086 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001087 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001088 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001089 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001090 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001091 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001092
kelvin8ec71442015-01-15 16:57:00 -08001093 # Check whether the user appended the port
1094 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 if "/" in ingressDevice:
1096 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001097 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001099 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001100 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001101 # Would it make sense to throw an exception and exit
1102 # the test?
1103 return None
andrewonlab36af3822014-11-18 17:48:18 -05001104
kelvin8ec71442015-01-15 16:57:00 -08001105 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 str( ingressDevice ) + "/" +\
1107 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 if "/" in egressDevice:
1110 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001111 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001112 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001113 main.log.error( "You must specify the egress port" )
1114 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001115
kelvin8ec71442015-01-15 16:57:00 -08001116 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 str( egressDevice ) + "/" +\
1118 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001119
kelvin-onlab898a6c62015-01-16 14:13:53 -08001120 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001121 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001122 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001123 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001124 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001125 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001126 # TODO: print out all the options in this message?
1127 main.log.info( "Point-to-point intent installed between " +
1128 str( ingressDevice ) + " and " +
1129 str( egressDevice ) )
1130 match = re.search('id=0x([\da-f]+),', handle)
1131 if match:
1132 return match.group()[3:-1]
1133 else:
1134 main.log.error( "Error, intent ID not found" )
1135 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001136 except TypeError:
1137 main.log.exception( self.name + ": Object not as expected" )
1138 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001139 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001140 main.log.error( self.name + ": EOF exception found" )
1141 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001142 main.cleanup()
1143 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001145 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001146 main.cleanup()
1147 main.exit()
1148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001150 self,
shahshreyac2f97072015-03-19 17:04:29 -07001151 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001152 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001153 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001155 ethType="",
1156 ethSrc="",
1157 ethDst="",
1158 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001160 ipProto="",
1161 ipSrc="",
1162 ipDst="",
1163 tcpSrc="",
1164 tcpDst="",
1165 setEthSrc="",
1166 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001167 """
shahshreyad0c80432014-12-04 16:56:05 -08001168 Note:
shahshreya70622b12015-03-19 17:19:00 -07001169 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001170 is same. That is, all ingress devices include port numbers
1171 with a "/" or all ingress devices could specify device
1172 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001173 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001174 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001175 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001177 Optional:
1178 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001179 * ethSrc: specify ethSrc ( i.e. src mac addr )
1180 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001181 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001183 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001184 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001185 * ipSrc: specify ip source address
1186 * ipDst: specify ip destination address
1187 * tcpSrc: specify tcp source port
1188 * tcpDst: specify tcp destination port
1189 * setEthSrc: action to Rewrite Source MAC Address
1190 * setEthDst: action to Rewrite Destination MAC Address
1191 Description:
kelvin8ec71442015-01-15 16:57:00 -08001192 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001193 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001194 Returns:
1195 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001196
Jon Halle3f39ff2015-01-13 11:50:53 -08001197 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001198 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001199 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001200 """
shahshreyad0c80432014-12-04 16:56:05 -08001201 try:
kelvin8ec71442015-01-15 16:57:00 -08001202 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001203 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001204 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001205 and not ipProto and not ipSrc and not ipDst\
1206 and not tcpSrc and not tcpDst and not setEthSrc\
1207 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001208 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001209
1210 else:
1211 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001212
shahshreyad0c80432014-12-04 16:56:05 -08001213 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001214 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001215 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " --ethSrc " + str( ethSrc )
1217 if ethDst:
1218 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001219 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001220 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001222 cmd += " --lambda "
1223 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001224 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001225 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001226 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001227 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001228 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001229 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001230 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001231 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001232 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001233 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001234 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001235 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001236 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001237
kelvin8ec71442015-01-15 16:57:00 -08001238 # Check whether the user appended the port
1239 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001240
1241 if portIngressList is None:
1242 for ingressDevice in ingressDeviceList:
1243 if "/" in ingressDevice:
1244 cmd += " " + str( ingressDevice )
1245 else:
1246 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001247 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001248 # TODO: perhaps more meaningful return
1249 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001250 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001251 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001252 for ingressDevice, portIngress in zip( ingressDeviceList,
1253 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001254 cmd += " " + \
1255 str( ingressDevice ) + "/" +\
1256 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001257 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001258 main.log.error( "Device list and port list does not " +
1259 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001260 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 if "/" in egressDevice:
1262 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001263 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001265 main.log.error( "You must specify " +
1266 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001267 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001268
kelvin8ec71442015-01-15 16:57:00 -08001269 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 str( egressDevice ) + "/" +\
1271 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001273 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001274 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001275 main.log.error( "Error in adding multipoint-to-singlepoint " +
1276 "intent" )
1277 return None
shahshreyad0c80432014-12-04 16:56:05 -08001278 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001279 match = re.search('id=0x([\da-f]+),', handle)
1280 if match:
1281 return match.group()[3:-1]
1282 else:
1283 main.log.error( "Error, intent ID not found" )
1284 return None
1285 except TypeError:
1286 main.log.exception( self.name + ": Object not as expected" )
1287 return None
1288 except pexpect.EOF:
1289 main.log.error( self.name + ": EOF exception found" )
1290 main.log.error( self.name + ": " + self.handle.before )
1291 main.cleanup()
1292 main.exit()
1293 except Exception:
1294 main.log.exception( self.name + ": Uncaught exception!" )
1295 main.cleanup()
1296 main.exit()
1297
1298 def addSinglepointToMultipointIntent(
1299 self,
1300 ingressDevice,
1301 egressDeviceList,
1302 portIngress="",
1303 portEgressList=None,
1304 ethType="",
1305 ethSrc="",
1306 ethDst="",
1307 bandwidth="",
1308 lambdaAlloc=False,
1309 ipProto="",
1310 ipSrc="",
1311 ipDst="",
1312 tcpSrc="",
1313 tcpDst="",
1314 setEthSrc="",
1315 setEthDst="" ):
1316 """
1317 Note:
1318 This function assumes the format of all egress devices
1319 is same. That is, all egress devices include port numbers
1320 with a "/" or all egress devices could specify device
1321 ids and port numbers seperately.
1322 Required:
1323 * EgressDeviceList: List of device ids of egress device
1324 ( Atleast 2 eress devices required in the list )
1325 * ingressDevice: device id of ingress device
1326 Optional:
1327 * ethType: specify ethType
1328 * ethSrc: specify ethSrc ( i.e. src mac addr )
1329 * ethDst: specify ethDst ( i.e. dst mac addr )
1330 * bandwidth: specify bandwidth capacity of link
1331 * lambdaAlloc: if True, intent will allocate lambda
1332 for the specified intent
1333 * ipProto: specify ip protocol
1334 * ipSrc: specify ip source address
1335 * ipDst: specify ip destination address
1336 * tcpSrc: specify tcp source port
1337 * tcpDst: specify tcp destination port
1338 * setEthSrc: action to Rewrite Source MAC Address
1339 * setEthDst: action to Rewrite Destination MAC Address
1340 Description:
1341 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1342 specifying device id's and optional fields
1343 Returns:
1344 A string of the intent id or None on error
1345
1346 NOTE: This function may change depending on the
1347 options developers provide for singlepoint-to-multipoint
1348 intent via cli
1349 """
1350 try:
1351 # If there are no optional arguments
1352 if not ethType and not ethSrc and not ethDst\
1353 and not bandwidth and not lambdaAlloc\
1354 and not ipProto and not ipSrc and not ipDst\
1355 and not tcpSrc and not tcpDst and not setEthSrc\
1356 and not setEthDst:
1357 cmd = "add-single-to-multi-intent"
1358
1359 else:
1360 cmd = "add-single-to-multi-intent"
1361
1362 if ethType:
1363 cmd += " --ethType " + str( ethType )
1364 if ethSrc:
1365 cmd += " --ethSrc " + str( ethSrc )
1366 if ethDst:
1367 cmd += " --ethDst " + str( ethDst )
1368 if bandwidth:
1369 cmd += " --bandwidth " + str( bandwidth )
1370 if lambdaAlloc:
1371 cmd += " --lambda "
1372 if ipProto:
1373 cmd += " --ipProto " + str( ipProto )
1374 if ipSrc:
1375 cmd += " --ipSrc " + str( ipSrc )
1376 if ipDst:
1377 cmd += " --ipDst " + str( ipDst )
1378 if tcpSrc:
1379 cmd += " --tcpSrc " + str( tcpSrc )
1380 if tcpDst:
1381 cmd += " --tcpDst " + str( tcpDst )
1382 if setEthSrc:
1383 cmd += " --setEthSrc " + str( setEthSrc )
1384 if setEthDst:
1385 cmd += " --setEthDst " + str( setEthDst )
1386
1387 # Check whether the user appended the port
1388 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001389
kelvin-onlabb9408212015-04-01 13:34:04 -07001390 if "/" in ingressDevice:
1391 cmd += " " + str( ingressDevice )
1392 else:
1393 if not portIngress:
1394 main.log.error( "You must specify " +
1395 "the Ingress port" )
1396 return main.FALSE
1397
1398 cmd += " " +\
1399 str( ingressDevice ) + "/" +\
1400 str( portIngress )
1401
1402 if portEgressList is None:
1403 for egressDevice in egressDeviceList:
1404 if "/" in egressDevice:
1405 cmd += " " + str( egressDevice )
1406 else:
1407 main.log.error( "You must specify " +
1408 "the egress port" )
1409 # TODO: perhaps more meaningful return
1410 return main.FALSE
1411 else:
1412 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001413 for egressDevice, portEgress in zip( egressDeviceList,
1414 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001415 cmd += " " + \
1416 str( egressDevice ) + "/" +\
1417 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001418 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001419 main.log.error( "Device list and port list does not " +
1420 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001421 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001422 handle = self.sendline( cmd )
1423 # If error, return error message
1424 if re.search( "Error", handle ):
1425 main.log.error( "Error in adding singlepoint-to-multipoint " +
1426 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001427 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001428 else:
1429 match = re.search('id=0x([\da-f]+),', handle)
1430 if match:
1431 return match.group()[3:-1]
1432 else:
1433 main.log.error( "Error, intent ID not found" )
1434 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001435 except TypeError:
1436 main.log.exception( self.name + ": Object not as expected" )
1437 return None
shahshreyad0c80432014-12-04 16:56:05 -08001438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001439 main.log.error( self.name + ": EOF exception found" )
1440 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001441 main.cleanup()
1442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001444 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001445 main.cleanup()
1446 main.exit()
1447
Hari Krishna9e232602015-04-13 17:29:08 -07001448 def addMplsIntent(
1449 self,
1450 ingressDevice,
1451 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001452 ingressPort="",
1453 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001454 ethType="",
1455 ethSrc="",
1456 ethDst="",
1457 bandwidth="",
1458 lambdaAlloc=False,
1459 ipProto="",
1460 ipSrc="",
1461 ipDst="",
1462 tcpSrc="",
1463 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001464 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001465 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001466 priority=""):
1467 """
1468 Required:
1469 * ingressDevice: device id of ingress device
1470 * egressDevice: device id of egress device
1471 Optional:
1472 * ethType: specify ethType
1473 * ethSrc: specify ethSrc ( i.e. src mac addr )
1474 * ethDst: specify ethDst ( i.e. dst mac addr )
1475 * bandwidth: specify bandwidth capacity of link
1476 * lambdaAlloc: if True, intent will allocate lambda
1477 for the specified intent
1478 * ipProto: specify ip protocol
1479 * ipSrc: specify ip source address
1480 * ipDst: specify ip destination address
1481 * tcpSrc: specify tcp source port
1482 * tcpDst: specify tcp destination port
1483 * ingressLabel: Ingress MPLS label
1484 * egressLabel: Egress MPLS label
1485 Description:
1486 Adds MPLS intent by
1487 specifying device id's and optional fields
1488 Returns:
1489 A string of the intent id or None on error
1490
1491 NOTE: This function may change depending on the
1492 options developers provide for MPLS
1493 intent via cli
1494 """
1495 try:
1496 # If there are no optional arguments
1497 if not ethType and not ethSrc and not ethDst\
1498 and not bandwidth and not lambdaAlloc \
1499 and not ipProto and not ipSrc and not ipDst \
1500 and not tcpSrc and not tcpDst and not ingressLabel \
1501 and not egressLabel:
1502 cmd = "add-mpls-intent"
1503
1504 else:
1505 cmd = "add-mpls-intent"
1506
1507 if ethType:
1508 cmd += " --ethType " + str( ethType )
1509 if ethSrc:
1510 cmd += " --ethSrc " + str( ethSrc )
1511 if ethDst:
1512 cmd += " --ethDst " + str( ethDst )
1513 if bandwidth:
1514 cmd += " --bandwidth " + str( bandwidth )
1515 if lambdaAlloc:
1516 cmd += " --lambda "
1517 if ipProto:
1518 cmd += " --ipProto " + str( ipProto )
1519 if ipSrc:
1520 cmd += " --ipSrc " + str( ipSrc )
1521 if ipDst:
1522 cmd += " --ipDst " + str( ipDst )
1523 if tcpSrc:
1524 cmd += " --tcpSrc " + str( tcpSrc )
1525 if tcpDst:
1526 cmd += " --tcpDst " + str( tcpDst )
1527 if ingressLabel:
1528 cmd += " --ingressLabel " + str( ingressLabel )
1529 if egressLabel:
1530 cmd += " --egressLabel " + str( egressLabel )
1531 if priority:
1532 cmd += " --priority " + str( priority )
1533
1534 # Check whether the user appended the port
1535 # or provided it as an input
1536 if "/" in ingressDevice:
1537 cmd += " " + str( ingressDevice )
1538 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001539 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001540 main.log.error( "You must specify the ingress port" )
1541 return None
1542
1543 cmd += " " + \
1544 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001545 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001546
1547 if "/" in egressDevice:
1548 cmd += " " + str( egressDevice )
1549 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001550 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001551 main.log.error( "You must specify the egress port" )
1552 return None
1553
1554 cmd += " " +\
1555 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001556 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001557
1558 handle = self.sendline( cmd )
1559 # If error, return error message
1560 if re.search( "Error", handle ):
1561 main.log.error( "Error in adding mpls intent" )
1562 return None
1563 else:
1564 # TODO: print out all the options in this message?
1565 main.log.info( "MPLS intent installed between " +
1566 str( ingressDevice ) + " and " +
1567 str( egressDevice ) )
1568 match = re.search('id=0x([\da-f]+),', handle)
1569 if match:
1570 return match.group()[3:-1]
1571 else:
1572 main.log.error( "Error, intent ID not found" )
1573 return None
1574 except TypeError:
1575 main.log.exception( self.name + ": Object not as expected" )
1576 return None
1577 except pexpect.EOF:
1578 main.log.error( self.name + ": EOF exception found" )
1579 main.log.error( self.name + ": " + self.handle.before )
1580 main.cleanup()
1581 main.exit()
1582 except Exception:
1583 main.log.exception( self.name + ": Uncaught exception!" )
1584 main.cleanup()
1585 main.exit()
1586
Jon Hallefbd9792015-03-05 16:11:36 -08001587 def removeIntent( self, intentId, app='org.onosproject.cli',
1588 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001589 """
shahshreya1c818fc2015-02-26 13:44:08 -08001590 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001591 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001592 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001593 -p or --purge: Purge the intent from the store after removal
1594
Jon Halle3f39ff2015-01-13 11:50:53 -08001595 Returns:
1596 main.False on error and
1597 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001598 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001599 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001600 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001601 if purge:
1602 cmdStr += " -p"
1603 if sync:
1604 cmdStr += " -s"
1605
1606 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001608 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001609 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001610 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001611 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001612 # TODO: Should this be main.TRUE
1613 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001614 except TypeError:
1615 main.log.exception( self.name + ": Object not as expected" )
1616 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001617 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001618 main.log.error( self.name + ": EOF exception found" )
1619 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001620 main.cleanup()
1621 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001622 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001623 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001624 main.cleanup()
1625 main.exit()
1626
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001627 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001628 """
1629 Purges all WITHDRAWN Intents
1630 """
1631 try:
1632 cmdStr = "purge-intents"
1633 handle = self.sendline( cmdStr )
1634 if re.search( "Error", handle ):
1635 main.log.error( "Error in purging intents" )
1636 return main.FALSE
1637 else:
1638 return main.TRUE
1639 except TypeError:
1640 main.log.exception( self.name + ": Object not as expected" )
1641 return None
1642 except pexpect.EOF:
1643 main.log.error( self.name + ": EOF exception found" )
1644 main.log.error( self.name + ": " + self.handle.before )
1645 main.cleanup()
1646 main.exit()
1647 except Exception:
1648 main.log.exception( self.name + ": Uncaught exception!" )
1649 main.cleanup()
1650 main.exit()
1651
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001653 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001654 NOTE: This method should be used after installing application:
1655 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001656 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001658 Description:
1659 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001660 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001661 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001662 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001664 cmdStr += " -j"
1665 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001666 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001667 except TypeError:
1668 main.log.exception( self.name + ": Object not as expected" )
1669 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001670 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001671 main.log.error( self.name + ": EOF exception found" )
1672 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001673 main.cleanup()
1674 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001676 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001677 main.cleanup()
1678 main.exit()
1679
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001681 """
andrewonlab377693f2014-10-21 16:00:30 -04001682 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001684 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001685 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001686 """
andrewonlabe6745342014-10-17 14:29:13 -04001687 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001688 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001690 cmdStr += " -j"
1691 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001692 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001693 except TypeError:
1694 main.log.exception( self.name + ": Object not as expected" )
1695 return None
andrewonlabe6745342014-10-17 14:29:13 -04001696 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001697 main.log.error( self.name + ": EOF exception found" )
1698 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001699 main.cleanup()
1700 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001701 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001702 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001703 main.cleanup()
1704 main.exit()
1705
kelvin-onlab54400a92015-02-26 18:05:51 -08001706 def getIntentState(self, intentsId, intentsJson=None):
1707 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001708 Check intent state.
1709 Accepts a single intent ID (string type) or a list of intent IDs.
1710 Returns the state(string type) of the id if a single intent ID is
1711 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001712 Returns a dictionary with intent IDs as the key and its
1713 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001714 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001715 intentId: intent ID (string type)
1716 intentsJson: parsed json object from the onos:intents api
1717 Returns:
1718 state = An intent's state- INSTALL,WITHDRAWN etc.
1719 stateDict = Dictionary of intent's state. intent ID as the keys and
1720 state as the values.
1721 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001722 try:
1723 state = "State is Undefined"
1724 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001725 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001726 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001727 intentsJsonTemp = json.loads( intentsJson )
1728 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001729 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001730 if intentsId == intent[ 'id' ]:
1731 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001732 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001733 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1734 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001735 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001736 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001737 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001738 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001739 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001740 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001741 if intentsId[ i ] == intents[ 'id' ]:
1742 stateDict[ 'state' ] = intents[ 'state' ]
1743 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001744 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001745 break
Jon Hallefbd9792015-03-05 16:11:36 -08001746 if len( intentsId ) != len( dictList ):
1747 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001748 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001749 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001750 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001751 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001752 except TypeError:
1753 main.log.exception( self.name + ": Object not as expected" )
1754 return None
1755 except pexpect.EOF:
1756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + ": " + self.handle.before )
1758 main.cleanup()
1759 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001760 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001761 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001762 main.cleanup()
1763 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001764
kelvin-onlabf512e942015-06-08 19:42:59 -07001765 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001766 """
1767 Description:
1768 Check intents state
1769 Required:
1770 intentsId - List of intents ID to be checked
1771 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001772 expectedState - Check the expected state(s) of each intents
1773 state in the list.
1774 *NOTE: You can pass in a list of expected state,
1775 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001776 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001777 Returns main.TRUE only if all intent are the same as expected states
1778 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001779 """
1780 try:
1781 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001782 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001783 intentsDict = self.getIntentState( intentsId )
kelvin-onlabf512e942015-06-08 19:42:59 -07001784
Jon Hall390696c2015-05-05 17:13:41 -07001785 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001786 if len( intentsId ) != len( intentsDict ):
1787 main.log.info( self.name + "There is something wrong " +
1788 "getting intents state" )
1789 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001790
1791 if isinstance( expectedState, types.StringType ):
1792 for intents in intentsDict:
1793 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001794 main.log.debug( self.name + " : Intent ID - " +
1795 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001796 " actual state = " +
1797 intents.get( 'state' )
1798 + " does not equal expected state = "
1799 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001800 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001801
1802 elif isinstance( expectedState, types.ListType ):
1803 for intents in intentsDict:
1804 if not any( state == intents.get( 'state' ) for state in
1805 expectedState ):
1806 main.log.debug( self.name + " : Intent ID - " +
1807 intents.get( 'id' ) +
1808 " actual state = " +
1809 intents.get( 'state' ) +
1810 " does not equal expected states = "
1811 + str( expectedState ) )
1812 returnValue = main.FALSE
1813
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001814 if returnValue == main.TRUE:
1815 main.log.info( self.name + ": All " +
1816 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001817 " intents are in " + str( expectedState ) +
1818 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001819 return returnValue
1820 except TypeError:
1821 main.log.exception( self.name + ": Object not as expected" )
1822 return None
1823 except pexpect.EOF:
1824 main.log.error( self.name + ": EOF exception found" )
1825 main.log.error( self.name + ": " + self.handle.before )
1826 main.cleanup()
1827 main.exit()
1828 except Exception:
1829 main.log.exception( self.name + ": Uncaught exception!" )
1830 main.cleanup()
1831 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001832
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001834 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001835 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001836 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001837 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001838 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001839 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001840 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001841 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001842 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001843 cmdStr += " -j"
1844 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001845 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001846 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001847 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001848 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001849 except TypeError:
1850 main.log.exception( self.name + ": Object not as expected" )
1851 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001852 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001853 main.log.error( self.name + ": EOF exception found" )
1854 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001855 main.cleanup()
1856 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001857 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001858 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001859 main.cleanup()
1860 main.exit()
1861
kelvin-onlab4df89f22015-04-13 18:10:23 -07001862 def checkFlowsState( self ):
1863 """
1864 Description:
1865 Check the if all the current flows are in ADDED state or
1866 PENDING_ADD state
1867 Return:
1868 returnValue - Returns main.TRUE only if all flows are in
1869 ADDED state or PENDING_ADD, return main.FALSE
1870 otherwise.
1871 """
1872 try:
1873 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001874 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001875 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001876
kelvin-onlab4df89f22015-04-13 18:10:23 -07001877 for device in tempFlows:
1878 for flow in device.get( 'flows' ):
1879 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1880 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001881
kelvin-onlab4df89f22015-04-13 18:10:23 -07001882 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001883 str( flow.get( 'groupId' ) ) +
1884 " | state:" +
1885 str( flow.get( 'state' ) ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07001886 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001887
kelvin-onlab4df89f22015-04-13 18:10:23 -07001888 return returnValue
1889 except TypeError:
1890 main.log.exception( self.name + ": Object not as expected" )
1891 return None
1892 except pexpect.EOF:
1893 main.log.error( self.name + ": EOF exception found" )
1894 main.log.error( self.name + ": " + self.handle.before )
1895 main.cleanup()
1896 main.exit()
1897 except Exception:
1898 main.log.exception( self.name + ": Uncaught exception!" )
1899 main.cleanup()
1900 main.exit()
1901
kelvin-onlabd3b64892015-01-20 13:26:24 -08001902 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001903 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001904 """
andrewonlab87852b02014-11-19 18:44:19 -05001905 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001906 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001907 a specific point-to-point intent definition
1908 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001909 * dpidSrc: specify source dpid
1910 * dpidDst: specify destination dpid
1911 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001912 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001913 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001914 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001916 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001917 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001918 """
andrewonlab87852b02014-11-19 18:44:19 -05001919 try:
kelvin8ec71442015-01-15 16:57:00 -08001920 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001921 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1922 str( numIntents )
1923 if numMult:
1924 cmd += " " + str( numMult )
1925 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001926 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001927 if appId:
1928 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001929 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001930 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001931 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001932 main.log.info( handle )
1933 # Split result by newline
1934 newline = handle.split( "\r\r\n" )
1935 # Ignore the first object of list, which is empty
1936 newline = newline[ 1: ]
1937 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001938 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001939 result = result.split( ": " )
1940 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001941 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1942 main.log.info( latResult )
1943 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001944 else:
1945 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001946 except TypeError:
1947 main.log.exception( self.name + ": Object not as expected" )
1948 return None
andrewonlab87852b02014-11-19 18:44:19 -05001949 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001950 main.log.error( self.name + ": EOF exception found" )
1951 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001952 main.cleanup()
1953 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001954 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001955 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001956 main.cleanup()
1957 main.exit()
1958
kelvin-onlabd3b64892015-01-20 13:26:24 -08001959 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001960 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001961 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001962 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001963 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001964 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001965 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001966 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001968 cmdStr += " -j"
1969 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001970 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001971 except TypeError:
1972 main.log.exception( self.name + ": Object not as expected" )
1973 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001974 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001975 main.log.error( self.name + ": EOF exception found" )
1976 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001977 main.cleanup()
1978 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001979 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001980 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001981 main.cleanup()
1982 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001983
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001985 """
1986 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001987 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001989 """
andrewonlab867212a2014-10-22 20:13:38 -04001990 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001991 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001992 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001993 cmdStr += " -j"
1994 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001995 if handle:
1996 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001997 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001998 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001999 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002000 else:
2001 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002002 except TypeError:
2003 main.log.exception( self.name + ": Object not as expected" )
2004 return None
andrewonlab867212a2014-10-22 20:13:38 -04002005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002006 main.log.error( self.name + ": EOF exception found" )
2007 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002008 main.cleanup()
2009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002011 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002012 main.cleanup()
2013 main.exit()
2014
kelvin8ec71442015-01-15 16:57:00 -08002015 # Wrapper functions ****************
2016 # Wrapper functions use existing driver
2017 # functions and extends their use case.
2018 # For example, we may use the output of
2019 # a normal driver function, and parse it
2020 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04002021
kelvin-onlabd3b64892015-01-20 13:26:24 -08002022 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002023 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002024 Description:
2025 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002026 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002027 try:
kelvin8ec71442015-01-15 16:57:00 -08002028 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002029 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002030 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002031
kelvin8ec71442015-01-15 16:57:00 -08002032 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2034 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002035 match = re.search('id=0x([\da-f]+),', intents)
2036 if match:
2037 tmpId = match.group()[3:-1]
2038 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002039 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002040
Jon Halld4d4b372015-01-28 16:02:41 -08002041 except TypeError:
2042 main.log.exception( self.name + ": Object not as expected" )
2043 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002044 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002045 main.log.error( self.name + ": EOF exception found" )
2046 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002047 main.cleanup()
2048 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002049 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002050 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002051 main.cleanup()
2052 main.exit()
2053
Jon Hall30b82fa2015-03-04 17:15:43 -08002054 def FlowAddedCount( self, deviceId ):
2055 """
2056 Determine the number of flow rules for the given device id that are
2057 in the added state
2058 """
2059 try:
2060 cmdStr = "flows any " + str( deviceId ) + " | " +\
2061 "grep 'state=ADDED' | wc -l"
2062 handle = self.sendline( cmdStr )
2063 return handle
2064 except pexpect.EOF:
2065 main.log.error( self.name + ": EOF exception found" )
2066 main.log.error( self.name + ": " + self.handle.before )
2067 main.cleanup()
2068 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002069 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002070 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002071 main.cleanup()
2072 main.exit()
2073
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002075 """
andrewonlab95ce8322014-10-13 14:12:04 -04002076 Use 'devices' function to obtain list of all devices
2077 and parse the result to obtain a list of all device
2078 id's. Returns this list. Returns empty list if no
2079 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002080 List is ordered sequentially
2081
andrewonlab95ce8322014-10-13 14:12:04 -04002082 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002083 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002084 the ids. By obtaining the list of device ids on the fly,
2085 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002086 """
andrewonlab95ce8322014-10-13 14:12:04 -04002087 try:
kelvin8ec71442015-01-15 16:57:00 -08002088 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002089 devicesStr = self.devices( jsonFormat=False )
2090 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002091
kelvin-onlabd3b64892015-01-20 13:26:24 -08002092 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002093 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002094 return idList
kelvin8ec71442015-01-15 16:57:00 -08002095
2096 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002098 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002099 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002100 # Split list further into arguments before and after string
2101 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002102 # append to idList
2103 for arg in tempList:
2104 idList.append( arg.split( "id=" )[ 1 ] )
2105 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002106
Jon Halld4d4b372015-01-28 16:02:41 -08002107 except TypeError:
2108 main.log.exception( self.name + ": Object not as expected" )
2109 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002110 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002111 main.log.error( self.name + ": EOF exception found" )
2112 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002113 main.cleanup()
2114 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002115 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002116 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002117 main.cleanup()
2118 main.exit()
2119
kelvin-onlabd3b64892015-01-20 13:26:24 -08002120 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002121 """
andrewonlab7c211572014-10-15 16:45:20 -04002122 Uses 'nodes' function to obtain list of all nodes
2123 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002124 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002125 Returns:
2126 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002127 """
andrewonlab7c211572014-10-15 16:45:20 -04002128 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002129 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002130 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002131 # Sample nodesStr output
2132 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002133 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002134 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002135 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002136 nodesJson = json.loads( nodesStr )
2137 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002138 return idList
kelvin8ec71442015-01-15 16:57:00 -08002139
Jon Halld4d4b372015-01-28 16:02:41 -08002140 except TypeError:
2141 main.log.exception( self.name + ": Object not as expected" )
2142 return None
andrewonlab7c211572014-10-15 16:45:20 -04002143 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002144 main.log.error( self.name + ": EOF exception found" )
2145 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002146 main.cleanup()
2147 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002148 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002149 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002150 main.cleanup()
2151 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002152
kelvin-onlabd3b64892015-01-20 13:26:24 -08002153 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002154 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002155 Return the first device from the devices api whose 'id' contains 'dpid'
2156 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002157 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002158 try:
kelvin8ec71442015-01-15 16:57:00 -08002159 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002160 return None
2161 else:
kelvin8ec71442015-01-15 16:57:00 -08002162 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002163 rawDevices = self.devices()
2164 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002165 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002166 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002167 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2168 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002169 return device
2170 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002171 except TypeError:
2172 main.log.exception( self.name + ": Object not as expected" )
2173 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002174 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002175 main.log.error( self.name + ": EOF exception found" )
2176 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002177 main.cleanup()
2178 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002179 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002180 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002181 main.cleanup()
2182 main.exit()
2183
kelvin-onlabd3b64892015-01-20 13:26:24 -08002184 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002185 """
Jon Hallefbd9792015-03-05 16:11:36 -08002186 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002187 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002188 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002189
Jon Hall42db6dc2014-10-24 19:03:48 -04002190 Params: ip = ip used for the onos cli
2191 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002192 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002193 logLevel = level to log to. Currently accepts
2194 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002195
2196
kelvin-onlabd3b64892015-01-20 13:26:24 -08002197 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002198
Jon Hallefbd9792015-03-05 16:11:36 -08002199 Returns: main.TRUE if the number of switches and links are correct,
2200 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002201 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002202 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002203 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002204 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002205 if topology == {}:
2206 return main.ERROR
2207 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002208 # Is the number of switches is what we expected
2209 devices = topology.get( 'devices', False )
2210 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002211 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002212 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002214 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002215 linkCheck = ( int( links ) == int( numolink ) )
2216 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002217 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002218 output += "The number of links and switches match " +\
2219 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002220 result = main.TRUE
2221 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002222 output += "The number of links and switches does not match " +\
2223 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002224 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002225 output = output + "\n ONOS sees %i devices (%i expected) \
2226 and %i links (%i expected)" % (
2227 int( devices ), int( numoswitch ), int( links ),
2228 int( numolink ) )
2229 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002230 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002231 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002232 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002233 else:
Jon Hall390696c2015-05-05 17:13:41 -07002234 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002235 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002236 except TypeError:
2237 main.log.exception( self.name + ": Object not as expected" )
2238 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002239 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002240 main.log.error( self.name + ": EOF exception found" )
2241 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002242 main.cleanup()
2243 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002244 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002245 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002246 main.cleanup()
2247 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002248
kelvin-onlabd3b64892015-01-20 13:26:24 -08002249 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002250 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002251 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002252 deviceId must be the id of a device as seen in the onos devices command
2253 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002254 role must be either master, standby, or none
2255
Jon Halle3f39ff2015-01-13 11:50:53 -08002256 Returns:
2257 main.TRUE or main.FALSE based on argument verification and
2258 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002259 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002260 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002261 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002262 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002263 cmdStr = "device-role " +\
2264 str( deviceId ) + " " +\
2265 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002266 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002267 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002268 if re.search( "Error", handle ):
2269 # end color output to escape any colours
2270 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002271 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002272 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002273 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002274 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002275 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002276 main.log.error( "Invalid 'role' given to device_role(). " +
2277 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002278 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002279 except TypeError:
2280 main.log.exception( self.name + ": Object not as expected" )
2281 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002282 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002283 main.log.error( self.name + ": EOF exception found" )
2284 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002285 main.cleanup()
2286 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002287 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002288 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002289 main.cleanup()
2290 main.exit()
2291
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002293 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002294 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002295 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002296 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002297 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002298 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002299 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002300 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002301 cmdStr += " -j"
2302 handle = self.sendline( cmdStr )
2303 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002304 except TypeError:
2305 main.log.exception( self.name + ": Object not as expected" )
2306 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002307 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002308 main.log.error( self.name + ": EOF exception found" )
2309 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002310 main.cleanup()
2311 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002312 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002313 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002314 main.cleanup()
2315 main.exit()
2316
kelvin-onlabd3b64892015-01-20 13:26:24 -08002317 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002318 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002319 CLI command to get the current leader for the Election test application
2320 NOTE: Requires installation of the onos-app-election feature
2321 Returns: Node IP of the leader if one exists
2322 None if none exists
2323 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002324 """
Jon Hall94fd0472014-12-08 11:52:42 -08002325 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002326 cmdStr = "election-test-leader"
2327 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002328 # Leader
2329 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002330 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002331 nodeSearch = re.search( leaderPattern, response )
2332 if nodeSearch:
2333 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002334 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002335 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002336 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002337 # no leader
2338 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002339 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002340 nullSearch = re.search( nullPattern, response )
2341 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002342 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002343 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002344 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002345 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002346 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002347 if re.search( errorPattern, response ):
2348 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002349 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002350 return main.FALSE
2351 else:
Jon Hall390696c2015-05-05 17:13:41 -07002352 main.log.error( "Error in electionTestLeader on " + self.name +
2353 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002354 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002355 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002356 except TypeError:
2357 main.log.exception( self.name + ": Object not as expected" )
2358 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002359 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002360 main.log.error( self.name + ": EOF exception found" )
2361 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002362 main.cleanup()
2363 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002364 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002365 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002366 main.cleanup()
2367 main.exit()
2368
kelvin-onlabd3b64892015-01-20 13:26:24 -08002369 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002370 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002371 CLI command to run for leadership of the Election test application.
2372 NOTE: Requires installation of the onos-app-election feature
2373 Returns: Main.TRUE on success
2374 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002375 """
Jon Hall94fd0472014-12-08 11:52:42 -08002376 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002377 cmdStr = "election-test-run"
2378 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002379 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002380 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002381 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002382 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002383 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002384 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002385 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002386 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002387 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002388 errorPattern = "Command\snot\sfound"
2389 if re.search( errorPattern, response ):
2390 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002391 return main.FALSE
2392 else:
Jon Hall390696c2015-05-05 17:13:41 -07002393 main.log.error( "Error in electionTestRun on " + self.name +
2394 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002395 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002396 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002397 except TypeError:
2398 main.log.exception( self.name + ": Object not as expected" )
2399 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002401 main.log.error( self.name + ": EOF exception found" )
2402 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002403 main.cleanup()
2404 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002405 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002406 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002407 main.cleanup()
2408 main.exit()
2409
kelvin-onlabd3b64892015-01-20 13:26:24 -08002410 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002411 """
Jon Hall94fd0472014-12-08 11:52:42 -08002412 * CLI command to withdraw the local node from leadership election for
2413 * the Election test application.
2414 #NOTE: Requires installation of the onos-app-election feature
2415 Returns: Main.TRUE on success
2416 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002417 """
Jon Hall94fd0472014-12-08 11:52:42 -08002418 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002419 cmdStr = "election-test-withdraw"
2420 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002421 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002422 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002423 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002424 if re.search( successPattern, response ):
2425 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002426 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002427 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002428 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002429 errorPattern = "Command\snot\sfound"
2430 if re.search( errorPattern, response ):
2431 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002432 return main.FALSE
2433 else:
Jon Hall390696c2015-05-05 17:13:41 -07002434 main.log.error( "Error in electionTestWithdraw on " +
2435 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002436 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002437 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002438 except TypeError:
2439 main.log.exception( self.name + ": Object not as expected" )
2440 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002442 main.log.error( self.name + ": EOF exception found" )
2443 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002444 main.cleanup()
2445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002446 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002447 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002448 main.cleanup()
2449 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002450
kelvin8ec71442015-01-15 16:57:00 -08002451 def getDevicePortsEnabledCount( self, dpid ):
2452 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002453 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002454 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002455 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002456 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2458 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002459 if re.search( "No such device", output ):
2460 main.log.error( "Error in getting ports" )
2461 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002462 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002463 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002464 except TypeError:
2465 main.log.exception( self.name + ": Object not as expected" )
2466 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002467 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002468 main.log.error( self.name + ": EOF exception found" )
2469 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002470 main.cleanup()
2471 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002472 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002473 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002474 main.cleanup()
2475 main.exit()
2476
kelvin8ec71442015-01-15 16:57:00 -08002477 def getDeviceLinksActiveCount( self, dpid ):
2478 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002479 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002480 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002481 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002482 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002483 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2484 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002485 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002486 main.log.error( "Error in getting ports " )
2487 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002488 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002489 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002490 except TypeError:
2491 main.log.exception( self.name + ": Object not as expected" )
2492 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002493 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002494 main.log.error( self.name + ": EOF exception found" )
2495 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002496 main.cleanup()
2497 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002498 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002499 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002500 main.cleanup()
2501 main.exit()
2502
kelvin8ec71442015-01-15 16:57:00 -08002503 def getAllIntentIds( self ):
2504 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002505 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002506 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002507 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002508 cmdStr = "onos:intents | grep id="
2509 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002510 if re.search( "Error", output ):
2511 main.log.error( "Error in getting ports" )
2512 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002513 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002514 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002515 except TypeError:
2516 main.log.exception( self.name + ": Object not as expected" )
2517 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002518 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002519 main.log.error( self.name + ": EOF exception found" )
2520 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002521 main.cleanup()
2522 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002523 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002524 main.log.exception( self.name + ": Uncaught exception!" )
2525 main.cleanup()
2526 main.exit()
2527
Jon Hall73509952015-02-24 16:42:56 -08002528 def intentSummary( self ):
2529 """
Jon Hallefbd9792015-03-05 16:11:36 -08002530 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002531 """
2532 try:
2533 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002534 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002535 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002536 states.append( intent.get( 'state', None ) )
2537 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002538 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002539 return dict( out )
2540 except TypeError:
2541 main.log.exception( self.name + ": Object not as expected" )
2542 return None
2543 except pexpect.EOF:
2544 main.log.error( self.name + ": EOF exception found" )
2545 main.log.error( self.name + ": " + self.handle.before )
2546 main.cleanup()
2547 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002548 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002549 main.log.exception( self.name + ": Uncaught exception!" )
2550 main.cleanup()
2551 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002552
Jon Hall61282e32015-03-19 11:34:11 -07002553 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002554 """
2555 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002556 Optional argument:
2557 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002558 """
2559 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002560 # Sample JSON
2561 # {
2562 # "electedTime": "13m ago",
2563 # "epoch": 4,
2564 # "leader": "10.128.30.17",
2565 # "topic": "intent-partition-3"
2566 # },
Jon Hall63604932015-02-26 17:09:50 -08002567 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002568 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002569 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002570 cmdStr += " -j"
2571 output = self.sendline( cmdStr )
2572 return output
Jon Hall63604932015-02-26 17:09:50 -08002573 except TypeError:
2574 main.log.exception( self.name + ": Object not as expected" )
2575 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002576 except pexpect.EOF:
2577 main.log.error( self.name + ": EOF exception found" )
2578 main.log.error( self.name + ": " + self.handle.before )
2579 main.cleanup()
2580 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002581 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002582 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002583 main.cleanup()
2584 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002585
Jon Hall61282e32015-03-19 11:34:11 -07002586 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002587 """
2588 Returns the output of the intent Pending map.
2589 """
Jon Hall63604932015-02-26 17:09:50 -08002590 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002591 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002592 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002593 cmdStr += " -j"
2594 output = self.sendline( cmdStr )
2595 return output
Jon Hall63604932015-02-26 17:09:50 -08002596 except TypeError:
2597 main.log.exception( self.name + ": Object not as expected" )
2598 return None
2599 except pexpect.EOF:
2600 main.log.error( self.name + ": EOF exception found" )
2601 main.log.error( self.name + ": " + self.handle.before )
2602 main.cleanup()
2603 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002604 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002605 main.log.exception( self.name + ": Uncaught exception!" )
2606 main.cleanup()
2607 main.exit()
2608
Jon Hall61282e32015-03-19 11:34:11 -07002609 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002610 """
2611 Returns the output of the raft partitions command for ONOS.
2612 """
Jon Hall61282e32015-03-19 11:34:11 -07002613 # Sample JSON
2614 # {
2615 # "leader": "tcp://10.128.30.11:7238",
2616 # "members": [
2617 # "tcp://10.128.30.11:7238",
2618 # "tcp://10.128.30.17:7238",
2619 # "tcp://10.128.30.13:7238",
2620 # ],
2621 # "name": "p1",
2622 # "term": 3
2623 # },
Jon Hall63604932015-02-26 17:09:50 -08002624 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002625 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002626 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002627 cmdStr += " -j"
2628 output = self.sendline( cmdStr )
2629 return output
Jon Hall63604932015-02-26 17:09:50 -08002630 except TypeError:
2631 main.log.exception( self.name + ": Object not as expected" )
2632 return None
2633 except pexpect.EOF:
2634 main.log.error( self.name + ": EOF exception found" )
2635 main.log.error( self.name + ": " + self.handle.before )
2636 main.cleanup()
2637 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002638 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002639 main.log.exception( self.name + ": Uncaught exception!" )
2640 main.cleanup()
2641 main.exit()
2642
Jon Hallbe379602015-03-24 13:39:32 -07002643 def apps( self, jsonFormat=True ):
2644 """
2645 Returns the output of the apps command for ONOS. This command lists
2646 information about installed ONOS applications
2647 """
2648 # Sample JSON object
2649 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2650 # "description":"ONOS OpenFlow protocol southbound providers",
2651 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2652 # "features":"[onos-openflow]","state":"ACTIVE"}]
2653 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002654 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002655 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002656 cmdStr += " -j"
2657 output = self.sendline( cmdStr )
2658 assert "Error executing command" not in output
2659 return output
Jon Hallbe379602015-03-24 13:39:32 -07002660 # FIXME: look at specific exceptions/Errors
2661 except AssertionError:
2662 main.log.error( "Error in processing onos:app command: " +
2663 str( output ) )
2664 return None
2665 except TypeError:
2666 main.log.exception( self.name + ": Object not as expected" )
2667 return None
2668 except pexpect.EOF:
2669 main.log.error( self.name + ": EOF exception found" )
2670 main.log.error( self.name + ": " + self.handle.before )
2671 main.cleanup()
2672 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002673 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002674 main.log.exception( self.name + ": Uncaught exception!" )
2675 main.cleanup()
2676 main.exit()
2677
Jon Hall146f1522015-03-24 15:33:24 -07002678 def appStatus( self, appName ):
2679 """
2680 Uses the onos:apps cli command to return the status of an application.
2681 Returns:
2682 "ACTIVE" - If app is installed and activated
2683 "INSTALLED" - If app is installed and deactivated
2684 "UNINSTALLED" - If app is not installed
2685 None - on error
2686 """
Jon Hall146f1522015-03-24 15:33:24 -07002687 try:
2688 if not isinstance( appName, types.StringType ):
2689 main.log.error( self.name + ".appStatus(): appName must be" +
2690 " a string" )
2691 return None
2692 output = self.apps( jsonFormat=True )
2693 appsJson = json.loads( output )
2694 state = None
2695 for app in appsJson:
2696 if appName == app.get('name'):
2697 state = app.get('state')
2698 break
2699 if state == "ACTIVE" or state == "INSTALLED":
2700 return state
2701 elif state is None:
2702 return "UNINSTALLED"
2703 elif state:
2704 main.log.error( "Unexpected state from 'onos:apps': " +
2705 str( state ) )
2706 return state
2707 except TypeError:
2708 main.log.exception( self.name + ": Object not as expected" )
2709 return None
2710 except pexpect.EOF:
2711 main.log.error( self.name + ": EOF exception found" )
2712 main.log.error( self.name + ": " + self.handle.before )
2713 main.cleanup()
2714 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002715 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002716 main.log.exception( self.name + ": Uncaught exception!" )
2717 main.cleanup()
2718 main.exit()
2719
Jon Hallbe379602015-03-24 13:39:32 -07002720 def app( self, appName, option ):
2721 """
2722 Interacts with the app command for ONOS. This command manages
2723 application inventory.
2724 """
Jon Hallbe379602015-03-24 13:39:32 -07002725 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002726 # Validate argument types
2727 valid = True
2728 if not isinstance( appName, types.StringType ):
2729 main.log.error( self.name + ".app(): appName must be a " +
2730 "string" )
2731 valid = False
2732 if not isinstance( option, types.StringType ):
2733 main.log.error( self.name + ".app(): option must be a string" )
2734 valid = False
2735 if not valid:
2736 return main.FALSE
2737 # Validate Option
2738 option = option.lower()
2739 # NOTE: Install may become a valid option
2740 if option == "activate":
2741 pass
2742 elif option == "deactivate":
2743 pass
2744 elif option == "uninstall":
2745 pass
2746 else:
2747 # Invalid option
2748 main.log.error( "The ONOS app command argument only takes " +
2749 "the values: (activate|deactivate|uninstall)" +
2750 "; was given '" + option + "'")
2751 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002752 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002753 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002754 if "Error executing command" in output:
2755 main.log.error( "Error in processing onos:app command: " +
2756 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002757 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002758 elif "No such application" in output:
2759 main.log.error( "The application '" + appName +
2760 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002761 return main.FALSE
2762 elif "Command not found:" in output:
2763 main.log.error( "Error in processing onos:app command: " +
2764 str( output ) )
2765 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002766 elif "Unsupported command:" in output:
2767 main.log.error( "Incorrect command given to 'app': " +
2768 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002769 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002770 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002771 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002772 return main.TRUE
2773 except TypeError:
2774 main.log.exception( self.name + ": Object not as expected" )
2775 return main.ERROR
2776 except pexpect.EOF:
2777 main.log.error( self.name + ": EOF exception found" )
2778 main.log.error( self.name + ": " + self.handle.before )
2779 main.cleanup()
2780 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002781 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002782 main.log.exception( self.name + ": Uncaught exception!" )
2783 main.cleanup()
2784 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002785
Jon Hallbd16b922015-03-26 17:53:15 -07002786 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002787 """
2788 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002789 appName is the hierarchical app name, not the feature name
2790 If check is True, method will check the status of the app after the
2791 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002792 Returns main.TRUE if the command was successfully sent
2793 main.FALSE if the cli responded with an error or given
2794 incorrect input
2795 """
2796 try:
2797 if not isinstance( appName, types.StringType ):
2798 main.log.error( self.name + ".activateApp(): appName must be" +
2799 " a string" )
2800 return main.FALSE
2801 status = self.appStatus( appName )
2802 if status == "INSTALLED":
2803 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002804 if check and response == main.TRUE:
2805 for i in range(10): # try 10 times then give up
2806 # TODO: Check with Thomas about this delay
2807 status = self.appStatus( appName )
2808 if status == "ACTIVE":
2809 return main.TRUE
2810 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002811 main.log.debug( "The state of application " +
2812 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002813 time.sleep( 1 )
2814 return main.FALSE
2815 else: # not 'check' or command didn't succeed
2816 return response
Jon Hall146f1522015-03-24 15:33:24 -07002817 elif status == "ACTIVE":
2818 return main.TRUE
2819 elif status == "UNINSTALLED":
2820 main.log.error( self.name + ": Tried to activate the " +
2821 "application '" + appName + "' which is not " +
2822 "installed." )
2823 else:
2824 main.log.error( "Unexpected return value from appStatus: " +
2825 str( status ) )
2826 return main.ERROR
2827 except TypeError:
2828 main.log.exception( self.name + ": Object not as expected" )
2829 return main.ERROR
2830 except pexpect.EOF:
2831 main.log.error( self.name + ": EOF exception found" )
2832 main.log.error( self.name + ": " + self.handle.before )
2833 main.cleanup()
2834 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002835 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002836 main.log.exception( self.name + ": Uncaught exception!" )
2837 main.cleanup()
2838 main.exit()
2839
Jon Hallbd16b922015-03-26 17:53:15 -07002840 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002841 """
2842 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002843 appName is the hierarchical app name, not the feature name
2844 If check is True, method will check the status of the app after the
2845 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002846 Returns main.TRUE if the command was successfully sent
2847 main.FALSE if the cli responded with an error or given
2848 incorrect input
2849 """
2850 try:
2851 if not isinstance( appName, types.StringType ):
2852 main.log.error( self.name + ".deactivateApp(): appName must " +
2853 "be a string" )
2854 return main.FALSE
2855 status = self.appStatus( appName )
2856 if status == "INSTALLED":
2857 return main.TRUE
2858 elif status == "ACTIVE":
2859 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002860 if check and response == main.TRUE:
2861 for i in range(10): # try 10 times then give up
2862 status = self.appStatus( appName )
2863 if status == "INSTALLED":
2864 return main.TRUE
2865 else:
2866 time.sleep( 1 )
2867 return main.FALSE
2868 else: # not check or command didn't succeed
2869 return response
Jon Hall146f1522015-03-24 15:33:24 -07002870 elif status == "UNINSTALLED":
2871 main.log.warn( self.name + ": Tried to deactivate the " +
2872 "application '" + appName + "' which is not " +
2873 "installed." )
2874 return main.TRUE
2875 else:
2876 main.log.error( "Unexpected return value from appStatus: " +
2877 str( status ) )
2878 return main.ERROR
2879 except TypeError:
2880 main.log.exception( self.name + ": Object not as expected" )
2881 return main.ERROR
2882 except pexpect.EOF:
2883 main.log.error( self.name + ": EOF exception found" )
2884 main.log.error( self.name + ": " + self.handle.before )
2885 main.cleanup()
2886 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002887 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002888 main.log.exception( self.name + ": Uncaught exception!" )
2889 main.cleanup()
2890 main.exit()
2891
Jon Hallbd16b922015-03-26 17:53:15 -07002892 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002893 """
2894 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002895 appName is the hierarchical app name, not the feature name
2896 If check is True, method will check the status of the app after the
2897 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002898 Returns main.TRUE if the command was successfully sent
2899 main.FALSE if the cli responded with an error or given
2900 incorrect input
2901 """
2902 # TODO: check with Thomas about the state machine for apps
2903 try:
2904 if not isinstance( appName, types.StringType ):
2905 main.log.error( self.name + ".uninstallApp(): appName must " +
2906 "be a string" )
2907 return main.FALSE
2908 status = self.appStatus( appName )
2909 if status == "INSTALLED":
2910 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002911 if check and response == main.TRUE:
2912 for i in range(10): # try 10 times then give up
2913 status = self.appStatus( appName )
2914 if status == "UNINSTALLED":
2915 return main.TRUE
2916 else:
2917 time.sleep( 1 )
2918 return main.FALSE
2919 else: # not check or command didn't succeed
2920 return response
Jon Hall146f1522015-03-24 15:33:24 -07002921 elif status == "ACTIVE":
2922 main.log.warn( self.name + ": Tried to uninstall the " +
2923 "application '" + appName + "' which is " +
2924 "currently active." )
2925 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002926 if check and response == main.TRUE:
2927 for i in range(10): # try 10 times then give up
2928 status = self.appStatus( appName )
2929 if status == "UNINSTALLED":
2930 return main.TRUE
2931 else:
2932 time.sleep( 1 )
2933 return main.FALSE
2934 else: # not check or command didn't succeed
2935 return response
Jon Hall146f1522015-03-24 15:33:24 -07002936 elif status == "UNINSTALLED":
2937 return main.TRUE
2938 else:
2939 main.log.error( "Unexpected return value from appStatus: " +
2940 str( status ) )
2941 return main.ERROR
2942 except TypeError:
2943 main.log.exception( self.name + ": Object not as expected" )
2944 return main.ERROR
2945 except pexpect.EOF:
2946 main.log.error( self.name + ": EOF exception found" )
2947 main.log.error( self.name + ": " + self.handle.before )
2948 main.cleanup()
2949 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002950 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002951 main.log.exception( self.name + ": Uncaught exception!" )
2952 main.cleanup()
2953 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002954
2955 def appIDs( self, jsonFormat=True ):
2956 """
2957 Show the mappings between app id and app names given by the 'app-ids'
2958 cli command
2959 """
2960 try:
2961 cmdStr = "app-ids"
2962 if jsonFormat:
2963 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002964 output = self.sendline( cmdStr )
2965 assert "Error executing command" not in output
2966 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002967 except AssertionError:
2968 main.log.error( "Error in processing onos:app-ids command: " +
2969 str( output ) )
2970 return None
2971 except TypeError:
2972 main.log.exception( self.name + ": Object not as expected" )
2973 return None
2974 except pexpect.EOF:
2975 main.log.error( self.name + ": EOF exception found" )
2976 main.log.error( self.name + ": " + self.handle.before )
2977 main.cleanup()
2978 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002979 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002980 main.log.exception( self.name + ": Uncaught exception!" )
2981 main.cleanup()
2982 main.exit()
2983
2984 def appToIDCheck( self ):
2985 """
2986 This method will check that each application's ID listed in 'apps' is
2987 the same as the ID listed in 'app-ids'. The check will also check that
2988 there are no duplicate IDs issued. Note that an app ID should be
2989 a globaly unique numerical identifier for app/app-like features. Once
2990 an ID is registered, the ID is never freed up so that if an app is
2991 reinstalled it will have the same ID.
2992
2993 Returns: main.TRUE if the check passes and
2994 main.FALSE if the check fails or
2995 main.ERROR if there is some error in processing the test
2996 """
2997 try:
Jon Hall390696c2015-05-05 17:13:41 -07002998 bail = False
2999 ids = self.appIDs( jsonFormat=True )
3000 if ids:
3001 ids = json.loads( ids )
3002 else:
3003 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3004 bail = True
3005 apps = self.apps( jsonFormat=True )
3006 if apps:
3007 apps = json.loads( apps )
3008 else:
3009 main.log.error( "apps returned nothing:" + repr( apps ) )
3010 bail = True
3011 if bail:
3012 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003013 result = main.TRUE
3014 for app in apps:
3015 appID = app.get( 'id' )
3016 if appID is None:
3017 main.log.error( "Error parsing app: " + str( app ) )
3018 result = main.FALSE
3019 appName = app.get( 'name' )
3020 if appName is None:
3021 main.log.error( "Error parsing app: " + str( app ) )
3022 result = main.FALSE
3023 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003024 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003025 # main.log.debug( "Comparing " + str( app ) + " to " +
3026 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003027 if not current: # if ids doesn't have this id
3028 result = main.FALSE
3029 main.log.error( "'app-ids' does not have the ID for " +
3030 str( appName ) + " that apps does." )
3031 elif len( current ) > 1:
3032 # there is more than one app with this ID
3033 result = main.FALSE
3034 # We will log this later in the method
3035 elif not current[0][ 'name' ] == appName:
3036 currentName = current[0][ 'name' ]
3037 result = main.FALSE
3038 main.log.error( "'app-ids' has " + str( currentName ) +
3039 " registered under id:" + str( appID ) +
3040 " but 'apps' has " + str( appName ) )
3041 else:
3042 pass # id and name match!
3043 # now make sure that app-ids has no duplicates
3044 idsList = []
3045 namesList = []
3046 for item in ids:
3047 idsList.append( item[ 'id' ] )
3048 namesList.append( item[ 'name' ] )
3049 if len( idsList ) != len( set( idsList ) ) or\
3050 len( namesList ) != len( set( namesList ) ):
3051 main.log.error( "'app-ids' has some duplicate entries: \n"
3052 + json.dumps( ids,
3053 sort_keys=True,
3054 indent=4,
3055 separators=( ',', ': ' ) ) )
3056 result = main.FALSE
3057 return result
3058 except ( ValueError, TypeError ):
3059 main.log.exception( self.name + ": Object not as expected" )
3060 return main.ERROR
3061 except pexpect.EOF:
3062 main.log.error( self.name + ": EOF exception found" )
3063 main.log.error( self.name + ": " + self.handle.before )
3064 main.cleanup()
3065 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003066 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003067 main.log.exception( self.name + ": Uncaught exception!" )
3068 main.cleanup()
3069 main.exit()
3070
Jon Hallfb760a02015-04-13 15:35:03 -07003071 def getCfg( self, component=None, propName=None, short=False,
3072 jsonFormat=True ):
3073 """
3074 Get configuration settings from onos cli
3075 Optional arguments:
3076 component - Optionally only list configurations for a specific
3077 component. If None, all components with configurations
3078 are displayed. Case Sensitive string.
3079 propName - If component is specified, propName option will show
3080 only this specific configuration from that component.
3081 Case Sensitive string.
3082 jsonFormat - Returns output as json. Note that this will override
3083 the short option
3084 short - Short, less verbose, version of configurations.
3085 This is overridden by the json option
3086 returns:
3087 Output from cli as a string or None on error
3088 """
3089 try:
3090 baseStr = "cfg"
3091 cmdStr = " get"
3092 componentStr = ""
3093 if component:
3094 componentStr += " " + component
3095 if propName:
3096 componentStr += " " + propName
3097 if jsonFormat:
3098 baseStr += " -j"
3099 elif short:
3100 baseStr += " -s"
3101 output = self.sendline( baseStr + cmdStr + componentStr )
3102 assert "Error executing command" not in output
3103 return output
3104 except AssertionError:
3105 main.log.error( "Error in processing 'cfg get' command: " +
3106 str( output ) )
3107 return None
3108 except TypeError:
3109 main.log.exception( self.name + ": Object not as expected" )
3110 return None
3111 except pexpect.EOF:
3112 main.log.error( self.name + ": EOF exception found" )
3113 main.log.error( self.name + ": " + self.handle.before )
3114 main.cleanup()
3115 main.exit()
3116 except Exception:
3117 main.log.exception( self.name + ": Uncaught exception!" )
3118 main.cleanup()
3119 main.exit()
3120
3121 def setCfg( self, component, propName, value=None, check=True ):
3122 """
3123 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003124 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003125 component - The case sensitive name of the component whose
3126 property is to be set
3127 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003128 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003129 value - The value to set the property to. If None, will unset the
3130 property and revert it to it's default value(if applicable)
3131 check - Boolean, Check whether the option was successfully set this
3132 only applies when a value is given.
3133 returns:
3134 main.TRUE on success or main.FALSE on failure. If check is False,
3135 will return main.TRUE unless there is an error
3136 """
3137 try:
3138 baseStr = "cfg"
3139 cmdStr = " set " + str( component ) + " " + str( propName )
3140 if value is not None:
3141 cmdStr += " " + str( value )
3142 output = self.sendline( baseStr + cmdStr )
3143 assert "Error executing command" not in output
3144 if value and check:
3145 results = self.getCfg( component=str( component ),
3146 propName=str( propName ),
3147 jsonFormat=True )
3148 # Check if current value is what we just set
3149 try:
3150 jsonOutput = json.loads( results )
3151 current = jsonOutput[ 'value' ]
3152 except ( ValueError, TypeError ):
3153 main.log.exception( "Error parsing cfg output" )
3154 main.log.error( "output:" + repr( results ) )
3155 return main.FALSE
3156 if current == str( value ):
3157 return main.TRUE
3158 return main.FALSE
3159 return main.TRUE
3160 except AssertionError:
3161 main.log.error( "Error in processing 'cfg set' command: " +
3162 str( output ) )
3163 return main.FALSE
3164 except TypeError:
3165 main.log.exception( self.name + ": Object not as expected" )
3166 return main.FALSE
3167 except pexpect.EOF:
3168 main.log.error( self.name + ": EOF exception found" )
3169 main.log.error( self.name + ": " + self.handle.before )
3170 main.cleanup()
3171 main.exit()
3172 except Exception:
3173 main.log.exception( self.name + ": Uncaught exception!" )
3174 main.cleanup()
3175 main.exit()
3176
Jon Hall390696c2015-05-05 17:13:41 -07003177 def setTestAdd( self, setName, values ):
3178 """
3179 CLI command to add elements to a distributed set.
3180 Arguments:
3181 setName - The name of the set to add to.
3182 values - The value(s) to add to the set, space seperated.
3183 Example usages:
3184 setTestAdd( "set1", "a b c" )
3185 setTestAdd( "set2", "1" )
3186 returns:
3187 main.TRUE on success OR
3188 main.FALSE if elements were already in the set OR
3189 main.ERROR on error
3190 """
3191 try:
3192 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3193 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003194 try:
3195 # TODO: Maybe make this less hardcoded
3196 # ConsistentMap Exceptions
3197 assert "org.onosproject.store.service" not in output
3198 # Node not leader
3199 assert "java.lang.IllegalStateException" not in output
3200 except AssertionError:
3201 main.log.error( "Error in processing 'set-test-add' " +
3202 "command: " + str( output ) )
3203 retryTime = 30 # Conservative time, given by Madan
3204 main.log.info( "Waiting " + str( retryTime ) +
3205 "seconds before retrying." )
3206 time.sleep( retryTime ) # Due to change in mastership
3207 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003208 assert "Error executing command" not in output
3209 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3210 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3211 main.log.info( self.name + ": " + output )
3212 if re.search( positiveMatch, output):
3213 return main.TRUE
3214 elif re.search( negativeMatch, output):
3215 return main.FALSE
3216 else:
3217 main.log.error( self.name + ": setTestAdd did not" +
3218 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003219 main.log.debug( self.name + " actual: " + repr( output ) )
3220 return main.ERROR
3221 except AssertionError:
3222 main.log.error( "Error in processing 'set-test-add' command: " +
3223 str( output ) )
3224 return main.ERROR
3225 except TypeError:
3226 main.log.exception( self.name + ": Object not as expected" )
3227 return main.ERROR
3228 except pexpect.EOF:
3229 main.log.error( self.name + ": EOF exception found" )
3230 main.log.error( self.name + ": " + self.handle.before )
3231 main.cleanup()
3232 main.exit()
3233 except Exception:
3234 main.log.exception( self.name + ": Uncaught exception!" )
3235 main.cleanup()
3236 main.exit()
3237
3238 def setTestRemove( self, setName, values, clear=False, retain=False ):
3239 """
3240 CLI command to remove elements from a distributed set.
3241 Required arguments:
3242 setName - The name of the set to remove from.
3243 values - The value(s) to remove from the set, space seperated.
3244 Optional arguments:
3245 clear - Clear all elements from the set
3246 retain - Retain only the given values. (intersection of the
3247 original set and the given set)
3248 returns:
3249 main.TRUE on success OR
3250 main.FALSE if the set was not changed OR
3251 main.ERROR on error
3252 """
3253 try:
3254 cmdStr = "set-test-remove "
3255 if clear:
3256 cmdStr += "-c " + str( setName )
3257 elif retain:
3258 cmdStr += "-r " + str( setName ) + " " + str( values )
3259 else:
3260 cmdStr += str( setName ) + " " + str( values )
3261 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003262 try:
3263 # TODO: Maybe make this less hardcoded
3264 # ConsistentMap Exceptions
3265 assert "org.onosproject.store.service" not in output
3266 # Node not leader
3267 assert "java.lang.IllegalStateException" not in output
3268 except AssertionError:
3269 main.log.error( "Error in processing 'set-test-add' " +
3270 "command: " + str( output ) )
3271 retryTime = 30 # Conservative time, given by Madan
3272 main.log.info( "Waiting " + str( retryTime ) +
3273 "seconds before retrying." )
3274 time.sleep( retryTime ) # Due to change in mastership
3275 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003276 assert "Error executing command" not in output
3277 main.log.info( self.name + ": " + output )
3278 if clear:
3279 pattern = "Set " + str( setName ) + " cleared"
3280 if re.search( pattern, output ):
3281 return main.TRUE
3282 elif retain:
3283 positivePattern = str( setName ) + " was pruned to contain " +\
3284 "only elements of set \[(.*)\]"
3285 negativePattern = str( setName ) + " was not changed by " +\
3286 "retaining only elements of the set " +\
3287 "\[(.*)\]"
3288 if re.search( positivePattern, output ):
3289 return main.TRUE
3290 elif re.search( negativePattern, output ):
3291 return main.FALSE
3292 else:
3293 positivePattern = "\[(.*)\] was removed from the set " +\
3294 str( setName )
3295 if ( len( values.split() ) == 1 ):
3296 negativePattern = "\[(.*)\] was not in set " +\
3297 str( setName )
3298 else:
3299 negativePattern = "No element of \[(.*)\] was in set " +\
3300 str( setName )
3301 if re.search( positivePattern, output ):
3302 return main.TRUE
3303 elif re.search( negativePattern, output ):
3304 return main.FALSE
3305 main.log.error( self.name + ": setTestRemove did not" +
3306 " match expected output" )
3307 main.log.debug( self.name + " expected: " + pattern )
3308 main.log.debug( self.name + " actual: " + repr( output ) )
3309 return main.ERROR
3310 except AssertionError:
3311 main.log.error( "Error in processing 'set-test-remove' command: " +
3312 str( output ) )
3313 return main.ERROR
3314 except TypeError:
3315 main.log.exception( self.name + ": Object not as expected" )
3316 return main.ERROR
3317 except pexpect.EOF:
3318 main.log.error( self.name + ": EOF exception found" )
3319 main.log.error( self.name + ": " + self.handle.before )
3320 main.cleanup()
3321 main.exit()
3322 except Exception:
3323 main.log.exception( self.name + ": Uncaught exception!" )
3324 main.cleanup()
3325 main.exit()
3326
3327 def setTestGet( self, setName, values="" ):
3328 """
3329 CLI command to get the elements in a distributed set.
3330 Required arguments:
3331 setName - The name of the set to remove from.
3332 Optional arguments:
3333 values - The value(s) to check if in the set, space seperated.
3334 returns:
3335 main.ERROR on error OR
3336 A list of elements in the set if no optional arguments are
3337 supplied OR
3338 A tuple containing the list then:
3339 main.FALSE if the given values are not in the set OR
3340 main.TRUE if the given values are in the set OR
3341 """
3342 try:
3343 values = str( values ).strip()
3344 setName = str( setName ).strip()
3345 length = len( values.split() )
3346 containsCheck = None
3347 # Patterns to match
3348 setPattern = "\[(.*)\]"
3349 pattern = "Items in set " + setName + ":\n" + setPattern
3350 containsTrue = "Set " + setName + " contains the value " + values
3351 containsFalse = "Set " + setName + " did not contain the value " +\
3352 values
3353 containsAllTrue = "Set " + setName + " contains the the subset " +\
3354 setPattern
3355 containsAllFalse = "Set " + setName + " did not contain the the" +\
3356 " subset " + setPattern
3357
3358 cmdStr = "set-test-get "
3359 cmdStr += setName + " " + values
3360 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003361 try:
3362 # TODO: Maybe make this less hardcoded
3363 # ConsistentMap Exceptions
3364 assert "org.onosproject.store.service" not in output
3365 # Node not leader
3366 assert "java.lang.IllegalStateException" not in output
3367 except AssertionError:
3368 main.log.error( "Error in processing 'set-test-add' " +
3369 "command: " + str( output ) )
3370 retryTime = 30 # Conservative time, given by Madan
3371 main.log.info( "Waiting " + str( retryTime ) +
3372 "seconds before retrying." )
3373 time.sleep( retryTime ) # Due to change in mastership
3374 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003375 assert "Error executing command" not in output
3376 main.log.info( self.name + ": " + output )
3377
3378 if length == 0:
3379 match = re.search( pattern, output )
3380 else: # if given values
3381 if length == 1: # Contains output
3382 patternTrue = pattern + "\n" + containsTrue
3383 patternFalse = pattern + "\n" + containsFalse
3384 else: # ContainsAll output
3385 patternTrue = pattern + "\n" + containsAllTrue
3386 patternFalse = pattern + "\n" + containsAllFalse
3387 matchTrue = re.search( patternTrue, output )
3388 matchFalse = re.search( patternFalse, output )
3389 if matchTrue:
3390 containsCheck = main.TRUE
3391 match = matchTrue
3392 elif matchFalse:
3393 containsCheck = main.FALSE
3394 match = matchFalse
3395 else:
3396 main.log.error( self.name + " setTestGet did not match " +\
3397 "expected output" )
3398 main.log.debug( self.name + " expected: " + pattern )
3399 main.log.debug( self.name + " actual: " + repr( output ) )
3400 match = None
3401 if match:
3402 setMatch = match.group( 1 )
3403 if setMatch == '':
3404 setList = []
3405 else:
3406 setList = setMatch.split( ", " )
3407 if length > 0:
3408 return ( setList, containsCheck )
3409 else:
3410 return setList
3411 else: # no match
3412 main.log.error( self.name + ": setTestGet did not" +
3413 " match expected output" )
3414 main.log.debug( self.name + " expected: " + pattern )
3415 main.log.debug( self.name + " actual: " + repr( output ) )
3416 return main.ERROR
3417 except AssertionError:
3418 main.log.error( "Error in processing 'set-test-get' command: " +
3419 str( output ) )
3420 return main.ERROR
3421 except TypeError:
3422 main.log.exception( self.name + ": Object not as expected" )
3423 return main.ERROR
3424 except pexpect.EOF:
3425 main.log.error( self.name + ": EOF exception found" )
3426 main.log.error( self.name + ": " + self.handle.before )
3427 main.cleanup()
3428 main.exit()
3429 except Exception:
3430 main.log.exception( self.name + ": Uncaught exception!" )
3431 main.cleanup()
3432 main.exit()
3433
3434 def setTestSize( self, setName ):
3435 """
3436 CLI command to get the elements in a distributed set.
3437 Required arguments:
3438 setName - The name of the set to remove from.
3439 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003440 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003441 None on error
3442 """
3443 try:
3444 # TODO: Should this check against the number of elements returned
3445 # and then return true/false based on that?
3446 setName = str( setName ).strip()
3447 # Patterns to match
3448 setPattern = "\[(.*)\]"
3449 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3450 setPattern
3451 cmdStr = "set-test-get -s "
3452 cmdStr += setName
3453 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003454 try:
3455 # TODO: Maybe make this less hardcoded
3456 # ConsistentMap Exceptions
3457 assert "org.onosproject.store.service" not in output
3458 # Node not leader
3459 assert "java.lang.IllegalStateException" not in output
3460 except AssertionError:
3461 main.log.error( "Error in processing 'set-test-add' " +
3462 "command: " + str( output ) )
3463 retryTime = 30 # Conservative time, given by Madan
3464 main.log.info( "Waiting " + str( retryTime ) +
3465 "seconds before retrying." )
3466 time.sleep( retryTime ) # Due to change in mastership
3467 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003468 assert "Error executing command" not in output
3469 main.log.info( self.name + ": " + output )
3470 match = re.search( pattern, output )
3471 if match:
3472 setSize = int( match.group( 1 ) )
3473 setMatch = match.group( 2 )
3474 if len( setMatch.split() ) == setSize:
3475 main.log.info( "The size returned by " + self.name +
3476 " matches the number of elements in " +
3477 "the returned set" )
3478 else:
3479 main.log.error( "The size returned by " + self.name +
3480 " does not match the number of " +
3481 "elements in the returned set." )
3482 return setSize
3483 else: # no match
3484 main.log.error( self.name + ": setTestGet did not" +
3485 " match expected output" )
3486 main.log.debug( self.name + " expected: " + pattern )
3487 main.log.debug( self.name + " actual: " + repr( output ) )
3488 return None
3489 except AssertionError:
3490 main.log.error( "Error in processing 'set-test-get' command: " +
3491 str( output ) )
3492 return None
3493 except TypeError:
3494 main.log.exception( self.name + ": Object not as expected" )
3495 return None
3496 except pexpect.EOF:
3497 main.log.error( self.name + ": EOF exception found" )
3498 main.log.error( self.name + ": " + self.handle.before )
3499 main.cleanup()
3500 main.exit()
3501 except Exception:
3502 main.log.exception( self.name + ": Uncaught exception!" )
3503 main.cleanup()
3504 main.exit()
3505
Jon Hall80daded2015-05-27 16:07:00 -07003506 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003507 """
3508 Command to list the various counters in the system.
3509 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003510 if jsonFormat, a string of the json object returned by the cli
3511 command
3512 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003513 None on error
3514 """
Jon Hall390696c2015-05-05 17:13:41 -07003515 try:
3516 counters = {}
3517 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003518 if jsonFormat:
3519 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003520 output = self.sendline( cmdStr )
3521 assert "Error executing command" not in output
3522 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003523 return output
Jon Hall390696c2015-05-05 17:13:41 -07003524 except AssertionError:
3525 main.log.error( "Error in processing 'counters' command: " +
3526 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003527 return None
Jon Hall390696c2015-05-05 17:13:41 -07003528 except TypeError:
3529 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003530 return None
Jon Hall390696c2015-05-05 17:13:41 -07003531 except pexpect.EOF:
3532 main.log.error( self.name + ": EOF exception found" )
3533 main.log.error( self.name + ": " + self.handle.before )
3534 main.cleanup()
3535 main.exit()
3536 except Exception:
3537 main.log.exception( self.name + ": Uncaught exception!" )
3538 main.cleanup()
3539 main.exit()
3540
3541 def counterTestIncrement( self, counter, inMemory=False ):
3542 """
3543 CLI command to increment and get a distributed counter.
3544 Required arguments:
3545 counter - The name of the counter to increment.
3546 Optional arguments:
3547 inMemory - use in memory map for the counter
3548 returns:
3549 integer value of the counter or
3550 None on Error
3551 """
3552 try:
3553 counter = str( counter )
3554 cmdStr = "counter-test-increment "
3555 if inMemory:
3556 cmdStr += "-i "
3557 cmdStr += counter
3558 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003559 try:
3560 # TODO: Maybe make this less hardcoded
3561 # ConsistentMap Exceptions
3562 assert "org.onosproject.store.service" not in output
3563 # Node not leader
3564 assert "java.lang.IllegalStateException" not in output
3565 except AssertionError:
3566 main.log.error( "Error in processing 'set-test-add' " +
3567 "command: " + str( output ) )
3568 retryTime = 30 # Conservative time, given by Madan
3569 main.log.info( "Waiting " + str( retryTime ) +
3570 "seconds before retrying." )
3571 time.sleep( retryTime ) # Due to change in mastership
3572 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003573 assert "Error executing command" not in output
3574 main.log.info( self.name + ": " + output )
3575 pattern = counter + " was incremented to (\d+)"
3576 match = re.search( pattern, output )
3577 if match:
3578 return int( match.group( 1 ) )
3579 else:
3580 main.log.error( self.name + ": counterTestIncrement did not" +
3581 " match expected output." )
3582 main.log.debug( self.name + " expected: " + pattern )
3583 main.log.debug( self.name + " actual: " + repr( output ) )
3584 return None
3585 except AssertionError:
3586 main.log.error( "Error in processing 'counter-test-increment'" +
3587 " command: " + str( output ) )
3588 return None
3589 except TypeError:
3590 main.log.exception( self.name + ": Object not as expected" )
3591 return None
3592 except pexpect.EOF:
3593 main.log.error( self.name + ": EOF exception found" )
3594 main.log.error( self.name + ": " + self.handle.before )
3595 main.cleanup()
3596 main.exit()
3597 except Exception:
3598 main.log.exception( self.name + ": Uncaught exception!" )
3599 main.cleanup()
3600 main.exit()
3601
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003602 def summary( self, jsonFormat=True ):
3603 """
3604 Description: Execute summary command in onos
3605 Returns: json object ( summary -j ), returns main.FALSE if there is
3606 no output
3607
3608 """
3609 try:
3610 cmdStr = "summary"
3611 if jsonFormat:
3612 cmdStr += " -j"
3613 handle = self.sendline( cmdStr )
3614
3615 if re.search( "Error:", handle ):
3616 main.log.error( self.name + ": summary() response: " +
3617 str( handle ) )
3618 if not handle:
3619 main.log.error( self.name + ": There is no output in " +
3620 "summary command" )
3621 return main.FALSE
3622 return handle
3623 except TypeError:
3624 main.log.exception( self.name + ": Object not as expected" )
3625 return None
3626 except pexpect.EOF:
3627 main.log.error( self.name + ": EOF exception found" )
3628 main.log.error( self.name + ": " + self.handle.before )
3629 main.cleanup()
3630 main.exit()
3631 except Exception:
3632 main.log.exception( self.name + ": Uncaught exception!" )
3633 main.cleanup()
3634 main.exit()