blob: 1f74984d8ad9324dbff5f87d15f57e76beb0b657 [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
GlennRCed771242016-01-13 17:02:47 -0800334 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
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.
GlennRCed771242016-01-13 17:02:47 -0800342
kelvin8ec71442015-01-15 16:57:00 -0800343 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400344 try:
GlennRCed771242016-01-13 17:02:47 -0800345
346 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
347 + self.name + "." )
kelvin-onlab338f5512015-02-06 10:53:16 -0800348 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
349 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800350 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800351 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800352 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800353 # TODO: do something with i
GlennRCed771242016-01-13 17:02:47 -0800354
Jon Hallc6358dd2015-04-10 12:44:28 -0700355 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700356 main.log.debug( self.name + ": Raw output" )
357 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700358
359 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800360 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800361 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700362 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700363 main.log.debug( self.name + ": ansiEscape output" )
364 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700365
kelvin-onlabfb521662015-02-27 09:52:40 -0800366 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800367 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700368 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700369 main.log.debug( self.name + ": Removed extra returns " +
370 "from output" )
371 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700372
373 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800374 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700375 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700376 main.log.debug( self.name + ": parsed and stripped output" )
377 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700378
Jon Hall63604932015-02-26 17:09:50 -0800379 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700380 output = response.split( cmdStr.strip(), 1 )
381 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700383 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700384 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800385 output = output[1].strip()
386 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800387 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800388 return output
GlennRCed771242016-01-13 17:02:47 -0800389 except pexpect.TIMEOUT:
390 main.log.error( self.name + ":ONOS timeout" )
391 if debug:
392 main.log.debug( self.handle.before )
393 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700394 except IndexError:
395 main.log.exception( self.name + ": Object not as expected" )
396 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800397 except TypeError:
398 main.log.exception( self.name + ": Object not as expected" )
399 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800401 main.log.error( self.name + ": EOF exception found" )
402 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400403 main.cleanup()
404 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800405 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800406 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400407 main.cleanup()
408 main.exit()
409
kelvin8ec71442015-01-15 16:57:00 -0800410 # IMPORTANT NOTE:
411 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800412 # the cli command changing 'a:b' with 'aB'.
413 # Ex ) onos:topology > onosTopology
414 # onos:links > onosLinks
415 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800416
kelvin-onlabd3b64892015-01-20 13:26:24 -0800417 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800418 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400419 Adds a new cluster node by ID and address information.
420 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800421 * nodeId
422 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400423 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800424 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800425 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400426 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800427 cmdStr = "add-node " + str( nodeId ) + " " +\
428 str( ONOSIp ) + " " + str( tcpPort )
429 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800430 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800431 main.log.error( "Error in adding node" )
432 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800433 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400434 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800435 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400436 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800437 except TypeError:
438 main.log.exception( self.name + ": Object not as expected" )
439 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( self.name + ": EOF exception found" )
442 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400443 main.cleanup()
444 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800445 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800446 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400447 main.cleanup()
448 main.exit()
449
kelvin-onlabd3b64892015-01-20 13:26:24 -0800450 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800451 """
andrewonlab86dc3082014-10-13 18:18:38 -0400452 Removes a cluster by ID
453 Issues command: 'remove-node [<node-id>]'
454 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800455 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800456 """
andrewonlab86dc3082014-10-13 18:18:38 -0400457 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400458
kelvin-onlabd3b64892015-01-20 13:26:24 -0800459 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700460 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700461 if re.search( "Error", handle ):
462 main.log.error( "Error in removing node" )
463 main.log.error( handle )
464 return main.FALSE
465 else:
466 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800467 except TypeError:
468 main.log.exception( self.name + ": Object not as expected" )
469 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400470 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800471 main.log.error( self.name + ": EOF exception found" )
472 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400473 main.cleanup()
474 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800475 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800476 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400477 main.cleanup()
478 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400479
Jon Hall61282e32015-03-19 11:34:11 -0700480 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800481 """
andrewonlab7c211572014-10-15 16:45:20 -0400482 List the nodes currently visible
483 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700484 Optional argument:
485 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800486 """
andrewonlab7c211572014-10-15 16:45:20 -0400487 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700489 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700490 cmdStr += " -j"
491 output = self.sendline( cmdStr )
492 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800493 except TypeError:
494 main.log.exception( self.name + ": Object not as expected" )
495 return None
andrewonlab7c211572014-10-15 16:45:20 -0400496 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800497 main.log.error( self.name + ": EOF exception found" )
498 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400499 main.cleanup()
500 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800501 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800502 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400503 main.cleanup()
504 main.exit()
505
kelvin8ec71442015-01-15 16:57:00 -0800506 def topology( self ):
507 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700508 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700509 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700510 Return:
511 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800512 """
andrewonlab95ce8322014-10-13 14:12:04 -0400513 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700514 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800515 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700516 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400517 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800518 except TypeError:
519 main.log.exception( self.name + ": Object not as expected" )
520 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800522 main.log.error( self.name + ": EOF exception found" )
523 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400524 main.cleanup()
525 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800526 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800527 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400528 main.cleanup()
529 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800530
kelvin-onlabd3b64892015-01-20 13:26:24 -0800531 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800532 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700533 Installs a specified feature by issuing command:
534 'feature:install <feature_str>'
535 NOTE: This is now deprecated, you should use the activateApp method
536 instead
kelvin8ec71442015-01-15 16:57:00 -0800537 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400538 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 handle = self.sendline( cmdStr )
541 if re.search( "Error", handle ):
542 main.log.error( "Error in installing feature" )
543 main.log.error( handle )
544 return main.FALSE
545 else:
546 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800547 except TypeError:
548 main.log.exception( self.name + ": Object not as expected" )
549 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800551 main.log.error( self.name + ": EOF exception found" )
552 main.log.error( self.name + ": " + self.handle.before )
553 main.log.report( "Failed to install feature" )
554 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400555 main.cleanup()
556 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800557 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800558 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800559 main.log.report( "Failed to install feature" )
560 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400561 main.cleanup()
562 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800563
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800565 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 Uninstalls a specified feature by issuing command:
567 'feature:uninstall <feature_str>'
568 NOTE: This is now deprecated, you should use the deactivateApp method
569 instead
kelvin8ec71442015-01-15 16:57:00 -0800570 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400571 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800572 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
573 handle = self.sendline( cmdStr )
574 if handle != '':
575 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700576 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800577 # TODO: Check for possible error responses from karaf
578 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800579 main.log.info( "Feature needs to be installed before " +
580 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700581 return main.TRUE
582 if re.search( "Error", output ):
583 main.log.error( "Error in uninstalling feature" )
584 main.log.error( output )
585 return main.FALSE
586 else:
587 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800588 except TypeError:
589 main.log.exception( self.name + ": Object not as expected" )
590 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400594 main.cleanup()
595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800597 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400598 main.cleanup()
599 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800600
jenkins7ead5a82015-03-13 10:28:21 -0700601 def deviceRemove( self, deviceId ):
602 """
603 Removes particular device from storage
604
605 TODO: refactor this function
606 """
607 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700608 cmdStr = "device-remove " + str( deviceId )
609 handle = self.sendline( cmdStr )
610 if re.search( "Error", handle ):
611 main.log.error( "Error in removing device" )
612 main.log.error( handle )
613 return main.FALSE
614 else:
615 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700616 except TypeError:
617 main.log.exception( self.name + ": Object not as expected" )
618 return None
619 except pexpect.EOF:
620 main.log.error( self.name + ": EOF exception found" )
621 main.log.error( self.name + ": " + self.handle.before )
622 main.cleanup()
623 main.exit()
624 except Exception:
625 main.log.exception( self.name + ": Uncaught exception!" )
626 main.cleanup()
627 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700628
kelvin-onlabd3b64892015-01-20 13:26:24 -0800629 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800630 """
Jon Hall7b02d952014-10-17 20:14:54 -0400631 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400632 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800634 """
andrewonlab86dc3082014-10-13 18:18:38 -0400635 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 cmdStr += " -j"
639 handle = self.sendline( cmdStr )
640 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800641 except TypeError:
642 main.log.exception( self.name + ": Object not as expected" )
643 return None
andrewonlab7c211572014-10-15 16:45:20 -0400644 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800645 main.log.error( self.name + ": EOF exception found" )
646 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400647 main.cleanup()
648 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800649 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800650 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400651 main.cleanup()
652 main.exit()
653
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800655 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800656 This balances the devices across all controllers
657 by issuing command: 'onos> onos:balance-masters'
658 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800659 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800660 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700662 handle = self.sendline( cmdStr )
663 if re.search( "Error", handle ):
664 main.log.error( "Error in balancing masters" )
665 main.log.error( handle )
666 return main.FALSE
667 else:
668 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800675 main.cleanup()
676 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800677 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800678 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800679 main.cleanup()
680 main.exit()
681
acsmars24950022015-07-30 18:00:43 -0700682 def checkMasters( self,jsonFormat=True ):
683 """
684 Returns the output of the masters command.
685 Optional argument:
686 * jsonFormat - boolean indicating if you want output in json
687 """
688 try:
689 cmdStr = "onos:masters"
690 if jsonFormat:
691 cmdStr += " -j"
692 output = self.sendline( cmdStr )
693 return output
694 except TypeError:
695 main.log.exception( self.name + ": Object not as expected" )
696 return None
697 except pexpect.EOF:
698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
700 main.cleanup()
701 main.exit()
702 except Exception:
703 main.log.exception( self.name + ": Uncaught exception!" )
704 main.cleanup()
705 main.exit()
706
707 def checkBalanceMasters( self,jsonFormat=True ):
708 """
709 Uses the master command to check that the devices' leadership
710 is evenly divided
711
712 Dependencies: checkMasters() and summary()
713
714 Returns main.True if the devices are balanced
715 Returns main.False if the devices are unbalanced
716 Exits on Exception
717 Returns None on TypeError
718 """
719 try:
720 totalDevices = json.loads( self.summary() )[ "devices" ]
721 totalOwnedDevices = 0
722 masters = json.loads( self.checkMasters() )
723 first = masters[ 0 ][ "size" ]
724 for master in masters:
725 totalOwnedDevices += master[ "size" ]
726 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
727 main.log.error( "Mastership not balanced" )
728 main.log.info( "\n" + self.checkMasters( False ) )
729 return main.FALSE
730 main.log.info( "Mastership balanced between " \
731 + str( len(masters) ) + " masters" )
732 return main.TRUE
733 except TypeError:
734 main.log.exception( self.name + ": Object not as expected" )
735 return None
736 except pexpect.EOF:
737 main.log.error( self.name + ": EOF exception found" )
738 main.log.error( self.name + ": " + self.handle.before )
739 main.cleanup()
740 main.exit()
741 except Exception:
742 main.log.exception( self.name + ": Uncaught exception!" )
743 main.cleanup()
744 main.exit()
745
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800747 """
Jon Halle8217482014-10-17 13:49:14 -0400748 Lists all core links
749 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800751 """
Jon Halle8217482014-10-17 13:49:14 -0400752 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800754 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 cmdStr += " -j"
756 handle = self.sendline( cmdStr )
757 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800758 except TypeError:
759 main.log.exception( self.name + ": Object not as expected" )
760 return None
Jon Halle8217482014-10-17 13:49:14 -0400761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400764 main.cleanup()
765 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800766 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800767 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400768 main.cleanup()
769 main.exit()
770
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Jon Halle8217482014-10-17 13:49:14 -0400773 Lists all ports
774 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800776 """
Jon Halle8217482014-10-17 13:49:14 -0400777 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800779 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700780 cmdStr += " -j"
781 handle = self.sendline( cmdStr )
782 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800783 except TypeError:
784 main.log.exception( self.name + ": Object not as expected" )
785 return None
Jon Halle8217482014-10-17 13:49:14 -0400786 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800787 main.log.error( self.name + ": EOF exception found" )
788 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400789 main.cleanup()
790 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800791 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800792 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400793 main.cleanup()
794 main.exit()
795
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800797 """
Jon Hall983a1702014-10-28 18:44:22 -0400798 Lists all devices and the controllers with roles assigned to them
799 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800801 """
andrewonlab7c211572014-10-15 16:45:20 -0400802 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700803 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800804 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700805 cmdStr += " -j"
806 handle = self.sendline( cmdStr )
807 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800808 except TypeError:
809 main.log.exception( self.name + ": Object not as expected" )
810 return None
Jon Hall983a1702014-10-28 18:44:22 -0400811 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.error( self.name + ": EOF exception found" )
813 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400814 main.cleanup()
815 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800817 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400818 main.cleanup()
819 main.exit()
820
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800822 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800823 Given the a string containing the json representation of the "roles"
824 cli command and a partial or whole device id, returns a json object
825 containing the roles output for the first device whose id contains
826 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400827
828 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800829 A dict of the role assignments for the given device or
830 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800831 """
Jon Hall983a1702014-10-28 18:44:22 -0400832 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800833 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400834 return None
835 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800836 rawRoles = self.roles()
837 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800838 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800839 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800840 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400842 return device
843 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800844 except TypeError:
845 main.log.exception( self.name + ": Object not as expected" )
846 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400847 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800848 main.log.error( self.name + ": EOF exception found" )
849 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400850 main.cleanup()
851 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800852 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800853 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400854 main.cleanup()
855 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800856
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800858 """
Jon Hall94fd0472014-12-08 11:52:42 -0800859 Iterates through each device and checks if there is a master assigned
860 Returns: main.TRUE if each device has a master
861 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800862 """
Jon Hall94fd0472014-12-08 11:52:42 -0800863 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 rawRoles = self.roles()
865 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800866 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800868 # print device
869 if device[ 'master' ] == "none":
870 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800871 return main.FALSE
872 return main.TRUE
873
Jon Halld4d4b372015-01-28 16:02:41 -0800874 except TypeError:
875 main.log.exception( self.name + ": Object not as expected" )
876 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800877 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800878 main.log.error( self.name + ": EOF exception found" )
879 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800880 main.cleanup()
881 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800882 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800883 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800884 main.cleanup()
885 main.exit()
886
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800888 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400889 Returns string of paths, and the cost.
890 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800891 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400892 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
894 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800895 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800896 main.log.error( "Error in getting paths" )
897 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400898 else:
kelvin8ec71442015-01-15 16:57:00 -0800899 path = handle.split( ";" )[ 0 ]
900 cost = handle.split( ";" )[ 1 ]
901 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800902 except TypeError:
903 main.log.exception( self.name + ": Object not as expected" )
904 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800906 main.log.error( self.name + ": EOF exception found" )
907 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400908 main.cleanup()
909 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800910 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800911 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400912 main.cleanup()
913 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800914
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800916 """
Jon Hallffb386d2014-11-21 13:43:38 -0800917 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400918 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800919 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800920 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400921 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700924 cmdStr += " -j"
925 handle = self.sendline( cmdStr )
Jon Hallbaf53162015-12-17 17:04:34 -0800926 try:
927 # TODO: Maybe make this less hardcoded
928 # ConsistentMap Exceptions
929 assert "org.onosproject.store.service" not in handle
930 # Node not leader
931 assert "java.lang.IllegalStateException" not in handle
932 except AssertionError:
933 main.log.error( "Error in processing '" + cmdStr + "' " +
934 "command: " + str( handle ) )
935 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700936 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800937 except TypeError:
938 main.log.exception( self.name + ": Object not as expected" )
939 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400940 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800941 main.log.error( self.name + ": EOF exception found" )
942 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400943 main.cleanup()
944 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800945 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800946 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400947 main.cleanup()
948 main.exit()
949
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800951 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400952 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800953
Jon Hallefbd9792015-03-05 16:11:36 -0800954 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 partial mac address
956
Jon Hall42db6dc2014-10-24 19:03:48 -0400957 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800958 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400959 try:
kelvin8ec71442015-01-15 16:57:00 -0800960 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400961 return None
962 else:
963 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 rawHosts = self.hosts()
965 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800966 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800968 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800969 if not host:
970 pass
971 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400972 return host
973 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800974 except TypeError:
975 main.log.exception( self.name + ": Object not as expected" )
976 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800978 main.log.error( self.name + ": EOF exception found" )
979 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400980 main.cleanup()
981 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800983 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400984 main.cleanup()
985 main.exit()
986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
989 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400990 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800991
andrewonlab3f0a4af2014-10-17 12:25:14 -0400992 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400994 IMPORTANT:
995 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800996 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400997 Furthermore, it assumes that value of VLAN is '-1'
998 Description:
kelvin8ec71442015-01-15 16:57:00 -0800999 Converts mininet hosts ( h1, h2, h3... ) into
1000 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1001 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001002 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001004
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001006 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001007 hostHex = hex( int( host ) ).zfill( 12 )
1008 hostHex = str( hostHex ).replace( 'x', '0' )
1009 i = iter( str( hostHex ) )
1010 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1011 hostHex = hostHex + "/-1"
1012 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001015
Jon Halld4d4b372015-01-28 16:02:41 -08001016 except TypeError:
1017 main.log.exception( self.name + ": Object not as expected" )
1018 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001022 main.cleanup()
1023 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001025 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001026 main.cleanup()
1027 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001028
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001030 """
andrewonlabe6745342014-10-17 14:29:13 -04001031 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001032 * hostIdOne: ONOS host id for host1
1033 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001034 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001035 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001036 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001037 Returns:
1038 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001039 """
andrewonlabe6745342014-10-17 14:29:13 -04001040 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1042 " " + str( hostIdTwo )
1043 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -08001044 if re.search( "Error", handle ):
1045 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001046 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001047 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001048 else:
1049 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001050 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1051 match = re.search('id=0x([\da-f]+),', handle)
1052 if match:
1053 return match.group()[3:-1]
1054 else:
1055 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001056 main.log.debug( "Response from ONOS was: " +
1057 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001058 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001059 except TypeError:
1060 main.log.exception( self.name + ": Object not as expected" )
1061 return None
andrewonlabe6745342014-10-17 14:29:13 -04001062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.error( self.name + ": EOF exception found" )
1064 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001065 main.cleanup()
1066 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
andrewonlab7b31d232014-10-24 13:31:47 -04001074 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * ingressDevice: device id of ingress device
1076 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001077 Optional:
1078 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001079 Description:
1080 Adds an optical intent by specifying an ingress and egress device
1081 Returns:
1082 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001083 """
andrewonlab7b31d232014-10-24 13:31:47 -04001084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1086 " " + str( egressDevice )
1087 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001088 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001089 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001090 main.log.error( "Error in adding Optical intent" )
1091 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001092 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001093 main.log.info( "Optical intent installed between " +
1094 str( ingressDevice ) + " and " +
1095 str( egressDevice ) )
1096 match = re.search('id=0x([\da-f]+),', handle)
1097 if match:
1098 return match.group()[3:-1]
1099 else:
1100 main.log.error( "Error, intent ID not found" )
1101 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001102 except TypeError:
1103 main.log.exception( self.name + ": Object not as expected" )
1104 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001106 main.log.error( self.name + ": EOF exception found" )
1107 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001108 main.cleanup()
1109 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001112 main.cleanup()
1113 main.exit()
1114
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001116 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 ingressDevice,
1118 egressDevice,
1119 portIngress="",
1120 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001121 ethType="",
1122 ethSrc="",
1123 ethDst="",
1124 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001126 ipProto="",
1127 ipSrc="",
1128 ipDst="",
1129 tcpSrc="",
1130 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001131 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001132 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 * ingressDevice: device id of ingress device
1134 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001135 Optional:
1136 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001137 * ethSrc: specify ethSrc ( i.e. src mac addr )
1138 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001139 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001141 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001142 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001143 * ipSrc: specify ip source address
1144 * ipDst: specify ip destination address
1145 * tcpSrc: specify tcp source port
1146 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001147 Description:
kelvin8ec71442015-01-15 16:57:00 -08001148 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001149 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001150 Returns:
1151 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001152
Jon Halle3f39ff2015-01-13 11:50:53 -08001153 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001154 options developers provide for point-to-point
1155 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001156 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001157 try:
kelvin8ec71442015-01-15 16:57:00 -08001158 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001159 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001161 and not ipProto and not ipSrc and not ipDst \
1162 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001163 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001164
andrewonlab289e4b72014-10-21 21:24:18 -04001165 else:
andrewonlab36af3822014-11-18 17:48:18 -05001166 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001167
andrewonlab0c0a6772014-10-22 12:31:18 -04001168 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001169 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001170 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001171 cmd += " --ethSrc " + str( ethSrc )
1172 if ethDst:
1173 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001174 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001175 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001177 cmd += " --lambda "
1178 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001179 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001180 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001181 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001182 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001184 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001186 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001187 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001188
kelvin8ec71442015-01-15 16:57:00 -08001189 # Check whether the user appended the port
1190 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 if "/" in ingressDevice:
1192 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001193 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001195 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001196 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001197 # Would it make sense to throw an exception and exit
1198 # the test?
1199 return None
andrewonlab36af3822014-11-18 17:48:18 -05001200
kelvin8ec71442015-01-15 16:57:00 -08001201 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 str( ingressDevice ) + "/" +\
1203 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001204
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 if "/" in egressDevice:
1206 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001207 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001209 main.log.error( "You must specify the egress port" )
1210 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001211
kelvin8ec71442015-01-15 16:57:00 -08001212 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 str( egressDevice ) + "/" +\
1214 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001215
kelvin-onlab898a6c62015-01-16 14:13:53 -08001216 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001217 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001218 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001219 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001220 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001221 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001222 # TODO: print out all the options in this message?
1223 main.log.info( "Point-to-point intent installed between " +
1224 str( ingressDevice ) + " and " +
1225 str( egressDevice ) )
1226 match = re.search('id=0x([\da-f]+),', handle)
1227 if match:
1228 return match.group()[3:-1]
1229 else:
1230 main.log.error( "Error, intent ID not found" )
1231 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001232 except TypeError:
1233 main.log.exception( self.name + ": Object not as expected" )
1234 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001235 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.error( self.name + ": EOF exception found" )
1237 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001238 main.cleanup()
1239 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001240 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001241 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001242 main.cleanup()
1243 main.exit()
1244
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001246 self,
shahshreyac2f97072015-03-19 17:04:29 -07001247 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001248 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001249 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001251 ethType="",
1252 ethSrc="",
1253 ethDst="",
1254 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001256 ipProto="",
1257 ipSrc="",
1258 ipDst="",
1259 tcpSrc="",
1260 tcpDst="",
1261 setEthSrc="",
1262 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001263 """
shahshreyad0c80432014-12-04 16:56:05 -08001264 Note:
shahshreya70622b12015-03-19 17:19:00 -07001265 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001266 is same. That is, all ingress devices include port numbers
1267 with a "/" or all ingress devices could specify device
1268 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001269 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001270 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001271 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001273 Optional:
1274 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001275 * ethSrc: specify ethSrc ( i.e. src mac addr )
1276 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001277 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001279 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001280 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001281 * ipSrc: specify ip source address
1282 * ipDst: specify ip destination address
1283 * tcpSrc: specify tcp source port
1284 * tcpDst: specify tcp destination port
1285 * setEthSrc: action to Rewrite Source MAC Address
1286 * setEthDst: action to Rewrite Destination MAC Address
1287 Description:
kelvin8ec71442015-01-15 16:57:00 -08001288 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001289 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001290 Returns:
1291 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001292
Jon Halle3f39ff2015-01-13 11:50:53 -08001293 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001294 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001295 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001296 """
shahshreyad0c80432014-12-04 16:56:05 -08001297 try:
kelvin8ec71442015-01-15 16:57:00 -08001298 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001299 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 and not ipProto and not ipSrc and not ipDst\
1302 and not tcpSrc and not tcpDst and not setEthSrc\
1303 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001304 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001305
1306 else:
1307 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001308
shahshreyad0c80432014-12-04 16:56:05 -08001309 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001310 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001311 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001312 cmd += " --ethSrc " + str( ethSrc )
1313 if ethDst:
1314 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001315 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001316 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001318 cmd += " --lambda "
1319 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001320 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001321 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001322 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001323 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001324 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001325 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001326 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001327 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001328 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001329 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001330 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001331 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001332 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001333
kelvin8ec71442015-01-15 16:57:00 -08001334 # Check whether the user appended the port
1335 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001336
1337 if portIngressList is None:
1338 for ingressDevice in ingressDeviceList:
1339 if "/" in ingressDevice:
1340 cmd += " " + str( ingressDevice )
1341 else:
1342 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001343 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001344 # TODO: perhaps more meaningful return
1345 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001346 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001347 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001348 for ingressDevice, portIngress in zip( ingressDeviceList,
1349 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001350 cmd += " " + \
1351 str( ingressDevice ) + "/" +\
1352 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001353 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001354 main.log.error( "Device list and port list does not " +
1355 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001356 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if "/" in egressDevice:
1358 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001359 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001361 main.log.error( "You must specify " +
1362 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001363 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001364
kelvin8ec71442015-01-15 16:57:00 -08001365 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 str( egressDevice ) + "/" +\
1367 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001368 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001369 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001370 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001371 main.log.error( "Error in adding multipoint-to-singlepoint " +
1372 "intent" )
1373 return None
shahshreyad0c80432014-12-04 16:56:05 -08001374 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001375 match = re.search('id=0x([\da-f]+),', handle)
1376 if match:
1377 return match.group()[3:-1]
1378 else:
1379 main.log.error( "Error, intent ID not found" )
1380 return None
1381 except TypeError:
1382 main.log.exception( self.name + ": Object not as expected" )
1383 return None
1384 except pexpect.EOF:
1385 main.log.error( self.name + ": EOF exception found" )
1386 main.log.error( self.name + ": " + self.handle.before )
1387 main.cleanup()
1388 main.exit()
1389 except Exception:
1390 main.log.exception( self.name + ": Uncaught exception!" )
1391 main.cleanup()
1392 main.exit()
1393
1394 def addSinglepointToMultipointIntent(
1395 self,
1396 ingressDevice,
1397 egressDeviceList,
1398 portIngress="",
1399 portEgressList=None,
1400 ethType="",
1401 ethSrc="",
1402 ethDst="",
1403 bandwidth="",
1404 lambdaAlloc=False,
1405 ipProto="",
1406 ipSrc="",
1407 ipDst="",
1408 tcpSrc="",
1409 tcpDst="",
1410 setEthSrc="",
1411 setEthDst="" ):
1412 """
1413 Note:
1414 This function assumes the format of all egress devices
1415 is same. That is, all egress devices include port numbers
1416 with a "/" or all egress devices could specify device
1417 ids and port numbers seperately.
1418 Required:
1419 * EgressDeviceList: List of device ids of egress device
1420 ( Atleast 2 eress devices required in the list )
1421 * ingressDevice: device id of ingress device
1422 Optional:
1423 * ethType: specify ethType
1424 * ethSrc: specify ethSrc ( i.e. src mac addr )
1425 * ethDst: specify ethDst ( i.e. dst mac addr )
1426 * bandwidth: specify bandwidth capacity of link
1427 * lambdaAlloc: if True, intent will allocate lambda
1428 for the specified intent
1429 * ipProto: specify ip protocol
1430 * ipSrc: specify ip source address
1431 * ipDst: specify ip destination address
1432 * tcpSrc: specify tcp source port
1433 * tcpDst: specify tcp destination port
1434 * setEthSrc: action to Rewrite Source MAC Address
1435 * setEthDst: action to Rewrite Destination MAC Address
1436 Description:
1437 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1438 specifying device id's and optional fields
1439 Returns:
1440 A string of the intent id or None on error
1441
1442 NOTE: This function may change depending on the
1443 options developers provide for singlepoint-to-multipoint
1444 intent via cli
1445 """
1446 try:
1447 # If there are no optional arguments
1448 if not ethType and not ethSrc and not ethDst\
1449 and not bandwidth and not lambdaAlloc\
1450 and not ipProto and not ipSrc and not ipDst\
1451 and not tcpSrc and not tcpDst and not setEthSrc\
1452 and not setEthDst:
1453 cmd = "add-single-to-multi-intent"
1454
1455 else:
1456 cmd = "add-single-to-multi-intent"
1457
1458 if ethType:
1459 cmd += " --ethType " + str( ethType )
1460 if ethSrc:
1461 cmd += " --ethSrc " + str( ethSrc )
1462 if ethDst:
1463 cmd += " --ethDst " + str( ethDst )
1464 if bandwidth:
1465 cmd += " --bandwidth " + str( bandwidth )
1466 if lambdaAlloc:
1467 cmd += " --lambda "
1468 if ipProto:
1469 cmd += " --ipProto " + str( ipProto )
1470 if ipSrc:
1471 cmd += " --ipSrc " + str( ipSrc )
1472 if ipDst:
1473 cmd += " --ipDst " + str( ipDst )
1474 if tcpSrc:
1475 cmd += " --tcpSrc " + str( tcpSrc )
1476 if tcpDst:
1477 cmd += " --tcpDst " + str( tcpDst )
1478 if setEthSrc:
1479 cmd += " --setEthSrc " + str( setEthSrc )
1480 if setEthDst:
1481 cmd += " --setEthDst " + str( setEthDst )
1482
1483 # Check whether the user appended the port
1484 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001485
kelvin-onlabb9408212015-04-01 13:34:04 -07001486 if "/" in ingressDevice:
1487 cmd += " " + str( ingressDevice )
1488 else:
1489 if not portIngress:
1490 main.log.error( "You must specify " +
1491 "the Ingress port" )
1492 return main.FALSE
1493
1494 cmd += " " +\
1495 str( ingressDevice ) + "/" +\
1496 str( portIngress )
1497
1498 if portEgressList is None:
1499 for egressDevice in egressDeviceList:
1500 if "/" in egressDevice:
1501 cmd += " " + str( egressDevice )
1502 else:
1503 main.log.error( "You must specify " +
1504 "the egress port" )
1505 # TODO: perhaps more meaningful return
1506 return main.FALSE
1507 else:
1508 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001509 for egressDevice, portEgress in zip( egressDeviceList,
1510 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001511 cmd += " " + \
1512 str( egressDevice ) + "/" +\
1513 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001514 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001515 main.log.error( "Device list and port list does not " +
1516 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001517 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001518 handle = self.sendline( cmd )
1519 # If error, return error message
1520 if re.search( "Error", handle ):
1521 main.log.error( "Error in adding singlepoint-to-multipoint " +
1522 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001523 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001524 else:
1525 match = re.search('id=0x([\da-f]+),', handle)
1526 if match:
1527 return match.group()[3:-1]
1528 else:
1529 main.log.error( "Error, intent ID not found" )
1530 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001531 except TypeError:
1532 main.log.exception( self.name + ": Object not as expected" )
1533 return None
shahshreyad0c80432014-12-04 16:56:05 -08001534 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001535 main.log.error( self.name + ": EOF exception found" )
1536 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001537 main.cleanup()
1538 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001539 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001540 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001541 main.cleanup()
1542 main.exit()
1543
Hari Krishna9e232602015-04-13 17:29:08 -07001544 def addMplsIntent(
1545 self,
1546 ingressDevice,
1547 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001548 ingressPort="",
1549 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001550 ethType="",
1551 ethSrc="",
1552 ethDst="",
1553 bandwidth="",
1554 lambdaAlloc=False,
1555 ipProto="",
1556 ipSrc="",
1557 ipDst="",
1558 tcpSrc="",
1559 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001560 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001561 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001562 priority=""):
1563 """
1564 Required:
1565 * ingressDevice: device id of ingress device
1566 * egressDevice: device id of egress device
1567 Optional:
1568 * ethType: specify ethType
1569 * ethSrc: specify ethSrc ( i.e. src mac addr )
1570 * ethDst: specify ethDst ( i.e. dst mac addr )
1571 * bandwidth: specify bandwidth capacity of link
1572 * lambdaAlloc: if True, intent will allocate lambda
1573 for the specified intent
1574 * ipProto: specify ip protocol
1575 * ipSrc: specify ip source address
1576 * ipDst: specify ip destination address
1577 * tcpSrc: specify tcp source port
1578 * tcpDst: specify tcp destination port
1579 * ingressLabel: Ingress MPLS label
1580 * egressLabel: Egress MPLS label
1581 Description:
1582 Adds MPLS intent by
1583 specifying device id's and optional fields
1584 Returns:
1585 A string of the intent id or None on error
1586
1587 NOTE: This function may change depending on the
1588 options developers provide for MPLS
1589 intent via cli
1590 """
1591 try:
1592 # If there are no optional arguments
1593 if not ethType and not ethSrc and not ethDst\
1594 and not bandwidth and not lambdaAlloc \
1595 and not ipProto and not ipSrc and not ipDst \
1596 and not tcpSrc and not tcpDst and not ingressLabel \
1597 and not egressLabel:
1598 cmd = "add-mpls-intent"
1599
1600 else:
1601 cmd = "add-mpls-intent"
1602
1603 if ethType:
1604 cmd += " --ethType " + str( ethType )
1605 if ethSrc:
1606 cmd += " --ethSrc " + str( ethSrc )
1607 if ethDst:
1608 cmd += " --ethDst " + str( ethDst )
1609 if bandwidth:
1610 cmd += " --bandwidth " + str( bandwidth )
1611 if lambdaAlloc:
1612 cmd += " --lambda "
1613 if ipProto:
1614 cmd += " --ipProto " + str( ipProto )
1615 if ipSrc:
1616 cmd += " --ipSrc " + str( ipSrc )
1617 if ipDst:
1618 cmd += " --ipDst " + str( ipDst )
1619 if tcpSrc:
1620 cmd += " --tcpSrc " + str( tcpSrc )
1621 if tcpDst:
1622 cmd += " --tcpDst " + str( tcpDst )
1623 if ingressLabel:
1624 cmd += " --ingressLabel " + str( ingressLabel )
1625 if egressLabel:
1626 cmd += " --egressLabel " + str( egressLabel )
1627 if priority:
1628 cmd += " --priority " + str( priority )
1629
1630 # Check whether the user appended the port
1631 # or provided it as an input
1632 if "/" in ingressDevice:
1633 cmd += " " + str( ingressDevice )
1634 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001635 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001636 main.log.error( "You must specify the ingress port" )
1637 return None
1638
1639 cmd += " " + \
1640 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001641 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001642
1643 if "/" in egressDevice:
1644 cmd += " " + str( egressDevice )
1645 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001646 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001647 main.log.error( "You must specify the egress port" )
1648 return None
1649
1650 cmd += " " +\
1651 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001652 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001653
1654 handle = self.sendline( cmd )
1655 # If error, return error message
1656 if re.search( "Error", handle ):
1657 main.log.error( "Error in adding mpls intent" )
1658 return None
1659 else:
1660 # TODO: print out all the options in this message?
1661 main.log.info( "MPLS intent installed between " +
1662 str( ingressDevice ) + " and " +
1663 str( egressDevice ) )
1664 match = re.search('id=0x([\da-f]+),', handle)
1665 if match:
1666 return match.group()[3:-1]
1667 else:
1668 main.log.error( "Error, intent ID not found" )
1669 return None
1670 except TypeError:
1671 main.log.exception( self.name + ": Object not as expected" )
1672 return None
1673 except pexpect.EOF:
1674 main.log.error( self.name + ": EOF exception found" )
1675 main.log.error( self.name + ": " + self.handle.before )
1676 main.cleanup()
1677 main.exit()
1678 except Exception:
1679 main.log.exception( self.name + ": Uncaught exception!" )
1680 main.cleanup()
1681 main.exit()
1682
Jon Hallefbd9792015-03-05 16:11:36 -08001683 def removeIntent( self, intentId, app='org.onosproject.cli',
1684 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001685 """
shahshreya1c818fc2015-02-26 13:44:08 -08001686 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001687 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001688 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001689 -p or --purge: Purge the intent from the store after removal
1690
Jon Halle3f39ff2015-01-13 11:50:53 -08001691 Returns:
1692 main.False on error and
1693 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001694 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001695 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001696 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001697 if purge:
1698 cmdStr += " -p"
1699 if sync:
1700 cmdStr += " -s"
1701
1702 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001704 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001705 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001706 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001707 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001708 # TODO: Should this be main.TRUE
1709 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001710 except TypeError:
1711 main.log.exception( self.name + ": Object not as expected" )
1712 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001713 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001714 main.log.error( self.name + ": EOF exception found" )
1715 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001716 main.cleanup()
1717 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001718 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001719 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001720 main.cleanup()
1721 main.exit()
1722
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001723 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001724 """
1725 Purges all WITHDRAWN Intents
1726 """
1727 try:
1728 cmdStr = "purge-intents"
1729 handle = self.sendline( cmdStr )
1730 if re.search( "Error", handle ):
1731 main.log.error( "Error in purging intents" )
1732 return main.FALSE
1733 else:
1734 return main.TRUE
1735 except TypeError:
1736 main.log.exception( self.name + ": Object not as expected" )
1737 return None
1738 except pexpect.EOF:
1739 main.log.error( self.name + ": EOF exception found" )
1740 main.log.error( self.name + ": " + self.handle.before )
1741 main.cleanup()
1742 main.exit()
1743 except Exception:
1744 main.log.exception( self.name + ": Uncaught exception!" )
1745 main.cleanup()
1746 main.exit()
1747
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001749 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001750 NOTE: This method should be used after installing application:
1751 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001752 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001753 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001754 Description:
1755 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001756 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001757 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001758 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001760 cmdStr += " -j"
1761 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001762 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001763 except TypeError:
1764 main.log.exception( self.name + ": Object not as expected" )
1765 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001769 main.cleanup()
1770 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001771 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001772 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001773 main.cleanup()
1774 main.exit()
1775
pingping-lin54b03372015-08-13 14:43:10 -07001776 def ipv4RouteNumber( self ):
1777 """
1778 NOTE: This method should be used after installing application:
1779 onos-app-sdnip
1780 Description:
1781 Obtain the total IPv4 routes number in the system
1782 """
1783 try:
1784 cmdStr = "routes -s -j"
1785 handle = self.sendline( cmdStr )
1786 jsonResult = json.loads( handle )
1787 return jsonResult['totalRoutes4']
pingping-lin54b03372015-08-13 14:43:10 -07001788 except TypeError:
1789 main.log.exception( self.name + ": Object not as expected" )
1790 return None
1791 except pexpect.EOF:
1792 main.log.error( self.name + ": EOF exception found" )
1793 main.log.error( self.name + ": " + self.handle.before )
1794 main.cleanup()
1795 main.exit()
1796 except Exception:
1797 main.log.exception( self.name + ": Uncaught exception!" )
1798 main.cleanup()
1799 main.exit()
1800
pingping-lin8244a3b2015-09-16 13:36:56 -07001801 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001802 """
andrewonlab377693f2014-10-21 16:00:30 -04001803 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001804 * jsonFormat: enable output formatting in json
pingping-lin8244a3b2015-09-16 13:36:56 -07001805 * summary: whether only output the intent summary
1806 * type: only output a certain type of intent
1807 This options is valid only when jsonFormat is true and summary is
1808 true
andrewonlabe6745342014-10-17 14:29:13 -04001809 Description:
pingping-lin8244a3b2015-09-16 13:36:56 -07001810 Obtain intents
kelvin-onlab898a6c62015-01-16 14:13:53 -08001811 """
andrewonlabe6745342014-10-17 14:29:13 -04001812 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001813 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001814 if summary:
1815 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001817 cmdStr += " -j"
1818 handle = self.sendline( cmdStr )
pingping-lin8244a3b2015-09-16 13:36:56 -07001819 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001820 if "TYPE" in args.keys():
1821 type = args[ "TYPE" ]
1822 else:
1823 type = ""
pingping-lin8244a3b2015-09-16 13:36:56 -07001824 if jsonFormat and summary and ( type != "" ):
1825 jsonResult = json.loads( handle )
1826 if type in jsonResult.keys():
1827 return jsonResult[ type ]
1828 else:
1829 main.log.error( "unknown TYPE, return all types of intents" )
1830 return handle
1831 else:
1832 return handle
pingping-lin54b03372015-08-13 14:43:10 -07001833
1834 except TypeError:
1835 main.log.exception( self.name + ": Object not as expected" )
1836 return None
1837 except pexpect.EOF:
1838 main.log.error( self.name + ": EOF exception found" )
1839 main.log.error( self.name + ": " + self.handle.before )
1840 main.cleanup()
1841 main.exit()
1842 except Exception:
1843 main.log.exception( self.name + ": Uncaught exception!" )
1844 main.cleanup()
1845 main.exit()
1846
pingping-lin8244a3b2015-09-16 13:36:56 -07001847
kelvin-onlab54400a92015-02-26 18:05:51 -08001848 def getIntentState(self, intentsId, intentsJson=None):
1849 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001850 Check intent state.
1851 Accepts a single intent ID (string type) or a list of intent IDs.
1852 Returns the state(string type) of the id if a single intent ID is
1853 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001854 Returns a dictionary with intent IDs as the key and its
1855 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001856 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001857 intentId: intent ID (string type)
1858 intentsJson: parsed json object from the onos:intents api
1859 Returns:
1860 state = An intent's state- INSTALL,WITHDRAWN etc.
1861 stateDict = Dictionary of intent's state. intent ID as the keys and
1862 state as the values.
1863 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001864 try:
1865 state = "State is Undefined"
1866 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001867 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001868 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001869 intentsJsonTemp = json.loads( intentsJson )
1870 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001871 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001872 if intentsId == intent[ 'id' ]:
1873 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001874 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001875 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1876 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001877 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001878 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001879 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001880 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001881 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001882 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001883 if intentsId[ i ] == intents[ 'id' ]:
1884 stateDict[ 'state' ] = intents[ 'state' ]
1885 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001886 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001887 break
Jon Hallefbd9792015-03-05 16:11:36 -08001888 if len( intentsId ) != len( dictList ):
1889 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001890 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001891 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001892 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001893 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001894 except TypeError:
1895 main.log.exception( self.name + ": Object not as expected" )
1896 return None
1897 except pexpect.EOF:
1898 main.log.error( self.name + ": EOF exception found" )
1899 main.log.error( self.name + ": " + self.handle.before )
1900 main.cleanup()
1901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001902 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001903 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001904 main.cleanup()
1905 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001906
kelvin-onlabf512e942015-06-08 19:42:59 -07001907 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001908 """
1909 Description:
1910 Check intents state
1911 Required:
1912 intentsId - List of intents ID to be checked
1913 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001914 expectedState - Check the expected state(s) of each intents
1915 state in the list.
1916 *NOTE: You can pass in a list of expected state,
1917 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001918 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001919 Returns main.TRUE only if all intent are the same as expected states
1920 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001921 """
1922 try:
1923 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001924 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001925 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001926 if len( intentsId ) != len( intentsDict ):
1927 main.log.info( self.name + "There is something wrong " +
1928 "getting intents state" )
1929 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001930
1931 if isinstance( expectedState, types.StringType ):
1932 for intents in intentsDict:
1933 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001934 main.log.debug( self.name + " : Intent ID - " +
1935 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001936 " actual state = " +
1937 intents.get( 'state' )
1938 + " does not equal expected state = "
1939 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001940 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001941
1942 elif isinstance( expectedState, types.ListType ):
1943 for intents in intentsDict:
1944 if not any( state == intents.get( 'state' ) for state in
1945 expectedState ):
1946 main.log.debug( self.name + " : Intent ID - " +
1947 intents.get( 'id' ) +
1948 " actual state = " +
1949 intents.get( 'state' ) +
1950 " does not equal expected states = "
1951 + str( expectedState ) )
1952 returnValue = main.FALSE
1953
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001954 if returnValue == main.TRUE:
1955 main.log.info( self.name + ": All " +
1956 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001957 " intents are in " + str( expectedState ) +
1958 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001959 return returnValue
1960 except TypeError:
1961 main.log.exception( self.name + ": Object not as expected" )
1962 return None
1963 except pexpect.EOF:
1964 main.log.error( self.name + ": EOF exception found" )
1965 main.log.error( self.name + ": " + self.handle.before )
1966 main.cleanup()
1967 main.exit()
1968 except Exception:
1969 main.log.exception( self.name + ": Uncaught exception!" )
1970 main.cleanup()
1971 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04001972
GlennRCed771242016-01-13 17:02:47 -08001973 def checkIntentSummary( self, timeout=60 ):
1974 """
1975 Description:
1976 Check the number of installed intents.
1977 Optional:
1978 timeout - the timeout for pexcept
1979 Return:
1980 Returns main.TRUE only if the number of all installed intents are the same as total intents number
1981 , otherwise, returns main.FALSE.
1982 """
1983
1984 try:
1985 cmd = "intents -s -j"
1986
1987 # Check response if something wrong
1988 response = self.sendline( cmd, timeout=timeout )
1989 if response == None:
1990 return main.False
1991 response = json.loads( response )
1992
1993 # get total and installed number, see if they are match
1994 allState = response.get( 'all' )
1995 if allState.get('total') == allState.get('installed'):
1996 main.log.info( 'successful verified Intents' )
1997 return main.TRUE
1998 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format(allState.get('total'), allState.get('installed')))
1999 return main.FALSE
2000
2001 except TypeError:
2002 main.log.exception( self.name + ": Object not as expected" )
2003 return None
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
2007 main.cleanup()
2008 main.exit()
2009 except Exception:
2010 main.log.exception( self.name + ": Uncaught exception!" )
2011 main.cleanup()
2012 main.exit()
2013
2014 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002015 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002016 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002017 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002018 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002019 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002020 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002021 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002022 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002023 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002024 cmdStr += " -j "
2025 cmdStr += state
2026
2027 response = self.sendline( cmdStr, timeout = timeout )
2028
2029 return response
2030
2031 except pexpect.TIMEOUT:
2032 main.log.error( self.name + ": ONOS timeout" )
2033 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002034 except TypeError:
2035 main.log.exception( self.name + ": Object not as expected" )
2036 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002038 main.log.error( self.name + ": EOF exception found" )
2039 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002040 main.cleanup()
2041 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002042 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002043 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002044 main.cleanup()
2045 main.exit()
2046
GlennRCed771242016-01-13 17:02:47 -08002047
2048 def checkFlowsState( self, isPENDING = True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002049 """
2050 Description:
GlennRCed771242016-01-13 17:02:47 -08002051 Check the if all the current flows are in ADDED state
2052 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows, if the count of those states is 0,
2053 which means all current flows are in ADDED state, and return main.TRUE
2054 otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002055 Optional:
GlennRCed771242016-01-13 17:02:47 -08002056 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002057 Return:
2058 returnValue - Returns main.TRUE only if all flows are in
GlennRCed771242016-01-13 17:02:47 -08002059 ADDED state or PENDING_ADD if the isPENDING_ADD
pingping-linbab7f8a2015-09-21 17:33:36 -07002060 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002061 """
2062 try:
GlennRCed771242016-01-13 17:02:47 -08002063 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2064 checkedStates = []
2065 statesCount = [0, 0, 0, 0]
2066 for s in states:
2067 checkedStates.append( json.loads( self.flows( state=s, timeout = timeout ) ) )
kelvin-onlabf0594d72015-05-19 17:25:12 -07002068
GlennRCed771242016-01-13 17:02:47 -08002069 for i in range (len( states )):
2070 for c in checkedStates[i]:
2071 statesCount[i] += int( c.get("flowCount"))
2072 main.log.info(states[i] + " flows: "+ str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002073
GlennRCed771242016-01-13 17:02:47 -08002074 # We want to count PENDING_ADD if isPENDING is true
2075 if isPENDING:
2076 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2077 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002078 else:
GlennRCed771242016-01-13 17:02:47 -08002079 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2080 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002081
GlennRCed771242016-01-13 17:02:47 -08002082 return main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002083
kelvin-onlab4df89f22015-04-13 18:10:23 -07002084 except TypeError:
2085 main.log.exception( self.name + ": Object not as expected" )
2086 return None
2087 except pexpect.EOF:
2088 main.log.error( self.name + ": EOF exception found" )
2089 main.log.error( self.name + ": " + self.handle.before )
2090 main.cleanup()
2091 main.exit()
2092 except Exception:
2093 main.log.exception( self.name + ": Uncaught exception!" )
2094 main.cleanup()
2095 main.exit()
2096
GlennRCed771242016-01-13 17:02:47 -08002097 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2098 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002099 """
andrewonlab87852b02014-11-19 18:44:19 -05002100 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002101 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002102 a specific point-to-point intent definition
2103 Required:
GlennRCed771242016-01-13 17:02:47 -08002104 * ingress: specify source dpid
2105 * egress: specify destination dpid
2106 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002107 Optional:
GlennRCed771242016-01-13 17:02:47 -08002108 * offset: the keyOffset is where the next batch of intents
2109 will be installed
2110 Returns: If failed to push test intents, it will returen None,
2111 if successful, return true.
2112 Timeout expection will return None,
2113 TypeError will return false
2114 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002115 """
andrewonlab87852b02014-11-19 18:44:19 -05002116 try:
GlennRCed771242016-01-13 17:02:47 -08002117 if background:
2118 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002119 else:
GlennRCed771242016-01-13 17:02:47 -08002120 back = ""
2121 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
2122 ingress,
2123 egress,
2124 batchSize,
2125 offset,
2126 back )
2127 response = self.sendline( cmd, timeout=timeout )
2128 main.log.info( response )
2129 if response == None:
2130 return None
2131
2132 # TODO: We should handle if there is failure in installation
2133 return main.TRUE
2134
2135 except pexpect.TIMEOUT:
2136 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002137 return None
andrewonlab87852b02014-11-19 18:44:19 -05002138 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002139 main.log.error( self.name + ": EOF exception found" )
2140 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002141 main.cleanup()
2142 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002143 except TypeError:
2144 main.log.exception( self.name + ": Object not as expected" )
2145 return main.FALSE
Jon Hallfebb1c72015-03-05 13:30:09 -08002146 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002147 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002148 main.cleanup()
2149 main.exit()
2150
kelvin-onlabd3b64892015-01-20 13:26:24 -08002151 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002152 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002153 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002154 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002156 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002157 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002158 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002159 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002160 cmdStr += " -j"
2161 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002162 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002163 except TypeError:
2164 main.log.exception( self.name + ": Object not as expected" )
2165 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002166 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002167 main.log.error( self.name + ": EOF exception found" )
2168 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002169 main.cleanup()
2170 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002171 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002172 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002173 main.cleanup()
2174 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002175
kelvin-onlabd3b64892015-01-20 13:26:24 -08002176 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002177 """
2178 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002179 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002180 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002181 """
andrewonlab867212a2014-10-22 20:13:38 -04002182 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002183 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002184 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002185 cmdStr += " -j"
2186 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002187 if handle:
2188 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002189 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002190 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002191 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002192 else:
2193 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002194 except TypeError:
2195 main.log.exception( self.name + ": Object not as expected" )
2196 return None
andrewonlab867212a2014-10-22 20:13:38 -04002197 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002198 main.log.error( self.name + ": EOF exception found" )
2199 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002200 main.cleanup()
2201 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002202 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002203 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002204 main.cleanup()
2205 main.exit()
2206
kelvin8ec71442015-01-15 16:57:00 -08002207 # Wrapper functions ****************
2208 # Wrapper functions use existing driver
2209 # functions and extends their use case.
2210 # For example, we may use the output of
2211 # a normal driver function, and parse it
2212 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002213
kelvin-onlabd3b64892015-01-20 13:26:24 -08002214 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002215 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002216 Description:
2217 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002218 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002219 try:
kelvin8ec71442015-01-15 16:57:00 -08002220 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002221 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002222 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002223
kelvin8ec71442015-01-15 16:57:00 -08002224 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002225 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2226 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002227 match = re.search('id=0x([\da-f]+),', intents)
2228 if match:
2229 tmpId = match.group()[3:-1]
2230 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002231 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002232
Jon Halld4d4b372015-01-28 16:02:41 -08002233 except TypeError:
2234 main.log.exception( self.name + ": Object not as expected" )
2235 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002236 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002237 main.log.error( self.name + ": EOF exception found" )
2238 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002239 main.cleanup()
2240 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002241 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002242 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002243 main.cleanup()
2244 main.exit()
2245
Jon Hall30b82fa2015-03-04 17:15:43 -08002246 def FlowAddedCount( self, deviceId ):
2247 """
2248 Determine the number of flow rules for the given device id that are
2249 in the added state
2250 """
2251 try:
2252 cmdStr = "flows any " + str( deviceId ) + " | " +\
2253 "grep 'state=ADDED' | wc -l"
2254 handle = self.sendline( cmdStr )
2255 return handle
2256 except pexpect.EOF:
2257 main.log.error( self.name + ": EOF exception found" )
2258 main.log.error( self.name + ": " + self.handle.before )
2259 main.cleanup()
2260 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002261 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002262 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002263 main.cleanup()
2264 main.exit()
2265
kelvin-onlabd3b64892015-01-20 13:26:24 -08002266 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002267 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002268 Use 'devices' function to obtain list of all devices
2269 and parse the result to obtain a list of all device
2270 id's. Returns this list. Returns empty list if no
2271 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002272 List is ordered sequentially
2273
andrewonlab3e15ead2014-10-15 14:21:34 -04002274 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002275 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002276 the ids. By obtaining the list of device ids on the fly,
2277 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002278 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002279 try:
kelvin8ec71442015-01-15 16:57:00 -08002280 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002281 devicesStr = self.devices( jsonFormat=False )
2282 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002283
kelvin-onlabd3b64892015-01-20 13:26:24 -08002284 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002285 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002286 return idList
kelvin8ec71442015-01-15 16:57:00 -08002287
2288 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002290 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002291 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002292 # Split list further into arguments before and after string
2293 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002294 # append to idList
2295 for arg in tempList:
2296 idList.append( arg.split( "id=" )[ 1 ] )
2297 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002298
Jon Halld4d4b372015-01-28 16:02:41 -08002299 except TypeError:
2300 main.log.exception( self.name + ": Object not as expected" )
2301 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002302 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002303 main.log.error( self.name + ": EOF exception found" )
2304 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002305 main.cleanup()
2306 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002307 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002308 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002309 main.cleanup()
2310 main.exit()
2311
kelvin-onlabd3b64892015-01-20 13:26:24 -08002312 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002313 """
andrewonlab7c211572014-10-15 16:45:20 -04002314 Uses 'nodes' function to obtain list of all nodes
2315 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002316 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002317 Returns:
2318 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002319 """
andrewonlab7c211572014-10-15 16:45:20 -04002320 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002321 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002323 # Sample nodesStr output
2324 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002325 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002326 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002327 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002328 nodesJson = json.loads( nodesStr )
2329 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002330 return idList
kelvin8ec71442015-01-15 16:57:00 -08002331
Jon Halld4d4b372015-01-28 16:02:41 -08002332 except TypeError:
2333 main.log.exception( self.name + ": Object not as expected" )
2334 return None
andrewonlab7c211572014-10-15 16:45:20 -04002335 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002336 main.log.error( self.name + ": EOF exception found" )
2337 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002338 main.cleanup()
2339 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002340 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002341 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002342 main.cleanup()
2343 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002344
kelvin-onlabd3b64892015-01-20 13:26:24 -08002345 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002346 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002347 Return the first device from the devices api whose 'id' contains 'dpid'
2348 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002349 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002350 try:
kelvin8ec71442015-01-15 16:57:00 -08002351 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002352 return None
2353 else:
kelvin8ec71442015-01-15 16:57:00 -08002354 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002355 rawDevices = self.devices()
2356 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002357 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002358 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002359 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2360 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002361 return device
2362 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002363 except TypeError:
2364 main.log.exception( self.name + ": Object not as expected" )
2365 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002366 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002367 main.log.error( self.name + ": EOF exception found" )
2368 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002369 main.cleanup()
2370 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002371 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002372 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002373 main.cleanup()
2374 main.exit()
2375
kelvin-onlabd3b64892015-01-20 13:26:24 -08002376 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002377 """
Jon Hallefbd9792015-03-05 16:11:36 -08002378 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002379 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002380 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002381
Jon Hall42db6dc2014-10-24 19:03:48 -04002382 Params: ip = ip used for the onos cli
2383 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002384 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002385 logLevel = level to log to. Currently accepts
2386 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002387
2388
kelvin-onlabd3b64892015-01-20 13:26:24 -08002389 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002390
Jon Hallefbd9792015-03-05 16:11:36 -08002391 Returns: main.TRUE if the number of switches and links are correct,
2392 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002393 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002394 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002395 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002396 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002397 if topology == {}:
2398 return main.ERROR
2399 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002400 # Is the number of switches is what we expected
2401 devices = topology.get( 'devices', False )
2402 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002403 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002404 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002405 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002406 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002407 linkCheck = ( int( links ) == int( numolink ) )
2408 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002409 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002410 output += "The number of links and switches match " +\
2411 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002412 result = main.TRUE
2413 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002414 output += "The number of links and switches does not match " +\
2415 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002416 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002417 output = output + "\n ONOS sees %i devices (%i expected) \
2418 and %i links (%i expected)" % (
2419 int( devices ), int( numoswitch ), int( links ),
2420 int( numolink ) )
2421 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002422 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002423 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002424 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002425 else:
Jon Hall390696c2015-05-05 17:13:41 -07002426 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002427 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002428 except TypeError:
2429 main.log.exception( self.name + ": Object not as expected" )
2430 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002431 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002432 main.log.error( self.name + ": EOF exception found" )
2433 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002434 main.cleanup()
2435 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002436 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002437 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002438 main.cleanup()
2439 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002440
kelvin-onlabd3b64892015-01-20 13:26:24 -08002441 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002442 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002443 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002444 deviceId must be the id of a device as seen in the onos devices command
2445 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002446 role must be either master, standby, or none
2447
Jon Halle3f39ff2015-01-13 11:50:53 -08002448 Returns:
2449 main.TRUE or main.FALSE based on argument verification and
2450 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002451 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002452 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002453 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002454 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002455 cmdStr = "device-role " +\
2456 str( deviceId ) + " " +\
2457 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002458 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002459 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002460 if re.search( "Error", handle ):
2461 # end color output to escape any colours
2462 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002463 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002464 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002465 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002466 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002467 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002468 main.log.error( "Invalid 'role' given to device_role(). " +
2469 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002470 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002471 except TypeError:
2472 main.log.exception( self.name + ": Object not as expected" )
2473 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002475 main.log.error( self.name + ": EOF exception found" )
2476 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002477 main.cleanup()
2478 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002479 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002480 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002481 main.cleanup()
2482 main.exit()
2483
kelvin-onlabd3b64892015-01-20 13:26:24 -08002484 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002485 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002486 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002487 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002488 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002489 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002490 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002491 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002492 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002493 cmdStr += " -j"
2494 handle = self.sendline( cmdStr )
2495 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002496 except TypeError:
2497 main.log.exception( self.name + ": Object not as expected" )
2498 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002500 main.log.error( self.name + ": EOF exception found" )
2501 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002502 main.cleanup()
2503 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002504 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002505 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002506 main.cleanup()
2507 main.exit()
2508
kelvin-onlabd3b64892015-01-20 13:26:24 -08002509 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002510 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002511 CLI command to get the current leader for the Election test application
2512 NOTE: Requires installation of the onos-app-election feature
2513 Returns: Node IP of the leader if one exists
2514 None if none exists
2515 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002516 """
Jon Hall94fd0472014-12-08 11:52:42 -08002517 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002518 cmdStr = "election-test-leader"
2519 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002520 # Leader
2521 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002522 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002523 nodeSearch = re.search( leaderPattern, response )
2524 if nodeSearch:
2525 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002526 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002527 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002528 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002529 # no leader
2530 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002531 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002532 nullSearch = re.search( nullPattern, response )
2533 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002534 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002535 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002536 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002537 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002538 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002539 if re.search( errorPattern, response ):
2540 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002541 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002542 return main.FALSE
2543 else:
Jon Hall390696c2015-05-05 17:13:41 -07002544 main.log.error( "Error in electionTestLeader on " + self.name +
2545 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002546 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002547 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002548 except TypeError:
2549 main.log.exception( self.name + ": Object not as expected" )
2550 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002551 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002552 main.log.error( self.name + ": EOF exception found" )
2553 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002554 main.cleanup()
2555 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002556 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002557 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002558 main.cleanup()
2559 main.exit()
2560
kelvin-onlabd3b64892015-01-20 13:26:24 -08002561 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002562 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002563 CLI command to run for leadership of the Election test application.
2564 NOTE: Requires installation of the onos-app-election feature
2565 Returns: Main.TRUE on success
2566 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002567 """
Jon Hall94fd0472014-12-08 11:52:42 -08002568 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002569 cmdStr = "election-test-run"
2570 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002571 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002572 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002573 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002574 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002575 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002576 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002577 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002578 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002579 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002580 errorPattern = "Command\snot\sfound"
2581 if re.search( errorPattern, response ):
2582 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002583 return main.FALSE
2584 else:
Jon Hall390696c2015-05-05 17:13:41 -07002585 main.log.error( "Error in electionTestRun on " + self.name +
2586 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002587 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002588 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002589 except TypeError:
2590 main.log.exception( self.name + ": Object not as expected" )
2591 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002593 main.log.error( self.name + ": EOF exception found" )
2594 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002595 main.cleanup()
2596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002598 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002599 main.cleanup()
2600 main.exit()
2601
kelvin-onlabd3b64892015-01-20 13:26:24 -08002602 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002603 """
Jon Hall94fd0472014-12-08 11:52:42 -08002604 * CLI command to withdraw the local node from leadership election for
2605 * the Election test application.
2606 #NOTE: Requires installation of the onos-app-election feature
2607 Returns: Main.TRUE on success
2608 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002609 """
Jon Hall94fd0472014-12-08 11:52:42 -08002610 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002611 cmdStr = "election-test-withdraw"
2612 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002613 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002614 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002615 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002616 if re.search( successPattern, response ):
2617 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002618 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002619 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002620 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002621 errorPattern = "Command\snot\sfound"
2622 if re.search( errorPattern, response ):
2623 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002624 return main.FALSE
2625 else:
Jon Hall390696c2015-05-05 17:13:41 -07002626 main.log.error( "Error in electionTestWithdraw on " +
2627 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002628 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002629 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002630 except TypeError:
2631 main.log.exception( self.name + ": Object not as expected" )
2632 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002633 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002634 main.log.error( self.name + ": EOF exception found" )
2635 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002636 main.cleanup()
2637 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002638 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002639 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002640 main.cleanup()
2641 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002642
kelvin8ec71442015-01-15 16:57:00 -08002643 def getDevicePortsEnabledCount( self, dpid ):
2644 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002645 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002646 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002647 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002648 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002649 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2650 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002651 if re.search( "No such device", output ):
2652 main.log.error( "Error in getting ports" )
2653 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002654 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002655 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002656 except TypeError:
2657 main.log.exception( self.name + ": Object not as expected" )
2658 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002659 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002660 main.log.error( self.name + ": EOF exception found" )
2661 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002662 main.cleanup()
2663 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002664 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002665 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002666 main.cleanup()
2667 main.exit()
2668
kelvin8ec71442015-01-15 16:57:00 -08002669 def getDeviceLinksActiveCount( self, dpid ):
2670 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002671 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002672 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002673 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002674 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002675 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2676 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002677 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002678 main.log.error( "Error in getting ports " )
2679 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002680 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002681 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002682 except TypeError:
2683 main.log.exception( self.name + ": Object not as expected" )
2684 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002685 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002686 main.log.error( self.name + ": EOF exception found" )
2687 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002688 main.cleanup()
2689 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002690 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002691 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002692 main.cleanup()
2693 main.exit()
2694
kelvin8ec71442015-01-15 16:57:00 -08002695 def getAllIntentIds( self ):
2696 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002697 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002698 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002699 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002700 cmdStr = "onos:intents | grep id="
2701 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002702 if re.search( "Error", output ):
2703 main.log.error( "Error in getting ports" )
2704 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002705 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002706 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002707 except TypeError:
2708 main.log.exception( self.name + ": Object not as expected" )
2709 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002710 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002711 main.log.error( self.name + ": EOF exception found" )
2712 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002713 main.cleanup()
2714 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002715 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002716 main.log.exception( self.name + ": Uncaught exception!" )
2717 main.cleanup()
2718 main.exit()
2719
Jon Hall73509952015-02-24 16:42:56 -08002720 def intentSummary( self ):
2721 """
Jon Hallefbd9792015-03-05 16:11:36 -08002722 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002723 """
2724 try:
2725 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002726 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002727 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002728 states.append( intent.get( 'state', None ) )
2729 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002730 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002731 return dict( out )
2732 except TypeError:
2733 main.log.exception( self.name + ": Object not as expected" )
2734 return None
2735 except pexpect.EOF:
2736 main.log.error( self.name + ": EOF exception found" )
2737 main.log.error( self.name + ": " + self.handle.before )
2738 main.cleanup()
2739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002740 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002741 main.log.exception( self.name + ": Uncaught exception!" )
2742 main.cleanup()
2743 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002744
Jon Hall61282e32015-03-19 11:34:11 -07002745 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002746 """
2747 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002748 Optional argument:
2749 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002750 """
Jon Hall63604932015-02-26 17:09:50 -08002751 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002752 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002753 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002754 cmdStr += " -j"
2755 output = self.sendline( cmdStr )
2756 return output
Jon Hall63604932015-02-26 17:09:50 -08002757 except TypeError:
2758 main.log.exception( self.name + ": Object not as expected" )
2759 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002760 except pexpect.EOF:
2761 main.log.error( self.name + ": EOF exception found" )
2762 main.log.error( self.name + ": " + self.handle.before )
2763 main.cleanup()
2764 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002765 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002766 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002767 main.cleanup()
2768 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002769
acsmarsa4a4d1e2015-07-10 16:01:24 -07002770 def leaderCandidates( self, jsonFormat=True ):
2771 """
2772 Returns the output of the leaders -c command.
2773 Optional argument:
2774 * jsonFormat - boolean indicating if you want output in json
2775 """
2776 try:
2777 cmdStr = "onos:leaders -c"
2778 if jsonFormat:
2779 cmdStr += " -j"
2780 output = self.sendline( cmdStr )
2781 return output
2782 except TypeError:
2783 main.log.exception( self.name + ": Object not as expected" )
2784 return None
2785 except pexpect.EOF:
2786 main.log.error( self.name + ": EOF exception found" )
2787 main.log.error( self.name + ": " + self.handle.before )
2788 main.cleanup()
2789 main.exit()
2790 except Exception:
2791 main.log.exception( self.name + ": Uncaught exception!" )
2792 main.cleanup()
2793 main.exit()
2794
2795 def specificLeaderCandidate(self,topic):
2796 """
2797 Returns a list in format [leader,candidate1,candidate2,...] for a given
2798 topic parameter and an empty list if the topic doesn't exist
2799 If no leader is elected leader in the returned list will be "none"
2800 Returns None if there is a type error processing the json object
2801 """
2802 try:
2803 cmdStr = "onos:leaders -c -j"
2804 output = self.sendline( cmdStr )
2805 output = json.loads(output)
2806 results = []
2807 for dict in output:
2808 if dict["topic"] == topic:
2809 leader = dict["leader"]
2810 candidates = re.split(", ",dict["candidates"][1:-1])
2811 results.append(leader)
2812 results.extend(candidates)
2813 return results
2814 except TypeError:
2815 main.log.exception( self.name + ": Object not as expected" )
2816 return None
2817 except pexpect.EOF:
2818 main.log.error( self.name + ": EOF exception found" )
2819 main.log.error( self.name + ": " + self.handle.before )
2820 main.cleanup()
2821 main.exit()
2822 except Exception:
2823 main.log.exception( self.name + ": Uncaught exception!" )
2824 main.cleanup()
2825 main.exit()
2826
Jon Hall61282e32015-03-19 11:34:11 -07002827 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002828 """
2829 Returns the output of the intent Pending map.
2830 """
Jon Hall63604932015-02-26 17:09:50 -08002831 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002832 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002833 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002834 cmdStr += " -j"
2835 output = self.sendline( cmdStr )
2836 return output
Jon Hall63604932015-02-26 17:09:50 -08002837 except TypeError:
2838 main.log.exception( self.name + ": Object not as expected" )
2839 return None
2840 except pexpect.EOF:
2841 main.log.error( self.name + ": EOF exception found" )
2842 main.log.error( self.name + ": " + self.handle.before )
2843 main.cleanup()
2844 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002845 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002846 main.log.exception( self.name + ": Uncaught exception!" )
2847 main.cleanup()
2848 main.exit()
2849
Jon Hall61282e32015-03-19 11:34:11 -07002850 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002851 """
2852 Returns the output of the raft partitions command for ONOS.
2853 """
Jon Hall61282e32015-03-19 11:34:11 -07002854 # Sample JSON
2855 # {
2856 # "leader": "tcp://10.128.30.11:7238",
2857 # "members": [
2858 # "tcp://10.128.30.11:7238",
2859 # "tcp://10.128.30.17:7238",
2860 # "tcp://10.128.30.13:7238",
2861 # ],
2862 # "name": "p1",
2863 # "term": 3
2864 # },
Jon Hall63604932015-02-26 17:09:50 -08002865 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002866 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002867 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002868 cmdStr += " -j"
2869 output = self.sendline( cmdStr )
2870 return output
Jon Hall63604932015-02-26 17:09:50 -08002871 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 Hall63604932015-02-26 17:09:50 -08002880 main.log.exception( self.name + ": Uncaught exception!" )
2881 main.cleanup()
2882 main.exit()
2883
Jon Hallbe379602015-03-24 13:39:32 -07002884 def apps( self, jsonFormat=True ):
2885 """
2886 Returns the output of the apps command for ONOS. This command lists
2887 information about installed ONOS applications
2888 """
2889 # Sample JSON object
2890 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2891 # "description":"ONOS OpenFlow protocol southbound providers",
2892 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2893 # "features":"[onos-openflow]","state":"ACTIVE"}]
2894 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002895 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002896 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002897 cmdStr += " -j"
2898 output = self.sendline( cmdStr )
2899 assert "Error executing command" not in output
2900 return output
Jon Hallbe379602015-03-24 13:39:32 -07002901 # FIXME: look at specific exceptions/Errors
2902 except AssertionError:
2903 main.log.error( "Error in processing onos:app command: " +
2904 str( output ) )
2905 return None
2906 except TypeError:
2907 main.log.exception( self.name + ": Object not as expected" )
2908 return None
2909 except pexpect.EOF:
2910 main.log.error( self.name + ": EOF exception found" )
2911 main.log.error( self.name + ": " + self.handle.before )
2912 main.cleanup()
2913 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002914 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002915 main.log.exception( self.name + ": Uncaught exception!" )
2916 main.cleanup()
2917 main.exit()
2918
Jon Hall146f1522015-03-24 15:33:24 -07002919 def appStatus( self, appName ):
2920 """
2921 Uses the onos:apps cli command to return the status of an application.
2922 Returns:
2923 "ACTIVE" - If app is installed and activated
2924 "INSTALLED" - If app is installed and deactivated
2925 "UNINSTALLED" - If app is not installed
2926 None - on error
2927 """
Jon Hall146f1522015-03-24 15:33:24 -07002928 try:
2929 if not isinstance( appName, types.StringType ):
2930 main.log.error( self.name + ".appStatus(): appName must be" +
2931 " a string" )
2932 return None
2933 output = self.apps( jsonFormat=True )
2934 appsJson = json.loads( output )
2935 state = None
2936 for app in appsJson:
2937 if appName == app.get('name'):
2938 state = app.get('state')
2939 break
2940 if state == "ACTIVE" or state == "INSTALLED":
2941 return state
2942 elif state is None:
2943 return "UNINSTALLED"
2944 elif state:
2945 main.log.error( "Unexpected state from 'onos:apps': " +
2946 str( state ) )
2947 return state
2948 except TypeError:
2949 main.log.exception( self.name + ": Object not as expected" )
2950 return None
2951 except pexpect.EOF:
2952 main.log.error( self.name + ": EOF exception found" )
2953 main.log.error( self.name + ": " + self.handle.before )
2954 main.cleanup()
2955 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002956 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002957 main.log.exception( self.name + ": Uncaught exception!" )
2958 main.cleanup()
2959 main.exit()
2960
Jon Hallbe379602015-03-24 13:39:32 -07002961 def app( self, appName, option ):
2962 """
2963 Interacts with the app command for ONOS. This command manages
2964 application inventory.
2965 """
Jon Hallbe379602015-03-24 13:39:32 -07002966 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002967 # Validate argument types
2968 valid = True
2969 if not isinstance( appName, types.StringType ):
2970 main.log.error( self.name + ".app(): appName must be a " +
2971 "string" )
2972 valid = False
2973 if not isinstance( option, types.StringType ):
2974 main.log.error( self.name + ".app(): option must be a string" )
2975 valid = False
2976 if not valid:
2977 return main.FALSE
2978 # Validate Option
2979 option = option.lower()
2980 # NOTE: Install may become a valid option
2981 if option == "activate":
2982 pass
2983 elif option == "deactivate":
2984 pass
2985 elif option == "uninstall":
2986 pass
2987 else:
2988 # Invalid option
2989 main.log.error( "The ONOS app command argument only takes " +
2990 "the values: (activate|deactivate|uninstall)" +
2991 "; was given '" + option + "'")
2992 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002993 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002994 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002995 if "Error executing command" in output:
2996 main.log.error( "Error in processing onos:app command: " +
2997 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002998 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002999 elif "No such application" in output:
3000 main.log.error( "The application '" + appName +
3001 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003002 return main.FALSE
3003 elif "Command not found:" in output:
3004 main.log.error( "Error in processing onos:app command: " +
3005 str( output ) )
3006 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003007 elif "Unsupported command:" in output:
3008 main.log.error( "Incorrect command given to 'app': " +
3009 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003010 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003011 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003012 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003013 return main.TRUE
3014 except TypeError:
3015 main.log.exception( self.name + ": Object not as expected" )
3016 return main.ERROR
3017 except pexpect.EOF:
3018 main.log.error( self.name + ": EOF exception found" )
3019 main.log.error( self.name + ": " + self.handle.before )
3020 main.cleanup()
3021 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003022 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003023 main.log.exception( self.name + ": Uncaught exception!" )
3024 main.cleanup()
3025 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003026
Jon Hallbd16b922015-03-26 17:53:15 -07003027 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003028 """
3029 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003030 appName is the hierarchical app name, not the feature name
3031 If check is True, method will check the status of the app after the
3032 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003033 Returns main.TRUE if the command was successfully sent
3034 main.FALSE if the cli responded with an error or given
3035 incorrect input
3036 """
3037 try:
3038 if not isinstance( appName, types.StringType ):
3039 main.log.error( self.name + ".activateApp(): appName must be" +
3040 " a string" )
3041 return main.FALSE
3042 status = self.appStatus( appName )
3043 if status == "INSTALLED":
3044 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003045 if check and response == main.TRUE:
3046 for i in range(10): # try 10 times then give up
3047 # TODO: Check with Thomas about this delay
3048 status = self.appStatus( appName )
3049 if status == "ACTIVE":
3050 return main.TRUE
3051 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003052 main.log.debug( "The state of application " +
3053 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003054 time.sleep( 1 )
3055 return main.FALSE
3056 else: # not 'check' or command didn't succeed
3057 return response
Jon Hall146f1522015-03-24 15:33:24 -07003058 elif status == "ACTIVE":
3059 return main.TRUE
3060 elif status == "UNINSTALLED":
3061 main.log.error( self.name + ": Tried to activate the " +
3062 "application '" + appName + "' which is not " +
3063 "installed." )
3064 else:
3065 main.log.error( "Unexpected return value from appStatus: " +
3066 str( status ) )
3067 return main.ERROR
3068 except TypeError:
3069 main.log.exception( self.name + ": Object not as expected" )
3070 return main.ERROR
3071 except pexpect.EOF:
3072 main.log.error( self.name + ": EOF exception found" )
3073 main.log.error( self.name + ": " + self.handle.before )
3074 main.cleanup()
3075 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003076 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003077 main.log.exception( self.name + ": Uncaught exception!" )
3078 main.cleanup()
3079 main.exit()
3080
Jon Hallbd16b922015-03-26 17:53:15 -07003081 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003082 """
3083 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003084 appName is the hierarchical app name, not the feature name
3085 If check is True, method will check the status of the app after the
3086 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003087 Returns main.TRUE if the command was successfully sent
3088 main.FALSE if the cli responded with an error or given
3089 incorrect input
3090 """
3091 try:
3092 if not isinstance( appName, types.StringType ):
3093 main.log.error( self.name + ".deactivateApp(): appName must " +
3094 "be a string" )
3095 return main.FALSE
3096 status = self.appStatus( appName )
3097 if status == "INSTALLED":
3098 return main.TRUE
3099 elif status == "ACTIVE":
3100 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003101 if check and response == main.TRUE:
3102 for i in range(10): # try 10 times then give up
3103 status = self.appStatus( appName )
3104 if status == "INSTALLED":
3105 return main.TRUE
3106 else:
3107 time.sleep( 1 )
3108 return main.FALSE
3109 else: # not check or command didn't succeed
3110 return response
Jon Hall146f1522015-03-24 15:33:24 -07003111 elif status == "UNINSTALLED":
3112 main.log.warn( self.name + ": Tried to deactivate the " +
3113 "application '" + appName + "' which is not " +
3114 "installed." )
3115 return main.TRUE
3116 else:
3117 main.log.error( "Unexpected return value from appStatus: " +
3118 str( status ) )
3119 return main.ERROR
3120 except TypeError:
3121 main.log.exception( self.name + ": Object not as expected" )
3122 return main.ERROR
3123 except pexpect.EOF:
3124 main.log.error( self.name + ": EOF exception found" )
3125 main.log.error( self.name + ": " + self.handle.before )
3126 main.cleanup()
3127 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003128 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003129 main.log.exception( self.name + ": Uncaught exception!" )
3130 main.cleanup()
3131 main.exit()
3132
Jon Hallbd16b922015-03-26 17:53:15 -07003133 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003134 """
3135 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003136 appName is the hierarchical app name, not the feature name
3137 If check is True, method will check the status of the app after the
3138 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003139 Returns main.TRUE if the command was successfully sent
3140 main.FALSE if the cli responded with an error or given
3141 incorrect input
3142 """
3143 # TODO: check with Thomas about the state machine for apps
3144 try:
3145 if not isinstance( appName, types.StringType ):
3146 main.log.error( self.name + ".uninstallApp(): appName must " +
3147 "be a string" )
3148 return main.FALSE
3149 status = self.appStatus( appName )
3150 if status == "INSTALLED":
3151 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003152 if check and response == main.TRUE:
3153 for i in range(10): # try 10 times then give up
3154 status = self.appStatus( appName )
3155 if status == "UNINSTALLED":
3156 return main.TRUE
3157 else:
3158 time.sleep( 1 )
3159 return main.FALSE
3160 else: # not check or command didn't succeed
3161 return response
Jon Hall146f1522015-03-24 15:33:24 -07003162 elif status == "ACTIVE":
3163 main.log.warn( self.name + ": Tried to uninstall the " +
3164 "application '" + appName + "' which is " +
3165 "currently active." )
3166 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003167 if check and response == main.TRUE:
3168 for i in range(10): # try 10 times then give up
3169 status = self.appStatus( appName )
3170 if status == "UNINSTALLED":
3171 return main.TRUE
3172 else:
3173 time.sleep( 1 )
3174 return main.FALSE
3175 else: # not check or command didn't succeed
3176 return response
Jon Hall146f1522015-03-24 15:33:24 -07003177 elif status == "UNINSTALLED":
3178 return main.TRUE
3179 else:
3180 main.log.error( "Unexpected return value from appStatus: " +
3181 str( status ) )
3182 return main.ERROR
3183 except TypeError:
3184 main.log.exception( self.name + ": Object not as expected" )
3185 return main.ERROR
3186 except pexpect.EOF:
3187 main.log.error( self.name + ": EOF exception found" )
3188 main.log.error( self.name + ": " + self.handle.before )
3189 main.cleanup()
3190 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003191 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003192 main.log.exception( self.name + ": Uncaught exception!" )
3193 main.cleanup()
3194 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003195
3196 def appIDs( self, jsonFormat=True ):
3197 """
3198 Show the mappings between app id and app names given by the 'app-ids'
3199 cli command
3200 """
3201 try:
3202 cmdStr = "app-ids"
3203 if jsonFormat:
3204 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003205 output = self.sendline( cmdStr )
3206 assert "Error executing command" not in output
3207 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003208 except AssertionError:
3209 main.log.error( "Error in processing onos:app-ids command: " +
3210 str( output ) )
3211 return None
3212 except TypeError:
3213 main.log.exception( self.name + ": Object not as expected" )
3214 return None
3215 except pexpect.EOF:
3216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
3218 main.cleanup()
3219 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003220 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003221 main.log.exception( self.name + ": Uncaught exception!" )
3222 main.cleanup()
3223 main.exit()
3224
3225 def appToIDCheck( self ):
3226 """
3227 This method will check that each application's ID listed in 'apps' is
3228 the same as the ID listed in 'app-ids'. The check will also check that
3229 there are no duplicate IDs issued. Note that an app ID should be
3230 a globaly unique numerical identifier for app/app-like features. Once
3231 an ID is registered, the ID is never freed up so that if an app is
3232 reinstalled it will have the same ID.
3233
3234 Returns: main.TRUE if the check passes and
3235 main.FALSE if the check fails or
3236 main.ERROR if there is some error in processing the test
3237 """
3238 try:
Jon Hall390696c2015-05-05 17:13:41 -07003239 bail = False
3240 ids = self.appIDs( jsonFormat=True )
3241 if ids:
3242 ids = json.loads( ids )
3243 else:
3244 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3245 bail = True
3246 apps = self.apps( jsonFormat=True )
3247 if apps:
3248 apps = json.loads( apps )
3249 else:
3250 main.log.error( "apps returned nothing:" + repr( apps ) )
3251 bail = True
3252 if bail:
3253 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003254 result = main.TRUE
3255 for app in apps:
3256 appID = app.get( 'id' )
3257 if appID is None:
3258 main.log.error( "Error parsing app: " + str( app ) )
3259 result = main.FALSE
3260 appName = app.get( 'name' )
3261 if appName is None:
3262 main.log.error( "Error parsing app: " + str( app ) )
3263 result = main.FALSE
3264 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003265 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003266 # main.log.debug( "Comparing " + str( app ) + " to " +
3267 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003268 if not current: # if ids doesn't have this id
3269 result = main.FALSE
3270 main.log.error( "'app-ids' does not have the ID for " +
3271 str( appName ) + " that apps does." )
3272 elif len( current ) > 1:
3273 # there is more than one app with this ID
3274 result = main.FALSE
3275 # We will log this later in the method
3276 elif not current[0][ 'name' ] == appName:
3277 currentName = current[0][ 'name' ]
3278 result = main.FALSE
3279 main.log.error( "'app-ids' has " + str( currentName ) +
3280 " registered under id:" + str( appID ) +
3281 " but 'apps' has " + str( appName ) )
3282 else:
3283 pass # id and name match!
3284 # now make sure that app-ids has no duplicates
3285 idsList = []
3286 namesList = []
3287 for item in ids:
3288 idsList.append( item[ 'id' ] )
3289 namesList.append( item[ 'name' ] )
3290 if len( idsList ) != len( set( idsList ) ) or\
3291 len( namesList ) != len( set( namesList ) ):
3292 main.log.error( "'app-ids' has some duplicate entries: \n"
3293 + json.dumps( ids,
3294 sort_keys=True,
3295 indent=4,
3296 separators=( ',', ': ' ) ) )
3297 result = main.FALSE
3298 return result
3299 except ( ValueError, TypeError ):
3300 main.log.exception( self.name + ": Object not as expected" )
3301 return main.ERROR
3302 except pexpect.EOF:
3303 main.log.error( self.name + ": EOF exception found" )
3304 main.log.error( self.name + ": " + self.handle.before )
3305 main.cleanup()
3306 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003307 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003308 main.log.exception( self.name + ": Uncaught exception!" )
3309 main.cleanup()
3310 main.exit()
3311
Jon Hallfb760a02015-04-13 15:35:03 -07003312 def getCfg( self, component=None, propName=None, short=False,
3313 jsonFormat=True ):
3314 """
3315 Get configuration settings from onos cli
3316 Optional arguments:
3317 component - Optionally only list configurations for a specific
3318 component. If None, all components with configurations
3319 are displayed. Case Sensitive string.
3320 propName - If component is specified, propName option will show
3321 only this specific configuration from that component.
3322 Case Sensitive string.
3323 jsonFormat - Returns output as json. Note that this will override
3324 the short option
3325 short - Short, less verbose, version of configurations.
3326 This is overridden by the json option
3327 returns:
3328 Output from cli as a string or None on error
3329 """
3330 try:
3331 baseStr = "cfg"
3332 cmdStr = " get"
3333 componentStr = ""
3334 if component:
3335 componentStr += " " + component
3336 if propName:
3337 componentStr += " " + propName
3338 if jsonFormat:
3339 baseStr += " -j"
3340 elif short:
3341 baseStr += " -s"
3342 output = self.sendline( baseStr + cmdStr + componentStr )
3343 assert "Error executing command" not in output
3344 return output
3345 except AssertionError:
3346 main.log.error( "Error in processing 'cfg get' command: " +
3347 str( output ) )
3348 return None
3349 except TypeError:
3350 main.log.exception( self.name + ": Object not as expected" )
3351 return None
3352 except pexpect.EOF:
3353 main.log.error( self.name + ": EOF exception found" )
3354 main.log.error( self.name + ": " + self.handle.before )
3355 main.cleanup()
3356 main.exit()
3357 except Exception:
3358 main.log.exception( self.name + ": Uncaught exception!" )
3359 main.cleanup()
3360 main.exit()
3361
3362 def setCfg( self, component, propName, value=None, check=True ):
3363 """
3364 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003365 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003366 component - The case sensitive name of the component whose
3367 property is to be set
3368 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003369 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003370 value - The value to set the property to. If None, will unset the
3371 property and revert it to it's default value(if applicable)
3372 check - Boolean, Check whether the option was successfully set this
3373 only applies when a value is given.
3374 returns:
3375 main.TRUE on success or main.FALSE on failure. If check is False,
3376 will return main.TRUE unless there is an error
3377 """
3378 try:
3379 baseStr = "cfg"
3380 cmdStr = " set " + str( component ) + " " + str( propName )
3381 if value is not None:
3382 cmdStr += " " + str( value )
3383 output = self.sendline( baseStr + cmdStr )
3384 assert "Error executing command" not in output
3385 if value and check:
3386 results = self.getCfg( component=str( component ),
3387 propName=str( propName ),
3388 jsonFormat=True )
3389 # Check if current value is what we just set
3390 try:
3391 jsonOutput = json.loads( results )
3392 current = jsonOutput[ 'value' ]
3393 except ( ValueError, TypeError ):
3394 main.log.exception( "Error parsing cfg output" )
3395 main.log.error( "output:" + repr( results ) )
3396 return main.FALSE
3397 if current == str( value ):
3398 return main.TRUE
3399 return main.FALSE
3400 return main.TRUE
3401 except AssertionError:
3402 main.log.error( "Error in processing 'cfg set' command: " +
3403 str( output ) )
3404 return main.FALSE
3405 except TypeError:
3406 main.log.exception( self.name + ": Object not as expected" )
3407 return main.FALSE
3408 except pexpect.EOF:
3409 main.log.error( self.name + ": EOF exception found" )
3410 main.log.error( self.name + ": " + self.handle.before )
3411 main.cleanup()
3412 main.exit()
3413 except Exception:
3414 main.log.exception( self.name + ": Uncaught exception!" )
3415 main.cleanup()
3416 main.exit()
3417
Jon Hall390696c2015-05-05 17:13:41 -07003418 def setTestAdd( self, setName, values ):
3419 """
3420 CLI command to add elements to a distributed set.
3421 Arguments:
3422 setName - The name of the set to add to.
3423 values - The value(s) to add to the set, space seperated.
3424 Example usages:
3425 setTestAdd( "set1", "a b c" )
3426 setTestAdd( "set2", "1" )
3427 returns:
3428 main.TRUE on success OR
3429 main.FALSE if elements were already in the set OR
3430 main.ERROR on error
3431 """
3432 try:
3433 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3434 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003435 try:
3436 # TODO: Maybe make this less hardcoded
3437 # ConsistentMap Exceptions
3438 assert "org.onosproject.store.service" not in output
3439 # Node not leader
3440 assert "java.lang.IllegalStateException" not in output
3441 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003442 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003443 "command: " + str( output ) )
3444 retryTime = 30 # Conservative time, given by Madan
3445 main.log.info( "Waiting " + str( retryTime ) +
3446 "seconds before retrying." )
3447 time.sleep( retryTime ) # Due to change in mastership
3448 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003449 assert "Error executing command" not in output
3450 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3451 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3452 main.log.info( self.name + ": " + output )
3453 if re.search( positiveMatch, output):
3454 return main.TRUE
3455 elif re.search( negativeMatch, output):
3456 return main.FALSE
3457 else:
3458 main.log.error( self.name + ": setTestAdd did not" +
3459 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003460 main.log.debug( self.name + " actual: " + repr( output ) )
3461 return main.ERROR
3462 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003463 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003464 str( output ) )
3465 return main.ERROR
3466 except TypeError:
3467 main.log.exception( self.name + ": Object not as expected" )
3468 return main.ERROR
3469 except pexpect.EOF:
3470 main.log.error( self.name + ": EOF exception found" )
3471 main.log.error( self.name + ": " + self.handle.before )
3472 main.cleanup()
3473 main.exit()
3474 except Exception:
3475 main.log.exception( self.name + ": Uncaught exception!" )
3476 main.cleanup()
3477 main.exit()
3478
3479 def setTestRemove( self, setName, values, clear=False, retain=False ):
3480 """
3481 CLI command to remove elements from a distributed set.
3482 Required arguments:
3483 setName - The name of the set to remove from.
3484 values - The value(s) to remove from the set, space seperated.
3485 Optional arguments:
3486 clear - Clear all elements from the set
3487 retain - Retain only the given values. (intersection of the
3488 original set and the given set)
3489 returns:
3490 main.TRUE on success OR
3491 main.FALSE if the set was not changed OR
3492 main.ERROR on error
3493 """
3494 try:
3495 cmdStr = "set-test-remove "
3496 if clear:
3497 cmdStr += "-c " + str( setName )
3498 elif retain:
3499 cmdStr += "-r " + str( setName ) + " " + str( values )
3500 else:
3501 cmdStr += str( setName ) + " " + str( values )
3502 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003503 try:
3504 # TODO: Maybe make this less hardcoded
3505 # ConsistentMap Exceptions
3506 assert "org.onosproject.store.service" not in output
3507 # Node not leader
3508 assert "java.lang.IllegalStateException" not in output
3509 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003510 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003511 "command: " + str( output ) )
3512 retryTime = 30 # Conservative time, given by Madan
3513 main.log.info( "Waiting " + str( retryTime ) +
3514 "seconds before retrying." )
3515 time.sleep( retryTime ) # Due to change in mastership
3516 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003517 assert "Error executing command" not in output
3518 main.log.info( self.name + ": " + output )
3519 if clear:
3520 pattern = "Set " + str( setName ) + " cleared"
3521 if re.search( pattern, output ):
3522 return main.TRUE
3523 elif retain:
3524 positivePattern = str( setName ) + " was pruned to contain " +\
3525 "only elements of set \[(.*)\]"
3526 negativePattern = str( setName ) + " was not changed by " +\
3527 "retaining only elements of the set " +\
3528 "\[(.*)\]"
3529 if re.search( positivePattern, output ):
3530 return main.TRUE
3531 elif re.search( negativePattern, output ):
3532 return main.FALSE
3533 else:
3534 positivePattern = "\[(.*)\] was removed from the set " +\
3535 str( setName )
3536 if ( len( values.split() ) == 1 ):
3537 negativePattern = "\[(.*)\] was not in set " +\
3538 str( setName )
3539 else:
3540 negativePattern = "No element of \[(.*)\] was in set " +\
3541 str( setName )
3542 if re.search( positivePattern, output ):
3543 return main.TRUE
3544 elif re.search( negativePattern, output ):
3545 return main.FALSE
3546 main.log.error( self.name + ": setTestRemove did not" +
3547 " match expected output" )
3548 main.log.debug( self.name + " expected: " + pattern )
3549 main.log.debug( self.name + " actual: " + repr( output ) )
3550 return main.ERROR
3551 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003552 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003553 str( output ) )
3554 return main.ERROR
3555 except TypeError:
3556 main.log.exception( self.name + ": Object not as expected" )
3557 return main.ERROR
3558 except pexpect.EOF:
3559 main.log.error( self.name + ": EOF exception found" )
3560 main.log.error( self.name + ": " + self.handle.before )
3561 main.cleanup()
3562 main.exit()
3563 except Exception:
3564 main.log.exception( self.name + ": Uncaught exception!" )
3565 main.cleanup()
3566 main.exit()
3567
3568 def setTestGet( self, setName, values="" ):
3569 """
3570 CLI command to get the elements in a distributed set.
3571 Required arguments:
3572 setName - The name of the set to remove from.
3573 Optional arguments:
3574 values - The value(s) to check if in the set, space seperated.
3575 returns:
3576 main.ERROR on error OR
3577 A list of elements in the set if no optional arguments are
3578 supplied OR
3579 A tuple containing the list then:
3580 main.FALSE if the given values are not in the set OR
3581 main.TRUE if the given values are in the set OR
3582 """
3583 try:
3584 values = str( values ).strip()
3585 setName = str( setName ).strip()
3586 length = len( values.split() )
3587 containsCheck = None
3588 # Patterns to match
3589 setPattern = "\[(.*)\]"
3590 pattern = "Items in set " + setName + ":\n" + setPattern
3591 containsTrue = "Set " + setName + " contains the value " + values
3592 containsFalse = "Set " + setName + " did not contain the value " +\
3593 values
3594 containsAllTrue = "Set " + setName + " contains the the subset " +\
3595 setPattern
3596 containsAllFalse = "Set " + setName + " did not contain the the" +\
3597 " subset " + setPattern
3598
3599 cmdStr = "set-test-get "
3600 cmdStr += setName + " " + values
3601 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003602 try:
3603 # TODO: Maybe make this less hardcoded
3604 # ConsistentMap Exceptions
3605 assert "org.onosproject.store.service" not in output
3606 # Node not leader
3607 assert "java.lang.IllegalStateException" not in output
3608 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003609 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003610 "command: " + str( output ) )
3611 retryTime = 30 # Conservative time, given by Madan
3612 main.log.info( "Waiting " + str( retryTime ) +
3613 "seconds before retrying." )
3614 time.sleep( retryTime ) # Due to change in mastership
3615 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003616 assert "Error executing command" not in output
3617 main.log.info( self.name + ": " + output )
3618
3619 if length == 0:
3620 match = re.search( pattern, output )
3621 else: # if given values
3622 if length == 1: # Contains output
3623 patternTrue = pattern + "\n" + containsTrue
3624 patternFalse = pattern + "\n" + containsFalse
3625 else: # ContainsAll output
3626 patternTrue = pattern + "\n" + containsAllTrue
3627 patternFalse = pattern + "\n" + containsAllFalse
3628 matchTrue = re.search( patternTrue, output )
3629 matchFalse = re.search( patternFalse, output )
3630 if matchTrue:
3631 containsCheck = main.TRUE
3632 match = matchTrue
3633 elif matchFalse:
3634 containsCheck = main.FALSE
3635 match = matchFalse
3636 else:
3637 main.log.error( self.name + " setTestGet did not match " +\
3638 "expected output" )
3639 main.log.debug( self.name + " expected: " + pattern )
3640 main.log.debug( self.name + " actual: " + repr( output ) )
3641 match = None
3642 if match:
3643 setMatch = match.group( 1 )
3644 if setMatch == '':
3645 setList = []
3646 else:
3647 setList = setMatch.split( ", " )
3648 if length > 0:
3649 return ( setList, containsCheck )
3650 else:
3651 return setList
3652 else: # no match
3653 main.log.error( self.name + ": setTestGet did not" +
3654 " match expected output" )
3655 main.log.debug( self.name + " expected: " + pattern )
3656 main.log.debug( self.name + " actual: " + repr( output ) )
3657 return main.ERROR
3658 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003659 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003660 str( output ) )
3661 return main.ERROR
3662 except TypeError:
3663 main.log.exception( self.name + ": Object not as expected" )
3664 return main.ERROR
3665 except pexpect.EOF:
3666 main.log.error( self.name + ": EOF exception found" )
3667 main.log.error( self.name + ": " + self.handle.before )
3668 main.cleanup()
3669 main.exit()
3670 except Exception:
3671 main.log.exception( self.name + ": Uncaught exception!" )
3672 main.cleanup()
3673 main.exit()
3674
3675 def setTestSize( self, setName ):
3676 """
3677 CLI command to get the elements in a distributed set.
3678 Required arguments:
3679 setName - The name of the set to remove from.
3680 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003681 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003682 None on error
3683 """
3684 try:
3685 # TODO: Should this check against the number of elements returned
3686 # and then return true/false based on that?
3687 setName = str( setName ).strip()
3688 # Patterns to match
3689 setPattern = "\[(.*)\]"
3690 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3691 setPattern
3692 cmdStr = "set-test-get -s "
3693 cmdStr += setName
3694 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003695 try:
3696 # TODO: Maybe make this less hardcoded
3697 # ConsistentMap Exceptions
3698 assert "org.onosproject.store.service" not in output
3699 # Node not leader
3700 assert "java.lang.IllegalStateException" not in output
3701 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003702 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003703 "command: " + str( output ) )
3704 retryTime = 30 # Conservative time, given by Madan
3705 main.log.info( "Waiting " + str( retryTime ) +
3706 "seconds before retrying." )
3707 time.sleep( retryTime ) # Due to change in mastership
3708 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003709 assert "Error executing command" not in output
3710 main.log.info( self.name + ": " + output )
3711 match = re.search( pattern, output )
3712 if match:
3713 setSize = int( match.group( 1 ) )
3714 setMatch = match.group( 2 )
3715 if len( setMatch.split() ) == setSize:
3716 main.log.info( "The size returned by " + self.name +
3717 " matches the number of elements in " +
3718 "the returned set" )
3719 else:
3720 main.log.error( "The size returned by " + self.name +
3721 " does not match the number of " +
3722 "elements in the returned set." )
3723 return setSize
3724 else: # no match
3725 main.log.error( self.name + ": setTestGet did not" +
3726 " match expected output" )
3727 main.log.debug( self.name + " expected: " + pattern )
3728 main.log.debug( self.name + " actual: " + repr( output ) )
3729 return None
3730 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003731 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003732 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003733 return None
Jon Hall390696c2015-05-05 17:13:41 -07003734 except TypeError:
3735 main.log.exception( self.name + ": Object not as expected" )
3736 return None
3737 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 Hall80daded2015-05-27 16:07:00 -07003747 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003748 """
3749 Command to list the various counters in the system.
3750 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003751 if jsonFormat, a string of the json object returned by the cli
3752 command
3753 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003754 None on error
3755 """
Jon Hall390696c2015-05-05 17:13:41 -07003756 try:
3757 counters = {}
3758 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003759 if jsonFormat:
3760 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003761 output = self.sendline( cmdStr )
3762 assert "Error executing command" not in output
3763 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003764 return output
Jon Hall390696c2015-05-05 17:13:41 -07003765 except AssertionError:
3766 main.log.error( "Error in processing 'counters' command: " +
3767 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003768 return None
Jon Hall390696c2015-05-05 17:13:41 -07003769 except TypeError:
3770 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003771 return None
Jon Hall390696c2015-05-05 17:13:41 -07003772 except pexpect.EOF:
3773 main.log.error( self.name + ": EOF exception found" )
3774 main.log.error( self.name + ": " + self.handle.before )
3775 main.cleanup()
3776 main.exit()
3777 except Exception:
3778 main.log.exception( self.name + ": Uncaught exception!" )
3779 main.cleanup()
3780 main.exit()
3781
Jon Halle1a3b752015-07-22 13:02:46 -07003782 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003783 """
Jon Halle1a3b752015-07-22 13:02:46 -07003784 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003785 Required arguments:
3786 counter - The name of the counter to increment.
3787 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003788 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003789 inMemory - use in memory map for the counter
3790 returns:
3791 integer value of the counter or
3792 None on Error
3793 """
3794 try:
3795 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003796 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003797 cmdStr = "counter-test-increment "
3798 if inMemory:
3799 cmdStr += "-i "
3800 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003801 if delta != 1:
3802 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003803 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003804 try:
3805 # TODO: Maybe make this less hardcoded
3806 # ConsistentMap Exceptions
3807 assert "org.onosproject.store.service" not in output
3808 # Node not leader
3809 assert "java.lang.IllegalStateException" not in output
3810 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003811 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003812 "command: " + str( output ) )
3813 retryTime = 30 # Conservative time, given by Madan
3814 main.log.info( "Waiting " + str( retryTime ) +
3815 "seconds before retrying." )
3816 time.sleep( retryTime ) # Due to change in mastership
3817 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003818 assert "Error executing command" not in output
3819 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003820 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003821 match = re.search( pattern, output )
3822 if match:
3823 return int( match.group( 1 ) )
3824 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003825 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003826 " match expected output." )
3827 main.log.debug( self.name + " expected: " + pattern )
3828 main.log.debug( self.name + " actual: " + repr( output ) )
3829 return None
3830 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003831 main.log.error( "Error in processing '" + cmdStr + "'" +
Jon Hall390696c2015-05-05 17:13:41 -07003832 " command: " + str( output ) )
3833 return None
3834 except TypeError:
3835 main.log.exception( self.name + ": Object not as expected" )
3836 return None
3837 except pexpect.EOF:
3838 main.log.error( self.name + ": EOF exception found" )
3839 main.log.error( self.name + ": " + self.handle.before )
3840 main.cleanup()
3841 main.exit()
3842 except Exception:
3843 main.log.exception( self.name + ": Uncaught exception!" )
3844 main.cleanup()
3845 main.exit()
3846
Jon Halle1a3b752015-07-22 13:02:46 -07003847 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
3848 """
3849 CLI command to get a distributed counter then add a delta to it.
3850 Required arguments:
3851 counter - The name of the counter to increment.
3852 Optional arguments:
3853 delta - The long to add to the counter
3854 inMemory - use in memory map for the counter
3855 returns:
3856 integer value of the counter or
3857 None on Error
3858 """
3859 try:
3860 counter = str( counter )
3861 delta = int( delta )
3862 cmdStr = "counter-test-increment -g "
3863 if inMemory:
3864 cmdStr += "-i "
3865 cmdStr += counter
3866 if delta != 1:
3867 cmdStr += " " + str( delta )
3868 output = self.sendline( cmdStr )
3869 try:
3870 # TODO: Maybe make this less hardcoded
3871 # ConsistentMap Exceptions
3872 assert "org.onosproject.store.service" not in output
3873 # Node not leader
3874 assert "java.lang.IllegalStateException" not in output
3875 except AssertionError:
3876 main.log.error( "Error in processing '" + cmdStr + "' " +
3877 "command: " + str( output ) )
3878 retryTime = 30 # Conservative time, given by Madan
3879 main.log.info( "Waiting " + str( retryTime ) +
3880 "seconds before retrying." )
3881 time.sleep( retryTime ) # Due to change in mastership
3882 output = self.sendline( cmdStr )
3883 assert "Error executing command" not in output
3884 main.log.info( self.name + ": " + output )
3885 pattern = counter + " was updated to (-?\d+)"
3886 match = re.search( pattern, output )
3887 if match:
3888 return int( match.group( 1 ) )
3889 else:
3890 main.log.error( self.name + ": counterTestGetAndAdd did not" +
3891 " match expected output." )
3892 main.log.debug( self.name + " expected: " + pattern )
3893 main.log.debug( self.name + " actual: " + repr( output ) )
3894 return None
3895 except AssertionError:
3896 main.log.error( "Error in processing '" + cmdStr + "'" +
3897 " command: " + str( output ) )
3898 return None
3899 except TypeError:
3900 main.log.exception( self.name + ": Object not as expected" )
3901 return None
3902 except pexpect.EOF:
3903 main.log.error( self.name + ": EOF exception found" )
3904 main.log.error( self.name + ": " + self.handle.before )
3905 main.cleanup()
3906 main.exit()
3907 except Exception:
3908 main.log.exception( self.name + ": Uncaught exception!" )
3909 main.cleanup()
3910 main.exit()
3911
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003912 def summary( self, jsonFormat=True ):
3913 """
3914 Description: Execute summary command in onos
3915 Returns: json object ( summary -j ), returns main.FALSE if there is
3916 no output
3917
3918 """
3919 try:
3920 cmdStr = "summary"
3921 if jsonFormat:
3922 cmdStr += " -j"
3923 handle = self.sendline( cmdStr )
3924
3925 if re.search( "Error:", handle ):
3926 main.log.error( self.name + ": summary() response: " +
3927 str( handle ) )
3928 if not handle:
3929 main.log.error( self.name + ": There is no output in " +
3930 "summary command" )
3931 return main.FALSE
3932 return handle
3933 except TypeError:
3934 main.log.exception( self.name + ": Object not as expected" )
3935 return None
3936 except pexpect.EOF:
3937 main.log.error( self.name + ": EOF exception found" )
3938 main.log.error( self.name + ": " + self.handle.before )
3939 main.cleanup()
3940 main.exit()
3941 except Exception:
3942 main.log.exception( self.name + ": Uncaught exception!" )
3943 main.cleanup()
3944 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07003945
3946 def transactionalMapGet( self, keyName, inMemory=False ):
3947 """
3948 CLI command to get the value of a key in a consistent map using
3949 transactions. This a test function and can only get keys from the
3950 test map hard coded into the cli command
3951 Required arguments:
3952 keyName - The name of the key to get
3953 Optional arguments:
3954 inMemory - use in memory map for the counter
3955 returns:
3956 The string value of the key or
3957 None on Error
3958 """
3959 try:
3960 keyName = str( keyName )
3961 cmdStr = "transactional-map-test-get "
3962 if inMemory:
3963 cmdStr += "-i "
3964 cmdStr += keyName
3965 output = self.sendline( cmdStr )
3966 try:
3967 # TODO: Maybe make this less hardcoded
3968 # ConsistentMap Exceptions
3969 assert "org.onosproject.store.service" not in output
3970 # Node not leader
3971 assert "java.lang.IllegalStateException" not in output
3972 except AssertionError:
3973 main.log.error( "Error in processing '" + cmdStr + "' " +
3974 "command: " + str( output ) )
3975 return None
3976 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
3977 if "Key " + keyName + " not found." in output:
3978 return None
3979 else:
3980 match = re.search( pattern, output )
3981 if match:
3982 return match.groupdict()[ 'value' ]
3983 else:
3984 main.log.error( self.name + ": transactionlMapGet did not" +
3985 " match expected output." )
3986 main.log.debug( self.name + " expected: " + pattern )
3987 main.log.debug( self.name + " actual: " + repr( output ) )
3988 return None
3989 except TypeError:
3990 main.log.exception( self.name + ": Object not as expected" )
3991 return None
3992 except pexpect.EOF:
3993 main.log.error( self.name + ": EOF exception found" )
3994 main.log.error( self.name + ": " + self.handle.before )
3995 main.cleanup()
3996 main.exit()
3997 except Exception:
3998 main.log.exception( self.name + ": Uncaught exception!" )
3999 main.cleanup()
4000 main.exit()
4001
4002 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4003 """
4004 CLI command to put a value into 'numKeys' number of keys in a
4005 consistent map using transactions. This a test function and can only
4006 put into keys named 'Key#' of the test map hard coded into the cli command
4007 Required arguments:
4008 numKeys - Number of keys to add the value to
4009 value - The string value to put into the keys
4010 Optional arguments:
4011 inMemory - use in memory map for the counter
4012 returns:
4013 A dictionary whose keys are the name of the keys put into the map
4014 and the values of the keys are dictionaries whose key-values are
4015 'value': value put into map and optionaly
4016 'oldValue': Previous value in the key or
4017 None on Error
4018
4019 Example output
4020 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4021 'Key2': {'value': 'Testing'} }
4022 """
4023 try:
4024 numKeys = str( numKeys )
4025 value = str( value )
4026 cmdStr = "transactional-map-test-put "
4027 if inMemory:
4028 cmdStr += "-i "
4029 cmdStr += numKeys + " " + value
4030 output = self.sendline( cmdStr )
4031 try:
4032 # TODO: Maybe make this less hardcoded
4033 # ConsistentMap Exceptions
4034 assert "org.onosproject.store.service" not in output
4035 # Node not leader
4036 assert "java.lang.IllegalStateException" not in output
4037 except AssertionError:
4038 main.log.error( "Error in processing '" + cmdStr + "' " +
4039 "command: " + str( output ) )
4040 return None
4041 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4042 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4043 results = {}
4044 for line in output.splitlines():
4045 new = re.search( newPattern, line )
4046 updated = re.search( updatedPattern, line )
4047 if new:
4048 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4049 elif updated:
4050 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
4051 'oldValue': updated.groupdict()[ 'oldValue' ] }
4052 else:
4053 main.log.error( self.name + ": transactionlMapGet did not" +
4054 " match expected output." )
4055 main.log.debug( self.name + " expected: " + pattern )
4056 main.log.debug( self.name + " actual: " + repr( output ) )
4057 return results
4058 except TypeError:
4059 main.log.exception( self.name + ": Object not as expected" )
4060 return None
4061 except pexpect.EOF:
4062 main.log.error( self.name + ": EOF exception found" )
4063 main.log.error( self.name + ": " + self.handle.before )
4064 main.cleanup()
4065 main.exit()
4066 except Exception:
4067 main.log.exception( self.name + ": Uncaught exception!" )
4068 main.cleanup()
4069 main.exit()
acsmarsdaea66c2015-09-03 11:44:06 -07004070 def maps( self, jsonFormat=True ):
4071 """
4072 Description: Returns result of onos:maps
4073 Optional:
4074 * jsonFormat: enable json formatting of output
4075 """
4076 try:
4077 cmdStr = "maps"
4078 if jsonFormat:
4079 cmdStr += " -j"
4080 handle = self.sendline( cmdStr )
4081 return handle
4082 except TypeError:
4083 main.log.exception( self.name + ": Object not as expected" )
4084 return None
4085 except pexpect.EOF:
4086 main.log.error( self.name + ": EOF exception found" )
4087 main.log.error( self.name + ": " + self.handle.before )
4088 main.cleanup()
4089 main.exit()
4090 except Exception:
4091 main.log.exception( self.name + ": Uncaught exception!" )
4092 main.cleanup()
4093 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004094
4095 def getSwController( self, uri, jsonFormat=True ):
4096 """
4097 Descrition: Gets the controller information from the device
4098 """
4099 try:
4100 cmd = "device-controllers "
4101 if jsonFormat:
4102 cmd += "-j "
4103 response = self.sendline( cmd + uri )
4104 return response
4105 except TypeError:
4106 main.log.exception( self.name + ": Object not as expected" )
4107 return None
4108 except pexpect.EOF:
4109 main.log.error( self.name + ": EOF exception found" )
4110 main.log.error( self.name + ": " + self.handle.before )
4111 main.cleanup()
4112 main.exit()
4113 except Exception:
4114 main.log.exception( self.name + ": Uncaught exception!" )
4115 main.cleanup()
4116 main.exit()
4117
4118 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4119 """
4120 Descrition: sets the controller(s) for the specified device
4121
4122 Parameters:
4123 Required: uri - String: The uri of the device(switch).
4124 ip - String or List: The ip address of the controller.
4125 This parameter can be formed in a couple of different ways.
4126 VALID:
4127 10.0.0.1 - just the ip address
4128 tcp:10.0.0.1 - the protocol and the ip address
4129 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4130 so that you can add controllers with different
4131 protocols and ports
4132 INVALID:
4133 10.0.0.1:6653 - this is not supported by ONOS
4134
4135 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4136 port - The port number.
4137 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4138
4139 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4140 """
4141 try:
4142 cmd = "device-setcontrollers"
4143
4144 if jsonFormat:
4145 cmd += " -j"
4146 cmd += " " + uri
4147 if isinstance( ip, str ):
4148 ip = [ip]
4149 for item in ip:
4150 if ":" in item:
4151 sitem = item.split( ":" )
4152 if len(sitem) == 3:
4153 cmd += " " + item
4154 elif "." in sitem[1]:
4155 cmd += " {}:{}".format(item, port)
4156 else:
4157 main.log.error( "Malformed entry: " + item )
4158 raise TypeError
4159 else:
4160 cmd += " {}:{}:{}".format( proto, item, port )
4161
4162 response = self.sendline( cmd )
4163
4164 if "Error" in response:
4165 main.log.error( response )
4166 return main.FALSE
4167
GlennRC050596c2015-11-18 17:06:41 -08004168 return main.TRUE
4169
4170 except TypeError:
4171 main.log.exception( self.name + ": Object not as expected" )
4172 return main.FALSE
4173 except pexpect.EOF:
4174 main.log.error( self.name + ": EOF exception found" )
4175 main.log.error( self.name + ": " + self.handle.before )
4176 main.cleanup()
4177 main.exit()
4178 except Exception:
4179 main.log.exception( self.name + ": Uncaught exception!" )
4180 main.cleanup()
4181 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004182
4183 def removeDevice( self, device ):
4184 '''
4185 Description:
4186 Remove a device from ONOS by passing the uri of the device(s).
4187 Parameters:
4188 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4189 Returns:
4190 Returns main.FALSE if an exception is thrown or an error is present
4191 in the response. Otherwise, returns main.TRUE.
4192 NOTE:
4193 If a host cannot be removed, then this function will return main.FALSE
4194 '''
4195 try:
4196 if type( device ) is str:
4197 device = list( device )
4198
4199 for d in device:
4200 time.sleep( 1 )
4201 response = self.sendline( "device-remove {}".format( d ) )
4202 if "Error" in response:
4203 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4204 return main.FALSE
4205
4206 return main.TRUE
4207
4208 except TypeError:
4209 main.log.exception( self.name + ": Object not as expected" )
4210 return main.FALSE
4211 except pexpect.EOF:
4212 main.log.error( self.name + ": EOF exception found" )
4213 main.log.error( self.name + ": " + self.handle.before )
4214 main.cleanup()
4215 main.exit()
4216 except Exception:
4217 main.log.exception( self.name + ": Uncaught exception!" )
4218 main.cleanup()
4219 main.exit()
4220
4221 def removeHost( self, host ):
4222 '''
4223 Description:
4224 Remove a host from ONOS by passing the id of the host(s)
4225 Parameters:
4226 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4227 Returns:
4228 Returns main.FALSE if an exception is thrown or an error is present
4229 in the response. Otherwise, returns main.TRUE.
4230 NOTE:
4231 If a host cannot be removed, then this function will return main.FALSE
4232 '''
4233 try:
4234 if type( host ) is str:
4235 host = list( host )
4236
4237 for h in host:
4238 time.sleep( 1 )
4239 response = self.sendline( "host-remove {}".format( h ) )
4240 if "Error" in response:
4241 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4242 return main.FALSE
4243
4244 return main.TRUE
4245
4246 except TypeError:
4247 main.log.exception( self.name + ": Object not as expected" )
4248 return main.FALSE
4249 except pexpect.EOF:
4250 main.log.error( self.name + ": EOF exception found" )
4251 main.log.error( self.name + ": " + self.handle.before )
4252 main.cleanup()
4253 main.exit()
4254 except Exception:
4255 main.log.exception( self.name + ": Uncaught exception!" )
4256 main.cleanup()
4257 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004258
4259 def link( self, begin, end, state):
4260 '''
4261 Description:
4262 Bring link down or up in the null-provider.
4263 params:
4264 begin - (string) One end of a device or switch.
4265 end - (string) the other end of the device or switch
4266 returns:
4267 main.TRUE if no exceptions were thrown and no Errors are
4268 present in the resoponse. Otherwise, returns main.FALSE
4269 '''
4270 try:
4271 cmd = "null-link null:{} null:{} {}".format(begin, end, state)
4272 response = self.sendline( cmd, showResponse=True )
4273
4274 if "Error" in response or "Failure" in response:
4275 main.log.error( response )
4276 return main.FALSE
4277
4278 return main.TRUE
4279 except TypeError:
4280 main.log.exception( self.name + ": Object not as expected" )
4281 return main.FALSE
4282 except pexpect.EOF:
4283 main.log.error( self.name + ": EOF exception found" )
4284 main.log.error( self.name + ": " + self.handle.before )
4285 main.cleanup()
4286 main.exit()
4287 except Exception:
4288 main.log.exception( self.name + ": Uncaught exception!" )
4289 main.cleanup()
4290 main.exit()
4291