blob: eafc7ab6cd527ad3a53b6c8798ddbcb0ba8d70d3 [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
GlennRC208d4af2015-11-24 12:30:00 -0800334 def sendline( self, cmdStr, showResponse=False, 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 ) )
GlennRC85870432015-11-23 11:45:51 -0800391 output = output[1].strip()
392 if showResponse:
393 main.log.info( "Resonse from ONOS: {}".format( output ) )
394 return output
Jon Hallc6358dd2015-04-10 12:44:28 -0700395 except IndexError:
396 main.log.exception( self.name + ": Object not as expected" )
397 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800398 except TypeError:
399 main.log.exception( self.name + ": Object not as expected" )
400 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400401 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800402 main.log.error( self.name + ": EOF exception found" )
403 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400404 main.cleanup()
405 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800406 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800407 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400408 main.cleanup()
409 main.exit()
410
kelvin8ec71442015-01-15 16:57:00 -0800411 # IMPORTANT NOTE:
412 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800413 # the cli command changing 'a:b' with 'aB'.
414 # Ex ) onos:topology > onosTopology
415 # onos:links > onosLinks
416 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800417
kelvin-onlabd3b64892015-01-20 13:26:24 -0800418 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800419 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400420 Adds a new cluster node by ID and address information.
421 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * nodeId
423 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400424 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800426 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400427 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800428 cmdStr = "add-node " + str( nodeId ) + " " +\
429 str( ONOSIp ) + " " + str( tcpPort )
430 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800431 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800432 main.log.error( "Error in adding node" )
433 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800434 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800436 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400437 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800438 except TypeError:
439 main.log.exception( self.name + ": Object not as expected" )
440 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800442 main.log.error( self.name + ": EOF exception found" )
443 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400444 main.cleanup()
445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800446 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800447 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400448 main.cleanup()
449 main.exit()
450
kelvin-onlabd3b64892015-01-20 13:26:24 -0800451 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800452 """
andrewonlab86dc3082014-10-13 18:18:38 -0400453 Removes a cluster by ID
454 Issues command: 'remove-node [<node-id>]'
455 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800456 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800457 """
andrewonlab86dc3082014-10-13 18:18:38 -0400458 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400459
kelvin-onlabd3b64892015-01-20 13:26:24 -0800460 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700461 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700462 if re.search( "Error", handle ):
463 main.log.error( "Error in removing node" )
464 main.log.error( handle )
465 return main.FALSE
466 else:
467 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800468 except TypeError:
469 main.log.exception( self.name + ": Object not as expected" )
470 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400471 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800472 main.log.error( self.name + ": EOF exception found" )
473 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400474 main.cleanup()
475 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800477 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400478 main.cleanup()
479 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400480
Jon Hall61282e32015-03-19 11:34:11 -0700481 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800482 """
andrewonlab7c211572014-10-15 16:45:20 -0400483 List the nodes currently visible
484 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700485 Optional argument:
486 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800487 """
andrewonlab7c211572014-10-15 16:45:20 -0400488 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700489 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700490 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700491 cmdStr += " -j"
492 output = self.sendline( cmdStr )
493 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800494 except TypeError:
495 main.log.exception( self.name + ": Object not as expected" )
496 return None
andrewonlab7c211572014-10-15 16:45:20 -0400497 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800498 main.log.error( self.name + ": EOF exception found" )
499 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400500 main.cleanup()
501 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800502 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800503 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400504 main.cleanup()
505 main.exit()
506
kelvin8ec71442015-01-15 16:57:00 -0800507 def topology( self ):
508 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700509 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700510 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700511 Return:
512 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800513 """
andrewonlab95ce8322014-10-13 14:12:04 -0400514 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700515 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800516 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400518 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800519 except TypeError:
520 main.log.exception( self.name + ": Object not as expected" )
521 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400522 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800523 main.log.error( self.name + ": EOF exception found" )
524 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400525 main.cleanup()
526 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800527 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800528 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400529 main.cleanup()
530 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800531
kelvin-onlabd3b64892015-01-20 13:26:24 -0800532 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800533 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 Installs a specified feature by issuing command:
535 'feature:install <feature_str>'
536 NOTE: This is now deprecated, you should use the activateApp method
537 instead
kelvin8ec71442015-01-15 16:57:00 -0800538 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400539 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800540 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700541 handle = self.sendline( cmdStr )
542 if re.search( "Error", handle ):
543 main.log.error( "Error in installing feature" )
544 main.log.error( handle )
545 return main.FALSE
546 else:
547 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800548 except TypeError:
549 main.log.exception( self.name + ": Object not as expected" )
550 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400551 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800552 main.log.error( self.name + ": EOF exception found" )
553 main.log.error( self.name + ": " + self.handle.before )
554 main.log.report( "Failed to install feature" )
555 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400556 main.cleanup()
557 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800558 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800559 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.report( "Failed to install feature" )
561 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400562 main.cleanup()
563 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800564
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800566 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700567 Uninstalls a specified feature by issuing command:
568 'feature:uninstall <feature_str>'
569 NOTE: This is now deprecated, you should use the deactivateApp method
570 instead
kelvin8ec71442015-01-15 16:57:00 -0800571 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800573 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
574 handle = self.sendline( cmdStr )
575 if handle != '':
576 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700577 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800578 # TODO: Check for possible error responses from karaf
579 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800580 main.log.info( "Feature needs to be installed before " +
581 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700582 return main.TRUE
583 if re.search( "Error", output ):
584 main.log.error( "Error in uninstalling feature" )
585 main.log.error( output )
586 return main.FALSE
587 else:
588 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800589 except TypeError:
590 main.log.exception( self.name + ": Object not as expected" )
591 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400595 main.cleanup()
596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800598 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400599 main.cleanup()
600 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800601
jenkins7ead5a82015-03-13 10:28:21 -0700602 def deviceRemove( self, deviceId ):
603 """
604 Removes particular device from storage
605
606 TODO: refactor this function
607 """
608 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700609 cmdStr = "device-remove " + str( deviceId )
610 handle = self.sendline( cmdStr )
611 if re.search( "Error", handle ):
612 main.log.error( "Error in removing device" )
613 main.log.error( handle )
614 return main.FALSE
615 else:
616 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700617 except TypeError:
618 main.log.exception( self.name + ": Object not as expected" )
619 return None
620 except pexpect.EOF:
621 main.log.error( self.name + ": EOF exception found" )
622 main.log.error( self.name + ": " + self.handle.before )
623 main.cleanup()
624 main.exit()
625 except Exception:
626 main.log.exception( self.name + ": Uncaught exception!" )
627 main.cleanup()
628 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700629
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800631 """
Jon Hall7b02d952014-10-17 20:14:54 -0400632 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400633 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800634 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800635 """
andrewonlab86dc3082014-10-13 18:18:38 -0400636 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700637 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800638 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700639 cmdStr += " -j"
640 handle = self.sendline( cmdStr )
641 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800642 except TypeError:
643 main.log.exception( self.name + ": Object not as expected" )
644 return None
andrewonlab7c211572014-10-15 16:45:20 -0400645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": EOF exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800651 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400652 main.cleanup()
653 main.exit()
654
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800656 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800657 This balances the devices across all controllers
658 by issuing command: 'onos> onos:balance-masters'
659 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800660 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800661 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700663 handle = self.sendline( cmdStr )
664 if re.search( "Error", handle ):
665 main.log.error( "Error in balancing masters" )
666 main.log.error( handle )
667 return main.FALSE
668 else:
669 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800670 except TypeError:
671 main.log.exception( self.name + ": Object not as expected" )
672 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800673 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800674 main.log.error( self.name + ": EOF exception found" )
675 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800676 main.cleanup()
677 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800678 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800679 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800680 main.cleanup()
681 main.exit()
682
acsmars24950022015-07-30 18:00:43 -0700683 def checkMasters( self,jsonFormat=True ):
684 """
685 Returns the output of the masters command.
686 Optional argument:
687 * jsonFormat - boolean indicating if you want output in json
688 """
689 try:
690 cmdStr = "onos:masters"
691 if jsonFormat:
692 cmdStr += " -j"
693 output = self.sendline( cmdStr )
694 return output
695 except TypeError:
696 main.log.exception( self.name + ": Object not as expected" )
697 return None
698 except pexpect.EOF:
699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
701 main.cleanup()
702 main.exit()
703 except Exception:
704 main.log.exception( self.name + ": Uncaught exception!" )
705 main.cleanup()
706 main.exit()
707
708 def checkBalanceMasters( self,jsonFormat=True ):
709 """
710 Uses the master command to check that the devices' leadership
711 is evenly divided
712
713 Dependencies: checkMasters() and summary()
714
715 Returns main.True if the devices are balanced
716 Returns main.False if the devices are unbalanced
717 Exits on Exception
718 Returns None on TypeError
719 """
720 try:
721 totalDevices = json.loads( self.summary() )[ "devices" ]
722 totalOwnedDevices = 0
723 masters = json.loads( self.checkMasters() )
724 first = masters[ 0 ][ "size" ]
725 for master in masters:
726 totalOwnedDevices += master[ "size" ]
727 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
728 main.log.error( "Mastership not balanced" )
729 main.log.info( "\n" + self.checkMasters( False ) )
730 return main.FALSE
731 main.log.info( "Mastership balanced between " \
732 + str( len(masters) ) + " masters" )
733 return main.TRUE
734 except TypeError:
735 main.log.exception( self.name + ": Object not as expected" )
736 return None
737 except pexpect.EOF:
738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
740 main.cleanup()
741 main.exit()
742 except Exception:
743 main.log.exception( self.name + ": Uncaught exception!" )
744 main.cleanup()
745 main.exit()
746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800748 """
Jon Halle8217482014-10-17 13:49:14 -0400749 Lists all core links
750 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800751 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800752 """
Jon Halle8217482014-10-17 13:49:14 -0400753 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700754 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700756 cmdStr += " -j"
757 handle = self.sendline( cmdStr )
758 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800759 except TypeError:
760 main.log.exception( self.name + ": Object not as expected" )
761 return None
Jon Halle8217482014-10-17 13:49:14 -0400762 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800763 main.log.error( self.name + ": EOF exception found" )
764 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400765 main.cleanup()
766 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800767 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800768 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400769 main.cleanup()
770 main.exit()
771
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800773 """
Jon Halle8217482014-10-17 13:49:14 -0400774 Lists all ports
775 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800776 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800777 """
Jon Halle8217482014-10-17 13:49:14 -0400778 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800780 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 cmdStr += " -j"
782 handle = self.sendline( cmdStr )
783 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
Jon Halle8217482014-10-17 13:49:14 -0400787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400790 main.cleanup()
791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400794 main.cleanup()
795 main.exit()
796
kelvin-onlabd3b64892015-01-20 13:26:24 -0800797 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800798 """
Jon Hall983a1702014-10-28 18:44:22 -0400799 Lists all devices and the controllers with roles assigned to them
800 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab7c211572014-10-15 16:45:20 -0400803 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700804 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 cmdStr += " -j"
807 handle = self.sendline( cmdStr )
808 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800809 except TypeError:
810 main.log.exception( self.name + ": Object not as expected" )
811 return None
Jon Hall983a1702014-10-28 18:44:22 -0400812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800813 main.log.error( self.name + ": EOF exception found" )
814 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400815 main.cleanup()
816 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800817 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800818 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400819 main.cleanup()
820 main.exit()
821
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800823 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800824 Given the a string containing the json representation of the "roles"
825 cli command and a partial or whole device id, returns a json object
826 containing the roles output for the first device whose id contains
827 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400828
829 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800830 A dict of the role assignments for the given device or
831 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800832 """
Jon Hall983a1702014-10-28 18:44:22 -0400833 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800834 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400835 return None
836 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 rawRoles = self.roles()
838 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800839 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800840 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800841 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800842 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400843 return device
844 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800845 except TypeError:
846 main.log.exception( self.name + ": Object not as expected" )
847 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400848 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400851 main.cleanup()
852 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800853 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800854 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400855 main.cleanup()
856 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800857
kelvin-onlabd3b64892015-01-20 13:26:24 -0800858 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800859 """
Jon Hall94fd0472014-12-08 11:52:42 -0800860 Iterates through each device and checks if there is a master assigned
861 Returns: main.TRUE if each device has a master
862 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800863 """
Jon Hall94fd0472014-12-08 11:52:42 -0800864 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 rawRoles = self.roles()
866 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800867 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800869 # print device
870 if device[ 'master' ] == "none":
871 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800872 return main.FALSE
873 return main.TRUE
874
Jon Halld4d4b372015-01-28 16:02:41 -0800875 except TypeError:
876 main.log.exception( self.name + ": Object not as expected" )
877 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800881 main.cleanup()
882 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400890 Returns string of paths, and the cost.
891 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800892 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
895 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800896 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( "Error in getting paths" )
898 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400899 else:
kelvin8ec71442015-01-15 16:57:00 -0800900 path = handle.split( ";" )[ 0 ]
901 cost = handle.split( ";" )[ 1 ]
902 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800903 except TypeError:
904 main.log.exception( self.name + ": Object not as expected" )
905 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400906 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400909 main.cleanup()
910 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800911 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800912 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400913 main.cleanup()
914 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800915
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800917 """
Jon Hallffb386d2014-11-21 13:43:38 -0800918 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400919 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800921 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400922 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700923 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700925 cmdStr += " -j"
926 handle = self.sendline( cmdStr )
Jon Hallbaf53162015-12-17 17:04:34 -0800927 try:
928 # TODO: Maybe make this less hardcoded
929 # ConsistentMap Exceptions
930 assert "org.onosproject.store.service" not in handle
931 # Node not leader
932 assert "java.lang.IllegalStateException" not in handle
933 except AssertionError:
934 main.log.error( "Error in processing '" + cmdStr + "' " +
935 "command: " + str( handle ) )
936 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700937 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800938 except TypeError:
939 main.log.exception( self.name + ": Object not as expected" )
940 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800942 main.log.error( self.name + ": EOF exception found" )
943 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400944 main.cleanup()
945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800947 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400948 main.cleanup()
949 main.exit()
950
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800952 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800954
Jon Hallefbd9792015-03-05 16:11:36 -0800955 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800956 partial mac address
957
Jon Hall42db6dc2014-10-24 19:03:48 -0400958 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800959 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400960 try:
kelvin8ec71442015-01-15 16:57:00 -0800961 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400962 return None
963 else:
964 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 rawHosts = self.hosts()
966 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800967 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800969 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800970 if not host:
971 pass
972 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400973 return host
974 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800975 except TypeError:
976 main.log.exception( self.name + ": Object not as expected" )
977 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400981 main.cleanup()
982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400985 main.cleanup()
986 main.exit()
987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800989 """
990 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400991 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800992
andrewonlab3f0a4af2014-10-17 12:25:14 -0400993 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400995 IMPORTANT:
996 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800997 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 Furthermore, it assumes that value of VLAN is '-1'
999 Description:
kelvin8ec71442015-01-15 16:57:00 -08001000 Converts mininet hosts ( h1, h2, h3... ) into
1001 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1002 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001003 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001005
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001007 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 hostHex = hex( int( host ) ).zfill( 12 )
1009 hostHex = str( hostHex ).replace( 'x', '0' )
1010 i = iter( str( hostHex ) )
1011 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1012 hostHex = hostHex + "/-1"
1013 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001014
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001016
Jon Halld4d4b372015-01-28 16:02:41 -08001017 except TypeError:
1018 main.log.exception( self.name + ": Object not as expected" )
1019 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( self.name + ": EOF exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001023 main.cleanup()
1024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001026 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001027 main.cleanup()
1028 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001029
kelvin-onlabd3b64892015-01-20 13:26:24 -08001030 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001031 """
andrewonlabe6745342014-10-17 14:29:13 -04001032 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * hostIdOne: ONOS host id for host1
1034 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001035 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001036 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001037 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001038 Returns:
1039 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001040 """
andrewonlabe6745342014-10-17 14:29:13 -04001041 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001042 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1043 " " + str( hostIdTwo )
1044 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -08001045 if re.search( "Error", handle ):
1046 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001047 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001048 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001049 else:
1050 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001051 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1052 match = re.search('id=0x([\da-f]+),', handle)
1053 if match:
1054 return match.group()[3:-1]
1055 else:
1056 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001057 main.log.debug( "Response from ONOS was: " +
1058 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001059 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001060 except TypeError:
1061 main.log.exception( self.name + ": Object not as expected" )
1062 return None
andrewonlabe6745342014-10-17 14:29:13 -04001063 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001064 main.log.error( self.name + ": EOF exception found" )
1065 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001066 main.cleanup()
1067 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001068 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001069 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001070 main.cleanup()
1071 main.exit()
1072
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001074 """
andrewonlab7b31d232014-10-24 13:31:47 -04001075 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 * ingressDevice: device id of ingress device
1077 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001078 Optional:
1079 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001080 Description:
1081 Adds an optical intent by specifying an ingress and egress device
1082 Returns:
1083 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001084 """
andrewonlab7b31d232014-10-24 13:31:47 -04001085 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1087 " " + str( egressDevice )
1088 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001089 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001091 main.log.error( "Error in adding Optical intent" )
1092 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001093 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001094 main.log.info( "Optical intent installed between " +
1095 str( ingressDevice ) + " and " +
1096 str( egressDevice ) )
1097 match = re.search('id=0x([\da-f]+),', handle)
1098 if match:
1099 return match.group()[3:-1]
1100 else:
1101 main.log.error( "Error, intent ID not found" )
1102 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001103 except TypeError:
1104 main.log.exception( self.name + ": Object not as expected" )
1105 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001109 main.cleanup()
1110 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001112 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001113 main.cleanup()
1114 main.exit()
1115
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001117 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 ingressDevice,
1119 egressDevice,
1120 portIngress="",
1121 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001122 ethType="",
1123 ethSrc="",
1124 ethDst="",
1125 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001127 ipProto="",
1128 ipSrc="",
1129 ipDst="",
1130 tcpSrc="",
1131 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001132 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001133 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 * ingressDevice: device id of ingress device
1135 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001136 Optional:
1137 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001138 * ethSrc: specify ethSrc ( i.e. src mac addr )
1139 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001140 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001142 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001143 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001144 * ipSrc: specify ip source address
1145 * ipDst: specify ip destination address
1146 * tcpSrc: specify tcp source port
1147 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001148 Description:
kelvin8ec71442015-01-15 16:57:00 -08001149 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001150 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001151 Returns:
1152 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001153
Jon Halle3f39ff2015-01-13 11:50:53 -08001154 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001155 options developers provide for point-to-point
1156 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001157 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001158 try:
kelvin8ec71442015-01-15 16:57:00 -08001159 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001160 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001162 and not ipProto and not ipSrc and not ipDst \
1163 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001164 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001165
andrewonlab289e4b72014-10-21 21:24:18 -04001166 else:
andrewonlab36af3822014-11-18 17:48:18 -05001167 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001168
andrewonlab0c0a6772014-10-22 12:31:18 -04001169 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001170 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001171 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001172 cmd += " --ethSrc " + str( ethSrc )
1173 if ethDst:
1174 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001175 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001176 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001178 cmd += " --lambda "
1179 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001180 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001181 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001182 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001183 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001184 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001185 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001186 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001187 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001188 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001189
kelvin8ec71442015-01-15 16:57:00 -08001190 # Check whether the user appended the port
1191 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 if "/" in ingressDevice:
1193 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001194 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001197 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001198 # Would it make sense to throw an exception and exit
1199 # the test?
1200 return None
andrewonlab36af3822014-11-18 17:48:18 -05001201
kelvin8ec71442015-01-15 16:57:00 -08001202 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 str( ingressDevice ) + "/" +\
1204 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001205
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 if "/" in egressDevice:
1207 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001208 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001210 main.log.error( "You must specify the egress port" )
1211 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001212
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 str( egressDevice ) + "/" +\
1215 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001216
kelvin-onlab898a6c62015-01-16 14:13:53 -08001217 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001218 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001219 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001220 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001221 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001222 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001223 # TODO: print out all the options in this message?
1224 main.log.info( "Point-to-point intent installed between " +
1225 str( ingressDevice ) + " and " +
1226 str( egressDevice ) )
1227 match = re.search('id=0x([\da-f]+),', handle)
1228 if match:
1229 return match.group()[3:-1]
1230 else:
1231 main.log.error( "Error, intent ID not found" )
1232 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001233 except TypeError:
1234 main.log.exception( self.name + ": Object not as expected" )
1235 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001236 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001237 main.log.error( self.name + ": EOF exception found" )
1238 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001239 main.cleanup()
1240 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001241 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001242 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001243 main.cleanup()
1244 main.exit()
1245
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001247 self,
shahshreyac2f97072015-03-19 17:04:29 -07001248 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001250 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001251 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001252 ethType="",
1253 ethSrc="",
1254 ethDst="",
1255 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001257 ipProto="",
1258 ipSrc="",
1259 ipDst="",
1260 tcpSrc="",
1261 tcpDst="",
1262 setEthSrc="",
1263 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001264 """
shahshreyad0c80432014-12-04 16:56:05 -08001265 Note:
shahshreya70622b12015-03-19 17:19:00 -07001266 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001267 is same. That is, all ingress devices include port numbers
1268 with a "/" or all ingress devices could specify device
1269 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001270 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001271 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001272 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001274 Optional:
1275 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001276 * ethSrc: specify ethSrc ( i.e. src mac addr )
1277 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001278 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001280 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001281 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001282 * ipSrc: specify ip source address
1283 * ipDst: specify ip destination address
1284 * tcpSrc: specify tcp source port
1285 * tcpDst: specify tcp destination port
1286 * setEthSrc: action to Rewrite Source MAC Address
1287 * setEthDst: action to Rewrite Destination MAC Address
1288 Description:
kelvin8ec71442015-01-15 16:57:00 -08001289 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001290 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 Returns:
1292 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001293
Jon Halle3f39ff2015-01-13 11:50:53 -08001294 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001295 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001296 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001297 """
shahshreyad0c80432014-12-04 16:56:05 -08001298 try:
kelvin8ec71442015-01-15 16:57:00 -08001299 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001300 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 and not ipProto and not ipSrc and not ipDst\
1303 and not tcpSrc and not tcpDst and not setEthSrc\
1304 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001305 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001306
1307 else:
1308 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001309
shahshreyad0c80432014-12-04 16:56:05 -08001310 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001311 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001312 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001313 cmd += " --ethSrc " + str( ethSrc )
1314 if ethDst:
1315 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001316 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001317 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001319 cmd += " --lambda "
1320 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001321 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001322 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001323 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001324 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001325 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001326 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001327 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001328 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001329 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001330 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001331 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001332 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001333 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001334
kelvin8ec71442015-01-15 16:57:00 -08001335 # Check whether the user appended the port
1336 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001337
1338 if portIngressList is None:
1339 for ingressDevice in ingressDeviceList:
1340 if "/" in ingressDevice:
1341 cmd += " " + str( ingressDevice )
1342 else:
1343 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001344 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001345 # TODO: perhaps more meaningful return
1346 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001347 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001348 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001349 for ingressDevice, portIngress in zip( ingressDeviceList,
1350 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001351 cmd += " " + \
1352 str( ingressDevice ) + "/" +\
1353 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001354 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001355 main.log.error( "Device list and port list does not " +
1356 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001357 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 if "/" in egressDevice:
1359 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001360 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001361 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001362 main.log.error( "You must specify " +
1363 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001364 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001365
kelvin8ec71442015-01-15 16:57:00 -08001366 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 str( egressDevice ) + "/" +\
1368 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001369 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001371 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001372 main.log.error( "Error in adding multipoint-to-singlepoint " +
1373 "intent" )
1374 return None
shahshreyad0c80432014-12-04 16:56:05 -08001375 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001376 match = re.search('id=0x([\da-f]+),', handle)
1377 if match:
1378 return match.group()[3:-1]
1379 else:
1380 main.log.error( "Error, intent ID not found" )
1381 return None
1382 except TypeError:
1383 main.log.exception( self.name + ": Object not as expected" )
1384 return None
1385 except pexpect.EOF:
1386 main.log.error( self.name + ": EOF exception found" )
1387 main.log.error( self.name + ": " + self.handle.before )
1388 main.cleanup()
1389 main.exit()
1390 except Exception:
1391 main.log.exception( self.name + ": Uncaught exception!" )
1392 main.cleanup()
1393 main.exit()
1394
1395 def addSinglepointToMultipointIntent(
1396 self,
1397 ingressDevice,
1398 egressDeviceList,
1399 portIngress="",
1400 portEgressList=None,
1401 ethType="",
1402 ethSrc="",
1403 ethDst="",
1404 bandwidth="",
1405 lambdaAlloc=False,
1406 ipProto="",
1407 ipSrc="",
1408 ipDst="",
1409 tcpSrc="",
1410 tcpDst="",
1411 setEthSrc="",
1412 setEthDst="" ):
1413 """
1414 Note:
1415 This function assumes the format of all egress devices
1416 is same. That is, all egress devices include port numbers
1417 with a "/" or all egress devices could specify device
1418 ids and port numbers seperately.
1419 Required:
1420 * EgressDeviceList: List of device ids of egress device
1421 ( Atleast 2 eress devices required in the list )
1422 * ingressDevice: device id of ingress device
1423 Optional:
1424 * ethType: specify ethType
1425 * ethSrc: specify ethSrc ( i.e. src mac addr )
1426 * ethDst: specify ethDst ( i.e. dst mac addr )
1427 * bandwidth: specify bandwidth capacity of link
1428 * lambdaAlloc: if True, intent will allocate lambda
1429 for the specified intent
1430 * ipProto: specify ip protocol
1431 * ipSrc: specify ip source address
1432 * ipDst: specify ip destination address
1433 * tcpSrc: specify tcp source port
1434 * tcpDst: specify tcp destination port
1435 * setEthSrc: action to Rewrite Source MAC Address
1436 * setEthDst: action to Rewrite Destination MAC Address
1437 Description:
1438 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1439 specifying device id's and optional fields
1440 Returns:
1441 A string of the intent id or None on error
1442
1443 NOTE: This function may change depending on the
1444 options developers provide for singlepoint-to-multipoint
1445 intent via cli
1446 """
1447 try:
1448 # If there are no optional arguments
1449 if not ethType and not ethSrc and not ethDst\
1450 and not bandwidth and not lambdaAlloc\
1451 and not ipProto and not ipSrc and not ipDst\
1452 and not tcpSrc and not tcpDst and not setEthSrc\
1453 and not setEthDst:
1454 cmd = "add-single-to-multi-intent"
1455
1456 else:
1457 cmd = "add-single-to-multi-intent"
1458
1459 if ethType:
1460 cmd += " --ethType " + str( ethType )
1461 if ethSrc:
1462 cmd += " --ethSrc " + str( ethSrc )
1463 if ethDst:
1464 cmd += " --ethDst " + str( ethDst )
1465 if bandwidth:
1466 cmd += " --bandwidth " + str( bandwidth )
1467 if lambdaAlloc:
1468 cmd += " --lambda "
1469 if ipProto:
1470 cmd += " --ipProto " + str( ipProto )
1471 if ipSrc:
1472 cmd += " --ipSrc " + str( ipSrc )
1473 if ipDst:
1474 cmd += " --ipDst " + str( ipDst )
1475 if tcpSrc:
1476 cmd += " --tcpSrc " + str( tcpSrc )
1477 if tcpDst:
1478 cmd += " --tcpDst " + str( tcpDst )
1479 if setEthSrc:
1480 cmd += " --setEthSrc " + str( setEthSrc )
1481 if setEthDst:
1482 cmd += " --setEthDst " + str( setEthDst )
1483
1484 # Check whether the user appended the port
1485 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001486
kelvin-onlabb9408212015-04-01 13:34:04 -07001487 if "/" in ingressDevice:
1488 cmd += " " + str( ingressDevice )
1489 else:
1490 if not portIngress:
1491 main.log.error( "You must specify " +
1492 "the Ingress port" )
1493 return main.FALSE
1494
1495 cmd += " " +\
1496 str( ingressDevice ) + "/" +\
1497 str( portIngress )
1498
1499 if portEgressList is None:
1500 for egressDevice in egressDeviceList:
1501 if "/" in egressDevice:
1502 cmd += " " + str( egressDevice )
1503 else:
1504 main.log.error( "You must specify " +
1505 "the egress port" )
1506 # TODO: perhaps more meaningful return
1507 return main.FALSE
1508 else:
1509 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001510 for egressDevice, portEgress in zip( egressDeviceList,
1511 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001512 cmd += " " + \
1513 str( egressDevice ) + "/" +\
1514 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001515 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001516 main.log.error( "Device list and port list does not " +
1517 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001518 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001519 handle = self.sendline( cmd )
1520 # If error, return error message
1521 if re.search( "Error", handle ):
1522 main.log.error( "Error in adding singlepoint-to-multipoint " +
1523 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001524 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001525 else:
1526 match = re.search('id=0x([\da-f]+),', handle)
1527 if match:
1528 return match.group()[3:-1]
1529 else:
1530 main.log.error( "Error, intent ID not found" )
1531 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001532 except TypeError:
1533 main.log.exception( self.name + ": Object not as expected" )
1534 return None
shahshreyad0c80432014-12-04 16:56:05 -08001535 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001536 main.log.error( self.name + ": EOF exception found" )
1537 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001538 main.cleanup()
1539 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001540 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001541 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001542 main.cleanup()
1543 main.exit()
1544
Hari Krishna9e232602015-04-13 17:29:08 -07001545 def addMplsIntent(
1546 self,
1547 ingressDevice,
1548 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001549 ingressPort="",
1550 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001551 ethType="",
1552 ethSrc="",
1553 ethDst="",
1554 bandwidth="",
1555 lambdaAlloc=False,
1556 ipProto="",
1557 ipSrc="",
1558 ipDst="",
1559 tcpSrc="",
1560 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001561 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001562 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001563 priority=""):
1564 """
1565 Required:
1566 * ingressDevice: device id of ingress device
1567 * egressDevice: device id of egress device
1568 Optional:
1569 * ethType: specify ethType
1570 * ethSrc: specify ethSrc ( i.e. src mac addr )
1571 * ethDst: specify ethDst ( i.e. dst mac addr )
1572 * bandwidth: specify bandwidth capacity of link
1573 * lambdaAlloc: if True, intent will allocate lambda
1574 for the specified intent
1575 * ipProto: specify ip protocol
1576 * ipSrc: specify ip source address
1577 * ipDst: specify ip destination address
1578 * tcpSrc: specify tcp source port
1579 * tcpDst: specify tcp destination port
1580 * ingressLabel: Ingress MPLS label
1581 * egressLabel: Egress MPLS label
1582 Description:
1583 Adds MPLS intent by
1584 specifying device id's and optional fields
1585 Returns:
1586 A string of the intent id or None on error
1587
1588 NOTE: This function may change depending on the
1589 options developers provide for MPLS
1590 intent via cli
1591 """
1592 try:
1593 # If there are no optional arguments
1594 if not ethType and not ethSrc and not ethDst\
1595 and not bandwidth and not lambdaAlloc \
1596 and not ipProto and not ipSrc and not ipDst \
1597 and not tcpSrc and not tcpDst and not ingressLabel \
1598 and not egressLabel:
1599 cmd = "add-mpls-intent"
1600
1601 else:
1602 cmd = "add-mpls-intent"
1603
1604 if ethType:
1605 cmd += " --ethType " + str( ethType )
1606 if ethSrc:
1607 cmd += " --ethSrc " + str( ethSrc )
1608 if ethDst:
1609 cmd += " --ethDst " + str( ethDst )
1610 if bandwidth:
1611 cmd += " --bandwidth " + str( bandwidth )
1612 if lambdaAlloc:
1613 cmd += " --lambda "
1614 if ipProto:
1615 cmd += " --ipProto " + str( ipProto )
1616 if ipSrc:
1617 cmd += " --ipSrc " + str( ipSrc )
1618 if ipDst:
1619 cmd += " --ipDst " + str( ipDst )
1620 if tcpSrc:
1621 cmd += " --tcpSrc " + str( tcpSrc )
1622 if tcpDst:
1623 cmd += " --tcpDst " + str( tcpDst )
1624 if ingressLabel:
1625 cmd += " --ingressLabel " + str( ingressLabel )
1626 if egressLabel:
1627 cmd += " --egressLabel " + str( egressLabel )
1628 if priority:
1629 cmd += " --priority " + str( priority )
1630
1631 # Check whether the user appended the port
1632 # or provided it as an input
1633 if "/" in ingressDevice:
1634 cmd += " " + str( ingressDevice )
1635 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001636 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001637 main.log.error( "You must specify the ingress port" )
1638 return None
1639
1640 cmd += " " + \
1641 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001642 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001643
1644 if "/" in egressDevice:
1645 cmd += " " + str( egressDevice )
1646 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001647 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001648 main.log.error( "You must specify the egress port" )
1649 return None
1650
1651 cmd += " " +\
1652 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001653 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001654
1655 handle = self.sendline( cmd )
1656 # If error, return error message
1657 if re.search( "Error", handle ):
1658 main.log.error( "Error in adding mpls intent" )
1659 return None
1660 else:
1661 # TODO: print out all the options in this message?
1662 main.log.info( "MPLS intent installed between " +
1663 str( ingressDevice ) + " and " +
1664 str( egressDevice ) )
1665 match = re.search('id=0x([\da-f]+),', handle)
1666 if match:
1667 return match.group()[3:-1]
1668 else:
1669 main.log.error( "Error, intent ID not found" )
1670 return None
1671 except TypeError:
1672 main.log.exception( self.name + ": Object not as expected" )
1673 return None
1674 except pexpect.EOF:
1675 main.log.error( self.name + ": EOF exception found" )
1676 main.log.error( self.name + ": " + self.handle.before )
1677 main.cleanup()
1678 main.exit()
1679 except Exception:
1680 main.log.exception( self.name + ": Uncaught exception!" )
1681 main.cleanup()
1682 main.exit()
1683
Jon Hallefbd9792015-03-05 16:11:36 -08001684 def removeIntent( self, intentId, app='org.onosproject.cli',
1685 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001686 """
shahshreya1c818fc2015-02-26 13:44:08 -08001687 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001688 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001689 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001690 -p or --purge: Purge the intent from the store after removal
1691
Jon Halle3f39ff2015-01-13 11:50:53 -08001692 Returns:
1693 main.False on error and
1694 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001695 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001696 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001697 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001698 if purge:
1699 cmdStr += " -p"
1700 if sync:
1701 cmdStr += " -s"
1702
1703 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001704 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001705 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001706 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001707 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001708 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001709 # TODO: Should this be main.TRUE
1710 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001711 except TypeError:
1712 main.log.exception( self.name + ": Object not as expected" )
1713 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001715 main.log.error( self.name + ": EOF exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001717 main.cleanup()
1718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001720 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001721 main.cleanup()
1722 main.exit()
1723
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001724 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001725 """
1726 Purges all WITHDRAWN Intents
1727 """
1728 try:
1729 cmdStr = "purge-intents"
1730 handle = self.sendline( cmdStr )
1731 if re.search( "Error", handle ):
1732 main.log.error( "Error in purging intents" )
1733 return main.FALSE
1734 else:
1735 return main.TRUE
1736 except TypeError:
1737 main.log.exception( self.name + ": Object not as expected" )
1738 return None
1739 except pexpect.EOF:
1740 main.log.error( self.name + ": EOF exception found" )
1741 main.log.error( self.name + ": " + self.handle.before )
1742 main.cleanup()
1743 main.exit()
1744 except Exception:
1745 main.log.exception( self.name + ": Uncaught exception!" )
1746 main.cleanup()
1747 main.exit()
1748
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001750 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001751 NOTE: This method should be used after installing application:
1752 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001753 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001754 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001755 Description:
1756 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001757 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001758 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001759 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001760 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001761 cmdStr += " -j"
1762 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001763 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001764 except TypeError:
1765 main.log.exception( self.name + ": Object not as expected" )
1766 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001768 main.log.error( self.name + ": EOF exception found" )
1769 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001770 main.cleanup()
1771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001773 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001774 main.cleanup()
1775 main.exit()
1776
pingping-lin54b03372015-08-13 14:43:10 -07001777 def ipv4RouteNumber( self ):
1778 """
1779 NOTE: This method should be used after installing application:
1780 onos-app-sdnip
1781 Description:
1782 Obtain the total IPv4 routes number in the system
1783 """
1784 try:
1785 cmdStr = "routes -s -j"
1786 handle = self.sendline( cmdStr )
1787 jsonResult = json.loads( handle )
1788 return jsonResult['totalRoutes4']
1789
1790 except TypeError:
1791 main.log.exception( self.name + ": Object not as expected" )
1792 return None
1793 except pexpect.EOF:
1794 main.log.error( self.name + ": EOF exception found" )
1795 main.log.error( self.name + ": " + self.handle.before )
1796 main.cleanup()
1797 main.exit()
1798 except Exception:
1799 main.log.exception( self.name + ": Uncaught exception!" )
1800 main.cleanup()
1801 main.exit()
1802
pingping-lin8244a3b2015-09-16 13:36:56 -07001803 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001804 """
andrewonlab377693f2014-10-21 16:00:30 -04001805 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 * jsonFormat: enable output formatting in json
pingping-lin8244a3b2015-09-16 13:36:56 -07001807 * summary: whether only output the intent summary
1808 * type: only output a certain type of intent
1809 This options is valid only when jsonFormat is true and summary is
1810 true
andrewonlabe6745342014-10-17 14:29:13 -04001811 Description:
pingping-lin8244a3b2015-09-16 13:36:56 -07001812 Obtain intents
kelvin-onlab898a6c62015-01-16 14:13:53 -08001813 """
andrewonlabe6745342014-10-17 14:29:13 -04001814 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001815 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001816 if summary:
1817 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001819 cmdStr += " -j"
1820 handle = self.sendline( cmdStr )
pingping-lin8244a3b2015-09-16 13:36:56 -07001821 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001822 if "TYPE" in args.keys():
1823 type = args[ "TYPE" ]
1824 else:
1825 type = ""
pingping-lin8244a3b2015-09-16 13:36:56 -07001826 if jsonFormat and summary and ( type != "" ):
1827 jsonResult = json.loads( handle )
1828 if type in jsonResult.keys():
1829 return jsonResult[ type ]
1830 else:
1831 main.log.error( "unknown TYPE, return all types of intents" )
1832 return handle
1833 else:
1834 return handle
pingping-lin54b03372015-08-13 14:43:10 -07001835
1836 except TypeError:
1837 main.log.exception( self.name + ": Object not as expected" )
1838 return None
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
1842 main.cleanup()
1843 main.exit()
1844 except Exception:
1845 main.log.exception( self.name + ": Uncaught exception!" )
1846 main.cleanup()
1847 main.exit()
1848
pingping-lin8244a3b2015-09-16 13:36:56 -07001849
kelvin-onlab54400a92015-02-26 18:05:51 -08001850 def getIntentState(self, intentsId, intentsJson=None):
1851 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001852 Check intent state.
1853 Accepts a single intent ID (string type) or a list of intent IDs.
1854 Returns the state(string type) of the id if a single intent ID is
1855 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001856 Returns a dictionary with intent IDs as the key and its
1857 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001858 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001859 intentId: intent ID (string type)
1860 intentsJson: parsed json object from the onos:intents api
1861 Returns:
1862 state = An intent's state- INSTALL,WITHDRAWN etc.
1863 stateDict = Dictionary of intent's state. intent ID as the keys and
1864 state as the values.
1865 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001866 try:
1867 state = "State is Undefined"
1868 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001869 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001870 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001871 intentsJsonTemp = json.loads( intentsJson )
1872 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001873 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001874 if intentsId == intent[ 'id' ]:
1875 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001876 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001877 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1878 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001879 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001880 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001881 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001882 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001883 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001884 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001885 if intentsId[ i ] == intents[ 'id' ]:
1886 stateDict[ 'state' ] = intents[ 'state' ]
1887 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001888 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001889 break
Jon Hallefbd9792015-03-05 16:11:36 -08001890 if len( intentsId ) != len( dictList ):
1891 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001892 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001893 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001894 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001895 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001896 except TypeError:
1897 main.log.exception( self.name + ": Object not as expected" )
1898 return None
1899 except pexpect.EOF:
1900 main.log.error( self.name + ": EOF exception found" )
1901 main.log.error( self.name + ": " + self.handle.before )
1902 main.cleanup()
1903 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001904 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001905 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001906 main.cleanup()
1907 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001908
kelvin-onlabf512e942015-06-08 19:42:59 -07001909 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001910 """
1911 Description:
1912 Check intents state
1913 Required:
1914 intentsId - List of intents ID to be checked
1915 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001916 expectedState - Check the expected state(s) of each intents
1917 state in the list.
1918 *NOTE: You can pass in a list of expected state,
1919 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001920 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001921 Returns main.TRUE only if all intent are the same as expected states
1922 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001923 """
1924 try:
1925 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001926 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001927 intentsDict = self.getIntentState( intentsId )
kelvin-onlabf512e942015-06-08 19:42:59 -07001928
Jon Hall390696c2015-05-05 17:13:41 -07001929 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001930 if len( intentsId ) != len( intentsDict ):
1931 main.log.info( self.name + "There is something wrong " +
1932 "getting intents state" )
1933 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001934
1935 if isinstance( expectedState, types.StringType ):
1936 for intents in intentsDict:
1937 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001938 main.log.debug( self.name + " : Intent ID - " +
1939 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001940 " actual state = " +
1941 intents.get( 'state' )
1942 + " does not equal expected state = "
1943 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001944 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001945
1946 elif isinstance( expectedState, types.ListType ):
1947 for intents in intentsDict:
1948 if not any( state == intents.get( 'state' ) for state in
1949 expectedState ):
1950 main.log.debug( self.name + " : Intent ID - " +
1951 intents.get( 'id' ) +
1952 " actual state = " +
1953 intents.get( 'state' ) +
1954 " does not equal expected states = "
1955 + str( expectedState ) )
1956 returnValue = main.FALSE
1957
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001958 if returnValue == main.TRUE:
1959 main.log.info( self.name + ": All " +
1960 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001961 " intents are in " + str( expectedState ) +
1962 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001963 return returnValue
1964 except TypeError:
1965 main.log.exception( self.name + ": Object not as expected" )
1966 return None
1967 except pexpect.EOF:
1968 main.log.error( self.name + ": EOF exception found" )
1969 main.log.error( self.name + ": " + self.handle.before )
1970 main.cleanup()
1971 main.exit()
1972 except Exception:
1973 main.log.exception( self.name + ": Uncaught exception!" )
1974 main.cleanup()
1975 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04001976
kelvin-onlabd3b64892015-01-20 13:26:24 -08001977 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001978 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001979 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001980 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001981 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001982 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001983 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001984 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001985 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001986 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001987 cmdStr += " -j"
1988 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001989 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001990 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001991 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001992 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001993 except TypeError:
1994 main.log.exception( self.name + ": Object not as expected" )
1995 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001996 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001997 main.log.error( self.name + ": EOF exception found" )
1998 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001999 main.cleanup()
2000 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002001 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002002 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002003 main.cleanup()
2004 main.exit()
2005
pingping-linbab7f8a2015-09-21 17:33:36 -07002006 def checkFlowsState( self, isPENDING_ADD = True ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002007 """
2008 Description:
2009 Check the if all the current flows are in ADDED state or
2010 PENDING_ADD state
pingping-linbab7f8a2015-09-21 17:33:36 -07002011 Optional:
2012 * isPENDING_ADD: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002013 Return:
2014 returnValue - Returns main.TRUE only if all flows are in
pingping-linbab7f8a2015-09-21 17:33:36 -07002015 ADDED state or PENDING_ADD if the PENDING_ADD
2016 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002017 """
2018 try:
2019 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07002020 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07002021 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002022
pingping-linbab7f8a2015-09-21 17:33:36 -07002023 if isPENDING_ADD:
2024 for device in tempFlows:
2025 for flow in device.get( 'flows' ):
2026 if flow.get( 'state' ) != 'ADDED' and \
2027 flow.get( 'state' ) != 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002028
pingping-linbab7f8a2015-09-21 17:33:36 -07002029 main.log.info( self.name + ": flow Id: " +
2030 str( flow.get( 'groupId' ) ) +
2031 " | state:" +
2032 str( flow.get( 'state' ) ) )
2033 returnValue = main.FALSE
2034 else:
2035 for device in tempFlows:
2036 for flow in device.get( 'flows' ):
2037 if flow.get( 'state' ) != 'ADDED':
2038
2039 main.log.info( self.name + ": flow Id: " +
2040 str( flow.get( 'groupId' ) ) +
2041 " | state:" +
2042 str( flow.get( 'state' ) ) )
2043 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002044
kelvin-onlab4df89f22015-04-13 18:10:23 -07002045 return returnValue
2046 except TypeError:
2047 main.log.exception( self.name + ": Object not as expected" )
2048 return None
2049 except pexpect.EOF:
2050 main.log.error( self.name + ": EOF exception found" )
2051 main.log.error( self.name + ": " + self.handle.before )
2052 main.cleanup()
2053 main.exit()
2054 except Exception:
2055 main.log.exception( self.name + ": Uncaught exception!" )
2056 main.cleanup()
2057 main.exit()
2058
kelvin-onlabd3b64892015-01-20 13:26:24 -08002059 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08002060 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08002061 """
andrewonlab87852b02014-11-19 18:44:19 -05002062 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002063 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002064 a specific point-to-point intent definition
2065 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002066 * dpidSrc: specify source dpid
2067 * dpidDst: specify destination dpid
2068 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002069 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002070 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05002071 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08002072 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05002073 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05002074 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08002075 """
andrewonlab87852b02014-11-19 18:44:19 -05002076 try:
kelvin8ec71442015-01-15 16:57:00 -08002077 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08002078 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
2079 str( numIntents )
2080 if numMult:
2081 cmd += " " + str( numMult )
2082 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08002083 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08002084 if appId:
2085 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002086 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05002087 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002088 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08002089 main.log.info( handle )
2090 # Split result by newline
2091 newline = handle.split( "\r\r\n" )
2092 # Ignore the first object of list, which is empty
2093 newline = newline[ 1: ]
2094 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05002095 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08002096 result = result.split( ": " )
2097 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08002098 latResult.append( result[ 1 ].split( " " )[ 0 ] )
2099 main.log.info( latResult )
2100 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05002101 else:
2102 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08002103 except TypeError:
2104 main.log.exception( self.name + ": Object not as expected" )
2105 return None
andrewonlab87852b02014-11-19 18:44:19 -05002106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002107 main.log.error( self.name + ": EOF exception found" )
2108 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002109 main.cleanup()
2110 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002112 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002113 main.cleanup()
2114 main.exit()
2115
kelvin-onlabd3b64892015-01-20 13:26:24 -08002116 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002117 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002118 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002119 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002120 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002121 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002122 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002123 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002124 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002125 cmdStr += " -j"
2126 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002127 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002128 except TypeError:
2129 main.log.exception( self.name + ": Object not as expected" )
2130 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002132 main.log.error( self.name + ": EOF exception found" )
2133 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002134 main.cleanup()
2135 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002137 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002138 main.cleanup()
2139 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002140
kelvin-onlabd3b64892015-01-20 13:26:24 -08002141 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002142 """
2143 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002144 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002145 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002146 """
andrewonlab867212a2014-10-22 20:13:38 -04002147 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002148 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002149 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002150 cmdStr += " -j"
2151 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002152 if handle:
2153 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002154 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002155 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002156 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002157 else:
2158 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002159 except TypeError:
2160 main.log.exception( self.name + ": Object not as expected" )
2161 return None
andrewonlab867212a2014-10-22 20:13:38 -04002162 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002163 main.log.error( self.name + ": EOF exception found" )
2164 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002165 main.cleanup()
2166 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002167 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002168 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002169 main.cleanup()
2170 main.exit()
2171
kelvin8ec71442015-01-15 16:57:00 -08002172 # Wrapper functions ****************
2173 # Wrapper functions use existing driver
2174 # functions and extends their use case.
2175 # For example, we may use the output of
2176 # a normal driver function, and parse it
2177 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002178
kelvin-onlabd3b64892015-01-20 13:26:24 -08002179 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002180 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002181 Description:
2182 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002183 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002184 try:
kelvin8ec71442015-01-15 16:57:00 -08002185 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002186 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002187 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002188
kelvin8ec71442015-01-15 16:57:00 -08002189 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2191 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002192 match = re.search('id=0x([\da-f]+),', intents)
2193 if match:
2194 tmpId = match.group()[3:-1]
2195 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002196 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002197
Jon Halld4d4b372015-01-28 16:02:41 -08002198 except TypeError:
2199 main.log.exception( self.name + ": Object not as expected" )
2200 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002202 main.log.error( self.name + ": EOF exception found" )
2203 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002204 main.cleanup()
2205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002208 main.cleanup()
2209 main.exit()
2210
Jon Hall30b82fa2015-03-04 17:15:43 -08002211 def FlowAddedCount( self, deviceId ):
2212 """
2213 Determine the number of flow rules for the given device id that are
2214 in the added state
2215 """
2216 try:
2217 cmdStr = "flows any " + str( deviceId ) + " | " +\
2218 "grep 'state=ADDED' | wc -l"
2219 handle = self.sendline( cmdStr )
2220 return handle
2221 except pexpect.EOF:
2222 main.log.error( self.name + ": EOF exception found" )
2223 main.log.error( self.name + ": " + self.handle.before )
2224 main.cleanup()
2225 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002226 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002227 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002228 main.cleanup()
2229 main.exit()
2230
kelvin-onlabd3b64892015-01-20 13:26:24 -08002231 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002232 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002233 Use 'devices' function to obtain list of all devices
2234 and parse the result to obtain a list of all device
2235 id's. Returns this list. Returns empty list if no
2236 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002237 List is ordered sequentially
2238
andrewonlab3e15ead2014-10-15 14:21:34 -04002239 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002240 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002241 the ids. By obtaining the list of device ids on the fly,
2242 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002243 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002244 try:
kelvin8ec71442015-01-15 16:57:00 -08002245 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002246 devicesStr = self.devices( jsonFormat=False )
2247 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002248
kelvin-onlabd3b64892015-01-20 13:26:24 -08002249 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002250 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002251 return idList
kelvin8ec71442015-01-15 16:57:00 -08002252
2253 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002254 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002255 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002256 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002257 # Split list further into arguments before and after string
2258 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002259 # append to idList
2260 for arg in tempList:
2261 idList.append( arg.split( "id=" )[ 1 ] )
2262 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002263
Jon Halld4d4b372015-01-28 16:02:41 -08002264 except TypeError:
2265 main.log.exception( self.name + ": Object not as expected" )
2266 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002267 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002268 main.log.error( self.name + ": EOF exception found" )
2269 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002270 main.cleanup()
2271 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002272 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002273 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002274 main.cleanup()
2275 main.exit()
2276
kelvin-onlabd3b64892015-01-20 13:26:24 -08002277 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002278 """
andrewonlab7c211572014-10-15 16:45:20 -04002279 Uses 'nodes' function to obtain list of all nodes
2280 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002281 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002282 Returns:
2283 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002284 """
andrewonlab7c211572014-10-15 16:45:20 -04002285 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002286 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002287 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002288 # Sample nodesStr output
2289 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002291 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002293 nodesJson = json.loads( nodesStr )
2294 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002295 return idList
kelvin8ec71442015-01-15 16:57:00 -08002296
Jon Halld4d4b372015-01-28 16:02:41 -08002297 except TypeError:
2298 main.log.exception( self.name + ": Object not as expected" )
2299 return None
andrewonlab7c211572014-10-15 16:45:20 -04002300 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002301 main.log.error( self.name + ": EOF exception found" )
2302 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002303 main.cleanup()
2304 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002305 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002306 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002307 main.cleanup()
2308 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002309
kelvin-onlabd3b64892015-01-20 13:26:24 -08002310 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002311 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002312 Return the first device from the devices api whose 'id' contains 'dpid'
2313 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002314 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002315 try:
kelvin8ec71442015-01-15 16:57:00 -08002316 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002317 return None
2318 else:
kelvin8ec71442015-01-15 16:57:00 -08002319 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002320 rawDevices = self.devices()
2321 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002322 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002323 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002324 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2325 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002326 return device
2327 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002328 except TypeError:
2329 main.log.exception( self.name + ": Object not as expected" )
2330 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002331 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002332 main.log.error( self.name + ": EOF exception found" )
2333 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002334 main.cleanup()
2335 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002336 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002337 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002338 main.cleanup()
2339 main.exit()
2340
kelvin-onlabd3b64892015-01-20 13:26:24 -08002341 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002342 """
Jon Hallefbd9792015-03-05 16:11:36 -08002343 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002344 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002345 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002346
Jon Hall42db6dc2014-10-24 19:03:48 -04002347 Params: ip = ip used for the onos cli
2348 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002349 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002350 logLevel = level to log to. Currently accepts
2351 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002352
2353
kelvin-onlabd3b64892015-01-20 13:26:24 -08002354 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002355
Jon Hallefbd9792015-03-05 16:11:36 -08002356 Returns: main.TRUE if the number of switches and links are correct,
2357 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002358 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002359 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002360 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002361 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002362 if topology == {}:
2363 return main.ERROR
2364 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002365 # Is the number of switches is what we expected
2366 devices = topology.get( 'devices', False )
2367 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002368 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002369 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002370 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002371 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002372 linkCheck = ( int( links ) == int( numolink ) )
2373 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002374 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002375 output += "The number of links and switches match " +\
2376 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002377 result = main.TRUE
2378 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002379 output += "The number of links and switches does not match " +\
2380 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002381 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002382 output = output + "\n ONOS sees %i devices (%i expected) \
2383 and %i links (%i expected)" % (
2384 int( devices ), int( numoswitch ), int( links ),
2385 int( numolink ) )
2386 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002387 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002388 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002389 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002390 else:
Jon Hall390696c2015-05-05 17:13:41 -07002391 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002392 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002393 except TypeError:
2394 main.log.exception( self.name + ": Object not as expected" )
2395 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002396 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002397 main.log.error( self.name + ": EOF exception found" )
2398 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002399 main.cleanup()
2400 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002401 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002402 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002403 main.cleanup()
2404 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002405
kelvin-onlabd3b64892015-01-20 13:26:24 -08002406 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002407 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002408 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002409 deviceId must be the id of a device as seen in the onos devices command
2410 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002411 role must be either master, standby, or none
2412
Jon Halle3f39ff2015-01-13 11:50:53 -08002413 Returns:
2414 main.TRUE or main.FALSE based on argument verification and
2415 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002416 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002417 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002418 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002419 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002420 cmdStr = "device-role " +\
2421 str( deviceId ) + " " +\
2422 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002423 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002424 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002425 if re.search( "Error", handle ):
2426 # end color output to escape any colours
2427 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002428 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002429 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002430 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002431 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002432 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002433 main.log.error( "Invalid 'role' given to device_role(). " +
2434 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002435 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002436 except TypeError:
2437 main.log.exception( self.name + ": Object not as expected" )
2438 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002440 main.log.error( self.name + ": EOF exception found" )
2441 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002442 main.cleanup()
2443 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002445 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002446 main.cleanup()
2447 main.exit()
2448
kelvin-onlabd3b64892015-01-20 13:26:24 -08002449 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002450 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002451 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002452 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002453 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002454 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002455 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002456 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002458 cmdStr += " -j"
2459 handle = self.sendline( cmdStr )
2460 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002461 except TypeError:
2462 main.log.exception( self.name + ": Object not as expected" )
2463 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002464 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002465 main.log.error( self.name + ": EOF exception found" )
2466 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002467 main.cleanup()
2468 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002469 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002470 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002471 main.cleanup()
2472 main.exit()
2473
kelvin-onlabd3b64892015-01-20 13:26:24 -08002474 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002475 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002476 CLI command to get the current leader for the Election test application
2477 NOTE: Requires installation of the onos-app-election feature
2478 Returns: Node IP of the leader if one exists
2479 None if none exists
2480 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002481 """
Jon Hall94fd0472014-12-08 11:52:42 -08002482 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002483 cmdStr = "election-test-leader"
2484 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002485 # Leader
2486 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002487 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002488 nodeSearch = re.search( leaderPattern, response )
2489 if nodeSearch:
2490 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002491 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002492 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002493 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002494 # no leader
2495 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002496 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002497 nullSearch = re.search( nullPattern, response )
2498 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002499 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002500 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002501 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002502 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002503 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002504 if re.search( errorPattern, response ):
2505 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002506 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002507 return main.FALSE
2508 else:
Jon Hall390696c2015-05-05 17:13:41 -07002509 main.log.error( "Error in electionTestLeader on " + self.name +
2510 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002511 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002512 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002513 except TypeError:
2514 main.log.exception( self.name + ": Object not as expected" )
2515 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002516 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002517 main.log.error( self.name + ": EOF exception found" )
2518 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002519 main.cleanup()
2520 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002521 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002522 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002523 main.cleanup()
2524 main.exit()
2525
kelvin-onlabd3b64892015-01-20 13:26:24 -08002526 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002527 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002528 CLI command to run for leadership of the Election test application.
2529 NOTE: Requires installation of the onos-app-election feature
2530 Returns: Main.TRUE on success
2531 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002532 """
Jon Hall94fd0472014-12-08 11:52:42 -08002533 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002534 cmdStr = "election-test-run"
2535 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002536 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002537 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002538 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002539 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002540 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002541 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002542 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002543 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002544 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002545 errorPattern = "Command\snot\sfound"
2546 if re.search( errorPattern, response ):
2547 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002548 return main.FALSE
2549 else:
Jon Hall390696c2015-05-05 17:13:41 -07002550 main.log.error( "Error in electionTestRun on " + self.name +
2551 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002552 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002553 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002554 except TypeError:
2555 main.log.exception( self.name + ": Object not as expected" )
2556 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002557 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002558 main.log.error( self.name + ": EOF exception found" )
2559 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002560 main.cleanup()
2561 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002562 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002563 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002564 main.cleanup()
2565 main.exit()
2566
kelvin-onlabd3b64892015-01-20 13:26:24 -08002567 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002568 """
Jon Hall94fd0472014-12-08 11:52:42 -08002569 * CLI command to withdraw the local node from leadership election for
2570 * the Election test application.
2571 #NOTE: Requires installation of the onos-app-election feature
2572 Returns: Main.TRUE on success
2573 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002574 """
Jon Hall94fd0472014-12-08 11:52:42 -08002575 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002576 cmdStr = "election-test-withdraw"
2577 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002578 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002579 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002580 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002581 if re.search( successPattern, response ):
2582 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002583 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002584 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002585 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002586 errorPattern = "Command\snot\sfound"
2587 if re.search( errorPattern, response ):
2588 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002589 return main.FALSE
2590 else:
Jon Hall390696c2015-05-05 17:13:41 -07002591 main.log.error( "Error in electionTestWithdraw on " +
2592 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002593 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002594 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002595 except TypeError:
2596 main.log.exception( self.name + ": Object not as expected" )
2597 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002598 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002599 main.log.error( self.name + ": EOF exception found" )
2600 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002601 main.cleanup()
2602 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002603 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002604 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002605 main.cleanup()
2606 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002607
kelvin8ec71442015-01-15 16:57:00 -08002608 def getDevicePortsEnabledCount( self, dpid ):
2609 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002610 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002611 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002612 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002613 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002614 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2615 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002616 if re.search( "No such device", output ):
2617 main.log.error( "Error in getting ports" )
2618 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002619 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002620 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002621 except TypeError:
2622 main.log.exception( self.name + ": Object not as expected" )
2623 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002624 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002625 main.log.error( self.name + ": EOF exception found" )
2626 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002627 main.cleanup()
2628 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002629 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002630 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002631 main.cleanup()
2632 main.exit()
2633
kelvin8ec71442015-01-15 16:57:00 -08002634 def getDeviceLinksActiveCount( self, dpid ):
2635 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002636 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002637 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002638 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002639 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2641 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002642 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002643 main.log.error( "Error in getting ports " )
2644 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002645 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002646 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002647 except TypeError:
2648 main.log.exception( self.name + ": Object not as expected" )
2649 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002650 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002651 main.log.error( self.name + ": EOF exception found" )
2652 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002653 main.cleanup()
2654 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002655 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002656 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002657 main.cleanup()
2658 main.exit()
2659
kelvin8ec71442015-01-15 16:57:00 -08002660 def getAllIntentIds( self ):
2661 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002662 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002663 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002664 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002665 cmdStr = "onos:intents | grep id="
2666 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002667 if re.search( "Error", output ):
2668 main.log.error( "Error in getting ports" )
2669 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002670 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002671 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002672 except TypeError:
2673 main.log.exception( self.name + ": Object not as expected" )
2674 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002675 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002676 main.log.error( self.name + ": EOF exception found" )
2677 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002678 main.cleanup()
2679 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002680 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002681 main.log.exception( self.name + ": Uncaught exception!" )
2682 main.cleanup()
2683 main.exit()
2684
Jon Hall73509952015-02-24 16:42:56 -08002685 def intentSummary( self ):
2686 """
Jon Hallefbd9792015-03-05 16:11:36 -08002687 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002688 """
2689 try:
2690 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002691 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002692 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002693 states.append( intent.get( 'state', None ) )
2694 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002695 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002696 return dict( out )
2697 except TypeError:
2698 main.log.exception( self.name + ": Object not as expected" )
2699 return None
2700 except pexpect.EOF:
2701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
2703 main.cleanup()
2704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002705 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002706 main.log.exception( self.name + ": Uncaught exception!" )
2707 main.cleanup()
2708 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002709
Jon Hall61282e32015-03-19 11:34:11 -07002710 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002711 """
2712 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002713 Optional argument:
2714 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002715 """
Jon Hall63604932015-02-26 17:09:50 -08002716 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002717 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002718 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002719 cmdStr += " -j"
2720 output = self.sendline( cmdStr )
2721 return output
Jon Hall63604932015-02-26 17:09:50 -08002722 except TypeError:
2723 main.log.exception( self.name + ": Object not as expected" )
2724 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002725 except pexpect.EOF:
2726 main.log.error( self.name + ": EOF exception found" )
2727 main.log.error( self.name + ": " + self.handle.before )
2728 main.cleanup()
2729 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002730 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002731 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002732 main.cleanup()
2733 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002734
acsmarsa4a4d1e2015-07-10 16:01:24 -07002735 def leaderCandidates( self, jsonFormat=True ):
2736 """
2737 Returns the output of the leaders -c command.
2738 Optional argument:
2739 * jsonFormat - boolean indicating if you want output in json
2740 """
2741 try:
2742 cmdStr = "onos:leaders -c"
2743 if jsonFormat:
2744 cmdStr += " -j"
2745 output = self.sendline( cmdStr )
2746 return output
2747 except TypeError:
2748 main.log.exception( self.name + ": Object not as expected" )
2749 return None
2750 except pexpect.EOF:
2751 main.log.error( self.name + ": EOF exception found" )
2752 main.log.error( self.name + ": " + self.handle.before )
2753 main.cleanup()
2754 main.exit()
2755 except Exception:
2756 main.log.exception( self.name + ": Uncaught exception!" )
2757 main.cleanup()
2758 main.exit()
2759
2760 def specificLeaderCandidate(self,topic):
2761 """
2762 Returns a list in format [leader,candidate1,candidate2,...] for a given
2763 topic parameter and an empty list if the topic doesn't exist
2764 If no leader is elected leader in the returned list will be "none"
2765 Returns None if there is a type error processing the json object
2766 """
2767 try:
2768 cmdStr = "onos:leaders -c -j"
2769 output = self.sendline( cmdStr )
2770 output = json.loads(output)
2771 results = []
2772 for dict in output:
2773 if dict["topic"] == topic:
2774 leader = dict["leader"]
2775 candidates = re.split(", ",dict["candidates"][1:-1])
2776 results.append(leader)
2777 results.extend(candidates)
2778 return results
2779 except TypeError:
2780 main.log.exception( self.name + ": Object not as expected" )
2781 return None
2782 except pexpect.EOF:
2783 main.log.error( self.name + ": EOF exception found" )
2784 main.log.error( self.name + ": " + self.handle.before )
2785 main.cleanup()
2786 main.exit()
2787 except Exception:
2788 main.log.exception( self.name + ": Uncaught exception!" )
2789 main.cleanup()
2790 main.exit()
2791
Jon Hall61282e32015-03-19 11:34:11 -07002792 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002793 """
2794 Returns the output of the intent Pending map.
2795 """
Jon Hall63604932015-02-26 17:09:50 -08002796 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002797 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002798 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002799 cmdStr += " -j"
2800 output = self.sendline( cmdStr )
2801 return output
Jon Hall63604932015-02-26 17:09:50 -08002802 except TypeError:
2803 main.log.exception( self.name + ": Object not as expected" )
2804 return None
2805 except pexpect.EOF:
2806 main.log.error( self.name + ": EOF exception found" )
2807 main.log.error( self.name + ": " + self.handle.before )
2808 main.cleanup()
2809 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002810 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002811 main.log.exception( self.name + ": Uncaught exception!" )
2812 main.cleanup()
2813 main.exit()
2814
Jon Hall61282e32015-03-19 11:34:11 -07002815 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002816 """
2817 Returns the output of the raft partitions command for ONOS.
2818 """
Jon Hall61282e32015-03-19 11:34:11 -07002819 # Sample JSON
2820 # {
2821 # "leader": "tcp://10.128.30.11:7238",
2822 # "members": [
2823 # "tcp://10.128.30.11:7238",
2824 # "tcp://10.128.30.17:7238",
2825 # "tcp://10.128.30.13:7238",
2826 # ],
2827 # "name": "p1",
2828 # "term": 3
2829 # },
Jon Hall63604932015-02-26 17:09:50 -08002830 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002831 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002832 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002833 cmdStr += " -j"
2834 output = self.sendline( cmdStr )
2835 return output
Jon Hall63604932015-02-26 17:09:50 -08002836 except TypeError:
2837 main.log.exception( self.name + ": Object not as expected" )
2838 return None
2839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
2842 main.cleanup()
2843 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002844 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002845 main.log.exception( self.name + ": Uncaught exception!" )
2846 main.cleanup()
2847 main.exit()
2848
Jon Hallbe379602015-03-24 13:39:32 -07002849 def apps( self, jsonFormat=True ):
2850 """
2851 Returns the output of the apps command for ONOS. This command lists
2852 information about installed ONOS applications
2853 """
2854 # Sample JSON object
2855 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2856 # "description":"ONOS OpenFlow protocol southbound providers",
2857 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2858 # "features":"[onos-openflow]","state":"ACTIVE"}]
2859 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002860 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002861 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002862 cmdStr += " -j"
2863 output = self.sendline( cmdStr )
2864 assert "Error executing command" not in output
2865 return output
Jon Hallbe379602015-03-24 13:39:32 -07002866 # FIXME: look at specific exceptions/Errors
2867 except AssertionError:
2868 main.log.error( "Error in processing onos:app command: " +
2869 str( output ) )
2870 return None
2871 except TypeError:
2872 main.log.exception( self.name + ": Object not as expected" )
2873 return None
2874 except pexpect.EOF:
2875 main.log.error( self.name + ": EOF exception found" )
2876 main.log.error( self.name + ": " + self.handle.before )
2877 main.cleanup()
2878 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002879 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002880 main.log.exception( self.name + ": Uncaught exception!" )
2881 main.cleanup()
2882 main.exit()
2883
Jon Hall146f1522015-03-24 15:33:24 -07002884 def appStatus( self, appName ):
2885 """
2886 Uses the onos:apps cli command to return the status of an application.
2887 Returns:
2888 "ACTIVE" - If app is installed and activated
2889 "INSTALLED" - If app is installed and deactivated
2890 "UNINSTALLED" - If app is not installed
2891 None - on error
2892 """
Jon Hall146f1522015-03-24 15:33:24 -07002893 try:
2894 if not isinstance( appName, types.StringType ):
2895 main.log.error( self.name + ".appStatus(): appName must be" +
2896 " a string" )
2897 return None
2898 output = self.apps( jsonFormat=True )
2899 appsJson = json.loads( output )
2900 state = None
2901 for app in appsJson:
2902 if appName == app.get('name'):
2903 state = app.get('state')
2904 break
2905 if state == "ACTIVE" or state == "INSTALLED":
2906 return state
2907 elif state is None:
2908 return "UNINSTALLED"
2909 elif state:
2910 main.log.error( "Unexpected state from 'onos:apps': " +
2911 str( state ) )
2912 return state
2913 except TypeError:
2914 main.log.exception( self.name + ": Object not as expected" )
2915 return None
2916 except pexpect.EOF:
2917 main.log.error( self.name + ": EOF exception found" )
2918 main.log.error( self.name + ": " + self.handle.before )
2919 main.cleanup()
2920 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002921 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002922 main.log.exception( self.name + ": Uncaught exception!" )
2923 main.cleanup()
2924 main.exit()
2925
Jon Hallbe379602015-03-24 13:39:32 -07002926 def app( self, appName, option ):
2927 """
2928 Interacts with the app command for ONOS. This command manages
2929 application inventory.
2930 """
Jon Hallbe379602015-03-24 13:39:32 -07002931 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002932 # Validate argument types
2933 valid = True
2934 if not isinstance( appName, types.StringType ):
2935 main.log.error( self.name + ".app(): appName must be a " +
2936 "string" )
2937 valid = False
2938 if not isinstance( option, types.StringType ):
2939 main.log.error( self.name + ".app(): option must be a string" )
2940 valid = False
2941 if not valid:
2942 return main.FALSE
2943 # Validate Option
2944 option = option.lower()
2945 # NOTE: Install may become a valid option
2946 if option == "activate":
2947 pass
2948 elif option == "deactivate":
2949 pass
2950 elif option == "uninstall":
2951 pass
2952 else:
2953 # Invalid option
2954 main.log.error( "The ONOS app command argument only takes " +
2955 "the values: (activate|deactivate|uninstall)" +
2956 "; was given '" + option + "'")
2957 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002958 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002959 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002960 if "Error executing command" in output:
2961 main.log.error( "Error in processing onos:app command: " +
2962 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002963 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002964 elif "No such application" in output:
2965 main.log.error( "The application '" + appName +
2966 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002967 return main.FALSE
2968 elif "Command not found:" in output:
2969 main.log.error( "Error in processing onos:app command: " +
2970 str( output ) )
2971 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002972 elif "Unsupported command:" in output:
2973 main.log.error( "Incorrect command given to 'app': " +
2974 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002975 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002976 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002977 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002978 return main.TRUE
2979 except TypeError:
2980 main.log.exception( self.name + ": Object not as expected" )
2981 return main.ERROR
2982 except pexpect.EOF:
2983 main.log.error( self.name + ": EOF exception found" )
2984 main.log.error( self.name + ": " + self.handle.before )
2985 main.cleanup()
2986 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002987 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002988 main.log.exception( self.name + ": Uncaught exception!" )
2989 main.cleanup()
2990 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002991
Jon Hallbd16b922015-03-26 17:53:15 -07002992 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002993 """
2994 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002995 appName is the hierarchical app name, not the feature name
2996 If check is True, method will check the status of the app after the
2997 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002998 Returns main.TRUE if the command was successfully sent
2999 main.FALSE if the cli responded with an error or given
3000 incorrect input
3001 """
3002 try:
3003 if not isinstance( appName, types.StringType ):
3004 main.log.error( self.name + ".activateApp(): appName must be" +
3005 " a string" )
3006 return main.FALSE
3007 status = self.appStatus( appName )
3008 if status == "INSTALLED":
3009 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003010 if check and response == main.TRUE:
3011 for i in range(10): # try 10 times then give up
3012 # TODO: Check with Thomas about this delay
3013 status = self.appStatus( appName )
3014 if status == "ACTIVE":
3015 return main.TRUE
3016 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003017 main.log.debug( "The state of application " +
3018 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003019 time.sleep( 1 )
3020 return main.FALSE
3021 else: # not 'check' or command didn't succeed
3022 return response
Jon Hall146f1522015-03-24 15:33:24 -07003023 elif status == "ACTIVE":
3024 return main.TRUE
3025 elif status == "UNINSTALLED":
3026 main.log.error( self.name + ": Tried to activate the " +
3027 "application '" + appName + "' which is not " +
3028 "installed." )
3029 else:
3030 main.log.error( "Unexpected return value from appStatus: " +
3031 str( status ) )
3032 return main.ERROR
3033 except TypeError:
3034 main.log.exception( self.name + ": Object not as expected" )
3035 return main.ERROR
3036 except pexpect.EOF:
3037 main.log.error( self.name + ": EOF exception found" )
3038 main.log.error( self.name + ": " + self.handle.before )
3039 main.cleanup()
3040 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003041 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003042 main.log.exception( self.name + ": Uncaught exception!" )
3043 main.cleanup()
3044 main.exit()
3045
Jon Hallbd16b922015-03-26 17:53:15 -07003046 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003047 """
3048 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003049 appName is the hierarchical app name, not the feature name
3050 If check is True, method will check the status of the app after the
3051 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003052 Returns main.TRUE if the command was successfully sent
3053 main.FALSE if the cli responded with an error or given
3054 incorrect input
3055 """
3056 try:
3057 if not isinstance( appName, types.StringType ):
3058 main.log.error( self.name + ".deactivateApp(): appName must " +
3059 "be a string" )
3060 return main.FALSE
3061 status = self.appStatus( appName )
3062 if status == "INSTALLED":
3063 return main.TRUE
3064 elif status == "ACTIVE":
3065 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003066 if check and response == main.TRUE:
3067 for i in range(10): # try 10 times then give up
3068 status = self.appStatus( appName )
3069 if status == "INSTALLED":
3070 return main.TRUE
3071 else:
3072 time.sleep( 1 )
3073 return main.FALSE
3074 else: # not check or command didn't succeed
3075 return response
Jon Hall146f1522015-03-24 15:33:24 -07003076 elif status == "UNINSTALLED":
3077 main.log.warn( self.name + ": Tried to deactivate the " +
3078 "application '" + appName + "' which is not " +
3079 "installed." )
3080 return main.TRUE
3081 else:
3082 main.log.error( "Unexpected return value from appStatus: " +
3083 str( status ) )
3084 return main.ERROR
3085 except TypeError:
3086 main.log.exception( self.name + ": Object not as expected" )
3087 return main.ERROR
3088 except pexpect.EOF:
3089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
3091 main.cleanup()
3092 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003093 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003094 main.log.exception( self.name + ": Uncaught exception!" )
3095 main.cleanup()
3096 main.exit()
3097
Jon Hallbd16b922015-03-26 17:53:15 -07003098 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003099 """
3100 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003101 appName is the hierarchical app name, not the feature name
3102 If check is True, method will check the status of the app after the
3103 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003104 Returns main.TRUE if the command was successfully sent
3105 main.FALSE if the cli responded with an error or given
3106 incorrect input
3107 """
3108 # TODO: check with Thomas about the state machine for apps
3109 try:
3110 if not isinstance( appName, types.StringType ):
3111 main.log.error( self.name + ".uninstallApp(): appName must " +
3112 "be a string" )
3113 return main.FALSE
3114 status = self.appStatus( appName )
3115 if status == "INSTALLED":
3116 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003117 if check and response == main.TRUE:
3118 for i in range(10): # try 10 times then give up
3119 status = self.appStatus( appName )
3120 if status == "UNINSTALLED":
3121 return main.TRUE
3122 else:
3123 time.sleep( 1 )
3124 return main.FALSE
3125 else: # not check or command didn't succeed
3126 return response
Jon Hall146f1522015-03-24 15:33:24 -07003127 elif status == "ACTIVE":
3128 main.log.warn( self.name + ": Tried to uninstall the " +
3129 "application '" + appName + "' which is " +
3130 "currently active." )
3131 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003132 if check and response == main.TRUE:
3133 for i in range(10): # try 10 times then give up
3134 status = self.appStatus( appName )
3135 if status == "UNINSTALLED":
3136 return main.TRUE
3137 else:
3138 time.sleep( 1 )
3139 return main.FALSE
3140 else: # not check or command didn't succeed
3141 return response
Jon Hall146f1522015-03-24 15:33:24 -07003142 elif status == "UNINSTALLED":
3143 return main.TRUE
3144 else:
3145 main.log.error( "Unexpected return value from appStatus: " +
3146 str( status ) )
3147 return main.ERROR
3148 except TypeError:
3149 main.log.exception( self.name + ": Object not as expected" )
3150 return main.ERROR
3151 except pexpect.EOF:
3152 main.log.error( self.name + ": EOF exception found" )
3153 main.log.error( self.name + ": " + self.handle.before )
3154 main.cleanup()
3155 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003156 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003157 main.log.exception( self.name + ": Uncaught exception!" )
3158 main.cleanup()
3159 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003160
3161 def appIDs( self, jsonFormat=True ):
3162 """
3163 Show the mappings between app id and app names given by the 'app-ids'
3164 cli command
3165 """
3166 try:
3167 cmdStr = "app-ids"
3168 if jsonFormat:
3169 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003170 output = self.sendline( cmdStr )
3171 assert "Error executing command" not in output
3172 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003173 except AssertionError:
3174 main.log.error( "Error in processing onos:app-ids command: " +
3175 str( output ) )
3176 return None
3177 except TypeError:
3178 main.log.exception( self.name + ": Object not as expected" )
3179 return None
3180 except pexpect.EOF:
3181 main.log.error( self.name + ": EOF exception found" )
3182 main.log.error( self.name + ": " + self.handle.before )
3183 main.cleanup()
3184 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003185 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003186 main.log.exception( self.name + ": Uncaught exception!" )
3187 main.cleanup()
3188 main.exit()
3189
3190 def appToIDCheck( self ):
3191 """
3192 This method will check that each application's ID listed in 'apps' is
3193 the same as the ID listed in 'app-ids'. The check will also check that
3194 there are no duplicate IDs issued. Note that an app ID should be
3195 a globaly unique numerical identifier for app/app-like features. Once
3196 an ID is registered, the ID is never freed up so that if an app is
3197 reinstalled it will have the same ID.
3198
3199 Returns: main.TRUE if the check passes and
3200 main.FALSE if the check fails or
3201 main.ERROR if there is some error in processing the test
3202 """
3203 try:
Jon Hall390696c2015-05-05 17:13:41 -07003204 bail = False
3205 ids = self.appIDs( jsonFormat=True )
3206 if ids:
3207 ids = json.loads( ids )
3208 else:
3209 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3210 bail = True
3211 apps = self.apps( jsonFormat=True )
3212 if apps:
3213 apps = json.loads( apps )
3214 else:
3215 main.log.error( "apps returned nothing:" + repr( apps ) )
3216 bail = True
3217 if bail:
3218 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003219 result = main.TRUE
3220 for app in apps:
3221 appID = app.get( 'id' )
3222 if appID is None:
3223 main.log.error( "Error parsing app: " + str( app ) )
3224 result = main.FALSE
3225 appName = app.get( 'name' )
3226 if appName is None:
3227 main.log.error( "Error parsing app: " + str( app ) )
3228 result = main.FALSE
3229 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003230 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003231 # main.log.debug( "Comparing " + str( app ) + " to " +
3232 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003233 if not current: # if ids doesn't have this id
3234 result = main.FALSE
3235 main.log.error( "'app-ids' does not have the ID for " +
3236 str( appName ) + " that apps does." )
3237 elif len( current ) > 1:
3238 # there is more than one app with this ID
3239 result = main.FALSE
3240 # We will log this later in the method
3241 elif not current[0][ 'name' ] == appName:
3242 currentName = current[0][ 'name' ]
3243 result = main.FALSE
3244 main.log.error( "'app-ids' has " + str( currentName ) +
3245 " registered under id:" + str( appID ) +
3246 " but 'apps' has " + str( appName ) )
3247 else:
3248 pass # id and name match!
3249 # now make sure that app-ids has no duplicates
3250 idsList = []
3251 namesList = []
3252 for item in ids:
3253 idsList.append( item[ 'id' ] )
3254 namesList.append( item[ 'name' ] )
3255 if len( idsList ) != len( set( idsList ) ) or\
3256 len( namesList ) != len( set( namesList ) ):
3257 main.log.error( "'app-ids' has some duplicate entries: \n"
3258 + json.dumps( ids,
3259 sort_keys=True,
3260 indent=4,
3261 separators=( ',', ': ' ) ) )
3262 result = main.FALSE
3263 return result
3264 except ( ValueError, TypeError ):
3265 main.log.exception( self.name + ": Object not as expected" )
3266 return main.ERROR
3267 except pexpect.EOF:
3268 main.log.error( self.name + ": EOF exception found" )
3269 main.log.error( self.name + ": " + self.handle.before )
3270 main.cleanup()
3271 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003272 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003273 main.log.exception( self.name + ": Uncaught exception!" )
3274 main.cleanup()
3275 main.exit()
3276
Jon Hallfb760a02015-04-13 15:35:03 -07003277 def getCfg( self, component=None, propName=None, short=False,
3278 jsonFormat=True ):
3279 """
3280 Get configuration settings from onos cli
3281 Optional arguments:
3282 component - Optionally only list configurations for a specific
3283 component. If None, all components with configurations
3284 are displayed. Case Sensitive string.
3285 propName - If component is specified, propName option will show
3286 only this specific configuration from that component.
3287 Case Sensitive string.
3288 jsonFormat - Returns output as json. Note that this will override
3289 the short option
3290 short - Short, less verbose, version of configurations.
3291 This is overridden by the json option
3292 returns:
3293 Output from cli as a string or None on error
3294 """
3295 try:
3296 baseStr = "cfg"
3297 cmdStr = " get"
3298 componentStr = ""
3299 if component:
3300 componentStr += " " + component
3301 if propName:
3302 componentStr += " " + propName
3303 if jsonFormat:
3304 baseStr += " -j"
3305 elif short:
3306 baseStr += " -s"
3307 output = self.sendline( baseStr + cmdStr + componentStr )
3308 assert "Error executing command" not in output
3309 return output
3310 except AssertionError:
3311 main.log.error( "Error in processing 'cfg get' command: " +
3312 str( output ) )
3313 return None
3314 except TypeError:
3315 main.log.exception( self.name + ": Object not as expected" )
3316 return None
3317 except pexpect.EOF:
3318 main.log.error( self.name + ": EOF exception found" )
3319 main.log.error( self.name + ": " + self.handle.before )
3320 main.cleanup()
3321 main.exit()
3322 except Exception:
3323 main.log.exception( self.name + ": Uncaught exception!" )
3324 main.cleanup()
3325 main.exit()
3326
3327 def setCfg( self, component, propName, value=None, check=True ):
3328 """
3329 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003330 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003331 component - The case sensitive name of the component whose
3332 property is to be set
3333 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003334 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003335 value - The value to set the property to. If None, will unset the
3336 property and revert it to it's default value(if applicable)
3337 check - Boolean, Check whether the option was successfully set this
3338 only applies when a value is given.
3339 returns:
3340 main.TRUE on success or main.FALSE on failure. If check is False,
3341 will return main.TRUE unless there is an error
3342 """
3343 try:
3344 baseStr = "cfg"
3345 cmdStr = " set " + str( component ) + " " + str( propName )
3346 if value is not None:
3347 cmdStr += " " + str( value )
3348 output = self.sendline( baseStr + cmdStr )
3349 assert "Error executing command" not in output
3350 if value and check:
3351 results = self.getCfg( component=str( component ),
3352 propName=str( propName ),
3353 jsonFormat=True )
3354 # Check if current value is what we just set
3355 try:
3356 jsonOutput = json.loads( results )
3357 current = jsonOutput[ 'value' ]
3358 except ( ValueError, TypeError ):
3359 main.log.exception( "Error parsing cfg output" )
3360 main.log.error( "output:" + repr( results ) )
3361 return main.FALSE
3362 if current == str( value ):
3363 return main.TRUE
3364 return main.FALSE
3365 return main.TRUE
3366 except AssertionError:
3367 main.log.error( "Error in processing 'cfg set' command: " +
3368 str( output ) )
3369 return main.FALSE
3370 except TypeError:
3371 main.log.exception( self.name + ": Object not as expected" )
3372 return main.FALSE
3373 except pexpect.EOF:
3374 main.log.error( self.name + ": EOF exception found" )
3375 main.log.error( self.name + ": " + self.handle.before )
3376 main.cleanup()
3377 main.exit()
3378 except Exception:
3379 main.log.exception( self.name + ": Uncaught exception!" )
3380 main.cleanup()
3381 main.exit()
3382
Jon Hall390696c2015-05-05 17:13:41 -07003383 def setTestAdd( self, setName, values ):
3384 """
3385 CLI command to add elements to a distributed set.
3386 Arguments:
3387 setName - The name of the set to add to.
3388 values - The value(s) to add to the set, space seperated.
3389 Example usages:
3390 setTestAdd( "set1", "a b c" )
3391 setTestAdd( "set2", "1" )
3392 returns:
3393 main.TRUE on success OR
3394 main.FALSE if elements were already in the set OR
3395 main.ERROR on error
3396 """
3397 try:
3398 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3399 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003400 try:
3401 # TODO: Maybe make this less hardcoded
3402 # ConsistentMap Exceptions
3403 assert "org.onosproject.store.service" not in output
3404 # Node not leader
3405 assert "java.lang.IllegalStateException" not in output
3406 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003407 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003408 "command: " + str( output ) )
3409 retryTime = 30 # Conservative time, given by Madan
3410 main.log.info( "Waiting " + str( retryTime ) +
3411 "seconds before retrying." )
3412 time.sleep( retryTime ) # Due to change in mastership
3413 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003414 assert "Error executing command" not in output
3415 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3416 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3417 main.log.info( self.name + ": " + output )
3418 if re.search( positiveMatch, output):
3419 return main.TRUE
3420 elif re.search( negativeMatch, output):
3421 return main.FALSE
3422 else:
3423 main.log.error( self.name + ": setTestAdd did not" +
3424 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003425 main.log.debug( self.name + " actual: " + repr( output ) )
3426 return main.ERROR
3427 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003428 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003429 str( output ) )
3430 return main.ERROR
3431 except TypeError:
3432 main.log.exception( self.name + ": Object not as expected" )
3433 return main.ERROR
3434 except pexpect.EOF:
3435 main.log.error( self.name + ": EOF exception found" )
3436 main.log.error( self.name + ": " + self.handle.before )
3437 main.cleanup()
3438 main.exit()
3439 except Exception:
3440 main.log.exception( self.name + ": Uncaught exception!" )
3441 main.cleanup()
3442 main.exit()
3443
3444 def setTestRemove( self, setName, values, clear=False, retain=False ):
3445 """
3446 CLI command to remove elements from a distributed set.
3447 Required arguments:
3448 setName - The name of the set to remove from.
3449 values - The value(s) to remove from the set, space seperated.
3450 Optional arguments:
3451 clear - Clear all elements from the set
3452 retain - Retain only the given values. (intersection of the
3453 original set and the given set)
3454 returns:
3455 main.TRUE on success OR
3456 main.FALSE if the set was not changed OR
3457 main.ERROR on error
3458 """
3459 try:
3460 cmdStr = "set-test-remove "
3461 if clear:
3462 cmdStr += "-c " + str( setName )
3463 elif retain:
3464 cmdStr += "-r " + str( setName ) + " " + str( values )
3465 else:
3466 cmdStr += str( setName ) + " " + str( values )
3467 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003468 try:
3469 # TODO: Maybe make this less hardcoded
3470 # ConsistentMap Exceptions
3471 assert "org.onosproject.store.service" not in output
3472 # Node not leader
3473 assert "java.lang.IllegalStateException" not in output
3474 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003475 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003476 "command: " + str( output ) )
3477 retryTime = 30 # Conservative time, given by Madan
3478 main.log.info( "Waiting " + str( retryTime ) +
3479 "seconds before retrying." )
3480 time.sleep( retryTime ) # Due to change in mastership
3481 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003482 assert "Error executing command" not in output
3483 main.log.info( self.name + ": " + output )
3484 if clear:
3485 pattern = "Set " + str( setName ) + " cleared"
3486 if re.search( pattern, output ):
3487 return main.TRUE
3488 elif retain:
3489 positivePattern = str( setName ) + " was pruned to contain " +\
3490 "only elements of set \[(.*)\]"
3491 negativePattern = str( setName ) + " was not changed by " +\
3492 "retaining only elements of the set " +\
3493 "\[(.*)\]"
3494 if re.search( positivePattern, output ):
3495 return main.TRUE
3496 elif re.search( negativePattern, output ):
3497 return main.FALSE
3498 else:
3499 positivePattern = "\[(.*)\] was removed from the set " +\
3500 str( setName )
3501 if ( len( values.split() ) == 1 ):
3502 negativePattern = "\[(.*)\] was not in set " +\
3503 str( setName )
3504 else:
3505 negativePattern = "No element of \[(.*)\] was in set " +\
3506 str( setName )
3507 if re.search( positivePattern, output ):
3508 return main.TRUE
3509 elif re.search( negativePattern, output ):
3510 return main.FALSE
3511 main.log.error( self.name + ": setTestRemove did not" +
3512 " match expected output" )
3513 main.log.debug( self.name + " expected: " + pattern )
3514 main.log.debug( self.name + " actual: " + repr( output ) )
3515 return main.ERROR
3516 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003517 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003518 str( output ) )
3519 return main.ERROR
3520 except TypeError:
3521 main.log.exception( self.name + ": Object not as expected" )
3522 return main.ERROR
3523 except pexpect.EOF:
3524 main.log.error( self.name + ": EOF exception found" )
3525 main.log.error( self.name + ": " + self.handle.before )
3526 main.cleanup()
3527 main.exit()
3528 except Exception:
3529 main.log.exception( self.name + ": Uncaught exception!" )
3530 main.cleanup()
3531 main.exit()
3532
3533 def setTestGet( self, setName, values="" ):
3534 """
3535 CLI command to get the elements in a distributed set.
3536 Required arguments:
3537 setName - The name of the set to remove from.
3538 Optional arguments:
3539 values - The value(s) to check if in the set, space seperated.
3540 returns:
3541 main.ERROR on error OR
3542 A list of elements in the set if no optional arguments are
3543 supplied OR
3544 A tuple containing the list then:
3545 main.FALSE if the given values are not in the set OR
3546 main.TRUE if the given values are in the set OR
3547 """
3548 try:
3549 values = str( values ).strip()
3550 setName = str( setName ).strip()
3551 length = len( values.split() )
3552 containsCheck = None
3553 # Patterns to match
3554 setPattern = "\[(.*)\]"
3555 pattern = "Items in set " + setName + ":\n" + setPattern
3556 containsTrue = "Set " + setName + " contains the value " + values
3557 containsFalse = "Set " + setName + " did not contain the value " +\
3558 values
3559 containsAllTrue = "Set " + setName + " contains the the subset " +\
3560 setPattern
3561 containsAllFalse = "Set " + setName + " did not contain the the" +\
3562 " subset " + setPattern
3563
3564 cmdStr = "set-test-get "
3565 cmdStr += setName + " " + values
3566 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003567 try:
3568 # TODO: Maybe make this less hardcoded
3569 # ConsistentMap Exceptions
3570 assert "org.onosproject.store.service" not in output
3571 # Node not leader
3572 assert "java.lang.IllegalStateException" not in output
3573 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003574 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003575 "command: " + str( output ) )
3576 retryTime = 30 # Conservative time, given by Madan
3577 main.log.info( "Waiting " + str( retryTime ) +
3578 "seconds before retrying." )
3579 time.sleep( retryTime ) # Due to change in mastership
3580 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003581 assert "Error executing command" not in output
3582 main.log.info( self.name + ": " + output )
3583
3584 if length == 0:
3585 match = re.search( pattern, output )
3586 else: # if given values
3587 if length == 1: # Contains output
3588 patternTrue = pattern + "\n" + containsTrue
3589 patternFalse = pattern + "\n" + containsFalse
3590 else: # ContainsAll output
3591 patternTrue = pattern + "\n" + containsAllTrue
3592 patternFalse = pattern + "\n" + containsAllFalse
3593 matchTrue = re.search( patternTrue, output )
3594 matchFalse = re.search( patternFalse, output )
3595 if matchTrue:
3596 containsCheck = main.TRUE
3597 match = matchTrue
3598 elif matchFalse:
3599 containsCheck = main.FALSE
3600 match = matchFalse
3601 else:
3602 main.log.error( self.name + " setTestGet did not match " +\
3603 "expected output" )
3604 main.log.debug( self.name + " expected: " + pattern )
3605 main.log.debug( self.name + " actual: " + repr( output ) )
3606 match = None
3607 if match:
3608 setMatch = match.group( 1 )
3609 if setMatch == '':
3610 setList = []
3611 else:
3612 setList = setMatch.split( ", " )
3613 if length > 0:
3614 return ( setList, containsCheck )
3615 else:
3616 return setList
3617 else: # no match
3618 main.log.error( self.name + ": setTestGet did not" +
3619 " match expected output" )
3620 main.log.debug( self.name + " expected: " + pattern )
3621 main.log.debug( self.name + " actual: " + repr( output ) )
3622 return main.ERROR
3623 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003624 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003625 str( output ) )
3626 return main.ERROR
3627 except TypeError:
3628 main.log.exception( self.name + ": Object not as expected" )
3629 return main.ERROR
3630 except pexpect.EOF:
3631 main.log.error( self.name + ": EOF exception found" )
3632 main.log.error( self.name + ": " + self.handle.before )
3633 main.cleanup()
3634 main.exit()
3635 except Exception:
3636 main.log.exception( self.name + ": Uncaught exception!" )
3637 main.cleanup()
3638 main.exit()
3639
3640 def setTestSize( self, setName ):
3641 """
3642 CLI command to get the elements in a distributed set.
3643 Required arguments:
3644 setName - The name of the set to remove from.
3645 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003646 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003647 None on error
3648 """
3649 try:
3650 # TODO: Should this check against the number of elements returned
3651 # and then return true/false based on that?
3652 setName = str( setName ).strip()
3653 # Patterns to match
3654 setPattern = "\[(.*)\]"
3655 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3656 setPattern
3657 cmdStr = "set-test-get -s "
3658 cmdStr += setName
3659 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003660 try:
3661 # TODO: Maybe make this less hardcoded
3662 # ConsistentMap Exceptions
3663 assert "org.onosproject.store.service" not in output
3664 # Node not leader
3665 assert "java.lang.IllegalStateException" not in output
3666 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003667 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003668 "command: " + str( output ) )
3669 retryTime = 30 # Conservative time, given by Madan
3670 main.log.info( "Waiting " + str( retryTime ) +
3671 "seconds before retrying." )
3672 time.sleep( retryTime ) # Due to change in mastership
3673 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003674 assert "Error executing command" not in output
3675 main.log.info( self.name + ": " + output )
3676 match = re.search( pattern, output )
3677 if match:
3678 setSize = int( match.group( 1 ) )
3679 setMatch = match.group( 2 )
3680 if len( setMatch.split() ) == setSize:
3681 main.log.info( "The size returned by " + self.name +
3682 " matches the number of elements in " +
3683 "the returned set" )
3684 else:
3685 main.log.error( "The size returned by " + self.name +
3686 " does not match the number of " +
3687 "elements in the returned set." )
3688 return setSize
3689 else: # no match
3690 main.log.error( self.name + ": setTestGet did not" +
3691 " match expected output" )
3692 main.log.debug( self.name + " expected: " + pattern )
3693 main.log.debug( self.name + " actual: " + repr( output ) )
3694 return None
3695 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003696 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003697 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003698 return None
Jon Hall390696c2015-05-05 17:13:41 -07003699 except TypeError:
3700 main.log.exception( self.name + ": Object not as expected" )
3701 return None
3702 except pexpect.EOF:
3703 main.log.error( self.name + ": EOF exception found" )
3704 main.log.error( self.name + ": " + self.handle.before )
3705 main.cleanup()
3706 main.exit()
3707 except Exception:
3708 main.log.exception( self.name + ": Uncaught exception!" )
3709 main.cleanup()
3710 main.exit()
3711
Jon Hall80daded2015-05-27 16:07:00 -07003712 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003713 """
3714 Command to list the various counters in the system.
3715 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003716 if jsonFormat, a string of the json object returned by the cli
3717 command
3718 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003719 None on error
3720 """
Jon Hall390696c2015-05-05 17:13:41 -07003721 try:
3722 counters = {}
3723 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003724 if jsonFormat:
3725 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003726 output = self.sendline( cmdStr )
3727 assert "Error executing command" not in output
3728 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003729 return output
Jon Hall390696c2015-05-05 17:13:41 -07003730 except AssertionError:
3731 main.log.error( "Error in processing 'counters' command: " +
3732 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003733 return None
Jon Hall390696c2015-05-05 17:13:41 -07003734 except TypeError:
3735 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003736 return None
Jon Hall390696c2015-05-05 17:13:41 -07003737 except pexpect.EOF:
3738 main.log.error( self.name + ": EOF exception found" )
3739 main.log.error( self.name + ": " + self.handle.before )
3740 main.cleanup()
3741 main.exit()
3742 except Exception:
3743 main.log.exception( self.name + ": Uncaught exception!" )
3744 main.cleanup()
3745 main.exit()
3746
Jon Halle1a3b752015-07-22 13:02:46 -07003747 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003748 """
Jon Halle1a3b752015-07-22 13:02:46 -07003749 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003750 Required arguments:
3751 counter - The name of the counter to increment.
3752 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003753 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003754 inMemory - use in memory map for the counter
3755 returns:
3756 integer value of the counter or
3757 None on Error
3758 """
3759 try:
3760 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003761 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003762 cmdStr = "counter-test-increment "
3763 if inMemory:
3764 cmdStr += "-i "
3765 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003766 if delta != 1:
3767 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003768 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003769 try:
3770 # TODO: Maybe make this less hardcoded
3771 # ConsistentMap Exceptions
3772 assert "org.onosproject.store.service" not in output
3773 # Node not leader
3774 assert "java.lang.IllegalStateException" not in output
3775 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003776 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003777 "command: " + str( output ) )
3778 retryTime = 30 # Conservative time, given by Madan
3779 main.log.info( "Waiting " + str( retryTime ) +
3780 "seconds before retrying." )
3781 time.sleep( retryTime ) # Due to change in mastership
3782 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003783 assert "Error executing command" not in output
3784 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003785 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003786 match = re.search( pattern, output )
3787 if match:
3788 return int( match.group( 1 ) )
3789 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003790 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003791 " match expected output." )
3792 main.log.debug( self.name + " expected: " + pattern )
3793 main.log.debug( self.name + " actual: " + repr( output ) )
3794 return None
3795 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003796 main.log.error( "Error in processing '" + cmdStr + "'" +
Jon Hall390696c2015-05-05 17:13:41 -07003797 " command: " + str( output ) )
3798 return None
3799 except TypeError:
3800 main.log.exception( self.name + ": Object not as expected" )
3801 return None
3802 except pexpect.EOF:
3803 main.log.error( self.name + ": EOF exception found" )
3804 main.log.error( self.name + ": " + self.handle.before )
3805 main.cleanup()
3806 main.exit()
3807 except Exception:
3808 main.log.exception( self.name + ": Uncaught exception!" )
3809 main.cleanup()
3810 main.exit()
3811
Jon Halle1a3b752015-07-22 13:02:46 -07003812 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
3813 """
3814 CLI command to get a distributed counter then add a delta to it.
3815 Required arguments:
3816 counter - The name of the counter to increment.
3817 Optional arguments:
3818 delta - The long to add to the counter
3819 inMemory - use in memory map for the counter
3820 returns:
3821 integer value of the counter or
3822 None on Error
3823 """
3824 try:
3825 counter = str( counter )
3826 delta = int( delta )
3827 cmdStr = "counter-test-increment -g "
3828 if inMemory:
3829 cmdStr += "-i "
3830 cmdStr += counter
3831 if delta != 1:
3832 cmdStr += " " + str( delta )
3833 output = self.sendline( cmdStr )
3834 try:
3835 # TODO: Maybe make this less hardcoded
3836 # ConsistentMap Exceptions
3837 assert "org.onosproject.store.service" not in output
3838 # Node not leader
3839 assert "java.lang.IllegalStateException" not in output
3840 except AssertionError:
3841 main.log.error( "Error in processing '" + cmdStr + "' " +
3842 "command: " + str( output ) )
3843 retryTime = 30 # Conservative time, given by Madan
3844 main.log.info( "Waiting " + str( retryTime ) +
3845 "seconds before retrying." )
3846 time.sleep( retryTime ) # Due to change in mastership
3847 output = self.sendline( cmdStr )
3848 assert "Error executing command" not in output
3849 main.log.info( self.name + ": " + output )
3850 pattern = counter + " was updated to (-?\d+)"
3851 match = re.search( pattern, output )
3852 if match:
3853 return int( match.group( 1 ) )
3854 else:
3855 main.log.error( self.name + ": counterTestGetAndAdd did not" +
3856 " match expected output." )
3857 main.log.debug( self.name + " expected: " + pattern )
3858 main.log.debug( self.name + " actual: " + repr( output ) )
3859 return None
3860 except AssertionError:
3861 main.log.error( "Error in processing '" + cmdStr + "'" +
3862 " command: " + str( output ) )
3863 return None
3864 except TypeError:
3865 main.log.exception( self.name + ": Object not as expected" )
3866 return None
3867 except pexpect.EOF:
3868 main.log.error( self.name + ": EOF exception found" )
3869 main.log.error( self.name + ": " + self.handle.before )
3870 main.cleanup()
3871 main.exit()
3872 except Exception:
3873 main.log.exception( self.name + ": Uncaught exception!" )
3874 main.cleanup()
3875 main.exit()
3876
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003877 def summary( self, jsonFormat=True ):
3878 """
3879 Description: Execute summary command in onos
3880 Returns: json object ( summary -j ), returns main.FALSE if there is
3881 no output
3882
3883 """
3884 try:
3885 cmdStr = "summary"
3886 if jsonFormat:
3887 cmdStr += " -j"
3888 handle = self.sendline( cmdStr )
3889
3890 if re.search( "Error:", handle ):
3891 main.log.error( self.name + ": summary() response: " +
3892 str( handle ) )
3893 if not handle:
3894 main.log.error( self.name + ": There is no output in " +
3895 "summary command" )
3896 return main.FALSE
3897 return handle
3898 except TypeError:
3899 main.log.exception( self.name + ": Object not as expected" )
3900 return None
3901 except pexpect.EOF:
3902 main.log.error( self.name + ": EOF exception found" )
3903 main.log.error( self.name + ": " + self.handle.before )
3904 main.cleanup()
3905 main.exit()
3906 except Exception:
3907 main.log.exception( self.name + ": Uncaught exception!" )
3908 main.cleanup()
3909 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07003910
3911 def transactionalMapGet( self, keyName, inMemory=False ):
3912 """
3913 CLI command to get the value of a key in a consistent map using
3914 transactions. This a test function and can only get keys from the
3915 test map hard coded into the cli command
3916 Required arguments:
3917 keyName - The name of the key to get
3918 Optional arguments:
3919 inMemory - use in memory map for the counter
3920 returns:
3921 The string value of the key or
3922 None on Error
3923 """
3924 try:
3925 keyName = str( keyName )
3926 cmdStr = "transactional-map-test-get "
3927 if inMemory:
3928 cmdStr += "-i "
3929 cmdStr += keyName
3930 output = self.sendline( cmdStr )
3931 try:
3932 # TODO: Maybe make this less hardcoded
3933 # ConsistentMap Exceptions
3934 assert "org.onosproject.store.service" not in output
3935 # Node not leader
3936 assert "java.lang.IllegalStateException" not in output
3937 except AssertionError:
3938 main.log.error( "Error in processing '" + cmdStr + "' " +
3939 "command: " + str( output ) )
3940 return None
3941 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
3942 if "Key " + keyName + " not found." in output:
3943 return None
3944 else:
3945 match = re.search( pattern, output )
3946 if match:
3947 return match.groupdict()[ 'value' ]
3948 else:
3949 main.log.error( self.name + ": transactionlMapGet did not" +
3950 " match expected output." )
3951 main.log.debug( self.name + " expected: " + pattern )
3952 main.log.debug( self.name + " actual: " + repr( output ) )
3953 return None
3954 except TypeError:
3955 main.log.exception( self.name + ": Object not as expected" )
3956 return None
3957 except pexpect.EOF:
3958 main.log.error( self.name + ": EOF exception found" )
3959 main.log.error( self.name + ": " + self.handle.before )
3960 main.cleanup()
3961 main.exit()
3962 except Exception:
3963 main.log.exception( self.name + ": Uncaught exception!" )
3964 main.cleanup()
3965 main.exit()
3966
3967 def transactionalMapPut( self, numKeys, value, inMemory=False ):
3968 """
3969 CLI command to put a value into 'numKeys' number of keys in a
3970 consistent map using transactions. This a test function and can only
3971 put into keys named 'Key#' of the test map hard coded into the cli command
3972 Required arguments:
3973 numKeys - Number of keys to add the value to
3974 value - The string value to put into the keys
3975 Optional arguments:
3976 inMemory - use in memory map for the counter
3977 returns:
3978 A dictionary whose keys are the name of the keys put into the map
3979 and the values of the keys are dictionaries whose key-values are
3980 'value': value put into map and optionaly
3981 'oldValue': Previous value in the key or
3982 None on Error
3983
3984 Example output
3985 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
3986 'Key2': {'value': 'Testing'} }
3987 """
3988 try:
3989 numKeys = str( numKeys )
3990 value = str( value )
3991 cmdStr = "transactional-map-test-put "
3992 if inMemory:
3993 cmdStr += "-i "
3994 cmdStr += numKeys + " " + value
3995 output = self.sendline( cmdStr )
3996 try:
3997 # TODO: Maybe make this less hardcoded
3998 # ConsistentMap Exceptions
3999 assert "org.onosproject.store.service" not in output
4000 # Node not leader
4001 assert "java.lang.IllegalStateException" not in output
4002 except AssertionError:
4003 main.log.error( "Error in processing '" + cmdStr + "' " +
4004 "command: " + str( output ) )
4005 return None
4006 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4007 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4008 results = {}
4009 for line in output.splitlines():
4010 new = re.search( newPattern, line )
4011 updated = re.search( updatedPattern, line )
4012 if new:
4013 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4014 elif updated:
4015 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
4016 'oldValue': updated.groupdict()[ 'oldValue' ] }
4017 else:
4018 main.log.error( self.name + ": transactionlMapGet did not" +
4019 " match expected output." )
4020 main.log.debug( self.name + " expected: " + pattern )
4021 main.log.debug( self.name + " actual: " + repr( output ) )
4022 return results
4023 except TypeError:
4024 main.log.exception( self.name + ": Object not as expected" )
4025 return None
4026 except pexpect.EOF:
4027 main.log.error( self.name + ": EOF exception found" )
4028 main.log.error( self.name + ": " + self.handle.before )
4029 main.cleanup()
4030 main.exit()
4031 except Exception:
4032 main.log.exception( self.name + ": Uncaught exception!" )
4033 main.cleanup()
4034 main.exit()
acsmarsdaea66c2015-09-03 11:44:06 -07004035 def maps( self, jsonFormat=True ):
4036 """
4037 Description: Returns result of onos:maps
4038 Optional:
4039 * jsonFormat: enable json formatting of output
4040 """
4041 try:
4042 cmdStr = "maps"
4043 if jsonFormat:
4044 cmdStr += " -j"
4045 handle = self.sendline( cmdStr )
4046 return handle
4047 except TypeError:
4048 main.log.exception( self.name + ": Object not as expected" )
4049 return None
4050 except pexpect.EOF:
4051 main.log.error( self.name + ": EOF exception found" )
4052 main.log.error( self.name + ": " + self.handle.before )
4053 main.cleanup()
4054 main.exit()
4055 except Exception:
4056 main.log.exception( self.name + ": Uncaught exception!" )
4057 main.cleanup()
4058 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004059
4060 def getSwController( self, uri, jsonFormat=True ):
4061 """
4062 Descrition: Gets the controller information from the device
4063 """
4064 try:
4065 cmd = "device-controllers "
4066 if jsonFormat:
4067 cmd += "-j "
4068 response = self.sendline( cmd + uri )
4069 return response
4070 except TypeError:
4071 main.log.exception( self.name + ": Object not as expected" )
4072 return None
4073 except pexpect.EOF:
4074 main.log.error( self.name + ": EOF exception found" )
4075 main.log.error( self.name + ": " + self.handle.before )
4076 main.cleanup()
4077 main.exit()
4078 except Exception:
4079 main.log.exception( self.name + ": Uncaught exception!" )
4080 main.cleanup()
4081 main.exit()
4082
4083 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4084 """
4085 Descrition: sets the controller(s) for the specified device
4086
4087 Parameters:
4088 Required: uri - String: The uri of the device(switch).
4089 ip - String or List: The ip address of the controller.
4090 This parameter can be formed in a couple of different ways.
4091 VALID:
4092 10.0.0.1 - just the ip address
4093 tcp:10.0.0.1 - the protocol and the ip address
4094 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4095 so that you can add controllers with different
4096 protocols and ports
4097 INVALID:
4098 10.0.0.1:6653 - this is not supported by ONOS
4099
4100 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4101 port - The port number.
4102 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4103
4104 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4105 """
4106 try:
4107 cmd = "device-setcontrollers"
4108
4109 if jsonFormat:
4110 cmd += " -j"
4111 cmd += " " + uri
4112 if isinstance( ip, str ):
4113 ip = [ip]
4114 for item in ip:
4115 if ":" in item:
4116 sitem = item.split( ":" )
4117 if len(sitem) == 3:
4118 cmd += " " + item
4119 elif "." in sitem[1]:
4120 cmd += " {}:{}".format(item, port)
4121 else:
4122 main.log.error( "Malformed entry: " + item )
4123 raise TypeError
4124 else:
4125 cmd += " {}:{}:{}".format( proto, item, port )
4126
4127 response = self.sendline( cmd )
4128
4129 if "Error" in response:
4130 main.log.error( response )
4131 return main.FALSE
4132
GlennRC050596c2015-11-18 17:06:41 -08004133 return main.TRUE
4134
4135 except TypeError:
4136 main.log.exception( self.name + ": Object not as expected" )
4137 return main.FALSE
4138 except pexpect.EOF:
4139 main.log.error( self.name + ": EOF exception found" )
4140 main.log.error( self.name + ": " + self.handle.before )
4141 main.cleanup()
4142 main.exit()
4143 except Exception:
4144 main.log.exception( self.name + ": Uncaught exception!" )
4145 main.cleanup()
4146 main.exit()