blob: 2eca3da0d256e216cb8bff8b28f5e651c111424b [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 pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
62 if os.getenv( str( self.ip_address ) ) != None:
63 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
145 self.handle.expect( "\$" )
146 return main.TRUE
147 elif i == 1: # not in CLI
148 return main.TRUE
149 elif i == 3: # Timeout
150 return main.FALSE
151 else:
andrewonlab9627f432014-11-14 12:45:10 -0500152 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800153 except TypeError:
154 main.log.exception( self.name + ": Object not as expected" )
155 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700158 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500159 main.cleanup()
160 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700161 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700162 main.log.error( self.name +
163 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 main.cleanup()
167 main.exit()
168
kelvin-onlabd3b64892015-01-20 13:26:24 -0800169 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab95ce8322014-10-13 14:12:04 -0400171 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800172
andrewonlab95ce8322014-10-13 14:12:04 -0400173 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800174 """
andrewonlab95ce8322014-10-13 14:12:04 -0400175 try:
176 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800177 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400178 main.cleanup()
179 main.exit()
180 else:
kelvin8ec71442015-01-15 16:57:00 -0800181 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800183 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400184 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800185 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800186 handleBefore = self.handle.before
187 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800188 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800189 self.handle.sendline("")
190 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800191 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400192
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 main.log.info( "Cell call returned: " + handleBefore +
194 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400195
196 return main.TRUE
197
Jon Halld4d4b372015-01-28 16:02:41 -0800198 except TypeError:
199 main.log.exception( self.name + ": Object not as expected" )
200 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800202 main.log.error( self.name + ": eof exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400204 main.cleanup()
205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400208 main.cleanup()
209 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800210
pingping-lin57a56ce2015-05-20 16:43:48 -0700211 def startOnosCli( self, ONOSIp, karafTimeout="",
212 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800213 """
Jon Hallefbd9792015-03-05 16:11:36 -0800214 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 by user would be used to set the current karaf shell idle timeout.
216 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800217 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 Below is an example to start a session with 60 seconds idle timeout
219 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800220
Hari Krishna25d42f72015-01-05 15:08:28 -0800221 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800223
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 Note: karafTimeout is left as str so that this could be read
225 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800226 """
andrewonlab95ce8322014-10-13 14:12:04 -0400227 try:
kelvin8ec71442015-01-15 16:57:00 -0800228 self.handle.sendline( "" )
229 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700230 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500231
232 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500234 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400235
kelvin8ec71442015-01-15 16:57:00 -0800236 # Wait for onos start ( -w ) and enter onos cli
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( [
239 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700240 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400241
242 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800244 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800246 "config:property-set -p org.apache.karaf.shell\
247 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800248 karafTimeout )
249 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800251 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400252 return main.TRUE
253 else:
kelvin8ec71442015-01-15 16:57:00 -0800254 # If failed, send ctrl+c to process and try again
255 main.log.info( "Starting CLI failed. Retrying..." )
256 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800258 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
259 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400260 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800262 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800263 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800264 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 "config:property-set -p org.apache.karaf.shell\
266 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800267 karafTimeout )
268 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800270 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400271 return main.TRUE
272 else:
kelvin8ec71442015-01-15 16:57:00 -0800273 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400275 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400276
Jon Halld4d4b372015-01-28 16:02:41 -0800277 except TypeError:
278 main.log.exception( self.name + ": Object not as expected" )
279 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400280 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800281 main.log.error( self.name + ": EOF exception found" )
282 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400283 main.cleanup()
284 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800285 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800286 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400287 main.cleanup()
288 main.exit()
289
Jon Hallefbd9792015-03-05 16:11:36 -0800290 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800291 """
292 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800293 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800294 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800295 Available level: DEBUG, TRACE, INFO, WARN, ERROR
296 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800297 """
298 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800299 lvlStr = ""
300 if level:
301 lvlStr = "--level=" + level
302
kelvin-onlab9f541032015-02-04 16:19:53 -0800303 self.handle.sendline( "" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700304 i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700305 if i == 1:
Jon Hallc9eabec2015-06-10 14:33:14 -0700306 main.log.error( self.name + ": onos cli session closed." )
307 main.cleanup()
308 main.exit()
309 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700310 self.handle.sendline( "" )
311 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800312 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700313 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800314 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800315
kelvin-onlab9f541032015-02-04 16:19:53 -0800316 response = self.handle.before
317 if re.search( "Error", response ):
318 return main.FALSE
319 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700320 except pexpect.TIMEOUT:
321 main.log.exception( self.name + ": TIMEOUT exception found" )
322 main.cleanup()
323 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800324 except pexpect.EOF:
325 main.log.error( self.name + ": EOF exception found" )
326 main.log.error( self.name + ": " + self.handle.before )
327 main.cleanup()
328 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800329 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800330 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400331 main.cleanup()
332 main.exit()
333
Jon Hallc6358dd2015-04-10 12:44:28 -0700334 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800335 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800336 Send a completely user specified string to
337 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400338 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800339
andrewonlaba18f6bf2014-10-13 19:31:54 -0400340 Warning: There are no sanity checking to commands
341 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800342 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400343 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800344 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
345 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800346 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800347 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
348 response = self.handle.before
349 if i == 2:
350 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700351 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800352 response += self.handle.before
353 print response
354 try:
355 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700356 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800357 pass
358 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800359 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800360 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700361 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700362 main.log.debug( self.name + ": Raw output" )
363 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700364
365 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800367 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700368 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700369 main.log.debug( self.name + ": ansiEscape output" )
370 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700371
kelvin-onlabfb521662015-02-27 09:52:40 -0800372 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800373 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700374 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700375 main.log.debug( self.name + ": Removed extra returns " +
376 "from output" )
377 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700378
379 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800380 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700381 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.log.debug( self.name + ": parsed and stripped output" )
383 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700384
Jon Hall63604932015-02-26 17:09:50 -0800385 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700386 output = response.split( cmdStr.strip(), 1 )
387 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700388 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700389 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700390 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700391 return output[1].strip()
392 except IndexError:
393 main.log.exception( self.name + ": Object not as expected" )
394 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800395 except TypeError:
396 main.log.exception( self.name + ": Object not as expected" )
397 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400398 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800399 main.log.error( self.name + ": EOF exception found" )
400 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400401 main.cleanup()
402 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800403 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800404 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400405 main.cleanup()
406 main.exit()
407
kelvin8ec71442015-01-15 16:57:00 -0800408 # IMPORTANT NOTE:
409 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800410 # the cli command changing 'a:b' with 'aB'.
411 # Ex ) onos:topology > onosTopology
412 # onos:links > onosLinks
413 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800414
kelvin-onlabd3b64892015-01-20 13:26:24 -0800415 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800416 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400417 Adds a new cluster node by ID and address information.
418 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800419 * nodeId
420 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400424 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 cmdStr = "add-node " + str( nodeId ) + " " +\
426 str( ONOSIp ) + " " + str( tcpPort )
427 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800428 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800429 main.log.error( "Error in adding node" )
430 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800431 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400432 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400434 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800435 except TypeError:
436 main.log.exception( self.name + ": Object not as expected" )
437 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800439 main.log.error( self.name + ": EOF exception found" )
440 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 main.cleanup()
442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800444 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400445 main.cleanup()
446 main.exit()
447
kelvin-onlabd3b64892015-01-20 13:26:24 -0800448 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800449 """
andrewonlab86dc3082014-10-13 18:18:38 -0400450 Removes a cluster by ID
451 Issues command: 'remove-node [<node-id>]'
452 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800453 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800454 """
andrewonlab86dc3082014-10-13 18:18:38 -0400455 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400456
kelvin-onlabd3b64892015-01-20 13:26:24 -0800457 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700458 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700459 if re.search( "Error", handle ):
460 main.log.error( "Error in removing node" )
461 main.log.error( handle )
462 return main.FALSE
463 else:
464 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800465 except TypeError:
466 main.log.exception( self.name + ": Object not as expected" )
467 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400468 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800469 main.log.error( self.name + ": EOF exception found" )
470 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400471 main.cleanup()
472 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800473 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800474 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400475 main.cleanup()
476 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400477
Jon Hall61282e32015-03-19 11:34:11 -0700478 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800479 """
andrewonlab7c211572014-10-15 16:45:20 -0400480 List the nodes currently visible
481 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700482 Optional argument:
483 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800484 """
andrewonlab7c211572014-10-15 16:45:20 -0400485 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700486 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700487 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 cmdStr += " -j"
489 output = self.sendline( cmdStr )
490 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800491 except TypeError:
492 main.log.exception( self.name + ": Object not as expected" )
493 return None
andrewonlab7c211572014-10-15 16:45:20 -0400494 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800495 main.log.error( self.name + ": EOF exception found" )
496 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400497 main.cleanup()
498 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800499 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800500 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400501 main.cleanup()
502 main.exit()
503
kelvin8ec71442015-01-15 16:57:00 -0800504 def topology( self ):
505 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700506 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700507 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700508 Return:
509 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800510 """
andrewonlab95ce8322014-10-13 14:12:04 -0400511 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700512 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800513 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400515 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800516 except TypeError:
517 main.log.exception( self.name + ": Object not as expected" )
518 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400519 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800520 main.log.error( self.name + ": EOF exception found" )
521 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400522 main.cleanup()
523 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800524 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800525 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400526 main.cleanup()
527 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800528
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800530 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700531 Installs a specified feature by issuing command:
532 'feature:install <feature_str>'
533 NOTE: This is now deprecated, you should use the activateApp method
534 instead
kelvin8ec71442015-01-15 16:57:00 -0800535 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400536 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800537 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 handle = self.sendline( cmdStr )
539 if re.search( "Error", handle ):
540 main.log.error( "Error in installing feature" )
541 main.log.error( handle )
542 return main.FALSE
543 else:
544 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800545 except TypeError:
546 main.log.exception( self.name + ": Object not as expected" )
547 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400548 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800549 main.log.error( self.name + ": EOF exception found" )
550 main.log.error( self.name + ": " + self.handle.before )
551 main.log.report( "Failed to install feature" )
552 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 main.cleanup()
554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800556 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800557 main.log.report( "Failed to install feature" )
558 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400559 main.cleanup()
560 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800561
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800563 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700564 Uninstalls a specified feature by issuing command:
565 'feature:uninstall <feature_str>'
566 NOTE: This is now deprecated, you should use the deactivateApp method
567 instead
kelvin8ec71442015-01-15 16:57:00 -0800568 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800570 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
571 handle = self.sendline( cmdStr )
572 if handle != '':
573 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700574 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800575 # TODO: Check for possible error responses from karaf
576 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800577 main.log.info( "Feature needs to be installed before " +
578 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700579 return main.TRUE
580 if re.search( "Error", output ):
581 main.log.error( "Error in uninstalling feature" )
582 main.log.error( output )
583 return main.FALSE
584 else:
585 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800586 except TypeError:
587 main.log.exception( self.name + ": Object not as expected" )
588 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400589 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800590 main.log.error( self.name + ": EOF exception found" )
591 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 main.cleanup()
593 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800594 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800595 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400596 main.cleanup()
597 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800598
jenkins7ead5a82015-03-13 10:28:21 -0700599 def deviceRemove( self, deviceId ):
600 """
601 Removes particular device from storage
602
603 TODO: refactor this function
604 """
605 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700606 cmdStr = "device-remove " + str( deviceId )
607 handle = self.sendline( cmdStr )
608 if re.search( "Error", handle ):
609 main.log.error( "Error in removing device" )
610 main.log.error( handle )
611 return main.FALSE
612 else:
613 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700614 except TypeError:
615 main.log.exception( self.name + ": Object not as expected" )
616 return None
617 except pexpect.EOF:
618 main.log.error( self.name + ": EOF exception found" )
619 main.log.error( self.name + ": " + self.handle.before )
620 main.cleanup()
621 main.exit()
622 except Exception:
623 main.log.exception( self.name + ": Uncaught exception!" )
624 main.cleanup()
625 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800628 """
Jon Hall7b02d952014-10-17 20:14:54 -0400629 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400630 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800632 """
andrewonlab86dc3082014-10-13 18:18:38 -0400633 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 cmdStr += " -j"
637 handle = self.sendline( cmdStr )
638 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlab7c211572014-10-15 16:45:20 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400645 main.cleanup()
646 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400649 main.cleanup()
650 main.exit()
651
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800653 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800654 This balances the devices across all controllers
655 by issuing command: 'onos> onos:balance-masters'
656 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800657 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800658 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 handle = self.sendline( cmdStr )
661 if re.search( "Error", handle ):
662 main.log.error( "Error in balancing masters" )
663 main.log.error( handle )
664 return main.FALSE
665 else:
666 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800667 except TypeError:
668 main.log.exception( self.name + ": Object not as expected" )
669 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800670 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800671 main.log.error( self.name + ": EOF exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800673 main.cleanup()
674 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800676 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800677 main.cleanup()
678 main.exit()
679
acsmars24950022015-07-30 18:00:43 -0700680 def checkMasters( self,jsonFormat=True ):
681 """
682 Returns the output of the masters command.
683 Optional argument:
684 * jsonFormat - boolean indicating if you want output in json
685 """
686 try:
687 cmdStr = "onos:masters"
688 if jsonFormat:
689 cmdStr += " -j"
690 output = self.sendline( cmdStr )
691 return output
692 except TypeError:
693 main.log.exception( self.name + ": Object not as expected" )
694 return None
695 except pexpect.EOF:
696 main.log.error( self.name + ": EOF exception found" )
697 main.log.error( self.name + ": " + self.handle.before )
698 main.cleanup()
699 main.exit()
700 except Exception:
701 main.log.exception( self.name + ": Uncaught exception!" )
702 main.cleanup()
703 main.exit()
704
705 def checkBalanceMasters( self,jsonFormat=True ):
706 """
707 Uses the master command to check that the devices' leadership
708 is evenly divided
709
710 Dependencies: checkMasters() and summary()
711
712 Returns main.True if the devices are balanced
713 Returns main.False if the devices are unbalanced
714 Exits on Exception
715 Returns None on TypeError
716 """
717 try:
718 totalDevices = json.loads( self.summary() )[ "devices" ]
719 totalOwnedDevices = 0
720 masters = json.loads( self.checkMasters() )
721 first = masters[ 0 ][ "size" ]
722 for master in masters:
723 totalOwnedDevices += master[ "size" ]
724 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
725 main.log.error( "Mastership not balanced" )
726 main.log.info( "\n" + self.checkMasters( False ) )
727 return main.FALSE
728 main.log.info( "Mastership balanced between " \
729 + str( len(masters) ) + " masters" )
730 return main.TRUE
731 except TypeError:
732 main.log.exception( self.name + ": Object not as expected" )
733 return None
734 except pexpect.EOF:
735 main.log.error( self.name + ": EOF exception found" )
736 main.log.error( self.name + ": " + self.handle.before )
737 main.cleanup()
738 main.exit()
739 except Exception:
740 main.log.exception( self.name + ": Uncaught exception!" )
741 main.cleanup()
742 main.exit()
743
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800745 """
Jon Halle8217482014-10-17 13:49:14 -0400746 Lists all core links
747 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800748 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800749 """
Jon Halle8217482014-10-17 13:49:14 -0400750 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700751 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 cmdStr += " -j"
754 handle = self.sendline( cmdStr )
755 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
Jon Halle8217482014-10-17 13:49:14 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400762 main.cleanup()
763 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800764 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800765 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400766 main.cleanup()
767 main.exit()
768
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800770 """
Jon Halle8217482014-10-17 13:49:14 -0400771 Lists all ports
772 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800774 """
Jon Halle8217482014-10-17 13:49:14 -0400775 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700776 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800777 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 cmdStr += " -j"
779 handle = self.sendline( cmdStr )
780 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800781 except TypeError:
782 main.log.exception( self.name + ": Object not as expected" )
783 return None
Jon Halle8217482014-10-17 13:49:14 -0400784 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800785 main.log.error( self.name + ": EOF exception found" )
786 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400787 main.cleanup()
788 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800789 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800790 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400791 main.cleanup()
792 main.exit()
793
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800795 """
Jon Hall983a1702014-10-28 18:44:22 -0400796 Lists all devices and the controllers with roles assigned to them
797 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800799 """
andrewonlab7c211572014-10-15 16:45:20 -0400800 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700801 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700803 cmdStr += " -j"
804 handle = self.sendline( cmdStr )
805 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800806 except TypeError:
807 main.log.exception( self.name + ": Object not as expected" )
808 return None
Jon Hall983a1702014-10-28 18:44:22 -0400809 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400812 main.cleanup()
813 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800814 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800815 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400816 main.cleanup()
817 main.exit()
818
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800820 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800821 Given the a string containing the json representation of the "roles"
822 cli command and a partial or whole device id, returns a json object
823 containing the roles output for the first device whose id contains
824 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400825
826 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800827 A dict of the role assignments for the given device or
828 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800829 """
Jon Hall983a1702014-10-28 18:44:22 -0400830 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800831 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400832 return None
833 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800834 rawRoles = self.roles()
835 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800836 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800838 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800839 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400840 return device
841 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800842 except TypeError:
843 main.log.exception( self.name + ": Object not as expected" )
844 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400845 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800846 main.log.error( self.name + ": EOF exception found" )
847 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400848 main.cleanup()
849 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800850 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800851 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400852 main.cleanup()
853 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800854
kelvin-onlabd3b64892015-01-20 13:26:24 -0800855 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800856 """
Jon Hall94fd0472014-12-08 11:52:42 -0800857 Iterates through each device and checks if there is a master assigned
858 Returns: main.TRUE if each device has a master
859 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Hall94fd0472014-12-08 11:52:42 -0800861 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 rawRoles = self.roles()
863 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800864 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800866 # print device
867 if device[ 'master' ] == "none":
868 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800869 return main.FALSE
870 return main.TRUE
871
Jon Halld4d4b372015-01-28 16:02:41 -0800872 except TypeError:
873 main.log.exception( self.name + ": Object not as expected" )
874 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800875 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800876 main.log.error( self.name + ": EOF exception found" )
877 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800878 main.cleanup()
879 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800880 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800881 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800882 main.cleanup()
883 main.exit()
884
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800886 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400887 Returns string of paths, and the cost.
888 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800889 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400890 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
892 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800893 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.error( "Error in getting paths" )
895 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400896 else:
kelvin8ec71442015-01-15 16:57:00 -0800897 path = handle.split( ";" )[ 0 ]
898 cost = handle.split( ";" )[ 1 ]
899 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800900 except TypeError:
901 main.log.exception( self.name + ": Object not as expected" )
902 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400903 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800904 main.log.error( self.name + ": EOF exception found" )
905 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400906 main.cleanup()
907 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800908 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800909 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400910 main.cleanup()
911 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800912
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800914 """
Jon Hallffb386d2014-11-21 13:43:38 -0800915 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400916 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800918 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400919 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700920 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 cmdStr += " -j"
923 handle = self.sendline( cmdStr )
924 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800925 except TypeError:
926 main.log.exception( self.name + ": Object not as expected" )
927 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800929 main.log.error( self.name + ": EOF exception found" )
930 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400931 main.cleanup()
932 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800934 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400935 main.cleanup()
936 main.exit()
937
kelvin-onlabd3b64892015-01-20 13:26:24 -0800938 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800939 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400940 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800941
Jon Hallefbd9792015-03-05 16:11:36 -0800942 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800943 partial mac address
944
Jon Hall42db6dc2014-10-24 19:03:48 -0400945 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800946 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400947 try:
kelvin8ec71442015-01-15 16:57:00 -0800948 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400949 return None
950 else:
951 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 rawHosts = self.hosts()
953 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800954 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800955 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800956 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800957 if not host:
958 pass
959 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400960 return host
961 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800962 except TypeError:
963 main.log.exception( self.name + ": Object not as expected" )
964 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400965 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400968 main.cleanup()
969 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800970 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800971 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400972 main.cleanup()
973 main.exit()
974
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800976 """
977 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400978 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800979
andrewonlab3f0a4af2014-10-17 12:25:14 -0400980 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800981 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400982 IMPORTANT:
983 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800984 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400985 Furthermore, it assumes that value of VLAN is '-1'
986 Description:
kelvin8ec71442015-01-15 16:57:00 -0800987 Converts mininet hosts ( h1, h2, h3... ) into
988 ONOS format ( 00:00:00:00:00:01/-1 , ... )
989 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400990 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400992
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800994 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 hostHex = hex( int( host ) ).zfill( 12 )
996 hostHex = str( hostHex ).replace( 'x', '0' )
997 i = iter( str( hostHex ) )
998 hostHex = ":".join( a + b for a, b in zip( i, i ) )
999 hostHex = hostHex + "/-1"
1000 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001001
kelvin-onlabd3b64892015-01-20 13:26:24 -08001002 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001003
Jon Halld4d4b372015-01-28 16:02:41 -08001004 except TypeError:
1005 main.log.exception( self.name + ": Object not as expected" )
1006 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001007 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001010 main.cleanup()
1011 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001012 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001013 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001014 main.cleanup()
1015 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001016
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlabe6745342014-10-17 14:29:13 -04001019 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 * hostIdOne: ONOS host id for host1
1021 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001022 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001023 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001024 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001025 Returns:
1026 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001027 """
andrewonlabe6745342014-10-17 14:29:13 -04001028 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1030 " " + str( hostIdTwo )
1031 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -08001032 if re.search( "Error", handle ):
1033 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001034 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001035 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001036 else:
1037 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001038 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1039 match = re.search('id=0x([\da-f]+),', handle)
1040 if match:
1041 return match.group()[3:-1]
1042 else:
1043 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001044 main.log.debug( "Response from ONOS was: " +
1045 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001046 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001047 except TypeError:
1048 main.log.exception( self.name + ": Object not as expected" )
1049 return None
andrewonlabe6745342014-10-17 14:29:13 -04001050 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001051 main.log.error( self.name + ": EOF exception found" )
1052 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001053 main.cleanup()
1054 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001055 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001056 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001057 main.cleanup()
1058 main.exit()
1059
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001061 """
andrewonlab7b31d232014-10-24 13:31:47 -04001062 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 * ingressDevice: device id of ingress device
1064 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001065 Optional:
1066 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001067 Description:
1068 Adds an optical intent by specifying an ingress and egress device
1069 Returns:
1070 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001071 """
andrewonlab7b31d232014-10-24 13:31:47 -04001072 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1074 " " + str( egressDevice )
1075 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001076 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001077 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001078 main.log.error( "Error in adding Optical intent" )
1079 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001080 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001081 main.log.info( "Optical intent installed between " +
1082 str( ingressDevice ) + " and " +
1083 str( egressDevice ) )
1084 match = re.search('id=0x([\da-f]+),', handle)
1085 if match:
1086 return match.group()[3:-1]
1087 else:
1088 main.log.error( "Error, intent ID not found" )
1089 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001090 except TypeError:
1091 main.log.exception( self.name + ": Object not as expected" )
1092 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001094 main.log.error( self.name + ": EOF exception found" )
1095 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001096 main.cleanup()
1097 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001100 main.cleanup()
1101 main.exit()
1102
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001104 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 ingressDevice,
1106 egressDevice,
1107 portIngress="",
1108 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 ethType="",
1110 ethSrc="",
1111 ethDst="",
1112 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001114 ipProto="",
1115 ipSrc="",
1116 ipDst="",
1117 tcpSrc="",
1118 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001119 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001120 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 * ingressDevice: device id of ingress device
1122 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001123 Optional:
1124 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001125 * ethSrc: specify ethSrc ( i.e. src mac addr )
1126 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001127 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001129 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001130 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001131 * ipSrc: specify ip source address
1132 * ipDst: specify ip destination address
1133 * tcpSrc: specify tcp source port
1134 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001135 Description:
kelvin8ec71442015-01-15 16:57:00 -08001136 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001137 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001138 Returns:
1139 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001140
Jon Halle3f39ff2015-01-13 11:50:53 -08001141 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001142 options developers provide for point-to-point
1143 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001144 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001145 try:
kelvin8ec71442015-01-15 16:57:00 -08001146 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001147 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001149 and not ipProto and not ipSrc and not ipDst \
1150 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001151 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001152
andrewonlab289e4b72014-10-21 21:24:18 -04001153 else:
andrewonlab36af3822014-11-18 17:48:18 -05001154 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001155
andrewonlab0c0a6772014-10-22 12:31:18 -04001156 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001157 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001158 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001159 cmd += " --ethSrc " + str( ethSrc )
1160 if ethDst:
1161 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001162 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001163 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001165 cmd += " --lambda "
1166 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001167 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001168 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001169 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001170 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001171 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001172 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001173 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001174 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001175 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001176
kelvin8ec71442015-01-15 16:57:00 -08001177 # Check whether the user appended the port
1178 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 if "/" in ingressDevice:
1180 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001181 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001183 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001184 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 # Would it make sense to throw an exception and exit
1186 # the test?
1187 return None
andrewonlab36af3822014-11-18 17:48:18 -05001188
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001190 str( ingressDevice ) + "/" +\
1191 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001192
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 if "/" in egressDevice:
1194 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001195 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001197 main.log.error( "You must specify the egress port" )
1198 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001199
kelvin8ec71442015-01-15 16:57:00 -08001200 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 str( egressDevice ) + "/" +\
1202 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001203
kelvin-onlab898a6c62015-01-16 14:13:53 -08001204 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001205 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001206 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001207 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001208 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001209 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001210 # TODO: print out all the options in this message?
1211 main.log.info( "Point-to-point intent installed between " +
1212 str( ingressDevice ) + " and " +
1213 str( egressDevice ) )
1214 match = re.search('id=0x([\da-f]+),', handle)
1215 if match:
1216 return match.group()[3:-1]
1217 else:
1218 main.log.error( "Error, intent ID not found" )
1219 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001220 except TypeError:
1221 main.log.exception( self.name + ": Object not as expected" )
1222 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001226 main.cleanup()
1227 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001229 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001230 main.cleanup()
1231 main.exit()
1232
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001234 self,
shahshreyac2f97072015-03-19 17:04:29 -07001235 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001237 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001238 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001239 ethType="",
1240 ethSrc="",
1241 ethDst="",
1242 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001244 ipProto="",
1245 ipSrc="",
1246 ipDst="",
1247 tcpSrc="",
1248 tcpDst="",
1249 setEthSrc="",
1250 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001251 """
shahshreyad0c80432014-12-04 16:56:05 -08001252 Note:
shahshreya70622b12015-03-19 17:19:00 -07001253 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001254 is same. That is, all ingress devices include port numbers
1255 with a "/" or all ingress devices could specify device
1256 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001257 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001258 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001259 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001261 Optional:
1262 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001263 * ethSrc: specify ethSrc ( i.e. src mac addr )
1264 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001265 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001267 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001268 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001269 * ipSrc: specify ip source address
1270 * ipDst: specify ip destination address
1271 * tcpSrc: specify tcp source port
1272 * tcpDst: specify tcp destination port
1273 * setEthSrc: action to Rewrite Source MAC Address
1274 * setEthDst: action to Rewrite Destination MAC Address
1275 Description:
kelvin8ec71442015-01-15 16:57:00 -08001276 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001277 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001278 Returns:
1279 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001280
Jon Halle3f39ff2015-01-13 11:50:53 -08001281 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001282 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001283 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001284 """
shahshreyad0c80432014-12-04 16:56:05 -08001285 try:
kelvin8ec71442015-01-15 16:57:00 -08001286 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001287 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001289 and not ipProto and not ipSrc and not ipDst\
1290 and not tcpSrc and not tcpDst and not setEthSrc\
1291 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001292 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001293
1294 else:
1295 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001296
shahshreyad0c80432014-12-04 16:56:05 -08001297 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001298 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001299 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001300 cmd += " --ethSrc " + str( ethSrc )
1301 if ethDst:
1302 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001303 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001304 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001306 cmd += " --lambda "
1307 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001308 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001309 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001310 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001311 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001312 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001313 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001314 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001315 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001316 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001317 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001318 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001319 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001320 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001321
kelvin8ec71442015-01-15 16:57:00 -08001322 # Check whether the user appended the port
1323 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001324
1325 if portIngressList is None:
1326 for ingressDevice in ingressDeviceList:
1327 if "/" in ingressDevice:
1328 cmd += " " + str( ingressDevice )
1329 else:
1330 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001331 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001332 # TODO: perhaps more meaningful return
1333 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001334 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001335 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001336 for ingressDevice, portIngress in zip( ingressDeviceList,
1337 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001338 cmd += " " + \
1339 str( ingressDevice ) + "/" +\
1340 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001341 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001342 main.log.error( "Device list and port list does not " +
1343 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001344 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 if "/" in egressDevice:
1346 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001347 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001349 main.log.error( "You must specify " +
1350 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001351 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001352
kelvin8ec71442015-01-15 16:57:00 -08001353 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 str( egressDevice ) + "/" +\
1355 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001356 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001357 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001358 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 main.log.error( "Error in adding multipoint-to-singlepoint " +
1360 "intent" )
1361 return None
shahshreyad0c80432014-12-04 16:56:05 -08001362 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001363 match = re.search('id=0x([\da-f]+),', handle)
1364 if match:
1365 return match.group()[3:-1]
1366 else:
1367 main.log.error( "Error, intent ID not found" )
1368 return None
1369 except TypeError:
1370 main.log.exception( self.name + ": Object not as expected" )
1371 return None
1372 except pexpect.EOF:
1373 main.log.error( self.name + ": EOF exception found" )
1374 main.log.error( self.name + ": " + self.handle.before )
1375 main.cleanup()
1376 main.exit()
1377 except Exception:
1378 main.log.exception( self.name + ": Uncaught exception!" )
1379 main.cleanup()
1380 main.exit()
1381
1382 def addSinglepointToMultipointIntent(
1383 self,
1384 ingressDevice,
1385 egressDeviceList,
1386 portIngress="",
1387 portEgressList=None,
1388 ethType="",
1389 ethSrc="",
1390 ethDst="",
1391 bandwidth="",
1392 lambdaAlloc=False,
1393 ipProto="",
1394 ipSrc="",
1395 ipDst="",
1396 tcpSrc="",
1397 tcpDst="",
1398 setEthSrc="",
1399 setEthDst="" ):
1400 """
1401 Note:
1402 This function assumes the format of all egress devices
1403 is same. That is, all egress devices include port numbers
1404 with a "/" or all egress devices could specify device
1405 ids and port numbers seperately.
1406 Required:
1407 * EgressDeviceList: List of device ids of egress device
1408 ( Atleast 2 eress devices required in the list )
1409 * ingressDevice: device id of ingress device
1410 Optional:
1411 * ethType: specify ethType
1412 * ethSrc: specify ethSrc ( i.e. src mac addr )
1413 * ethDst: specify ethDst ( i.e. dst mac addr )
1414 * bandwidth: specify bandwidth capacity of link
1415 * lambdaAlloc: if True, intent will allocate lambda
1416 for the specified intent
1417 * ipProto: specify ip protocol
1418 * ipSrc: specify ip source address
1419 * ipDst: specify ip destination address
1420 * tcpSrc: specify tcp source port
1421 * tcpDst: specify tcp destination port
1422 * setEthSrc: action to Rewrite Source MAC Address
1423 * setEthDst: action to Rewrite Destination MAC Address
1424 Description:
1425 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1426 specifying device id's and optional fields
1427 Returns:
1428 A string of the intent id or None on error
1429
1430 NOTE: This function may change depending on the
1431 options developers provide for singlepoint-to-multipoint
1432 intent via cli
1433 """
1434 try:
1435 # If there are no optional arguments
1436 if not ethType and not ethSrc and not ethDst\
1437 and not bandwidth and not lambdaAlloc\
1438 and not ipProto and not ipSrc and not ipDst\
1439 and not tcpSrc and not tcpDst and not setEthSrc\
1440 and not setEthDst:
1441 cmd = "add-single-to-multi-intent"
1442
1443 else:
1444 cmd = "add-single-to-multi-intent"
1445
1446 if ethType:
1447 cmd += " --ethType " + str( ethType )
1448 if ethSrc:
1449 cmd += " --ethSrc " + str( ethSrc )
1450 if ethDst:
1451 cmd += " --ethDst " + str( ethDst )
1452 if bandwidth:
1453 cmd += " --bandwidth " + str( bandwidth )
1454 if lambdaAlloc:
1455 cmd += " --lambda "
1456 if ipProto:
1457 cmd += " --ipProto " + str( ipProto )
1458 if ipSrc:
1459 cmd += " --ipSrc " + str( ipSrc )
1460 if ipDst:
1461 cmd += " --ipDst " + str( ipDst )
1462 if tcpSrc:
1463 cmd += " --tcpSrc " + str( tcpSrc )
1464 if tcpDst:
1465 cmd += " --tcpDst " + str( tcpDst )
1466 if setEthSrc:
1467 cmd += " --setEthSrc " + str( setEthSrc )
1468 if setEthDst:
1469 cmd += " --setEthDst " + str( setEthDst )
1470
1471 # Check whether the user appended the port
1472 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001473
kelvin-onlabb9408212015-04-01 13:34:04 -07001474 if "/" in ingressDevice:
1475 cmd += " " + str( ingressDevice )
1476 else:
1477 if not portIngress:
1478 main.log.error( "You must specify " +
1479 "the Ingress port" )
1480 return main.FALSE
1481
1482 cmd += " " +\
1483 str( ingressDevice ) + "/" +\
1484 str( portIngress )
1485
1486 if portEgressList is None:
1487 for egressDevice in egressDeviceList:
1488 if "/" in egressDevice:
1489 cmd += " " + str( egressDevice )
1490 else:
1491 main.log.error( "You must specify " +
1492 "the egress port" )
1493 # TODO: perhaps more meaningful return
1494 return main.FALSE
1495 else:
1496 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001497 for egressDevice, portEgress in zip( egressDeviceList,
1498 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001499 cmd += " " + \
1500 str( egressDevice ) + "/" +\
1501 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001502 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001503 main.log.error( "Device list and port list does not " +
1504 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001505 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001506 handle = self.sendline( cmd )
1507 # If error, return error message
1508 if re.search( "Error", handle ):
1509 main.log.error( "Error in adding singlepoint-to-multipoint " +
1510 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001511 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001512 else:
1513 match = re.search('id=0x([\da-f]+),', handle)
1514 if match:
1515 return match.group()[3:-1]
1516 else:
1517 main.log.error( "Error, intent ID not found" )
1518 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001519 except TypeError:
1520 main.log.exception( self.name + ": Object not as expected" )
1521 return None
shahshreyad0c80432014-12-04 16:56:05 -08001522 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001523 main.log.error( self.name + ": EOF exception found" )
1524 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001525 main.cleanup()
1526 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001527 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001528 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001529 main.cleanup()
1530 main.exit()
1531
Hari Krishna9e232602015-04-13 17:29:08 -07001532 def addMplsIntent(
1533 self,
1534 ingressDevice,
1535 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001536 ingressPort="",
1537 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001538 ethType="",
1539 ethSrc="",
1540 ethDst="",
1541 bandwidth="",
1542 lambdaAlloc=False,
1543 ipProto="",
1544 ipSrc="",
1545 ipDst="",
1546 tcpSrc="",
1547 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001548 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001549 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001550 priority=""):
1551 """
1552 Required:
1553 * ingressDevice: device id of ingress device
1554 * egressDevice: device id of egress device
1555 Optional:
1556 * ethType: specify ethType
1557 * ethSrc: specify ethSrc ( i.e. src mac addr )
1558 * ethDst: specify ethDst ( i.e. dst mac addr )
1559 * bandwidth: specify bandwidth capacity of link
1560 * lambdaAlloc: if True, intent will allocate lambda
1561 for the specified intent
1562 * ipProto: specify ip protocol
1563 * ipSrc: specify ip source address
1564 * ipDst: specify ip destination address
1565 * tcpSrc: specify tcp source port
1566 * tcpDst: specify tcp destination port
1567 * ingressLabel: Ingress MPLS label
1568 * egressLabel: Egress MPLS label
1569 Description:
1570 Adds MPLS intent by
1571 specifying device id's and optional fields
1572 Returns:
1573 A string of the intent id or None on error
1574
1575 NOTE: This function may change depending on the
1576 options developers provide for MPLS
1577 intent via cli
1578 """
1579 try:
1580 # If there are no optional arguments
1581 if not ethType and not ethSrc and not ethDst\
1582 and not bandwidth and not lambdaAlloc \
1583 and not ipProto and not ipSrc and not ipDst \
1584 and not tcpSrc and not tcpDst and not ingressLabel \
1585 and not egressLabel:
1586 cmd = "add-mpls-intent"
1587
1588 else:
1589 cmd = "add-mpls-intent"
1590
1591 if ethType:
1592 cmd += " --ethType " + str( ethType )
1593 if ethSrc:
1594 cmd += " --ethSrc " + str( ethSrc )
1595 if ethDst:
1596 cmd += " --ethDst " + str( ethDst )
1597 if bandwidth:
1598 cmd += " --bandwidth " + str( bandwidth )
1599 if lambdaAlloc:
1600 cmd += " --lambda "
1601 if ipProto:
1602 cmd += " --ipProto " + str( ipProto )
1603 if ipSrc:
1604 cmd += " --ipSrc " + str( ipSrc )
1605 if ipDst:
1606 cmd += " --ipDst " + str( ipDst )
1607 if tcpSrc:
1608 cmd += " --tcpSrc " + str( tcpSrc )
1609 if tcpDst:
1610 cmd += " --tcpDst " + str( tcpDst )
1611 if ingressLabel:
1612 cmd += " --ingressLabel " + str( ingressLabel )
1613 if egressLabel:
1614 cmd += " --egressLabel " + str( egressLabel )
1615 if priority:
1616 cmd += " --priority " + str( priority )
1617
1618 # Check whether the user appended the port
1619 # or provided it as an input
1620 if "/" in ingressDevice:
1621 cmd += " " + str( ingressDevice )
1622 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001623 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001624 main.log.error( "You must specify the ingress port" )
1625 return None
1626
1627 cmd += " " + \
1628 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001629 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001630
1631 if "/" in egressDevice:
1632 cmd += " " + str( egressDevice )
1633 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001634 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001635 main.log.error( "You must specify the egress port" )
1636 return None
1637
1638 cmd += " " +\
1639 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001640 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001641
1642 handle = self.sendline( cmd )
1643 # If error, return error message
1644 if re.search( "Error", handle ):
1645 main.log.error( "Error in adding mpls intent" )
1646 return None
1647 else:
1648 # TODO: print out all the options in this message?
1649 main.log.info( "MPLS intent installed between " +
1650 str( ingressDevice ) + " and " +
1651 str( egressDevice ) )
1652 match = re.search('id=0x([\da-f]+),', handle)
1653 if match:
1654 return match.group()[3:-1]
1655 else:
1656 main.log.error( "Error, intent ID not found" )
1657 return None
1658 except TypeError:
1659 main.log.exception( self.name + ": Object not as expected" )
1660 return None
1661 except pexpect.EOF:
1662 main.log.error( self.name + ": EOF exception found" )
1663 main.log.error( self.name + ": " + self.handle.before )
1664 main.cleanup()
1665 main.exit()
1666 except Exception:
1667 main.log.exception( self.name + ": Uncaught exception!" )
1668 main.cleanup()
1669 main.exit()
1670
Jon Hallefbd9792015-03-05 16:11:36 -08001671 def removeIntent( self, intentId, app='org.onosproject.cli',
1672 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001673 """
shahshreya1c818fc2015-02-26 13:44:08 -08001674 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001675 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001676 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001677 -p or --purge: Purge the intent from the store after removal
1678
Jon Halle3f39ff2015-01-13 11:50:53 -08001679 Returns:
1680 main.False on error and
1681 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001682 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001683 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001684 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001685 if purge:
1686 cmdStr += " -p"
1687 if sync:
1688 cmdStr += " -s"
1689
1690 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001691 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001692 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001693 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001694 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001695 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001696 # TODO: Should this be main.TRUE
1697 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001698 except TypeError:
1699 main.log.exception( self.name + ": Object not as expected" )
1700 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001701 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001702 main.log.error( self.name + ": EOF exception found" )
1703 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001704 main.cleanup()
1705 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001706 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001707 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001708 main.cleanup()
1709 main.exit()
1710
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001711 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001712 """
1713 Purges all WITHDRAWN Intents
1714 """
1715 try:
1716 cmdStr = "purge-intents"
1717 handle = self.sendline( cmdStr )
1718 if re.search( "Error", handle ):
1719 main.log.error( "Error in purging intents" )
1720 return main.FALSE
1721 else:
1722 return main.TRUE
1723 except TypeError:
1724 main.log.exception( self.name + ": Object not as expected" )
1725 return None
1726 except pexpect.EOF:
1727 main.log.error( self.name + ": EOF exception found" )
1728 main.log.error( self.name + ": " + self.handle.before )
1729 main.cleanup()
1730 main.exit()
1731 except Exception:
1732 main.log.exception( self.name + ": Uncaught exception!" )
1733 main.cleanup()
1734 main.exit()
1735
kelvin-onlabd3b64892015-01-20 13:26:24 -08001736 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001737 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001738 NOTE: This method should be used after installing application:
1739 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001740 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001742 Description:
1743 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001744 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001745 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001746 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001748 cmdStr += " -j"
1749 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001750 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001751 except TypeError:
1752 main.log.exception( self.name + ": Object not as expected" )
1753 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001754 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001755 main.log.error( self.name + ": EOF exception found" )
1756 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001757 main.cleanup()
1758 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001759 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001760 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001761 main.cleanup()
1762 main.exit()
1763
pingping-lin54b03372015-08-13 14:43:10 -07001764 def ipv4RouteNumber( self ):
1765 """
1766 NOTE: This method should be used after installing application:
1767 onos-app-sdnip
1768 Description:
1769 Obtain the total IPv4 routes number in the system
1770 """
1771 try:
1772 cmdStr = "routes -s -j"
1773 handle = self.sendline( cmdStr )
1774 jsonResult = json.loads( handle )
1775 return jsonResult['totalRoutes4']
1776
1777 except TypeError:
1778 main.log.exception( self.name + ": Object not as expected" )
1779 return None
1780 except pexpect.EOF:
1781 main.log.error( self.name + ": EOF exception found" )
1782 main.log.error( self.name + ": " + self.handle.before )
1783 main.cleanup()
1784 main.exit()
1785 except Exception:
1786 main.log.exception( self.name + ": Uncaught exception!" )
1787 main.cleanup()
1788 main.exit()
1789
pingping-lin8244a3b2015-09-16 13:36:56 -07001790 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001791 """
andrewonlab377693f2014-10-21 16:00:30 -04001792 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 * jsonFormat: enable output formatting in json
pingping-lin8244a3b2015-09-16 13:36:56 -07001794 * summary: whether only output the intent summary
1795 * type: only output a certain type of intent
1796 This options is valid only when jsonFormat is true and summary is
1797 true
andrewonlabe6745342014-10-17 14:29:13 -04001798 Description:
pingping-lin8244a3b2015-09-16 13:36:56 -07001799 Obtain intents
kelvin-onlab898a6c62015-01-16 14:13:53 -08001800 """
andrewonlabe6745342014-10-17 14:29:13 -04001801 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001802 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001803 if summary:
1804 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001806 cmdStr += " -j"
1807 handle = self.sendline( cmdStr )
pingping-lin8244a3b2015-09-16 13:36:56 -07001808 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001809 if "TYPE" in args.keys():
1810 type = args[ "TYPE" ]
1811 else:
1812 type = ""
pingping-lin8244a3b2015-09-16 13:36:56 -07001813 if jsonFormat and summary and ( type != "" ):
1814 jsonResult = json.loads( handle )
1815 if type in jsonResult.keys():
1816 return jsonResult[ type ]
1817 else:
1818 main.log.error( "unknown TYPE, return all types of intents" )
1819 return handle
1820 else:
1821 return handle
pingping-lin54b03372015-08-13 14:43:10 -07001822
1823 except TypeError:
1824 main.log.exception( self.name + ": Object not as expected" )
1825 return None
1826 except pexpect.EOF:
1827 main.log.error( self.name + ": EOF exception found" )
1828 main.log.error( self.name + ": " + self.handle.before )
1829 main.cleanup()
1830 main.exit()
1831 except Exception:
1832 main.log.exception( self.name + ": Uncaught exception!" )
1833 main.cleanup()
1834 main.exit()
1835
pingping-lin8244a3b2015-09-16 13:36:56 -07001836
kelvin-onlab54400a92015-02-26 18:05:51 -08001837 def getIntentState(self, intentsId, intentsJson=None):
1838 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001839 Check intent state.
1840 Accepts a single intent ID (string type) or a list of intent IDs.
1841 Returns the state(string type) of the id if a single intent ID is
1842 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001843 Returns a dictionary with intent IDs as the key and its
1844 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001845 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001846 intentId: intent ID (string type)
1847 intentsJson: parsed json object from the onos:intents api
1848 Returns:
1849 state = An intent's state- INSTALL,WITHDRAWN etc.
1850 stateDict = Dictionary of intent's state. intent ID as the keys and
1851 state as the values.
1852 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001853 try:
1854 state = "State is Undefined"
1855 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001856 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001857 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001858 intentsJsonTemp = json.loads( intentsJson )
1859 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001860 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001861 if intentsId == intent[ 'id' ]:
1862 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001863 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001864 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1865 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001866 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001867 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001868 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001869 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001870 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001871 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001872 if intentsId[ i ] == intents[ 'id' ]:
1873 stateDict[ 'state' ] = intents[ 'state' ]
1874 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001875 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001876 break
Jon Hallefbd9792015-03-05 16:11:36 -08001877 if len( intentsId ) != len( dictList ):
1878 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001879 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001880 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001881 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001882 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001883 except TypeError:
1884 main.log.exception( self.name + ": Object not as expected" )
1885 return None
1886 except pexpect.EOF:
1887 main.log.error( self.name + ": EOF exception found" )
1888 main.log.error( self.name + ": " + self.handle.before )
1889 main.cleanup()
1890 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001891 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001892 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001893 main.cleanup()
1894 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001895
kelvin-onlabf512e942015-06-08 19:42:59 -07001896 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001897 """
1898 Description:
1899 Check intents state
1900 Required:
1901 intentsId - List of intents ID to be checked
1902 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001903 expectedState - Check the expected state(s) of each intents
1904 state in the list.
1905 *NOTE: You can pass in a list of expected state,
1906 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001907 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001908 Returns main.TRUE only if all intent are the same as expected states
1909 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001910 """
1911 try:
1912 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001913 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001914 intentsDict = self.getIntentState( intentsId )
kelvin-onlabf512e942015-06-08 19:42:59 -07001915
Jon Hall390696c2015-05-05 17:13:41 -07001916 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001917 if len( intentsId ) != len( intentsDict ):
1918 main.log.info( self.name + "There is something wrong " +
1919 "getting intents state" )
1920 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001921
1922 if isinstance( expectedState, types.StringType ):
1923 for intents in intentsDict:
1924 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001925 main.log.debug( self.name + " : Intent ID - " +
1926 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001927 " actual state = " +
1928 intents.get( 'state' )
1929 + " does not equal expected state = "
1930 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001931 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001932
1933 elif isinstance( expectedState, types.ListType ):
1934 for intents in intentsDict:
1935 if not any( state == intents.get( 'state' ) for state in
1936 expectedState ):
1937 main.log.debug( self.name + " : Intent ID - " +
1938 intents.get( 'id' ) +
1939 " actual state = " +
1940 intents.get( 'state' ) +
1941 " does not equal expected states = "
1942 + str( expectedState ) )
1943 returnValue = main.FALSE
1944
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001945 if returnValue == main.TRUE:
1946 main.log.info( self.name + ": All " +
1947 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001948 " intents are in " + str( expectedState ) +
1949 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001950 return returnValue
1951 except TypeError:
1952 main.log.exception( self.name + ": Object not as expected" )
1953 return None
1954 except pexpect.EOF:
1955 main.log.error( self.name + ": EOF exception found" )
1956 main.log.error( self.name + ": " + self.handle.before )
1957 main.cleanup()
1958 main.exit()
1959 except Exception:
1960 main.log.exception( self.name + ": Uncaught exception!" )
1961 main.cleanup()
1962 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04001963
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001965 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001966 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001968 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001969 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001970 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001971 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001972 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001973 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001974 cmdStr += " -j"
1975 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001976 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001977 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001978 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001979 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001980 except TypeError:
1981 main.log.exception( self.name + ": Object not as expected" )
1982 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001984 main.log.error( self.name + ": EOF exception found" )
1985 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001986 main.cleanup()
1987 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001989 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001990 main.cleanup()
1991 main.exit()
1992
pingping-linbab7f8a2015-09-21 17:33:36 -07001993 def checkFlowsState( self, isPENDING_ADD = True ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07001994 """
1995 Description:
1996 Check the if all the current flows are in ADDED state or
1997 PENDING_ADD state
pingping-linbab7f8a2015-09-21 17:33:36 -07001998 Optional:
1999 * isPENDING_ADD: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002000 Return:
2001 returnValue - Returns main.TRUE only if all flows are in
pingping-linbab7f8a2015-09-21 17:33:36 -07002002 ADDED state or PENDING_ADD if the PENDING_ADD
2003 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002004 """
2005 try:
2006 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07002007 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07002008 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002009
pingping-linbab7f8a2015-09-21 17:33:36 -07002010 if isPENDING_ADD:
2011 for device in tempFlows:
2012 for flow in device.get( 'flows' ):
2013 if flow.get( 'state' ) != 'ADDED' and \
2014 flow.get( 'state' ) != 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002015
pingping-linbab7f8a2015-09-21 17:33:36 -07002016 main.log.info( self.name + ": flow Id: " +
2017 str( flow.get( 'groupId' ) ) +
2018 " | state:" +
2019 str( flow.get( 'state' ) ) )
2020 returnValue = main.FALSE
2021 else:
2022 for device in tempFlows:
2023 for flow in device.get( 'flows' ):
2024 if flow.get( 'state' ) != 'ADDED':
2025
2026 main.log.info( self.name + ": flow Id: " +
2027 str( flow.get( 'groupId' ) ) +
2028 " | state:" +
2029 str( flow.get( 'state' ) ) )
2030 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002031
kelvin-onlab4df89f22015-04-13 18:10:23 -07002032 return returnValue
2033 except TypeError:
2034 main.log.exception( self.name + ": Object not as expected" )
2035 return None
2036 except pexpect.EOF:
2037 main.log.error( self.name + ": EOF exception found" )
2038 main.log.error( self.name + ": " + self.handle.before )
2039 main.cleanup()
2040 main.exit()
2041 except Exception:
2042 main.log.exception( self.name + ": Uncaught exception!" )
2043 main.cleanup()
2044 main.exit()
2045
kelvin-onlabd3b64892015-01-20 13:26:24 -08002046 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08002047 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08002048 """
andrewonlab87852b02014-11-19 18:44:19 -05002049 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002050 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002051 a specific point-to-point intent definition
2052 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002053 * dpidSrc: specify source dpid
2054 * dpidDst: specify destination dpid
2055 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002056 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002057 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05002058 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08002059 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05002060 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05002061 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08002062 """
andrewonlab87852b02014-11-19 18:44:19 -05002063 try:
kelvin8ec71442015-01-15 16:57:00 -08002064 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08002065 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
2066 str( numIntents )
2067 if numMult:
2068 cmd += " " + str( numMult )
2069 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08002070 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 if appId:
2072 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002073 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05002074 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002075 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08002076 main.log.info( handle )
2077 # Split result by newline
2078 newline = handle.split( "\r\r\n" )
2079 # Ignore the first object of list, which is empty
2080 newline = newline[ 1: ]
2081 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05002082 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08002083 result = result.split( ": " )
2084 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08002085 latResult.append( result[ 1 ].split( " " )[ 0 ] )
2086 main.log.info( latResult )
2087 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05002088 else:
2089 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08002090 except TypeError:
2091 main.log.exception( self.name + ": Object not as expected" )
2092 return None
andrewonlab87852b02014-11-19 18:44:19 -05002093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002094 main.log.error( self.name + ": EOF exception found" )
2095 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002096 main.cleanup()
2097 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002100 main.cleanup()
2101 main.exit()
2102
kelvin-onlabd3b64892015-01-20 13:26:24 -08002103 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002104 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002105 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002106 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002107 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002108 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002109 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002110 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002112 cmdStr += " -j"
2113 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002114 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002115 except TypeError:
2116 main.log.exception( self.name + ": Object not as expected" )
2117 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002118 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002119 main.log.error( self.name + ": EOF exception found" )
2120 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002121 main.cleanup()
2122 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002123 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002124 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002125 main.cleanup()
2126 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002127
kelvin-onlabd3b64892015-01-20 13:26:24 -08002128 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002129 """
2130 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002131 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002132 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002133 """
andrewonlab867212a2014-10-22 20:13:38 -04002134 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002135 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002136 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002137 cmdStr += " -j"
2138 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002139 if handle:
2140 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002141 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002142 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002143 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002144 else:
2145 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002146 except TypeError:
2147 main.log.exception( self.name + ": Object not as expected" )
2148 return None
andrewonlab867212a2014-10-22 20:13:38 -04002149 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002150 main.log.error( self.name + ": EOF exception found" )
2151 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002152 main.cleanup()
2153 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002154 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002155 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002156 main.cleanup()
2157 main.exit()
2158
kelvin8ec71442015-01-15 16:57:00 -08002159 # Wrapper functions ****************
2160 # Wrapper functions use existing driver
2161 # functions and extends their use case.
2162 # For example, we may use the output of
2163 # a normal driver function, and parse it
2164 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002165
kelvin-onlabd3b64892015-01-20 13:26:24 -08002166 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002167 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002168 Description:
2169 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002170 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002171 try:
kelvin8ec71442015-01-15 16:57:00 -08002172 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002173 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002175
kelvin8ec71442015-01-15 16:57:00 -08002176 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002177 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2178 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002179 match = re.search('id=0x([\da-f]+),', intents)
2180 if match:
2181 tmpId = match.group()[3:-1]
2182 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002183 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002184
Jon Halld4d4b372015-01-28 16:02:41 -08002185 except TypeError:
2186 main.log.exception( self.name + ": Object not as expected" )
2187 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002188 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002189 main.log.error( self.name + ": EOF exception found" )
2190 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002191 main.cleanup()
2192 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002193 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002194 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002195 main.cleanup()
2196 main.exit()
2197
Jon Hall30b82fa2015-03-04 17:15:43 -08002198 def FlowAddedCount( self, deviceId ):
2199 """
2200 Determine the number of flow rules for the given device id that are
2201 in the added state
2202 """
2203 try:
2204 cmdStr = "flows any " + str( deviceId ) + " | " +\
2205 "grep 'state=ADDED' | wc -l"
2206 handle = self.sendline( cmdStr )
2207 return handle
2208 except pexpect.EOF:
2209 main.log.error( self.name + ": EOF exception found" )
2210 main.log.error( self.name + ": " + self.handle.before )
2211 main.cleanup()
2212 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002213 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002214 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002215 main.cleanup()
2216 main.exit()
2217
kelvin-onlabd3b64892015-01-20 13:26:24 -08002218 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002219 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002220 Use 'devices' function to obtain list of all devices
2221 and parse the result to obtain a list of all device
2222 id's. Returns this list. Returns empty list if no
2223 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002224 List is ordered sequentially
2225
andrewonlab3e15ead2014-10-15 14:21:34 -04002226 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002227 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002228 the ids. By obtaining the list of device ids on the fly,
2229 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002230 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002231 try:
kelvin8ec71442015-01-15 16:57:00 -08002232 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002233 devicesStr = self.devices( jsonFormat=False )
2234 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002235
kelvin-onlabd3b64892015-01-20 13:26:24 -08002236 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002237 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002238 return idList
kelvin8ec71442015-01-15 16:57:00 -08002239
2240 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002241 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002242 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002244 # Split list further into arguments before and after string
2245 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002246 # append to idList
2247 for arg in tempList:
2248 idList.append( arg.split( "id=" )[ 1 ] )
2249 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002250
Jon Halld4d4b372015-01-28 16:02:41 -08002251 except TypeError:
2252 main.log.exception( self.name + ": Object not as expected" )
2253 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002254 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002255 main.log.error( self.name + ": EOF exception found" )
2256 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002257 main.cleanup()
2258 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002259 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002260 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002261 main.cleanup()
2262 main.exit()
2263
kelvin-onlabd3b64892015-01-20 13:26:24 -08002264 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002265 """
andrewonlab7c211572014-10-15 16:45:20 -04002266 Uses 'nodes' function to obtain list of all nodes
2267 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002268 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002269 Returns:
2270 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002271 """
andrewonlab7c211572014-10-15 16:45:20 -04002272 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002273 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002274 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002275 # Sample nodesStr output
2276 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002277 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002278 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002279 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002280 nodesJson = json.loads( nodesStr )
2281 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002282 return idList
kelvin8ec71442015-01-15 16:57:00 -08002283
Jon Halld4d4b372015-01-28 16:02:41 -08002284 except TypeError:
2285 main.log.exception( self.name + ": Object not as expected" )
2286 return None
andrewonlab7c211572014-10-15 16:45:20 -04002287 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002288 main.log.error( self.name + ": EOF exception found" )
2289 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002290 main.cleanup()
2291 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002292 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002293 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002294 main.cleanup()
2295 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002296
kelvin-onlabd3b64892015-01-20 13:26:24 -08002297 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002298 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002299 Return the first device from the devices api whose 'id' contains 'dpid'
2300 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002301 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002302 try:
kelvin8ec71442015-01-15 16:57:00 -08002303 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002304 return None
2305 else:
kelvin8ec71442015-01-15 16:57:00 -08002306 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002307 rawDevices = self.devices()
2308 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002309 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002310 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002311 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2312 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002313 return device
2314 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002315 except TypeError:
2316 main.log.exception( self.name + ": Object not as expected" )
2317 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002318 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002319 main.log.error( self.name + ": EOF exception found" )
2320 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002321 main.cleanup()
2322 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002323 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002324 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002325 main.cleanup()
2326 main.exit()
2327
kelvin-onlabd3b64892015-01-20 13:26:24 -08002328 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002329 """
Jon Hallefbd9792015-03-05 16:11:36 -08002330 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002331 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002332 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002333
Jon Hall42db6dc2014-10-24 19:03:48 -04002334 Params: ip = ip used for the onos cli
2335 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002336 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002337 logLevel = level to log to. Currently accepts
2338 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002339
2340
kelvin-onlabd3b64892015-01-20 13:26:24 -08002341 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002342
Jon Hallefbd9792015-03-05 16:11:36 -08002343 Returns: main.TRUE if the number of switches and links are correct,
2344 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002345 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002346 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002347 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002348 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002349 if topology == {}:
2350 return main.ERROR
2351 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002352 # Is the number of switches is what we expected
2353 devices = topology.get( 'devices', False )
2354 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002355 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002356 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002357 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002358 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002359 linkCheck = ( int( links ) == int( numolink ) )
2360 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002361 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002362 output += "The number of links and switches match " +\
2363 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002364 result = main.TRUE
2365 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002366 output += "The number of links and switches does not match " +\
2367 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002368 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002369 output = output + "\n ONOS sees %i devices (%i expected) \
2370 and %i links (%i expected)" % (
2371 int( devices ), int( numoswitch ), int( links ),
2372 int( numolink ) )
2373 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002374 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002375 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002376 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002377 else:
Jon Hall390696c2015-05-05 17:13:41 -07002378 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002379 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002380 except TypeError:
2381 main.log.exception( self.name + ": Object not as expected" )
2382 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002383 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002384 main.log.error( self.name + ": EOF exception found" )
2385 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002386 main.cleanup()
2387 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002388 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002389 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002390 main.cleanup()
2391 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002392
kelvin-onlabd3b64892015-01-20 13:26:24 -08002393 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002394 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002395 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002396 deviceId must be the id of a device as seen in the onos devices command
2397 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002398 role must be either master, standby, or none
2399
Jon Halle3f39ff2015-01-13 11:50:53 -08002400 Returns:
2401 main.TRUE or main.FALSE based on argument verification and
2402 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002403 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002404 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002405 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002406 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002407 cmdStr = "device-role " +\
2408 str( deviceId ) + " " +\
2409 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002410 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002411 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002412 if re.search( "Error", handle ):
2413 # end color output to escape any colours
2414 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002415 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002416 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002417 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002418 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002419 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002420 main.log.error( "Invalid 'role' given to device_role(). " +
2421 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002422 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002423 except TypeError:
2424 main.log.exception( self.name + ": Object not as expected" )
2425 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002427 main.log.error( self.name + ": EOF exception found" )
2428 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002429 main.cleanup()
2430 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002431 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002432 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002433 main.cleanup()
2434 main.exit()
2435
kelvin-onlabd3b64892015-01-20 13:26:24 -08002436 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002437 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002438 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002439 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002440 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002441 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002442 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002443 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002444 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002445 cmdStr += " -j"
2446 handle = self.sendline( cmdStr )
2447 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002448 except TypeError:
2449 main.log.exception( self.name + ": Object not as expected" )
2450 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002451 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002452 main.log.error( self.name + ": EOF exception found" )
2453 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002454 main.cleanup()
2455 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002456 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002457 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002458 main.cleanup()
2459 main.exit()
2460
kelvin-onlabd3b64892015-01-20 13:26:24 -08002461 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002462 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002463 CLI command to get the current leader for the Election test application
2464 NOTE: Requires installation of the onos-app-election feature
2465 Returns: Node IP of the leader if one exists
2466 None if none exists
2467 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002468 """
Jon Hall94fd0472014-12-08 11:52:42 -08002469 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002470 cmdStr = "election-test-leader"
2471 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002472 # Leader
2473 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002474 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002475 nodeSearch = re.search( leaderPattern, response )
2476 if nodeSearch:
2477 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002478 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002479 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002480 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002481 # no leader
2482 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002483 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002484 nullSearch = re.search( nullPattern, response )
2485 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002486 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002487 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002488 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002489 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002490 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002491 if re.search( errorPattern, response ):
2492 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002493 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002494 return main.FALSE
2495 else:
Jon Hall390696c2015-05-05 17:13:41 -07002496 main.log.error( "Error in electionTestLeader on " + self.name +
2497 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002498 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002499 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002500 except TypeError:
2501 main.log.exception( self.name + ": Object not as expected" )
2502 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002503 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002504 main.log.error( self.name + ": EOF exception found" )
2505 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002506 main.cleanup()
2507 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002508 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002509 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002510 main.cleanup()
2511 main.exit()
2512
kelvin-onlabd3b64892015-01-20 13:26:24 -08002513 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002514 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002515 CLI command to run for leadership of the Election test application.
2516 NOTE: Requires installation of the onos-app-election feature
2517 Returns: Main.TRUE on success
2518 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002519 """
Jon Hall94fd0472014-12-08 11:52:42 -08002520 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002521 cmdStr = "election-test-run"
2522 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002523 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002524 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002525 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002526 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002527 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002528 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002529 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002530 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002531 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002532 errorPattern = "Command\snot\sfound"
2533 if re.search( errorPattern, response ):
2534 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002535 return main.FALSE
2536 else:
Jon Hall390696c2015-05-05 17:13:41 -07002537 main.log.error( "Error in electionTestRun on " + self.name +
2538 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002539 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002540 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002541 except TypeError:
2542 main.log.exception( self.name + ": Object not as expected" )
2543 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002544 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002545 main.log.error( self.name + ": EOF exception found" )
2546 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002547 main.cleanup()
2548 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002549 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002550 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002551 main.cleanup()
2552 main.exit()
2553
kelvin-onlabd3b64892015-01-20 13:26:24 -08002554 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002555 """
Jon Hall94fd0472014-12-08 11:52:42 -08002556 * CLI command to withdraw the local node from leadership election for
2557 * the Election test application.
2558 #NOTE: Requires installation of the onos-app-election feature
2559 Returns: Main.TRUE on success
2560 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002561 """
Jon Hall94fd0472014-12-08 11:52:42 -08002562 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002563 cmdStr = "election-test-withdraw"
2564 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002565 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002566 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002567 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002568 if re.search( successPattern, response ):
2569 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002570 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002571 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002572 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002573 errorPattern = "Command\snot\sfound"
2574 if re.search( errorPattern, response ):
2575 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002576 return main.FALSE
2577 else:
Jon Hall390696c2015-05-05 17:13:41 -07002578 main.log.error( "Error in electionTestWithdraw on " +
2579 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002580 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002581 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002582 except TypeError:
2583 main.log.exception( self.name + ": Object not as expected" )
2584 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002585 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002586 main.log.error( self.name + ": EOF exception found" )
2587 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002588 main.cleanup()
2589 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002590 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002591 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002592 main.cleanup()
2593 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002594
kelvin8ec71442015-01-15 16:57:00 -08002595 def getDevicePortsEnabledCount( self, dpid ):
2596 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002597 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002598 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002599 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002600 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2602 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002603 if re.search( "No such device", output ):
2604 main.log.error( "Error in getting ports" )
2605 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002606 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002607 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002608 except TypeError:
2609 main.log.exception( self.name + ": Object not as expected" )
2610 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002612 main.log.error( self.name + ": EOF exception found" )
2613 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002614 main.cleanup()
2615 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002617 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002618 main.cleanup()
2619 main.exit()
2620
kelvin8ec71442015-01-15 16:57:00 -08002621 def getDeviceLinksActiveCount( self, dpid ):
2622 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002623 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002624 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002625 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002626 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002627 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2628 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002629 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002630 main.log.error( "Error in getting ports " )
2631 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002632 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002633 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002634 except TypeError:
2635 main.log.exception( self.name + ": Object not as expected" )
2636 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002637 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002638 main.log.error( self.name + ": EOF exception found" )
2639 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002640 main.cleanup()
2641 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002642 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002643 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002644 main.cleanup()
2645 main.exit()
2646
kelvin8ec71442015-01-15 16:57:00 -08002647 def getAllIntentIds( self ):
2648 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002649 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002650 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002651 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002652 cmdStr = "onos:intents | grep id="
2653 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002654 if re.search( "Error", output ):
2655 main.log.error( "Error in getting ports" )
2656 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002657 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002658 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002659 except TypeError:
2660 main.log.exception( self.name + ": Object not as expected" )
2661 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002662 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002663 main.log.error( self.name + ": EOF exception found" )
2664 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002665 main.cleanup()
2666 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002667 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002668 main.log.exception( self.name + ": Uncaught exception!" )
2669 main.cleanup()
2670 main.exit()
2671
Jon Hall73509952015-02-24 16:42:56 -08002672 def intentSummary( self ):
2673 """
Jon Hallefbd9792015-03-05 16:11:36 -08002674 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002675 """
2676 try:
2677 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002678 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002679 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002680 states.append( intent.get( 'state', None ) )
2681 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002682 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002683 return dict( out )
2684 except TypeError:
2685 main.log.exception( self.name + ": Object not as expected" )
2686 return None
2687 except pexpect.EOF:
2688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
2690 main.cleanup()
2691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002692 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002693 main.log.exception( self.name + ": Uncaught exception!" )
2694 main.cleanup()
2695 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002696
Jon Hall61282e32015-03-19 11:34:11 -07002697 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002698 """
2699 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002700 Optional argument:
2701 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002702 """
Jon Hall63604932015-02-26 17:09:50 -08002703 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002704 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002705 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002706 cmdStr += " -j"
2707 output = self.sendline( cmdStr )
2708 return output
Jon Hall63604932015-02-26 17:09:50 -08002709 except TypeError:
2710 main.log.exception( self.name + ": Object not as expected" )
2711 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002712 except pexpect.EOF:
2713 main.log.error( self.name + ": EOF exception found" )
2714 main.log.error( self.name + ": " + self.handle.before )
2715 main.cleanup()
2716 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002717 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002718 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002719 main.cleanup()
2720 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002721
acsmarsa4a4d1e2015-07-10 16:01:24 -07002722 def leaderCandidates( self, jsonFormat=True ):
2723 """
2724 Returns the output of the leaders -c command.
2725 Optional argument:
2726 * jsonFormat - boolean indicating if you want output in json
2727 """
2728 try:
2729 cmdStr = "onos:leaders -c"
2730 if jsonFormat:
2731 cmdStr += " -j"
2732 output = self.sendline( cmdStr )
2733 return output
2734 except TypeError:
2735 main.log.exception( self.name + ": Object not as expected" )
2736 return None
2737 except pexpect.EOF:
2738 main.log.error( self.name + ": EOF exception found" )
2739 main.log.error( self.name + ": " + self.handle.before )
2740 main.cleanup()
2741 main.exit()
2742 except Exception:
2743 main.log.exception( self.name + ": Uncaught exception!" )
2744 main.cleanup()
2745 main.exit()
2746
2747 def specificLeaderCandidate(self,topic):
2748 """
2749 Returns a list in format [leader,candidate1,candidate2,...] for a given
2750 topic parameter and an empty list if the topic doesn't exist
2751 If no leader is elected leader in the returned list will be "none"
2752 Returns None if there is a type error processing the json object
2753 """
2754 try:
2755 cmdStr = "onos:leaders -c -j"
2756 output = self.sendline( cmdStr )
2757 output = json.loads(output)
2758 results = []
2759 for dict in output:
2760 if dict["topic"] == topic:
2761 leader = dict["leader"]
2762 candidates = re.split(", ",dict["candidates"][1:-1])
2763 results.append(leader)
2764 results.extend(candidates)
2765 return results
2766 except TypeError:
2767 main.log.exception( self.name + ": Object not as expected" )
2768 return None
2769 except pexpect.EOF:
2770 main.log.error( self.name + ": EOF exception found" )
2771 main.log.error( self.name + ": " + self.handle.before )
2772 main.cleanup()
2773 main.exit()
2774 except Exception:
2775 main.log.exception( self.name + ": Uncaught exception!" )
2776 main.cleanup()
2777 main.exit()
2778
Jon Hall61282e32015-03-19 11:34:11 -07002779 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002780 """
2781 Returns the output of the intent Pending map.
2782 """
Jon Hall63604932015-02-26 17:09:50 -08002783 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002784 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002785 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002786 cmdStr += " -j"
2787 output = self.sendline( cmdStr )
2788 return output
Jon Hall63604932015-02-26 17:09:50 -08002789 except TypeError:
2790 main.log.exception( self.name + ": Object not as expected" )
2791 return None
2792 except pexpect.EOF:
2793 main.log.error( self.name + ": EOF exception found" )
2794 main.log.error( self.name + ": " + self.handle.before )
2795 main.cleanup()
2796 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002797 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002798 main.log.exception( self.name + ": Uncaught exception!" )
2799 main.cleanup()
2800 main.exit()
2801
Jon Hall61282e32015-03-19 11:34:11 -07002802 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002803 """
2804 Returns the output of the raft partitions command for ONOS.
2805 """
Jon Hall61282e32015-03-19 11:34:11 -07002806 # Sample JSON
2807 # {
2808 # "leader": "tcp://10.128.30.11:7238",
2809 # "members": [
2810 # "tcp://10.128.30.11:7238",
2811 # "tcp://10.128.30.17:7238",
2812 # "tcp://10.128.30.13:7238",
2813 # ],
2814 # "name": "p1",
2815 # "term": 3
2816 # },
Jon Hall63604932015-02-26 17:09:50 -08002817 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002818 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002819 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002820 cmdStr += " -j"
2821 output = self.sendline( cmdStr )
2822 return output
Jon Hall63604932015-02-26 17:09:50 -08002823 except TypeError:
2824 main.log.exception( self.name + ": Object not as expected" )
2825 return None
2826 except pexpect.EOF:
2827 main.log.error( self.name + ": EOF exception found" )
2828 main.log.error( self.name + ": " + self.handle.before )
2829 main.cleanup()
2830 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002831 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002832 main.log.exception( self.name + ": Uncaught exception!" )
2833 main.cleanup()
2834 main.exit()
2835
Jon Hallbe379602015-03-24 13:39:32 -07002836 def apps( self, jsonFormat=True ):
2837 """
2838 Returns the output of the apps command for ONOS. This command lists
2839 information about installed ONOS applications
2840 """
2841 # Sample JSON object
2842 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2843 # "description":"ONOS OpenFlow protocol southbound providers",
2844 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2845 # "features":"[onos-openflow]","state":"ACTIVE"}]
2846 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002847 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002848 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002849 cmdStr += " -j"
2850 output = self.sendline( cmdStr )
2851 assert "Error executing command" not in output
2852 return output
Jon Hallbe379602015-03-24 13:39:32 -07002853 # FIXME: look at specific exceptions/Errors
2854 except AssertionError:
2855 main.log.error( "Error in processing onos:app command: " +
2856 str( output ) )
2857 return None
2858 except TypeError:
2859 main.log.exception( self.name + ": Object not as expected" )
2860 return None
2861 except pexpect.EOF:
2862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
2864 main.cleanup()
2865 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002866 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002867 main.log.exception( self.name + ": Uncaught exception!" )
2868 main.cleanup()
2869 main.exit()
2870
Jon Hall146f1522015-03-24 15:33:24 -07002871 def appStatus( self, appName ):
2872 """
2873 Uses the onos:apps cli command to return the status of an application.
2874 Returns:
2875 "ACTIVE" - If app is installed and activated
2876 "INSTALLED" - If app is installed and deactivated
2877 "UNINSTALLED" - If app is not installed
2878 None - on error
2879 """
Jon Hall146f1522015-03-24 15:33:24 -07002880 try:
2881 if not isinstance( appName, types.StringType ):
2882 main.log.error( self.name + ".appStatus(): appName must be" +
2883 " a string" )
2884 return None
2885 output = self.apps( jsonFormat=True )
2886 appsJson = json.loads( output )
2887 state = None
2888 for app in appsJson:
2889 if appName == app.get('name'):
2890 state = app.get('state')
2891 break
2892 if state == "ACTIVE" or state == "INSTALLED":
2893 return state
2894 elif state is None:
2895 return "UNINSTALLED"
2896 elif state:
2897 main.log.error( "Unexpected state from 'onos:apps': " +
2898 str( state ) )
2899 return state
2900 except TypeError:
2901 main.log.exception( self.name + ": Object not as expected" )
2902 return None
2903 except pexpect.EOF:
2904 main.log.error( self.name + ": EOF exception found" )
2905 main.log.error( self.name + ": " + self.handle.before )
2906 main.cleanup()
2907 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002908 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002909 main.log.exception( self.name + ": Uncaught exception!" )
2910 main.cleanup()
2911 main.exit()
2912
Jon Hallbe379602015-03-24 13:39:32 -07002913 def app( self, appName, option ):
2914 """
2915 Interacts with the app command for ONOS. This command manages
2916 application inventory.
2917 """
Jon Hallbe379602015-03-24 13:39:32 -07002918 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002919 # Validate argument types
2920 valid = True
2921 if not isinstance( appName, types.StringType ):
2922 main.log.error( self.name + ".app(): appName must be a " +
2923 "string" )
2924 valid = False
2925 if not isinstance( option, types.StringType ):
2926 main.log.error( self.name + ".app(): option must be a string" )
2927 valid = False
2928 if not valid:
2929 return main.FALSE
2930 # Validate Option
2931 option = option.lower()
2932 # NOTE: Install may become a valid option
2933 if option == "activate":
2934 pass
2935 elif option == "deactivate":
2936 pass
2937 elif option == "uninstall":
2938 pass
2939 else:
2940 # Invalid option
2941 main.log.error( "The ONOS app command argument only takes " +
2942 "the values: (activate|deactivate|uninstall)" +
2943 "; was given '" + option + "'")
2944 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002945 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002946 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002947 if "Error executing command" in output:
2948 main.log.error( "Error in processing onos:app command: " +
2949 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002950 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002951 elif "No such application" in output:
2952 main.log.error( "The application '" + appName +
2953 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002954 return main.FALSE
2955 elif "Command not found:" in output:
2956 main.log.error( "Error in processing onos:app command: " +
2957 str( output ) )
2958 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002959 elif "Unsupported command:" in output:
2960 main.log.error( "Incorrect command given to 'app': " +
2961 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002962 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002963 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002964 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002965 return main.TRUE
2966 except TypeError:
2967 main.log.exception( self.name + ": Object not as expected" )
2968 return main.ERROR
2969 except pexpect.EOF:
2970 main.log.error( self.name + ": EOF exception found" )
2971 main.log.error( self.name + ": " + self.handle.before )
2972 main.cleanup()
2973 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002974 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002975 main.log.exception( self.name + ": Uncaught exception!" )
2976 main.cleanup()
2977 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002978
Jon Hallbd16b922015-03-26 17:53:15 -07002979 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002980 """
2981 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002982 appName is the hierarchical app name, not the feature name
2983 If check is True, method will check the status of the app after the
2984 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002985 Returns main.TRUE if the command was successfully sent
2986 main.FALSE if the cli responded with an error or given
2987 incorrect input
2988 """
2989 try:
2990 if not isinstance( appName, types.StringType ):
2991 main.log.error( self.name + ".activateApp(): appName must be" +
2992 " a string" )
2993 return main.FALSE
2994 status = self.appStatus( appName )
2995 if status == "INSTALLED":
2996 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002997 if check and response == main.TRUE:
2998 for i in range(10): # try 10 times then give up
2999 # TODO: Check with Thomas about this delay
3000 status = self.appStatus( appName )
3001 if status == "ACTIVE":
3002 return main.TRUE
3003 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003004 main.log.debug( "The state of application " +
3005 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003006 time.sleep( 1 )
3007 return main.FALSE
3008 else: # not 'check' or command didn't succeed
3009 return response
Jon Hall146f1522015-03-24 15:33:24 -07003010 elif status == "ACTIVE":
3011 return main.TRUE
3012 elif status == "UNINSTALLED":
3013 main.log.error( self.name + ": Tried to activate the " +
3014 "application '" + appName + "' which is not " +
3015 "installed." )
3016 else:
3017 main.log.error( "Unexpected return value from appStatus: " +
3018 str( status ) )
3019 return main.ERROR
3020 except TypeError:
3021 main.log.exception( self.name + ": Object not as expected" )
3022 return main.ERROR
3023 except pexpect.EOF:
3024 main.log.error( self.name + ": EOF exception found" )
3025 main.log.error( self.name + ": " + self.handle.before )
3026 main.cleanup()
3027 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003028 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003029 main.log.exception( self.name + ": Uncaught exception!" )
3030 main.cleanup()
3031 main.exit()
3032
Jon Hallbd16b922015-03-26 17:53:15 -07003033 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003034 """
3035 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003036 appName is the hierarchical app name, not the feature name
3037 If check is True, method will check the status of the app after the
3038 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003039 Returns main.TRUE if the command was successfully sent
3040 main.FALSE if the cli responded with an error or given
3041 incorrect input
3042 """
3043 try:
3044 if not isinstance( appName, types.StringType ):
3045 main.log.error( self.name + ".deactivateApp(): appName must " +
3046 "be a string" )
3047 return main.FALSE
3048 status = self.appStatus( appName )
3049 if status == "INSTALLED":
3050 return main.TRUE
3051 elif status == "ACTIVE":
3052 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003053 if check and response == main.TRUE:
3054 for i in range(10): # try 10 times then give up
3055 status = self.appStatus( appName )
3056 if status == "INSTALLED":
3057 return main.TRUE
3058 else:
3059 time.sleep( 1 )
3060 return main.FALSE
3061 else: # not check or command didn't succeed
3062 return response
Jon Hall146f1522015-03-24 15:33:24 -07003063 elif status == "UNINSTALLED":
3064 main.log.warn( self.name + ": Tried to deactivate the " +
3065 "application '" + appName + "' which is not " +
3066 "installed." )
3067 return main.TRUE
3068 else:
3069 main.log.error( "Unexpected return value from appStatus: " +
3070 str( status ) )
3071 return main.ERROR
3072 except TypeError:
3073 main.log.exception( self.name + ": Object not as expected" )
3074 return main.ERROR
3075 except pexpect.EOF:
3076 main.log.error( self.name + ": EOF exception found" )
3077 main.log.error( self.name + ": " + self.handle.before )
3078 main.cleanup()
3079 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003080 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003081 main.log.exception( self.name + ": Uncaught exception!" )
3082 main.cleanup()
3083 main.exit()
3084
Jon Hallbd16b922015-03-26 17:53:15 -07003085 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003086 """
3087 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003088 appName is the hierarchical app name, not the feature name
3089 If check is True, method will check the status of the app after the
3090 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003091 Returns main.TRUE if the command was successfully sent
3092 main.FALSE if the cli responded with an error or given
3093 incorrect input
3094 """
3095 # TODO: check with Thomas about the state machine for apps
3096 try:
3097 if not isinstance( appName, types.StringType ):
3098 main.log.error( self.name + ".uninstallApp(): appName must " +
3099 "be a string" )
3100 return main.FALSE
3101 status = self.appStatus( appName )
3102 if status == "INSTALLED":
3103 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003104 if check and response == main.TRUE:
3105 for i in range(10): # try 10 times then give up
3106 status = self.appStatus( appName )
3107 if status == "UNINSTALLED":
3108 return main.TRUE
3109 else:
3110 time.sleep( 1 )
3111 return main.FALSE
3112 else: # not check or command didn't succeed
3113 return response
Jon Hall146f1522015-03-24 15:33:24 -07003114 elif status == "ACTIVE":
3115 main.log.warn( self.name + ": Tried to uninstall the " +
3116 "application '" + appName + "' which is " +
3117 "currently active." )
3118 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003119 if check and response == main.TRUE:
3120 for i in range(10): # try 10 times then give up
3121 status = self.appStatus( appName )
3122 if status == "UNINSTALLED":
3123 return main.TRUE
3124 else:
3125 time.sleep( 1 )
3126 return main.FALSE
3127 else: # not check or command didn't succeed
3128 return response
Jon Hall146f1522015-03-24 15:33:24 -07003129 elif status == "UNINSTALLED":
3130 return main.TRUE
3131 else:
3132 main.log.error( "Unexpected return value from appStatus: " +
3133 str( status ) )
3134 return main.ERROR
3135 except TypeError:
3136 main.log.exception( self.name + ": Object not as expected" )
3137 return main.ERROR
3138 except pexpect.EOF:
3139 main.log.error( self.name + ": EOF exception found" )
3140 main.log.error( self.name + ": " + self.handle.before )
3141 main.cleanup()
3142 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003143 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003144 main.log.exception( self.name + ": Uncaught exception!" )
3145 main.cleanup()
3146 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003147
3148 def appIDs( self, jsonFormat=True ):
3149 """
3150 Show the mappings between app id and app names given by the 'app-ids'
3151 cli command
3152 """
3153 try:
3154 cmdStr = "app-ids"
3155 if jsonFormat:
3156 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003157 output = self.sendline( cmdStr )
3158 assert "Error executing command" not in output
3159 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003160 except AssertionError:
3161 main.log.error( "Error in processing onos:app-ids command: " +
3162 str( output ) )
3163 return None
3164 except TypeError:
3165 main.log.exception( self.name + ": Object not as expected" )
3166 return None
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()
Jon Hall77ba41c2015-04-06 10:25:40 -07003172 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003173 main.log.exception( self.name + ": Uncaught exception!" )
3174 main.cleanup()
3175 main.exit()
3176
3177 def appToIDCheck( self ):
3178 """
3179 This method will check that each application's ID listed in 'apps' is
3180 the same as the ID listed in 'app-ids'. The check will also check that
3181 there are no duplicate IDs issued. Note that an app ID should be
3182 a globaly unique numerical identifier for app/app-like features. Once
3183 an ID is registered, the ID is never freed up so that if an app is
3184 reinstalled it will have the same ID.
3185
3186 Returns: main.TRUE if the check passes and
3187 main.FALSE if the check fails or
3188 main.ERROR if there is some error in processing the test
3189 """
3190 try:
Jon Hall390696c2015-05-05 17:13:41 -07003191 bail = False
3192 ids = self.appIDs( jsonFormat=True )
3193 if ids:
3194 ids = json.loads( ids )
3195 else:
3196 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3197 bail = True
3198 apps = self.apps( jsonFormat=True )
3199 if apps:
3200 apps = json.loads( apps )
3201 else:
3202 main.log.error( "apps returned nothing:" + repr( apps ) )
3203 bail = True
3204 if bail:
3205 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003206 result = main.TRUE
3207 for app in apps:
3208 appID = app.get( 'id' )
3209 if appID is None:
3210 main.log.error( "Error parsing app: " + str( app ) )
3211 result = main.FALSE
3212 appName = app.get( 'name' )
3213 if appName is None:
3214 main.log.error( "Error parsing app: " + str( app ) )
3215 result = main.FALSE
3216 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003217 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003218 # main.log.debug( "Comparing " + str( app ) + " to " +
3219 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003220 if not current: # if ids doesn't have this id
3221 result = main.FALSE
3222 main.log.error( "'app-ids' does not have the ID for " +
3223 str( appName ) + " that apps does." )
3224 elif len( current ) > 1:
3225 # there is more than one app with this ID
3226 result = main.FALSE
3227 # We will log this later in the method
3228 elif not current[0][ 'name' ] == appName:
3229 currentName = current[0][ 'name' ]
3230 result = main.FALSE
3231 main.log.error( "'app-ids' has " + str( currentName ) +
3232 " registered under id:" + str( appID ) +
3233 " but 'apps' has " + str( appName ) )
3234 else:
3235 pass # id and name match!
3236 # now make sure that app-ids has no duplicates
3237 idsList = []
3238 namesList = []
3239 for item in ids:
3240 idsList.append( item[ 'id' ] )
3241 namesList.append( item[ 'name' ] )
3242 if len( idsList ) != len( set( idsList ) ) or\
3243 len( namesList ) != len( set( namesList ) ):
3244 main.log.error( "'app-ids' has some duplicate entries: \n"
3245 + json.dumps( ids,
3246 sort_keys=True,
3247 indent=4,
3248 separators=( ',', ': ' ) ) )
3249 result = main.FALSE
3250 return result
3251 except ( ValueError, TypeError ):
3252 main.log.exception( self.name + ": Object not as expected" )
3253 return main.ERROR
3254 except pexpect.EOF:
3255 main.log.error( self.name + ": EOF exception found" )
3256 main.log.error( self.name + ": " + self.handle.before )
3257 main.cleanup()
3258 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003259 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003260 main.log.exception( self.name + ": Uncaught exception!" )
3261 main.cleanup()
3262 main.exit()
3263
Jon Hallfb760a02015-04-13 15:35:03 -07003264 def getCfg( self, component=None, propName=None, short=False,
3265 jsonFormat=True ):
3266 """
3267 Get configuration settings from onos cli
3268 Optional arguments:
3269 component - Optionally only list configurations for a specific
3270 component. If None, all components with configurations
3271 are displayed. Case Sensitive string.
3272 propName - If component is specified, propName option will show
3273 only this specific configuration from that component.
3274 Case Sensitive string.
3275 jsonFormat - Returns output as json. Note that this will override
3276 the short option
3277 short - Short, less verbose, version of configurations.
3278 This is overridden by the json option
3279 returns:
3280 Output from cli as a string or None on error
3281 """
3282 try:
3283 baseStr = "cfg"
3284 cmdStr = " get"
3285 componentStr = ""
3286 if component:
3287 componentStr += " " + component
3288 if propName:
3289 componentStr += " " + propName
3290 if jsonFormat:
3291 baseStr += " -j"
3292 elif short:
3293 baseStr += " -s"
3294 output = self.sendline( baseStr + cmdStr + componentStr )
3295 assert "Error executing command" not in output
3296 return output
3297 except AssertionError:
3298 main.log.error( "Error in processing 'cfg get' command: " +
3299 str( output ) )
3300 return None
3301 except TypeError:
3302 main.log.exception( self.name + ": Object not as expected" )
3303 return None
3304 except pexpect.EOF:
3305 main.log.error( self.name + ": EOF exception found" )
3306 main.log.error( self.name + ": " + self.handle.before )
3307 main.cleanup()
3308 main.exit()
3309 except Exception:
3310 main.log.exception( self.name + ": Uncaught exception!" )
3311 main.cleanup()
3312 main.exit()
3313
3314 def setCfg( self, component, propName, value=None, check=True ):
3315 """
3316 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003317 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003318 component - The case sensitive name of the component whose
3319 property is to be set
3320 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003321 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003322 value - The value to set the property to. If None, will unset the
3323 property and revert it to it's default value(if applicable)
3324 check - Boolean, Check whether the option was successfully set this
3325 only applies when a value is given.
3326 returns:
3327 main.TRUE on success or main.FALSE on failure. If check is False,
3328 will return main.TRUE unless there is an error
3329 """
3330 try:
3331 baseStr = "cfg"
3332 cmdStr = " set " + str( component ) + " " + str( propName )
3333 if value is not None:
3334 cmdStr += " " + str( value )
3335 output = self.sendline( baseStr + cmdStr )
3336 assert "Error executing command" not in output
3337 if value and check:
3338 results = self.getCfg( component=str( component ),
3339 propName=str( propName ),
3340 jsonFormat=True )
3341 # Check if current value is what we just set
3342 try:
3343 jsonOutput = json.loads( results )
3344 current = jsonOutput[ 'value' ]
3345 except ( ValueError, TypeError ):
3346 main.log.exception( "Error parsing cfg output" )
3347 main.log.error( "output:" + repr( results ) )
3348 return main.FALSE
3349 if current == str( value ):
3350 return main.TRUE
3351 return main.FALSE
3352 return main.TRUE
3353 except AssertionError:
3354 main.log.error( "Error in processing 'cfg set' command: " +
3355 str( output ) )
3356 return main.FALSE
3357 except TypeError:
3358 main.log.exception( self.name + ": Object not as expected" )
3359 return main.FALSE
3360 except pexpect.EOF:
3361 main.log.error( self.name + ": EOF exception found" )
3362 main.log.error( self.name + ": " + self.handle.before )
3363 main.cleanup()
3364 main.exit()
3365 except Exception:
3366 main.log.exception( self.name + ": Uncaught exception!" )
3367 main.cleanup()
3368 main.exit()
3369
Jon Hall390696c2015-05-05 17:13:41 -07003370 def setTestAdd( self, setName, values ):
3371 """
3372 CLI command to add elements to a distributed set.
3373 Arguments:
3374 setName - The name of the set to add to.
3375 values - The value(s) to add to the set, space seperated.
3376 Example usages:
3377 setTestAdd( "set1", "a b c" )
3378 setTestAdd( "set2", "1" )
3379 returns:
3380 main.TRUE on success OR
3381 main.FALSE if elements were already in the set OR
3382 main.ERROR on error
3383 """
3384 try:
3385 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3386 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003387 try:
3388 # TODO: Maybe make this less hardcoded
3389 # ConsistentMap Exceptions
3390 assert "org.onosproject.store.service" not in output
3391 # Node not leader
3392 assert "java.lang.IllegalStateException" not in output
3393 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003394 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003395 "command: " + str( output ) )
3396 retryTime = 30 # Conservative time, given by Madan
3397 main.log.info( "Waiting " + str( retryTime ) +
3398 "seconds before retrying." )
3399 time.sleep( retryTime ) # Due to change in mastership
3400 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003401 assert "Error executing command" not in output
3402 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3403 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3404 main.log.info( self.name + ": " + output )
3405 if re.search( positiveMatch, output):
3406 return main.TRUE
3407 elif re.search( negativeMatch, output):
3408 return main.FALSE
3409 else:
3410 main.log.error( self.name + ": setTestAdd did not" +
3411 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003412 main.log.debug( self.name + " actual: " + repr( output ) )
3413 return main.ERROR
3414 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003415 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003416 str( output ) )
3417 return main.ERROR
3418 except TypeError:
3419 main.log.exception( self.name + ": Object not as expected" )
3420 return main.ERROR
3421 except pexpect.EOF:
3422 main.log.error( self.name + ": EOF exception found" )
3423 main.log.error( self.name + ": " + self.handle.before )
3424 main.cleanup()
3425 main.exit()
3426 except Exception:
3427 main.log.exception( self.name + ": Uncaught exception!" )
3428 main.cleanup()
3429 main.exit()
3430
3431 def setTestRemove( self, setName, values, clear=False, retain=False ):
3432 """
3433 CLI command to remove elements from a distributed set.
3434 Required arguments:
3435 setName - The name of the set to remove from.
3436 values - The value(s) to remove from the set, space seperated.
3437 Optional arguments:
3438 clear - Clear all elements from the set
3439 retain - Retain only the given values. (intersection of the
3440 original set and the given set)
3441 returns:
3442 main.TRUE on success OR
3443 main.FALSE if the set was not changed OR
3444 main.ERROR on error
3445 """
3446 try:
3447 cmdStr = "set-test-remove "
3448 if clear:
3449 cmdStr += "-c " + str( setName )
3450 elif retain:
3451 cmdStr += "-r " + str( setName ) + " " + str( values )
3452 else:
3453 cmdStr += str( setName ) + " " + str( values )
3454 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003455 try:
3456 # TODO: Maybe make this less hardcoded
3457 # ConsistentMap Exceptions
3458 assert "org.onosproject.store.service" not in output
3459 # Node not leader
3460 assert "java.lang.IllegalStateException" not in output
3461 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003462 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003463 "command: " + str( output ) )
3464 retryTime = 30 # Conservative time, given by Madan
3465 main.log.info( "Waiting " + str( retryTime ) +
3466 "seconds before retrying." )
3467 time.sleep( retryTime ) # Due to change in mastership
3468 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003469 assert "Error executing command" not in output
3470 main.log.info( self.name + ": " + output )
3471 if clear:
3472 pattern = "Set " + str( setName ) + " cleared"
3473 if re.search( pattern, output ):
3474 return main.TRUE
3475 elif retain:
3476 positivePattern = str( setName ) + " was pruned to contain " +\
3477 "only elements of set \[(.*)\]"
3478 negativePattern = str( setName ) + " was not changed by " +\
3479 "retaining only elements of the set " +\
3480 "\[(.*)\]"
3481 if re.search( positivePattern, output ):
3482 return main.TRUE
3483 elif re.search( negativePattern, output ):
3484 return main.FALSE
3485 else:
3486 positivePattern = "\[(.*)\] was removed from the set " +\
3487 str( setName )
3488 if ( len( values.split() ) == 1 ):
3489 negativePattern = "\[(.*)\] was not in set " +\
3490 str( setName )
3491 else:
3492 negativePattern = "No element of \[(.*)\] was in set " +\
3493 str( setName )
3494 if re.search( positivePattern, output ):
3495 return main.TRUE
3496 elif re.search( negativePattern, output ):
3497 return main.FALSE
3498 main.log.error( self.name + ": setTestRemove did not" +
3499 " match expected output" )
3500 main.log.debug( self.name + " expected: " + pattern )
3501 main.log.debug( self.name + " actual: " + repr( output ) )
3502 return main.ERROR
3503 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003504 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003505 str( output ) )
3506 return main.ERROR
3507 except TypeError:
3508 main.log.exception( self.name + ": Object not as expected" )
3509 return main.ERROR
3510 except pexpect.EOF:
3511 main.log.error( self.name + ": EOF exception found" )
3512 main.log.error( self.name + ": " + self.handle.before )
3513 main.cleanup()
3514 main.exit()
3515 except Exception:
3516 main.log.exception( self.name + ": Uncaught exception!" )
3517 main.cleanup()
3518 main.exit()
3519
3520 def setTestGet( self, setName, values="" ):
3521 """
3522 CLI command to get the elements in a distributed set.
3523 Required arguments:
3524 setName - The name of the set to remove from.
3525 Optional arguments:
3526 values - The value(s) to check if in the set, space seperated.
3527 returns:
3528 main.ERROR on error OR
3529 A list of elements in the set if no optional arguments are
3530 supplied OR
3531 A tuple containing the list then:
3532 main.FALSE if the given values are not in the set OR
3533 main.TRUE if the given values are in the set OR
3534 """
3535 try:
3536 values = str( values ).strip()
3537 setName = str( setName ).strip()
3538 length = len( values.split() )
3539 containsCheck = None
3540 # Patterns to match
3541 setPattern = "\[(.*)\]"
3542 pattern = "Items in set " + setName + ":\n" + setPattern
3543 containsTrue = "Set " + setName + " contains the value " + values
3544 containsFalse = "Set " + setName + " did not contain the value " +\
3545 values
3546 containsAllTrue = "Set " + setName + " contains the the subset " +\
3547 setPattern
3548 containsAllFalse = "Set " + setName + " did not contain the the" +\
3549 " subset " + setPattern
3550
3551 cmdStr = "set-test-get "
3552 cmdStr += setName + " " + values
3553 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003554 try:
3555 # TODO: Maybe make this less hardcoded
3556 # ConsistentMap Exceptions
3557 assert "org.onosproject.store.service" not in output
3558 # Node not leader
3559 assert "java.lang.IllegalStateException" not in output
3560 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003561 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003562 "command: " + str( output ) )
3563 retryTime = 30 # Conservative time, given by Madan
3564 main.log.info( "Waiting " + str( retryTime ) +
3565 "seconds before retrying." )
3566 time.sleep( retryTime ) # Due to change in mastership
3567 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003568 assert "Error executing command" not in output
3569 main.log.info( self.name + ": " + output )
3570
3571 if length == 0:
3572 match = re.search( pattern, output )
3573 else: # if given values
3574 if length == 1: # Contains output
3575 patternTrue = pattern + "\n" + containsTrue
3576 patternFalse = pattern + "\n" + containsFalse
3577 else: # ContainsAll output
3578 patternTrue = pattern + "\n" + containsAllTrue
3579 patternFalse = pattern + "\n" + containsAllFalse
3580 matchTrue = re.search( patternTrue, output )
3581 matchFalse = re.search( patternFalse, output )
3582 if matchTrue:
3583 containsCheck = main.TRUE
3584 match = matchTrue
3585 elif matchFalse:
3586 containsCheck = main.FALSE
3587 match = matchFalse
3588 else:
3589 main.log.error( self.name + " setTestGet did not match " +\
3590 "expected output" )
3591 main.log.debug( self.name + " expected: " + pattern )
3592 main.log.debug( self.name + " actual: " + repr( output ) )
3593 match = None
3594 if match:
3595 setMatch = match.group( 1 )
3596 if setMatch == '':
3597 setList = []
3598 else:
3599 setList = setMatch.split( ", " )
3600 if length > 0:
3601 return ( setList, containsCheck )
3602 else:
3603 return setList
3604 else: # no match
3605 main.log.error( self.name + ": setTestGet did not" +
3606 " match expected output" )
3607 main.log.debug( self.name + " expected: " + pattern )
3608 main.log.debug( self.name + " actual: " + repr( output ) )
3609 return main.ERROR
3610 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003611 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003612 str( output ) )
3613 return main.ERROR
3614 except TypeError:
3615 main.log.exception( self.name + ": Object not as expected" )
3616 return main.ERROR
3617 except pexpect.EOF:
3618 main.log.error( self.name + ": EOF exception found" )
3619 main.log.error( self.name + ": " + self.handle.before )
3620 main.cleanup()
3621 main.exit()
3622 except Exception:
3623 main.log.exception( self.name + ": Uncaught exception!" )
3624 main.cleanup()
3625 main.exit()
3626
3627 def setTestSize( self, setName ):
3628 """
3629 CLI command to get the elements in a distributed set.
3630 Required arguments:
3631 setName - The name of the set to remove from.
3632 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003633 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003634 None on error
3635 """
3636 try:
3637 # TODO: Should this check against the number of elements returned
3638 # and then return true/false based on that?
3639 setName = str( setName ).strip()
3640 # Patterns to match
3641 setPattern = "\[(.*)\]"
3642 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3643 setPattern
3644 cmdStr = "set-test-get -s "
3645 cmdStr += setName
3646 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003647 try:
3648 # TODO: Maybe make this less hardcoded
3649 # ConsistentMap Exceptions
3650 assert "org.onosproject.store.service" not in output
3651 # Node not leader
3652 assert "java.lang.IllegalStateException" not in output
3653 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003654 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003655 "command: " + str( output ) )
3656 retryTime = 30 # Conservative time, given by Madan
3657 main.log.info( "Waiting " + str( retryTime ) +
3658 "seconds before retrying." )
3659 time.sleep( retryTime ) # Due to change in mastership
3660 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003661 assert "Error executing command" not in output
3662 main.log.info( self.name + ": " + output )
3663 match = re.search( pattern, output )
3664 if match:
3665 setSize = int( match.group( 1 ) )
3666 setMatch = match.group( 2 )
3667 if len( setMatch.split() ) == setSize:
3668 main.log.info( "The size returned by " + self.name +
3669 " matches the number of elements in " +
3670 "the returned set" )
3671 else:
3672 main.log.error( "The size returned by " + self.name +
3673 " does not match the number of " +
3674 "elements in the returned set." )
3675 return setSize
3676 else: # no match
3677 main.log.error( self.name + ": setTestGet did not" +
3678 " match expected output" )
3679 main.log.debug( self.name + " expected: " + pattern )
3680 main.log.debug( self.name + " actual: " + repr( output ) )
3681 return None
3682 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003683 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003684 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003685 return None
Jon Hall390696c2015-05-05 17:13:41 -07003686 except TypeError:
3687 main.log.exception( self.name + ": Object not as expected" )
3688 return None
3689 except pexpect.EOF:
3690 main.log.error( self.name + ": EOF exception found" )
3691 main.log.error( self.name + ": " + self.handle.before )
3692 main.cleanup()
3693 main.exit()
3694 except Exception:
3695 main.log.exception( self.name + ": Uncaught exception!" )
3696 main.cleanup()
3697 main.exit()
3698
Jon Hall80daded2015-05-27 16:07:00 -07003699 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003700 """
3701 Command to list the various counters in the system.
3702 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003703 if jsonFormat, a string of the json object returned by the cli
3704 command
3705 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003706 None on error
3707 """
Jon Hall390696c2015-05-05 17:13:41 -07003708 try:
3709 counters = {}
3710 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003711 if jsonFormat:
3712 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003713 output = self.sendline( cmdStr )
3714 assert "Error executing command" not in output
3715 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003716 return output
Jon Hall390696c2015-05-05 17:13:41 -07003717 except AssertionError:
3718 main.log.error( "Error in processing 'counters' command: " +
3719 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003720 return None
Jon Hall390696c2015-05-05 17:13:41 -07003721 except TypeError:
3722 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003723 return None
Jon Hall390696c2015-05-05 17:13:41 -07003724 except pexpect.EOF:
3725 main.log.error( self.name + ": EOF exception found" )
3726 main.log.error( self.name + ": " + self.handle.before )
3727 main.cleanup()
3728 main.exit()
3729 except Exception:
3730 main.log.exception( self.name + ": Uncaught exception!" )
3731 main.cleanup()
3732 main.exit()
3733
Jon Halle1a3b752015-07-22 13:02:46 -07003734 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003735 """
Jon Halle1a3b752015-07-22 13:02:46 -07003736 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003737 Required arguments:
3738 counter - The name of the counter to increment.
3739 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003740 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003741 inMemory - use in memory map for the counter
3742 returns:
3743 integer value of the counter or
3744 None on Error
3745 """
3746 try:
3747 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003748 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003749 cmdStr = "counter-test-increment "
3750 if inMemory:
3751 cmdStr += "-i "
3752 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003753 if delta != 1:
3754 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003755 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003756 try:
3757 # TODO: Maybe make this less hardcoded
3758 # ConsistentMap Exceptions
3759 assert "org.onosproject.store.service" not in output
3760 # Node not leader
3761 assert "java.lang.IllegalStateException" not in output
3762 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003763 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003764 "command: " + str( output ) )
3765 retryTime = 30 # Conservative time, given by Madan
3766 main.log.info( "Waiting " + str( retryTime ) +
3767 "seconds before retrying." )
3768 time.sleep( retryTime ) # Due to change in mastership
3769 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003770 assert "Error executing command" not in output
3771 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003772 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003773 match = re.search( pattern, output )
3774 if match:
3775 return int( match.group( 1 ) )
3776 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003777 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003778 " match expected output." )
3779 main.log.debug( self.name + " expected: " + pattern )
3780 main.log.debug( self.name + " actual: " + repr( output ) )
3781 return None
3782 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003783 main.log.error( "Error in processing '" + cmdStr + "'" +
Jon Hall390696c2015-05-05 17:13:41 -07003784 " command: " + str( output ) )
3785 return None
3786 except TypeError:
3787 main.log.exception( self.name + ": Object not as expected" )
3788 return None
3789 except pexpect.EOF:
3790 main.log.error( self.name + ": EOF exception found" )
3791 main.log.error( self.name + ": " + self.handle.before )
3792 main.cleanup()
3793 main.exit()
3794 except Exception:
3795 main.log.exception( self.name + ": Uncaught exception!" )
3796 main.cleanup()
3797 main.exit()
3798
Jon Halle1a3b752015-07-22 13:02:46 -07003799 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
3800 """
3801 CLI command to get a distributed counter then add a delta to it.
3802 Required arguments:
3803 counter - The name of the counter to increment.
3804 Optional arguments:
3805 delta - The long to add to the counter
3806 inMemory - use in memory map for the counter
3807 returns:
3808 integer value of the counter or
3809 None on Error
3810 """
3811 try:
3812 counter = str( counter )
3813 delta = int( delta )
3814 cmdStr = "counter-test-increment -g "
3815 if inMemory:
3816 cmdStr += "-i "
3817 cmdStr += counter
3818 if delta != 1:
3819 cmdStr += " " + str( delta )
3820 output = self.sendline( cmdStr )
3821 try:
3822 # TODO: Maybe make this less hardcoded
3823 # ConsistentMap Exceptions
3824 assert "org.onosproject.store.service" not in output
3825 # Node not leader
3826 assert "java.lang.IllegalStateException" not in output
3827 except AssertionError:
3828 main.log.error( "Error in processing '" + cmdStr + "' " +
3829 "command: " + str( output ) )
3830 retryTime = 30 # Conservative time, given by Madan
3831 main.log.info( "Waiting " + str( retryTime ) +
3832 "seconds before retrying." )
3833 time.sleep( retryTime ) # Due to change in mastership
3834 output = self.sendline( cmdStr )
3835 assert "Error executing command" not in output
3836 main.log.info( self.name + ": " + output )
3837 pattern = counter + " was updated to (-?\d+)"
3838 match = re.search( pattern, output )
3839 if match:
3840 return int( match.group( 1 ) )
3841 else:
3842 main.log.error( self.name + ": counterTestGetAndAdd did not" +
3843 " match expected output." )
3844 main.log.debug( self.name + " expected: " + pattern )
3845 main.log.debug( self.name + " actual: " + repr( output ) )
3846 return None
3847 except AssertionError:
3848 main.log.error( "Error in processing '" + cmdStr + "'" +
3849 " command: " + str( output ) )
3850 return None
3851 except TypeError:
3852 main.log.exception( self.name + ": Object not as expected" )
3853 return None
3854 except pexpect.EOF:
3855 main.log.error( self.name + ": EOF exception found" )
3856 main.log.error( self.name + ": " + self.handle.before )
3857 main.cleanup()
3858 main.exit()
3859 except Exception:
3860 main.log.exception( self.name + ": Uncaught exception!" )
3861 main.cleanup()
3862 main.exit()
3863
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003864 def summary( self, jsonFormat=True ):
3865 """
3866 Description: Execute summary command in onos
3867 Returns: json object ( summary -j ), returns main.FALSE if there is
3868 no output
3869
3870 """
3871 try:
3872 cmdStr = "summary"
3873 if jsonFormat:
3874 cmdStr += " -j"
3875 handle = self.sendline( cmdStr )
3876
3877 if re.search( "Error:", handle ):
3878 main.log.error( self.name + ": summary() response: " +
3879 str( handle ) )
3880 if not handle:
3881 main.log.error( self.name + ": There is no output in " +
3882 "summary command" )
3883 return main.FALSE
3884 return handle
3885 except TypeError:
3886 main.log.exception( self.name + ": Object not as expected" )
3887 return None
3888 except pexpect.EOF:
3889 main.log.error( self.name + ": EOF exception found" )
3890 main.log.error( self.name + ": " + self.handle.before )
3891 main.cleanup()
3892 main.exit()
3893 except Exception:
3894 main.log.exception( self.name + ": Uncaught exception!" )
3895 main.cleanup()
3896 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07003897
3898 def transactionalMapGet( self, keyName, inMemory=False ):
3899 """
3900 CLI command to get the value of a key in a consistent map using
3901 transactions. This a test function and can only get keys from the
3902 test map hard coded into the cli command
3903 Required arguments:
3904 keyName - The name of the key to get
3905 Optional arguments:
3906 inMemory - use in memory map for the counter
3907 returns:
3908 The string value of the key or
3909 None on Error
3910 """
3911 try:
3912 keyName = str( keyName )
3913 cmdStr = "transactional-map-test-get "
3914 if inMemory:
3915 cmdStr += "-i "
3916 cmdStr += keyName
3917 output = self.sendline( cmdStr )
3918 try:
3919 # TODO: Maybe make this less hardcoded
3920 # ConsistentMap Exceptions
3921 assert "org.onosproject.store.service" not in output
3922 # Node not leader
3923 assert "java.lang.IllegalStateException" not in output
3924 except AssertionError:
3925 main.log.error( "Error in processing '" + cmdStr + "' " +
3926 "command: " + str( output ) )
3927 return None
3928 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
3929 if "Key " + keyName + " not found." in output:
3930 return None
3931 else:
3932 match = re.search( pattern, output )
3933 if match:
3934 return match.groupdict()[ 'value' ]
3935 else:
3936 main.log.error( self.name + ": transactionlMapGet did not" +
3937 " match expected output." )
3938 main.log.debug( self.name + " expected: " + pattern )
3939 main.log.debug( self.name + " actual: " + repr( output ) )
3940 return None
3941 except TypeError:
3942 main.log.exception( self.name + ": Object not as expected" )
3943 return None
3944 except pexpect.EOF:
3945 main.log.error( self.name + ": EOF exception found" )
3946 main.log.error( self.name + ": " + self.handle.before )
3947 main.cleanup()
3948 main.exit()
3949 except Exception:
3950 main.log.exception( self.name + ": Uncaught exception!" )
3951 main.cleanup()
3952 main.exit()
3953
3954 def transactionalMapPut( self, numKeys, value, inMemory=False ):
3955 """
3956 CLI command to put a value into 'numKeys' number of keys in a
3957 consistent map using transactions. This a test function and can only
3958 put into keys named 'Key#' of the test map hard coded into the cli command
3959 Required arguments:
3960 numKeys - Number of keys to add the value to
3961 value - The string value to put into the keys
3962 Optional arguments:
3963 inMemory - use in memory map for the counter
3964 returns:
3965 A dictionary whose keys are the name of the keys put into the map
3966 and the values of the keys are dictionaries whose key-values are
3967 'value': value put into map and optionaly
3968 'oldValue': Previous value in the key or
3969 None on Error
3970
3971 Example output
3972 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
3973 'Key2': {'value': 'Testing'} }
3974 """
3975 try:
3976 numKeys = str( numKeys )
3977 value = str( value )
3978 cmdStr = "transactional-map-test-put "
3979 if inMemory:
3980 cmdStr += "-i "
3981 cmdStr += numKeys + " " + value
3982 output = self.sendline( cmdStr )
3983 try:
3984 # TODO: Maybe make this less hardcoded
3985 # ConsistentMap Exceptions
3986 assert "org.onosproject.store.service" not in output
3987 # Node not leader
3988 assert "java.lang.IllegalStateException" not in output
3989 except AssertionError:
3990 main.log.error( "Error in processing '" + cmdStr + "' " +
3991 "command: " + str( output ) )
3992 return None
3993 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
3994 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
3995 results = {}
3996 for line in output.splitlines():
3997 new = re.search( newPattern, line )
3998 updated = re.search( updatedPattern, line )
3999 if new:
4000 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4001 elif updated:
4002 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
4003 'oldValue': updated.groupdict()[ 'oldValue' ] }
4004 else:
4005 main.log.error( self.name + ": transactionlMapGet did not" +
4006 " match expected output." )
4007 main.log.debug( self.name + " expected: " + pattern )
4008 main.log.debug( self.name + " actual: " + repr( output ) )
4009 return results
4010 except TypeError:
4011 main.log.exception( self.name + ": Object not as expected" )
4012 return None
4013 except pexpect.EOF:
4014 main.log.error( self.name + ": EOF exception found" )
4015 main.log.error( self.name + ": " + self.handle.before )
4016 main.cleanup()
4017 main.exit()
4018 except Exception:
4019 main.log.exception( self.name + ": Uncaught exception!" )
4020 main.cleanup()
4021 main.exit()
acsmarsdaea66c2015-09-03 11:44:06 -07004022 def maps( self, jsonFormat=True ):
4023 """
4024 Description: Returns result of onos:maps
4025 Optional:
4026 * jsonFormat: enable json formatting of output
4027 """
4028 try:
4029 cmdStr = "maps"
4030 if jsonFormat:
4031 cmdStr += " -j"
4032 handle = self.sendline( cmdStr )
4033 return handle
4034 except TypeError:
4035 main.log.exception( self.name + ": Object not as expected" )
4036 return None
4037 except pexpect.EOF:
4038 main.log.error( self.name + ": EOF exception found" )
4039 main.log.error( self.name + ": " + self.handle.before )
4040 main.cleanup()
4041 main.exit()
4042 except Exception:
4043 main.log.exception( self.name + ": Uncaught exception!" )
4044 main.cleanup()
4045 main.exit()