blob: 002fc17b3f08f7188fc425fe8d7a5ec492e94983 [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 """
andrewonlabe6745342014-10-17 14:29:13 -04001803 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001804 Obtain intents from the ONOS cli.
1805 Optional:
1806 * jsonFormat: Enable output formatting in json, default to True
1807 * summary: Whether only output the intent summary, defaults to False
1808 * type: Only output a certain type of intent. This options is valid
1809 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001810 """
andrewonlabe6745342014-10-17 14:29:13 -04001811 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001812 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001813 if summary:
1814 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001816 cmdStr += " -j"
1817 handle = self.sendline( cmdStr )
pingping-lin8244a3b2015-09-16 13:36:56 -07001818 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001819 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001820 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001821 else:
Jon Hallff566d52016-01-15 14:45:36 -08001822 intentType = ""
1823 # IF we want the summary of a specific intent type
1824 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001825 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001826 if intentType in jsonResult.keys():
1827 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001828 else:
Jon Hallff566d52016-01-15 14:45:36 -08001829 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001830 return handle
1831 else:
Jon Hallff566d52016-01-15 14:45:36 -08001832 main.log.error( handle )
pingping-lin8244a3b2015-09-16 13:36:56 -07001833 return handle
pingping-lin54b03372015-08-13 14:43:10 -07001834 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
kelvin-onlab54400a92015-02-26 18:05:51 -08001847 def getIntentState(self, intentsId, intentsJson=None):
1848 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001849 Check intent state.
1850 Accepts a single intent ID (string type) or a list of intent IDs.
1851 Returns the state(string type) of the id if a single intent ID is
1852 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001853 Returns a dictionary with intent IDs as the key and its
1854 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001855 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001856 intentId: intent ID (string type)
1857 intentsJson: parsed json object from the onos:intents api
1858 Returns:
1859 state = An intent's state- INSTALL,WITHDRAWN etc.
1860 stateDict = Dictionary of intent's state. intent ID as the keys and
1861 state as the values.
1862 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001863 try:
1864 state = "State is Undefined"
1865 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001866 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001867 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001868 intentsJsonTemp = json.loads( intentsJson )
1869 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001870 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001871 if intentsId == intent[ 'id' ]:
1872 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001873 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001874 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1875 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001876 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001877 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001878 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001879 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001880 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001881 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001882 if intentsId[ i ] == intents[ 'id' ]:
1883 stateDict[ 'state' ] = intents[ 'state' ]
1884 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001885 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001886 break
Jon Hallefbd9792015-03-05 16:11:36 -08001887 if len( intentsId ) != len( dictList ):
1888 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001889 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001890 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001891 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001892 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001893 except TypeError:
1894 main.log.exception( self.name + ": Object not as expected" )
1895 return None
1896 except pexpect.EOF:
1897 main.log.error( self.name + ": EOF exception found" )
1898 main.log.error( self.name + ": " + self.handle.before )
1899 main.cleanup()
1900 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001901 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001902 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001903 main.cleanup()
1904 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001905
kelvin-onlabf512e942015-06-08 19:42:59 -07001906 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001907 """
1908 Description:
1909 Check intents state
1910 Required:
1911 intentsId - List of intents ID to be checked
1912 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001913 expectedState - Check the expected state(s) of each intents
1914 state in the list.
1915 *NOTE: You can pass in a list of expected state,
1916 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001917 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001918 Returns main.TRUE only if all intent are the same as expected states
1919 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001920 """
1921 try:
1922 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001923 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001924 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001925 if len( intentsId ) != len( intentsDict ):
1926 main.log.info( self.name + "There is something wrong " +
1927 "getting intents state" )
1928 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001929
1930 if isinstance( expectedState, types.StringType ):
1931 for intents in intentsDict:
1932 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001933 main.log.debug( self.name + " : Intent ID - " +
1934 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001935 " actual state = " +
1936 intents.get( 'state' )
1937 + " does not equal expected state = "
1938 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001939 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001940
1941 elif isinstance( expectedState, types.ListType ):
1942 for intents in intentsDict:
1943 if not any( state == intents.get( 'state' ) for state in
1944 expectedState ):
1945 main.log.debug( self.name + " : Intent ID - " +
1946 intents.get( 'id' ) +
1947 " actual state = " +
1948 intents.get( 'state' ) +
1949 " does not equal expected states = "
1950 + str( expectedState ) )
1951 returnValue = main.FALSE
1952
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001953 if returnValue == main.TRUE:
1954 main.log.info( self.name + ": All " +
1955 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001956 " intents are in " + str( expectedState ) +
1957 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001958 return returnValue
1959 except TypeError:
1960 main.log.exception( self.name + ": Object not as expected" )
1961 return None
1962 except pexpect.EOF:
1963 main.log.error( self.name + ": EOF exception found" )
1964 main.log.error( self.name + ": " + self.handle.before )
1965 main.cleanup()
1966 main.exit()
1967 except Exception:
1968 main.log.exception( self.name + ": Uncaught exception!" )
1969 main.cleanup()
1970 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04001971
GlennRCed771242016-01-13 17:02:47 -08001972 def checkIntentSummary( self, timeout=60 ):
1973 """
1974 Description:
1975 Check the number of installed intents.
1976 Optional:
1977 timeout - the timeout for pexcept
1978 Return:
1979 Returns main.TRUE only if the number of all installed intents are the same as total intents number
1980 , otherwise, returns main.FALSE.
1981 """
1982
1983 try:
1984 cmd = "intents -s -j"
1985
1986 # Check response if something wrong
1987 response = self.sendline( cmd, timeout=timeout )
1988 if response == None:
1989 return main.False
1990 response = json.loads( response )
1991
1992 # get total and installed number, see if they are match
1993 allState = response.get( 'all' )
1994 if allState.get('total') == allState.get('installed'):
1995 main.log.info( 'successful verified Intents' )
1996 return main.TRUE
1997 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format(allState.get('total'), allState.get('installed')))
1998 return main.FALSE
1999
2000 except TypeError:
2001 main.log.exception( self.name + ": Object not as expected" )
2002 return None
2003 except pexpect.EOF:
2004 main.log.error( self.name + ": EOF exception found" )
2005 main.log.error( self.name + ": " + self.handle.before )
2006 main.cleanup()
2007 main.exit()
2008 except Exception:
2009 main.log.exception( self.name + ": Uncaught exception!" )
2010 main.cleanup()
2011 main.exit()
2012
2013 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002014 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002015 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002016 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002017 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002018 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002019 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002020 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002021 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002022 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002023 cmdStr += " -j "
2024 cmdStr += state
2025
2026 response = self.sendline( cmdStr, timeout = timeout )
2027
2028 return response
2029
2030 except pexpect.TIMEOUT:
2031 main.log.error( self.name + ": ONOS timeout" )
2032 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002033 except TypeError:
2034 main.log.exception( self.name + ": Object not as expected" )
2035 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002036 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002037 main.log.error( self.name + ": EOF exception found" )
2038 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002039 main.cleanup()
2040 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002042 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002043 main.cleanup()
2044 main.exit()
2045
GlennRCed771242016-01-13 17:02:47 -08002046
2047 def checkFlowsState( self, isPENDING = True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002048 """
2049 Description:
GlennRCed771242016-01-13 17:02:47 -08002050 Check the if all the current flows are in ADDED state
2051 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows, if the count of those states is 0,
2052 which means all current flows are in ADDED state, and return main.TRUE
2053 otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002054 Optional:
GlennRCed771242016-01-13 17:02:47 -08002055 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002056 Return:
2057 returnValue - Returns main.TRUE only if all flows are in
GlennRCed771242016-01-13 17:02:47 -08002058 ADDED state or PENDING_ADD if the isPENDING_ADD
pingping-linbab7f8a2015-09-21 17:33:36 -07002059 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002060 """
2061 try:
GlennRCed771242016-01-13 17:02:47 -08002062 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2063 checkedStates = []
2064 statesCount = [0, 0, 0, 0]
2065 for s in states:
2066 checkedStates.append( json.loads( self.flows( state=s, timeout = timeout ) ) )
kelvin-onlabf0594d72015-05-19 17:25:12 -07002067
GlennRCed771242016-01-13 17:02:47 -08002068 for i in range (len( states )):
2069 for c in checkedStates[i]:
2070 statesCount[i] += int( c.get("flowCount"))
2071 main.log.info(states[i] + " flows: "+ str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002072
GlennRCed771242016-01-13 17:02:47 -08002073 # We want to count PENDING_ADD if isPENDING is true
2074 if isPENDING:
2075 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2076 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002077 else:
GlennRCed771242016-01-13 17:02:47 -08002078 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2079 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002080
GlennRCed771242016-01-13 17:02:47 -08002081 return main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002082
kelvin-onlab4df89f22015-04-13 18:10:23 -07002083 except TypeError:
2084 main.log.exception( self.name + ": Object not as expected" )
2085 return None
2086 except pexpect.EOF:
2087 main.log.error( self.name + ": EOF exception found" )
2088 main.log.error( self.name + ": " + self.handle.before )
2089 main.cleanup()
2090 main.exit()
2091 except Exception:
2092 main.log.exception( self.name + ": Uncaught exception!" )
2093 main.cleanup()
2094 main.exit()
2095
GlennRCed771242016-01-13 17:02:47 -08002096 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2097 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002098 """
andrewonlab87852b02014-11-19 18:44:19 -05002099 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002100 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002101 a specific point-to-point intent definition
2102 Required:
GlennRCed771242016-01-13 17:02:47 -08002103 * ingress: specify source dpid
2104 * egress: specify destination dpid
2105 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002106 Optional:
GlennRCed771242016-01-13 17:02:47 -08002107 * offset: the keyOffset is where the next batch of intents
2108 will be installed
2109 Returns: If failed to push test intents, it will returen None,
2110 if successful, return true.
2111 Timeout expection will return None,
2112 TypeError will return false
2113 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002114 """
andrewonlab87852b02014-11-19 18:44:19 -05002115 try:
GlennRCed771242016-01-13 17:02:47 -08002116 if background:
2117 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002118 else:
GlennRCed771242016-01-13 17:02:47 -08002119 back = ""
2120 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
2121 ingress,
2122 egress,
2123 batchSize,
2124 offset,
2125 back )
2126 response = self.sendline( cmd, timeout=timeout )
2127 main.log.info( response )
2128 if response == None:
2129 return None
2130
2131 # TODO: We should handle if there is failure in installation
2132 return main.TRUE
2133
2134 except pexpect.TIMEOUT:
2135 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002136 return None
andrewonlab87852b02014-11-19 18:44:19 -05002137 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002138 main.log.error( self.name + ": EOF exception found" )
2139 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002140 main.cleanup()
2141 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002142 except TypeError:
2143 main.log.exception( self.name + ": Object not as expected" )
2144 return main.FALSE
Jon Hallfebb1c72015-03-05 13:30:09 -08002145 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002146 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002147 main.cleanup()
2148 main.exit()
2149
kelvin-onlabd3b64892015-01-20 13:26:24 -08002150 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002151 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002152 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002153 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002154 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002155 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002156 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002157 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002158 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002159 cmdStr += " -j"
2160 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002161 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002162 except TypeError:
2163 main.log.exception( self.name + ": Object not as expected" )
2164 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002166 main.log.error( self.name + ": EOF exception found" )
2167 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002168 main.cleanup()
2169 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002170 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002171 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002172 main.cleanup()
2173 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002174
kelvin-onlabd3b64892015-01-20 13:26:24 -08002175 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002176 """
2177 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002178 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002179 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002180 """
andrewonlab867212a2014-10-22 20:13:38 -04002181 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002182 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002183 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002184 cmdStr += " -j"
2185 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002186 if handle:
2187 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002188 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002189 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002190 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002191 else:
2192 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002193 except TypeError:
2194 main.log.exception( self.name + ": Object not as expected" )
2195 return None
andrewonlab867212a2014-10-22 20:13:38 -04002196 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002197 main.log.error( self.name + ": EOF exception found" )
2198 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002199 main.cleanup()
2200 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002201 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002202 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002203 main.cleanup()
2204 main.exit()
2205
kelvin8ec71442015-01-15 16:57:00 -08002206 # Wrapper functions ****************
2207 # Wrapper functions use existing driver
2208 # functions and extends their use case.
2209 # For example, we may use the output of
2210 # a normal driver function, and parse it
2211 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002212
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002214 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002215 Description:
2216 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002217 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002218 try:
kelvin8ec71442015-01-15 16:57:00 -08002219 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002220 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002221 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002222
kelvin8ec71442015-01-15 16:57:00 -08002223 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002224 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2225 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002226 match = re.search('id=0x([\da-f]+),', intents)
2227 if match:
2228 tmpId = match.group()[3:-1]
2229 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002230 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002231
Jon Halld4d4b372015-01-28 16:02:41 -08002232 except TypeError:
2233 main.log.exception( self.name + ": Object not as expected" )
2234 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002235 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002236 main.log.error( self.name + ": EOF exception found" )
2237 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002238 main.cleanup()
2239 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002240 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002241 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002242 main.cleanup()
2243 main.exit()
2244
Jon Hall30b82fa2015-03-04 17:15:43 -08002245 def FlowAddedCount( self, deviceId ):
2246 """
2247 Determine the number of flow rules for the given device id that are
2248 in the added state
2249 """
2250 try:
2251 cmdStr = "flows any " + str( deviceId ) + " | " +\
2252 "grep 'state=ADDED' | wc -l"
2253 handle = self.sendline( cmdStr )
2254 return handle
2255 except pexpect.EOF:
2256 main.log.error( self.name + ": EOF exception found" )
2257 main.log.error( self.name + ": " + self.handle.before )
2258 main.cleanup()
2259 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002260 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002261 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002262 main.cleanup()
2263 main.exit()
2264
kelvin-onlabd3b64892015-01-20 13:26:24 -08002265 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002266 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002267 Use 'devices' function to obtain list of all devices
2268 and parse the result to obtain a list of all device
2269 id's. Returns this list. Returns empty list if no
2270 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002271 List is ordered sequentially
2272
andrewonlab3e15ead2014-10-15 14:21:34 -04002273 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002274 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002275 the ids. By obtaining the list of device ids on the fly,
2276 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002277 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002278 try:
kelvin8ec71442015-01-15 16:57:00 -08002279 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002280 devicesStr = self.devices( jsonFormat=False )
2281 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002282
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002284 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 return idList
kelvin8ec71442015-01-15 16:57:00 -08002286
2287 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002288 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002289 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002291 # Split list further into arguments before and after string
2292 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002293 # append to idList
2294 for arg in tempList:
2295 idList.append( arg.split( "id=" )[ 1 ] )
2296 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002297
Jon Halld4d4b372015-01-28 16:02:41 -08002298 except TypeError:
2299 main.log.exception( self.name + ": Object not as expected" )
2300 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002301 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002302 main.log.error( self.name + ": EOF exception found" )
2303 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002304 main.cleanup()
2305 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002306 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002307 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002308 main.cleanup()
2309 main.exit()
2310
kelvin-onlabd3b64892015-01-20 13:26:24 -08002311 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002312 """
andrewonlab7c211572014-10-15 16:45:20 -04002313 Uses 'nodes' function to obtain list of all nodes
2314 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002315 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002316 Returns:
2317 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002318 """
andrewonlab7c211572014-10-15 16:45:20 -04002319 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002320 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002321 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002322 # Sample nodesStr output
2323 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002324 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002325 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002326 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002327 nodesJson = json.loads( nodesStr )
2328 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002329 return idList
kelvin8ec71442015-01-15 16:57:00 -08002330
Jon Halld4d4b372015-01-28 16:02:41 -08002331 except TypeError:
2332 main.log.exception( self.name + ": Object not as expected" )
2333 return None
andrewonlab7c211572014-10-15 16:45:20 -04002334 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002335 main.log.error( self.name + ": EOF exception found" )
2336 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002337 main.cleanup()
2338 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002339 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002340 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002341 main.cleanup()
2342 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002343
kelvin-onlabd3b64892015-01-20 13:26:24 -08002344 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002345 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002346 Return the first device from the devices api whose 'id' contains 'dpid'
2347 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002348 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002349 try:
kelvin8ec71442015-01-15 16:57:00 -08002350 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002351 return None
2352 else:
kelvin8ec71442015-01-15 16:57:00 -08002353 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002354 rawDevices = self.devices()
2355 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002356 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002357 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002358 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2359 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002360 return device
2361 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002362 except TypeError:
2363 main.log.exception( self.name + ": Object not as expected" )
2364 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002365 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002366 main.log.error( self.name + ": EOF exception found" )
2367 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002368 main.cleanup()
2369 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002370 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002371 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002372 main.cleanup()
2373 main.exit()
2374
kelvin-onlabd3b64892015-01-20 13:26:24 -08002375 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002376 """
Jon Hallefbd9792015-03-05 16:11:36 -08002377 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002378 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002379 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002380
Jon Hall42db6dc2014-10-24 19:03:48 -04002381 Params: ip = ip used for the onos cli
2382 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002383 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002384 logLevel = level to log to. Currently accepts
2385 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002386
2387
kelvin-onlabd3b64892015-01-20 13:26:24 -08002388 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002389
Jon Hallefbd9792015-03-05 16:11:36 -08002390 Returns: main.TRUE if the number of switches and links are correct,
2391 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002392 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002393 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002394 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002395 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002396 if topology == {}:
2397 return main.ERROR
2398 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002399 # Is the number of switches is what we expected
2400 devices = topology.get( 'devices', False )
2401 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002402 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002403 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002404 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002405 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002406 linkCheck = ( int( links ) == int( numolink ) )
2407 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002408 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002409 output += "The number of links and switches match " +\
2410 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002411 result = main.TRUE
2412 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002413 output += "The number of links and switches does not match " +\
2414 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002415 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002416 output = output + "\n ONOS sees %i devices (%i expected) \
2417 and %i links (%i expected)" % (
2418 int( devices ), int( numoswitch ), int( links ),
2419 int( numolink ) )
2420 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002421 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002422 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002423 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002424 else:
Jon Hall390696c2015-05-05 17:13:41 -07002425 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002426 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002427 except TypeError:
2428 main.log.exception( self.name + ": Object not as expected" )
2429 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002430 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002431 main.log.error( self.name + ": EOF exception found" )
2432 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002433 main.cleanup()
2434 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002435 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002436 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002437 main.cleanup()
2438 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002439
kelvin-onlabd3b64892015-01-20 13:26:24 -08002440 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002441 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002442 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002443 deviceId must be the id of a device as seen in the onos devices command
2444 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002445 role must be either master, standby, or none
2446
Jon Halle3f39ff2015-01-13 11:50:53 -08002447 Returns:
2448 main.TRUE or main.FALSE based on argument verification and
2449 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002450 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002451 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002452 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002453 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002454 cmdStr = "device-role " +\
2455 str( deviceId ) + " " +\
2456 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002457 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002458 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002459 if re.search( "Error", handle ):
2460 # end color output to escape any colours
2461 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002462 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002463 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002464 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002465 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002466 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002467 main.log.error( "Invalid 'role' given to device_role(). " +
2468 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002469 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002470 except TypeError:
2471 main.log.exception( self.name + ": Object not as expected" )
2472 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002473 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002474 main.log.error( self.name + ": EOF exception found" )
2475 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002476 main.cleanup()
2477 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002478 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002479 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002480 main.cleanup()
2481 main.exit()
2482
kelvin-onlabd3b64892015-01-20 13:26:24 -08002483 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002484 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002485 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002486 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002487 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002488 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002489 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002490 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002491 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002492 cmdStr += " -j"
2493 handle = self.sendline( cmdStr )
2494 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002495 except TypeError:
2496 main.log.exception( self.name + ": Object not as expected" )
2497 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002498 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002499 main.log.error( self.name + ": EOF exception found" )
2500 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002501 main.cleanup()
2502 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002503 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002504 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002505 main.cleanup()
2506 main.exit()
2507
kelvin-onlabd3b64892015-01-20 13:26:24 -08002508 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002509 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002510 CLI command to get the current leader for the Election test application
2511 NOTE: Requires installation of the onos-app-election feature
2512 Returns: Node IP of the leader if one exists
2513 None if none exists
2514 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002515 """
Jon Hall94fd0472014-12-08 11:52:42 -08002516 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002517 cmdStr = "election-test-leader"
2518 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002519 # Leader
2520 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002521 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002522 nodeSearch = re.search( leaderPattern, response )
2523 if nodeSearch:
2524 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002525 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002526 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002527 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002528 # no leader
2529 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002530 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002531 nullSearch = re.search( nullPattern, response )
2532 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002533 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002534 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002535 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002536 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002537 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002538 if re.search( errorPattern, response ):
2539 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002540 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002541 return main.FALSE
2542 else:
Jon Hall390696c2015-05-05 17:13:41 -07002543 main.log.error( "Error in electionTestLeader on " + self.name +
2544 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002545 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002546 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002547 except TypeError:
2548 main.log.exception( self.name + ": Object not as expected" )
2549 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002551 main.log.error( self.name + ": EOF exception found" )
2552 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002553 main.cleanup()
2554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002556 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002557 main.cleanup()
2558 main.exit()
2559
kelvin-onlabd3b64892015-01-20 13:26:24 -08002560 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002561 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002562 CLI command to run for leadership of the Election test application.
2563 NOTE: Requires installation of the onos-app-election feature
2564 Returns: Main.TRUE on success
2565 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002566 """
Jon Hall94fd0472014-12-08 11:52:42 -08002567 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 cmdStr = "election-test-run"
2569 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002570 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002571 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002572 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002573 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002574 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002575 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002576 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002577 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002578 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002579 errorPattern = "Command\snot\sfound"
2580 if re.search( errorPattern, response ):
2581 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002582 return main.FALSE
2583 else:
Jon Hall390696c2015-05-05 17:13:41 -07002584 main.log.error( "Error in electionTestRun on " + self.name +
2585 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002586 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002587 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002588 except TypeError:
2589 main.log.exception( self.name + ": Object not as expected" )
2590 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002592 main.log.error( self.name + ": EOF exception found" )
2593 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002594 main.cleanup()
2595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002597 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002598 main.cleanup()
2599 main.exit()
2600
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002602 """
Jon Hall94fd0472014-12-08 11:52:42 -08002603 * CLI command to withdraw the local node from leadership election for
2604 * the Election test application.
2605 #NOTE: Requires installation of the onos-app-election feature
2606 Returns: Main.TRUE on success
2607 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002608 """
Jon Hall94fd0472014-12-08 11:52:42 -08002609 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002610 cmdStr = "election-test-withdraw"
2611 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002612 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002613 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002614 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002615 if re.search( successPattern, response ):
2616 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002617 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002618 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002619 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002620 errorPattern = "Command\snot\sfound"
2621 if re.search( errorPattern, response ):
2622 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002623 return main.FALSE
2624 else:
Jon Hall390696c2015-05-05 17:13:41 -07002625 main.log.error( "Error in electionTestWithdraw on " +
2626 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002627 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002628 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002629 except TypeError:
2630 main.log.exception( self.name + ": Object not as expected" )
2631 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002632 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002633 main.log.error( self.name + ": EOF exception found" )
2634 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002635 main.cleanup()
2636 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002637 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002638 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002639 main.cleanup()
2640 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002641
kelvin8ec71442015-01-15 16:57:00 -08002642 def getDevicePortsEnabledCount( self, dpid ):
2643 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002644 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002645 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002646 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002647 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002648 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2649 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002650 if re.search( "No such device", output ):
2651 main.log.error( "Error in getting ports" )
2652 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002653 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002654 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002655 except TypeError:
2656 main.log.exception( self.name + ": Object not as expected" )
2657 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002659 main.log.error( self.name + ": EOF exception found" )
2660 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002661 main.cleanup()
2662 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002663 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002664 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002665 main.cleanup()
2666 main.exit()
2667
kelvin8ec71442015-01-15 16:57:00 -08002668 def getDeviceLinksActiveCount( self, dpid ):
2669 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002670 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002671 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002672 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002673 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2675 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002676 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002677 main.log.error( "Error in getting ports " )
2678 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002679 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002680 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002681 except TypeError:
2682 main.log.exception( self.name + ": Object not as expected" )
2683 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002684 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002685 main.log.error( self.name + ": EOF exception found" )
2686 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002687 main.cleanup()
2688 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002689 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002690 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002691 main.cleanup()
2692 main.exit()
2693
kelvin8ec71442015-01-15 16:57:00 -08002694 def getAllIntentIds( self ):
2695 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002696 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002697 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002698 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002699 cmdStr = "onos:intents | grep id="
2700 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002701 if re.search( "Error", output ):
2702 main.log.error( "Error in getting ports" )
2703 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002704 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002705 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002706 except TypeError:
2707 main.log.exception( self.name + ": Object not as expected" )
2708 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002709 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002710 main.log.error( self.name + ": EOF exception found" )
2711 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002712 main.cleanup()
2713 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002714 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002715 main.log.exception( self.name + ": Uncaught exception!" )
2716 main.cleanup()
2717 main.exit()
2718
Jon Hall73509952015-02-24 16:42:56 -08002719 def intentSummary( self ):
2720 """
Jon Hallefbd9792015-03-05 16:11:36 -08002721 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002722 """
2723 try:
2724 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002725 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002726 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002727 states.append( intent.get( 'state', None ) )
2728 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002729 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002730 return dict( out )
2731 except TypeError:
2732 main.log.exception( self.name + ": Object not as expected" )
2733 return None
2734 except pexpect.EOF:
2735 main.log.error( self.name + ": EOF exception found" )
2736 main.log.error( self.name + ": " + self.handle.before )
2737 main.cleanup()
2738 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002739 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002740 main.log.exception( self.name + ": Uncaught exception!" )
2741 main.cleanup()
2742 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002743
Jon Hall61282e32015-03-19 11:34:11 -07002744 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002745 """
2746 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002747 Optional argument:
2748 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002749 """
Jon Hall63604932015-02-26 17:09:50 -08002750 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002751 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002752 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002753 cmdStr += " -j"
2754 output = self.sendline( cmdStr )
2755 return output
Jon Hall63604932015-02-26 17:09:50 -08002756 except TypeError:
2757 main.log.exception( self.name + ": Object not as expected" )
2758 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002759 except pexpect.EOF:
2760 main.log.error( self.name + ": EOF exception found" )
2761 main.log.error( self.name + ": " + self.handle.before )
2762 main.cleanup()
2763 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002764 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002765 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002766 main.cleanup()
2767 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002768
acsmarsa4a4d1e2015-07-10 16:01:24 -07002769 def leaderCandidates( self, jsonFormat=True ):
2770 """
2771 Returns the output of the leaders -c command.
2772 Optional argument:
2773 * jsonFormat - boolean indicating if you want output in json
2774 """
2775 try:
2776 cmdStr = "onos:leaders -c"
2777 if jsonFormat:
2778 cmdStr += " -j"
2779 output = self.sendline( cmdStr )
2780 return output
2781 except TypeError:
2782 main.log.exception( self.name + ": Object not as expected" )
2783 return None
2784 except pexpect.EOF:
2785 main.log.error( self.name + ": EOF exception found" )
2786 main.log.error( self.name + ": " + self.handle.before )
2787 main.cleanup()
2788 main.exit()
2789 except Exception:
2790 main.log.exception( self.name + ": Uncaught exception!" )
2791 main.cleanup()
2792 main.exit()
2793
2794 def specificLeaderCandidate(self,topic):
2795 """
2796 Returns a list in format [leader,candidate1,candidate2,...] for a given
2797 topic parameter and an empty list if the topic doesn't exist
2798 If no leader is elected leader in the returned list will be "none"
2799 Returns None if there is a type error processing the json object
2800 """
2801 try:
2802 cmdStr = "onos:leaders -c -j"
2803 output = self.sendline( cmdStr )
2804 output = json.loads(output)
2805 results = []
2806 for dict in output:
2807 if dict["topic"] == topic:
2808 leader = dict["leader"]
2809 candidates = re.split(", ",dict["candidates"][1:-1])
2810 results.append(leader)
2811 results.extend(candidates)
2812 return results
2813 except TypeError:
2814 main.log.exception( self.name + ": Object not as expected" )
2815 return None
2816 except pexpect.EOF:
2817 main.log.error( self.name + ": EOF exception found" )
2818 main.log.error( self.name + ": " + self.handle.before )
2819 main.cleanup()
2820 main.exit()
2821 except Exception:
2822 main.log.exception( self.name + ": Uncaught exception!" )
2823 main.cleanup()
2824 main.exit()
2825
Jon Hall61282e32015-03-19 11:34:11 -07002826 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002827 """
2828 Returns the output of the intent Pending map.
2829 """
Jon Hall63604932015-02-26 17:09:50 -08002830 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002831 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002832 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002833 cmdStr += " -j"
2834 output = self.sendline( cmdStr )
2835 return output
Jon Hall63604932015-02-26 17:09:50 -08002836 except TypeError:
2837 main.log.exception( self.name + ": Object not as expected" )
2838 return None
2839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
2842 main.cleanup()
2843 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002844 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002845 main.log.exception( self.name + ": Uncaught exception!" )
2846 main.cleanup()
2847 main.exit()
2848
Jon Hall61282e32015-03-19 11:34:11 -07002849 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002850 """
2851 Returns the output of the raft partitions command for ONOS.
2852 """
Jon Hall61282e32015-03-19 11:34:11 -07002853 # Sample JSON
2854 # {
2855 # "leader": "tcp://10.128.30.11:7238",
2856 # "members": [
2857 # "tcp://10.128.30.11:7238",
2858 # "tcp://10.128.30.17:7238",
2859 # "tcp://10.128.30.13:7238",
2860 # ],
2861 # "name": "p1",
2862 # "term": 3
2863 # },
Jon Hall63604932015-02-26 17:09:50 -08002864 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002865 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002866 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002867 cmdStr += " -j"
2868 output = self.sendline( cmdStr )
2869 return output
Jon Hall63604932015-02-26 17:09:50 -08002870 except TypeError:
2871 main.log.exception( self.name + ": Object not as expected" )
2872 return None
2873 except pexpect.EOF:
2874 main.log.error( self.name + ": EOF exception found" )
2875 main.log.error( self.name + ": " + self.handle.before )
2876 main.cleanup()
2877 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002878 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002879 main.log.exception( self.name + ": Uncaught exception!" )
2880 main.cleanup()
2881 main.exit()
2882
Jon Hallbe379602015-03-24 13:39:32 -07002883 def apps( self, jsonFormat=True ):
2884 """
2885 Returns the output of the apps command for ONOS. This command lists
2886 information about installed ONOS applications
2887 """
2888 # Sample JSON object
2889 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2890 # "description":"ONOS OpenFlow protocol southbound providers",
2891 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2892 # "features":"[onos-openflow]","state":"ACTIVE"}]
2893 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002894 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002895 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002896 cmdStr += " -j"
2897 output = self.sendline( cmdStr )
2898 assert "Error executing command" not in output
2899 return output
Jon Hallbe379602015-03-24 13:39:32 -07002900 # FIXME: look at specific exceptions/Errors
2901 except AssertionError:
2902 main.log.error( "Error in processing onos:app command: " +
2903 str( output ) )
2904 return None
2905 except TypeError:
2906 main.log.exception( self.name + ": Object not as expected" )
2907 return None
2908 except pexpect.EOF:
2909 main.log.error( self.name + ": EOF exception found" )
2910 main.log.error( self.name + ": " + self.handle.before )
2911 main.cleanup()
2912 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002913 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002914 main.log.exception( self.name + ": Uncaught exception!" )
2915 main.cleanup()
2916 main.exit()
2917
Jon Hall146f1522015-03-24 15:33:24 -07002918 def appStatus( self, appName ):
2919 """
2920 Uses the onos:apps cli command to return the status of an application.
2921 Returns:
2922 "ACTIVE" - If app is installed and activated
2923 "INSTALLED" - If app is installed and deactivated
2924 "UNINSTALLED" - If app is not installed
2925 None - on error
2926 """
Jon Hall146f1522015-03-24 15:33:24 -07002927 try:
2928 if not isinstance( appName, types.StringType ):
2929 main.log.error( self.name + ".appStatus(): appName must be" +
2930 " a string" )
2931 return None
2932 output = self.apps( jsonFormat=True )
2933 appsJson = json.loads( output )
2934 state = None
2935 for app in appsJson:
2936 if appName == app.get('name'):
2937 state = app.get('state')
2938 break
2939 if state == "ACTIVE" or state == "INSTALLED":
2940 return state
2941 elif state is None:
2942 return "UNINSTALLED"
2943 elif state:
2944 main.log.error( "Unexpected state from 'onos:apps': " +
2945 str( state ) )
2946 return state
2947 except TypeError:
2948 main.log.exception( self.name + ": Object not as expected" )
2949 return None
2950 except pexpect.EOF:
2951 main.log.error( self.name + ": EOF exception found" )
2952 main.log.error( self.name + ": " + self.handle.before )
2953 main.cleanup()
2954 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002955 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002956 main.log.exception( self.name + ": Uncaught exception!" )
2957 main.cleanup()
2958 main.exit()
2959
Jon Hallbe379602015-03-24 13:39:32 -07002960 def app( self, appName, option ):
2961 """
2962 Interacts with the app command for ONOS. This command manages
2963 application inventory.
2964 """
Jon Hallbe379602015-03-24 13:39:32 -07002965 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002966 # Validate argument types
2967 valid = True
2968 if not isinstance( appName, types.StringType ):
2969 main.log.error( self.name + ".app(): appName must be a " +
2970 "string" )
2971 valid = False
2972 if not isinstance( option, types.StringType ):
2973 main.log.error( self.name + ".app(): option must be a string" )
2974 valid = False
2975 if not valid:
2976 return main.FALSE
2977 # Validate Option
2978 option = option.lower()
2979 # NOTE: Install may become a valid option
2980 if option == "activate":
2981 pass
2982 elif option == "deactivate":
2983 pass
2984 elif option == "uninstall":
2985 pass
2986 else:
2987 # Invalid option
2988 main.log.error( "The ONOS app command argument only takes " +
2989 "the values: (activate|deactivate|uninstall)" +
2990 "; was given '" + option + "'")
2991 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002992 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002993 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002994 if "Error executing command" in output:
2995 main.log.error( "Error in processing onos:app command: " +
2996 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002997 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002998 elif "No such application" in output:
2999 main.log.error( "The application '" + appName +
3000 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003001 return main.FALSE
3002 elif "Command not found:" in output:
3003 main.log.error( "Error in processing onos:app command: " +
3004 str( output ) )
3005 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003006 elif "Unsupported command:" in output:
3007 main.log.error( "Incorrect command given to 'app': " +
3008 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003009 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003010 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003011 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003012 return main.TRUE
3013 except TypeError:
3014 main.log.exception( self.name + ": Object not as expected" )
3015 return main.ERROR
3016 except pexpect.EOF:
3017 main.log.error( self.name + ": EOF exception found" )
3018 main.log.error( self.name + ": " + self.handle.before )
3019 main.cleanup()
3020 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003021 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003022 main.log.exception( self.name + ": Uncaught exception!" )
3023 main.cleanup()
3024 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003025
Jon Hallbd16b922015-03-26 17:53:15 -07003026 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003027 """
3028 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003029 appName is the hierarchical app name, not the feature name
3030 If check is True, method will check the status of the app after the
3031 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003032 Returns main.TRUE if the command was successfully sent
3033 main.FALSE if the cli responded with an error or given
3034 incorrect input
3035 """
3036 try:
3037 if not isinstance( appName, types.StringType ):
3038 main.log.error( self.name + ".activateApp(): appName must be" +
3039 " a string" )
3040 return main.FALSE
3041 status = self.appStatus( appName )
3042 if status == "INSTALLED":
3043 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003044 if check and response == main.TRUE:
3045 for i in range(10): # try 10 times then give up
3046 # TODO: Check with Thomas about this delay
3047 status = self.appStatus( appName )
3048 if status == "ACTIVE":
3049 return main.TRUE
3050 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003051 main.log.debug( "The state of application " +
3052 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003053 time.sleep( 1 )
3054 return main.FALSE
3055 else: # not 'check' or command didn't succeed
3056 return response
Jon Hall146f1522015-03-24 15:33:24 -07003057 elif status == "ACTIVE":
3058 return main.TRUE
3059 elif status == "UNINSTALLED":
3060 main.log.error( self.name + ": Tried to activate the " +
3061 "application '" + appName + "' which is not " +
3062 "installed." )
3063 else:
3064 main.log.error( "Unexpected return value from appStatus: " +
3065 str( status ) )
3066 return main.ERROR
3067 except TypeError:
3068 main.log.exception( self.name + ": Object not as expected" )
3069 return main.ERROR
3070 except pexpect.EOF:
3071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
3073 main.cleanup()
3074 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003075 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003076 main.log.exception( self.name + ": Uncaught exception!" )
3077 main.cleanup()
3078 main.exit()
3079
Jon Hallbd16b922015-03-26 17:53:15 -07003080 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003081 """
3082 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003083 appName is the hierarchical app name, not the feature name
3084 If check is True, method will check the status of the app after the
3085 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003086 Returns main.TRUE if the command was successfully sent
3087 main.FALSE if the cli responded with an error or given
3088 incorrect input
3089 """
3090 try:
3091 if not isinstance( appName, types.StringType ):
3092 main.log.error( self.name + ".deactivateApp(): appName must " +
3093 "be a string" )
3094 return main.FALSE
3095 status = self.appStatus( appName )
3096 if status == "INSTALLED":
3097 return main.TRUE
3098 elif status == "ACTIVE":
3099 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003100 if check and response == main.TRUE:
3101 for i in range(10): # try 10 times then give up
3102 status = self.appStatus( appName )
3103 if status == "INSTALLED":
3104 return main.TRUE
3105 else:
3106 time.sleep( 1 )
3107 return main.FALSE
3108 else: # not check or command didn't succeed
3109 return response
Jon Hall146f1522015-03-24 15:33:24 -07003110 elif status == "UNINSTALLED":
3111 main.log.warn( self.name + ": Tried to deactivate the " +
3112 "application '" + appName + "' which is not " +
3113 "installed." )
3114 return main.TRUE
3115 else:
3116 main.log.error( "Unexpected return value from appStatus: " +
3117 str( status ) )
3118 return main.ERROR
3119 except TypeError:
3120 main.log.exception( self.name + ": Object not as expected" )
3121 return main.ERROR
3122 except pexpect.EOF:
3123 main.log.error( self.name + ": EOF exception found" )
3124 main.log.error( self.name + ": " + self.handle.before )
3125 main.cleanup()
3126 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003127 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003128 main.log.exception( self.name + ": Uncaught exception!" )
3129 main.cleanup()
3130 main.exit()
3131
Jon Hallbd16b922015-03-26 17:53:15 -07003132 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003133 """
3134 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003135 appName is the hierarchical app name, not the feature name
3136 If check is True, method will check the status of the app after the
3137 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003138 Returns main.TRUE if the command was successfully sent
3139 main.FALSE if the cli responded with an error or given
3140 incorrect input
3141 """
3142 # TODO: check with Thomas about the state machine for apps
3143 try:
3144 if not isinstance( appName, types.StringType ):
3145 main.log.error( self.name + ".uninstallApp(): appName must " +
3146 "be a string" )
3147 return main.FALSE
3148 status = self.appStatus( appName )
3149 if status == "INSTALLED":
3150 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003151 if check and response == main.TRUE:
3152 for i in range(10): # try 10 times then give up
3153 status = self.appStatus( appName )
3154 if status == "UNINSTALLED":
3155 return main.TRUE
3156 else:
3157 time.sleep( 1 )
3158 return main.FALSE
3159 else: # not check or command didn't succeed
3160 return response
Jon Hall146f1522015-03-24 15:33:24 -07003161 elif status == "ACTIVE":
3162 main.log.warn( self.name + ": Tried to uninstall the " +
3163 "application '" + appName + "' which is " +
3164 "currently active." )
3165 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003166 if check and response == main.TRUE:
3167 for i in range(10): # try 10 times then give up
3168 status = self.appStatus( appName )
3169 if status == "UNINSTALLED":
3170 return main.TRUE
3171 else:
3172 time.sleep( 1 )
3173 return main.FALSE
3174 else: # not check or command didn't succeed
3175 return response
Jon Hall146f1522015-03-24 15:33:24 -07003176 elif status == "UNINSTALLED":
3177 return main.TRUE
3178 else:
3179 main.log.error( "Unexpected return value from appStatus: " +
3180 str( status ) )
3181 return main.ERROR
3182 except TypeError:
3183 main.log.exception( self.name + ": Object not as expected" )
3184 return main.ERROR
3185 except pexpect.EOF:
3186 main.log.error( self.name + ": EOF exception found" )
3187 main.log.error( self.name + ": " + self.handle.before )
3188 main.cleanup()
3189 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003190 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003191 main.log.exception( self.name + ": Uncaught exception!" )
3192 main.cleanup()
3193 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003194
3195 def appIDs( self, jsonFormat=True ):
3196 """
3197 Show the mappings between app id and app names given by the 'app-ids'
3198 cli command
3199 """
3200 try:
3201 cmdStr = "app-ids"
3202 if jsonFormat:
3203 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003204 output = self.sendline( cmdStr )
3205 assert "Error executing command" not in output
3206 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003207 except AssertionError:
3208 main.log.error( "Error in processing onos:app-ids command: " +
3209 str( output ) )
3210 return None
3211 except TypeError:
3212 main.log.exception( self.name + ": Object not as expected" )
3213 return None
3214 except pexpect.EOF:
3215 main.log.error( self.name + ": EOF exception found" )
3216 main.log.error( self.name + ": " + self.handle.before )
3217 main.cleanup()
3218 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003219 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003220 main.log.exception( self.name + ": Uncaught exception!" )
3221 main.cleanup()
3222 main.exit()
3223
3224 def appToIDCheck( self ):
3225 """
3226 This method will check that each application's ID listed in 'apps' is
3227 the same as the ID listed in 'app-ids'. The check will also check that
3228 there are no duplicate IDs issued. Note that an app ID should be
3229 a globaly unique numerical identifier for app/app-like features. Once
3230 an ID is registered, the ID is never freed up so that if an app is
3231 reinstalled it will have the same ID.
3232
3233 Returns: main.TRUE if the check passes and
3234 main.FALSE if the check fails or
3235 main.ERROR if there is some error in processing the test
3236 """
3237 try:
Jon Hall390696c2015-05-05 17:13:41 -07003238 bail = False
3239 ids = self.appIDs( jsonFormat=True )
3240 if ids:
3241 ids = json.loads( ids )
3242 else:
3243 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3244 bail = True
3245 apps = self.apps( jsonFormat=True )
3246 if apps:
3247 apps = json.loads( apps )
3248 else:
3249 main.log.error( "apps returned nothing:" + repr( apps ) )
3250 bail = True
3251 if bail:
3252 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003253 result = main.TRUE
3254 for app in apps:
3255 appID = app.get( 'id' )
3256 if appID is None:
3257 main.log.error( "Error parsing app: " + str( app ) )
3258 result = main.FALSE
3259 appName = app.get( 'name' )
3260 if appName is None:
3261 main.log.error( "Error parsing app: " + str( app ) )
3262 result = main.FALSE
3263 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003264 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003265 # main.log.debug( "Comparing " + str( app ) + " to " +
3266 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003267 if not current: # if ids doesn't have this id
3268 result = main.FALSE
3269 main.log.error( "'app-ids' does not have the ID for " +
3270 str( appName ) + " that apps does." )
3271 elif len( current ) > 1:
3272 # there is more than one app with this ID
3273 result = main.FALSE
3274 # We will log this later in the method
3275 elif not current[0][ 'name' ] == appName:
3276 currentName = current[0][ 'name' ]
3277 result = main.FALSE
3278 main.log.error( "'app-ids' has " + str( currentName ) +
3279 " registered under id:" + str( appID ) +
3280 " but 'apps' has " + str( appName ) )
3281 else:
3282 pass # id and name match!
3283 # now make sure that app-ids has no duplicates
3284 idsList = []
3285 namesList = []
3286 for item in ids:
3287 idsList.append( item[ 'id' ] )
3288 namesList.append( item[ 'name' ] )
3289 if len( idsList ) != len( set( idsList ) ) or\
3290 len( namesList ) != len( set( namesList ) ):
3291 main.log.error( "'app-ids' has some duplicate entries: \n"
3292 + json.dumps( ids,
3293 sort_keys=True,
3294 indent=4,
3295 separators=( ',', ': ' ) ) )
3296 result = main.FALSE
3297 return result
3298 except ( ValueError, TypeError ):
3299 main.log.exception( self.name + ": Object not as expected" )
3300 return main.ERROR
3301 except pexpect.EOF:
3302 main.log.error( self.name + ": EOF exception found" )
3303 main.log.error( self.name + ": " + self.handle.before )
3304 main.cleanup()
3305 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003306 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003307 main.log.exception( self.name + ": Uncaught exception!" )
3308 main.cleanup()
3309 main.exit()
3310
Jon Hallfb760a02015-04-13 15:35:03 -07003311 def getCfg( self, component=None, propName=None, short=False,
3312 jsonFormat=True ):
3313 """
3314 Get configuration settings from onos cli
3315 Optional arguments:
3316 component - Optionally only list configurations for a specific
3317 component. If None, all components with configurations
3318 are displayed. Case Sensitive string.
3319 propName - If component is specified, propName option will show
3320 only this specific configuration from that component.
3321 Case Sensitive string.
3322 jsonFormat - Returns output as json. Note that this will override
3323 the short option
3324 short - Short, less verbose, version of configurations.
3325 This is overridden by the json option
3326 returns:
3327 Output from cli as a string or None on error
3328 """
3329 try:
3330 baseStr = "cfg"
3331 cmdStr = " get"
3332 componentStr = ""
3333 if component:
3334 componentStr += " " + component
3335 if propName:
3336 componentStr += " " + propName
3337 if jsonFormat:
3338 baseStr += " -j"
3339 elif short:
3340 baseStr += " -s"
3341 output = self.sendline( baseStr + cmdStr + componentStr )
3342 assert "Error executing command" not in output
3343 return output
3344 except AssertionError:
3345 main.log.error( "Error in processing 'cfg get' command: " +
3346 str( output ) )
3347 return None
3348 except TypeError:
3349 main.log.exception( self.name + ": Object not as expected" )
3350 return None
3351 except pexpect.EOF:
3352 main.log.error( self.name + ": EOF exception found" )
3353 main.log.error( self.name + ": " + self.handle.before )
3354 main.cleanup()
3355 main.exit()
3356 except Exception:
3357 main.log.exception( self.name + ": Uncaught exception!" )
3358 main.cleanup()
3359 main.exit()
3360
3361 def setCfg( self, component, propName, value=None, check=True ):
3362 """
3363 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003364 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003365 component - The case sensitive name of the component whose
3366 property is to be set
3367 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003368 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003369 value - The value to set the property to. If None, will unset the
3370 property and revert it to it's default value(if applicable)
3371 check - Boolean, Check whether the option was successfully set this
3372 only applies when a value is given.
3373 returns:
3374 main.TRUE on success or main.FALSE on failure. If check is False,
3375 will return main.TRUE unless there is an error
3376 """
3377 try:
3378 baseStr = "cfg"
3379 cmdStr = " set " + str( component ) + " " + str( propName )
3380 if value is not None:
3381 cmdStr += " " + str( value )
3382 output = self.sendline( baseStr + cmdStr )
3383 assert "Error executing command" not in output
3384 if value and check:
3385 results = self.getCfg( component=str( component ),
3386 propName=str( propName ),
3387 jsonFormat=True )
3388 # Check if current value is what we just set
3389 try:
3390 jsonOutput = json.loads( results )
3391 current = jsonOutput[ 'value' ]
3392 except ( ValueError, TypeError ):
3393 main.log.exception( "Error parsing cfg output" )
3394 main.log.error( "output:" + repr( results ) )
3395 return main.FALSE
3396 if current == str( value ):
3397 return main.TRUE
3398 return main.FALSE
3399 return main.TRUE
3400 except AssertionError:
3401 main.log.error( "Error in processing 'cfg set' command: " +
3402 str( output ) )
3403 return main.FALSE
3404 except TypeError:
3405 main.log.exception( self.name + ": Object not as expected" )
3406 return main.FALSE
3407 except pexpect.EOF:
3408 main.log.error( self.name + ": EOF exception found" )
3409 main.log.error( self.name + ": " + self.handle.before )
3410 main.cleanup()
3411 main.exit()
3412 except Exception:
3413 main.log.exception( self.name + ": Uncaught exception!" )
3414 main.cleanup()
3415 main.exit()
3416
Jon Hall390696c2015-05-05 17:13:41 -07003417 def setTestAdd( self, setName, values ):
3418 """
3419 CLI command to add elements to a distributed set.
3420 Arguments:
3421 setName - The name of the set to add to.
3422 values - The value(s) to add to the set, space seperated.
3423 Example usages:
3424 setTestAdd( "set1", "a b c" )
3425 setTestAdd( "set2", "1" )
3426 returns:
3427 main.TRUE on success OR
3428 main.FALSE if elements were already in the set OR
3429 main.ERROR on error
3430 """
3431 try:
3432 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3433 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003434 try:
3435 # TODO: Maybe make this less hardcoded
3436 # ConsistentMap Exceptions
3437 assert "org.onosproject.store.service" not in output
3438 # Node not leader
3439 assert "java.lang.IllegalStateException" not in output
3440 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003441 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003442 "command: " + str( output ) )
3443 retryTime = 30 # Conservative time, given by Madan
3444 main.log.info( "Waiting " + str( retryTime ) +
3445 "seconds before retrying." )
3446 time.sleep( retryTime ) # Due to change in mastership
3447 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003448 assert "Error executing command" not in output
3449 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3450 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3451 main.log.info( self.name + ": " + output )
3452 if re.search( positiveMatch, output):
3453 return main.TRUE
3454 elif re.search( negativeMatch, output):
3455 return main.FALSE
3456 else:
3457 main.log.error( self.name + ": setTestAdd did not" +
3458 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003459 main.log.debug( self.name + " actual: " + repr( output ) )
3460 return main.ERROR
3461 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003462 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003463 str( output ) )
3464 return main.ERROR
3465 except TypeError:
3466 main.log.exception( self.name + ": Object not as expected" )
3467 return main.ERROR
3468 except pexpect.EOF:
3469 main.log.error( self.name + ": EOF exception found" )
3470 main.log.error( self.name + ": " + self.handle.before )
3471 main.cleanup()
3472 main.exit()
3473 except Exception:
3474 main.log.exception( self.name + ": Uncaught exception!" )
3475 main.cleanup()
3476 main.exit()
3477
3478 def setTestRemove( self, setName, values, clear=False, retain=False ):
3479 """
3480 CLI command to remove elements from a distributed set.
3481 Required arguments:
3482 setName - The name of the set to remove from.
3483 values - The value(s) to remove from the set, space seperated.
3484 Optional arguments:
3485 clear - Clear all elements from the set
3486 retain - Retain only the given values. (intersection of the
3487 original set and the given set)
3488 returns:
3489 main.TRUE on success OR
3490 main.FALSE if the set was not changed OR
3491 main.ERROR on error
3492 """
3493 try:
3494 cmdStr = "set-test-remove "
3495 if clear:
3496 cmdStr += "-c " + str( setName )
3497 elif retain:
3498 cmdStr += "-r " + str( setName ) + " " + str( values )
3499 else:
3500 cmdStr += str( setName ) + " " + str( values )
3501 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003502 try:
3503 # TODO: Maybe make this less hardcoded
3504 # ConsistentMap Exceptions
3505 assert "org.onosproject.store.service" not in output
3506 # Node not leader
3507 assert "java.lang.IllegalStateException" not in output
3508 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003509 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003510 "command: " + str( output ) )
3511 retryTime = 30 # Conservative time, given by Madan
3512 main.log.info( "Waiting " + str( retryTime ) +
3513 "seconds before retrying." )
3514 time.sleep( retryTime ) # Due to change in mastership
3515 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003516 assert "Error executing command" not in output
3517 main.log.info( self.name + ": " + output )
3518 if clear:
3519 pattern = "Set " + str( setName ) + " cleared"
3520 if re.search( pattern, output ):
3521 return main.TRUE
3522 elif retain:
3523 positivePattern = str( setName ) + " was pruned to contain " +\
3524 "only elements of set \[(.*)\]"
3525 negativePattern = str( setName ) + " was not changed by " +\
3526 "retaining only elements of the set " +\
3527 "\[(.*)\]"
3528 if re.search( positivePattern, output ):
3529 return main.TRUE
3530 elif re.search( negativePattern, output ):
3531 return main.FALSE
3532 else:
3533 positivePattern = "\[(.*)\] was removed from the set " +\
3534 str( setName )
3535 if ( len( values.split() ) == 1 ):
3536 negativePattern = "\[(.*)\] was not in set " +\
3537 str( setName )
3538 else:
3539 negativePattern = "No element of \[(.*)\] was in set " +\
3540 str( setName )
3541 if re.search( positivePattern, output ):
3542 return main.TRUE
3543 elif re.search( negativePattern, output ):
3544 return main.FALSE
3545 main.log.error( self.name + ": setTestRemove did not" +
3546 " match expected output" )
3547 main.log.debug( self.name + " expected: " + pattern )
3548 main.log.debug( self.name + " actual: " + repr( output ) )
3549 return main.ERROR
3550 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003551 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003552 str( output ) )
3553 return main.ERROR
3554 except TypeError:
3555 main.log.exception( self.name + ": Object not as expected" )
3556 return main.ERROR
3557 except pexpect.EOF:
3558 main.log.error( self.name + ": EOF exception found" )
3559 main.log.error( self.name + ": " + self.handle.before )
3560 main.cleanup()
3561 main.exit()
3562 except Exception:
3563 main.log.exception( self.name + ": Uncaught exception!" )
3564 main.cleanup()
3565 main.exit()
3566
3567 def setTestGet( self, setName, values="" ):
3568 """
3569 CLI command to get the elements in a distributed set.
3570 Required arguments:
3571 setName - The name of the set to remove from.
3572 Optional arguments:
3573 values - The value(s) to check if in the set, space seperated.
3574 returns:
3575 main.ERROR on error OR
3576 A list of elements in the set if no optional arguments are
3577 supplied OR
3578 A tuple containing the list then:
3579 main.FALSE if the given values are not in the set OR
3580 main.TRUE if the given values are in the set OR
3581 """
3582 try:
3583 values = str( values ).strip()
3584 setName = str( setName ).strip()
3585 length = len( values.split() )
3586 containsCheck = None
3587 # Patterns to match
3588 setPattern = "\[(.*)\]"
3589 pattern = "Items in set " + setName + ":\n" + setPattern
3590 containsTrue = "Set " + setName + " contains the value " + values
3591 containsFalse = "Set " + setName + " did not contain the value " +\
3592 values
3593 containsAllTrue = "Set " + setName + " contains the the subset " +\
3594 setPattern
3595 containsAllFalse = "Set " + setName + " did not contain the the" +\
3596 " subset " + setPattern
3597
3598 cmdStr = "set-test-get "
3599 cmdStr += setName + " " + values
3600 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003601 try:
3602 # TODO: Maybe make this less hardcoded
3603 # ConsistentMap Exceptions
3604 assert "org.onosproject.store.service" not in output
3605 # Node not leader
3606 assert "java.lang.IllegalStateException" not in output
3607 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003608 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003609 "command: " + str( output ) )
3610 retryTime = 30 # Conservative time, given by Madan
3611 main.log.info( "Waiting " + str( retryTime ) +
3612 "seconds before retrying." )
3613 time.sleep( retryTime ) # Due to change in mastership
3614 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003615 assert "Error executing command" not in output
3616 main.log.info( self.name + ": " + output )
3617
3618 if length == 0:
3619 match = re.search( pattern, output )
3620 else: # if given values
3621 if length == 1: # Contains output
3622 patternTrue = pattern + "\n" + containsTrue
3623 patternFalse = pattern + "\n" + containsFalse
3624 else: # ContainsAll output
3625 patternTrue = pattern + "\n" + containsAllTrue
3626 patternFalse = pattern + "\n" + containsAllFalse
3627 matchTrue = re.search( patternTrue, output )
3628 matchFalse = re.search( patternFalse, output )
3629 if matchTrue:
3630 containsCheck = main.TRUE
3631 match = matchTrue
3632 elif matchFalse:
3633 containsCheck = main.FALSE
3634 match = matchFalse
3635 else:
3636 main.log.error( self.name + " setTestGet did not match " +\
3637 "expected output" )
3638 main.log.debug( self.name + " expected: " + pattern )
3639 main.log.debug( self.name + " actual: " + repr( output ) )
3640 match = None
3641 if match:
3642 setMatch = match.group( 1 )
3643 if setMatch == '':
3644 setList = []
3645 else:
3646 setList = setMatch.split( ", " )
3647 if length > 0:
3648 return ( setList, containsCheck )
3649 else:
3650 return setList
3651 else: # no match
3652 main.log.error( self.name + ": setTestGet did not" +
3653 " match expected output" )
3654 main.log.debug( self.name + " expected: " + pattern )
3655 main.log.debug( self.name + " actual: " + repr( output ) )
3656 return main.ERROR
3657 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003658 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003659 str( output ) )
3660 return main.ERROR
3661 except TypeError:
3662 main.log.exception( self.name + ": Object not as expected" )
3663 return main.ERROR
3664 except pexpect.EOF:
3665 main.log.error( self.name + ": EOF exception found" )
3666 main.log.error( self.name + ": " + self.handle.before )
3667 main.cleanup()
3668 main.exit()
3669 except Exception:
3670 main.log.exception( self.name + ": Uncaught exception!" )
3671 main.cleanup()
3672 main.exit()
3673
3674 def setTestSize( self, setName ):
3675 """
3676 CLI command to get the elements in a distributed set.
3677 Required arguments:
3678 setName - The name of the set to remove from.
3679 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003680 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003681 None on error
3682 """
3683 try:
3684 # TODO: Should this check against the number of elements returned
3685 # and then return true/false based on that?
3686 setName = str( setName ).strip()
3687 # Patterns to match
3688 setPattern = "\[(.*)\]"
3689 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3690 setPattern
3691 cmdStr = "set-test-get -s "
3692 cmdStr += setName
3693 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003694 try:
3695 # TODO: Maybe make this less hardcoded
3696 # ConsistentMap Exceptions
3697 assert "org.onosproject.store.service" not in output
3698 # Node not leader
3699 assert "java.lang.IllegalStateException" not in output
3700 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003701 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003702 "command: " + str( output ) )
3703 retryTime = 30 # Conservative time, given by Madan
3704 main.log.info( "Waiting " + str( retryTime ) +
3705 "seconds before retrying." )
3706 time.sleep( retryTime ) # Due to change in mastership
3707 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003708 assert "Error executing command" not in output
3709 main.log.info( self.name + ": " + output )
3710 match = re.search( pattern, output )
3711 if match:
3712 setSize = int( match.group( 1 ) )
3713 setMatch = match.group( 2 )
3714 if len( setMatch.split() ) == setSize:
3715 main.log.info( "The size returned by " + self.name +
3716 " matches the number of elements in " +
3717 "the returned set" )
3718 else:
3719 main.log.error( "The size returned by " + self.name +
3720 " does not match the number of " +
3721 "elements in the returned set." )
3722 return setSize
3723 else: # no match
3724 main.log.error( self.name + ": setTestGet did not" +
3725 " match expected output" )
3726 main.log.debug( self.name + " expected: " + pattern )
3727 main.log.debug( self.name + " actual: " + repr( output ) )
3728 return None
3729 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003730 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003731 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003732 return None
Jon Hall390696c2015-05-05 17:13:41 -07003733 except TypeError:
3734 main.log.exception( self.name + ": Object not as expected" )
3735 return None
3736 except pexpect.EOF:
3737 main.log.error( self.name + ": EOF exception found" )
3738 main.log.error( self.name + ": " + self.handle.before )
3739 main.cleanup()
3740 main.exit()
3741 except Exception:
3742 main.log.exception( self.name + ": Uncaught exception!" )
3743 main.cleanup()
3744 main.exit()
3745
Jon Hall80daded2015-05-27 16:07:00 -07003746 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003747 """
3748 Command to list the various counters in the system.
3749 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003750 if jsonFormat, a string of the json object returned by the cli
3751 command
3752 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003753 None on error
3754 """
Jon Hall390696c2015-05-05 17:13:41 -07003755 try:
3756 counters = {}
3757 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003758 if jsonFormat:
3759 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003760 output = self.sendline( cmdStr )
3761 assert "Error executing command" not in output
3762 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003763 return output
Jon Hall390696c2015-05-05 17:13:41 -07003764 except AssertionError:
3765 main.log.error( "Error in processing 'counters' command: " +
3766 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003767 return None
Jon Hall390696c2015-05-05 17:13:41 -07003768 except TypeError:
3769 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003770 return None
Jon Hall390696c2015-05-05 17:13:41 -07003771 except pexpect.EOF:
3772 main.log.error( self.name + ": EOF exception found" )
3773 main.log.error( self.name + ": " + self.handle.before )
3774 main.cleanup()
3775 main.exit()
3776 except Exception:
3777 main.log.exception( self.name + ": Uncaught exception!" )
3778 main.cleanup()
3779 main.exit()
3780
Jon Halle1a3b752015-07-22 13:02:46 -07003781 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003782 """
Jon Halle1a3b752015-07-22 13:02:46 -07003783 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003784 Required arguments:
3785 counter - The name of the counter to increment.
3786 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003787 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003788 inMemory - use in memory map for the counter
3789 returns:
3790 integer value of the counter or
3791 None on Error
3792 """
3793 try:
3794 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003795 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003796 cmdStr = "counter-test-increment "
3797 if inMemory:
3798 cmdStr += "-i "
3799 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003800 if delta != 1:
3801 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003802 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003803 try:
3804 # TODO: Maybe make this less hardcoded
3805 # ConsistentMap Exceptions
3806 assert "org.onosproject.store.service" not in output
3807 # Node not leader
3808 assert "java.lang.IllegalStateException" not in output
3809 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003810 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003811 "command: " + str( output ) )
3812 retryTime = 30 # Conservative time, given by Madan
3813 main.log.info( "Waiting " + str( retryTime ) +
3814 "seconds before retrying." )
3815 time.sleep( retryTime ) # Due to change in mastership
3816 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003817 assert "Error executing command" not in output
3818 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003819 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003820 match = re.search( pattern, output )
3821 if match:
3822 return int( match.group( 1 ) )
3823 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003824 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003825 " match expected output." )
3826 main.log.debug( self.name + " expected: " + pattern )
3827 main.log.debug( self.name + " actual: " + repr( output ) )
3828 return None
3829 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003830 main.log.error( "Error in processing '" + cmdStr + "'" +
Jon Hall390696c2015-05-05 17:13:41 -07003831 " command: " + str( output ) )
3832 return None
3833 except TypeError:
3834 main.log.exception( self.name + ": Object not as expected" )
3835 return None
3836 except pexpect.EOF:
3837 main.log.error( self.name + ": EOF exception found" )
3838 main.log.error( self.name + ": " + self.handle.before )
3839 main.cleanup()
3840 main.exit()
3841 except Exception:
3842 main.log.exception( self.name + ": Uncaught exception!" )
3843 main.cleanup()
3844 main.exit()
3845
Jon Halle1a3b752015-07-22 13:02:46 -07003846 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
3847 """
3848 CLI command to get a distributed counter then add a delta to it.
3849 Required arguments:
3850 counter - The name of the counter to increment.
3851 Optional arguments:
3852 delta - The long to add to the counter
3853 inMemory - use in memory map for the counter
3854 returns:
3855 integer value of the counter or
3856 None on Error
3857 """
3858 try:
3859 counter = str( counter )
3860 delta = int( delta )
3861 cmdStr = "counter-test-increment -g "
3862 if inMemory:
3863 cmdStr += "-i "
3864 cmdStr += counter
3865 if delta != 1:
3866 cmdStr += " " + str( delta )
3867 output = self.sendline( cmdStr )
3868 try:
3869 # TODO: Maybe make this less hardcoded
3870 # ConsistentMap Exceptions
3871 assert "org.onosproject.store.service" not in output
3872 # Node not leader
3873 assert "java.lang.IllegalStateException" not in output
3874 except AssertionError:
3875 main.log.error( "Error in processing '" + cmdStr + "' " +
3876 "command: " + str( output ) )
3877 retryTime = 30 # Conservative time, given by Madan
3878 main.log.info( "Waiting " + str( retryTime ) +
3879 "seconds before retrying." )
3880 time.sleep( retryTime ) # Due to change in mastership
3881 output = self.sendline( cmdStr )
3882 assert "Error executing command" not in output
3883 main.log.info( self.name + ": " + output )
3884 pattern = counter + " was updated to (-?\d+)"
3885 match = re.search( pattern, output )
3886 if match:
3887 return int( match.group( 1 ) )
3888 else:
3889 main.log.error( self.name + ": counterTestGetAndAdd did not" +
3890 " match expected output." )
3891 main.log.debug( self.name + " expected: " + pattern )
3892 main.log.debug( self.name + " actual: " + repr( output ) )
3893 return None
3894 except AssertionError:
3895 main.log.error( "Error in processing '" + cmdStr + "'" +
3896 " command: " + str( output ) )
3897 return None
3898 except TypeError:
3899 main.log.exception( self.name + ": Object not as expected" )
3900 return None
3901 except pexpect.EOF:
3902 main.log.error( self.name + ": EOF exception found" )
3903 main.log.error( self.name + ": " + self.handle.before )
3904 main.cleanup()
3905 main.exit()
3906 except Exception:
3907 main.log.exception( self.name + ": Uncaught exception!" )
3908 main.cleanup()
3909 main.exit()
3910
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003911 def summary( self, jsonFormat=True ):
3912 """
3913 Description: Execute summary command in onos
3914 Returns: json object ( summary -j ), returns main.FALSE if there is
3915 no output
3916
3917 """
3918 try:
3919 cmdStr = "summary"
3920 if jsonFormat:
3921 cmdStr += " -j"
3922 handle = self.sendline( cmdStr )
3923
3924 if re.search( "Error:", handle ):
3925 main.log.error( self.name + ": summary() response: " +
3926 str( handle ) )
3927 if not handle:
3928 main.log.error( self.name + ": There is no output in " +
3929 "summary command" )
3930 return main.FALSE
3931 return handle
3932 except TypeError:
3933 main.log.exception( self.name + ": Object not as expected" )
3934 return None
3935 except pexpect.EOF:
3936 main.log.error( self.name + ": EOF exception found" )
3937 main.log.error( self.name + ": " + self.handle.before )
3938 main.cleanup()
3939 main.exit()
3940 except Exception:
3941 main.log.exception( self.name + ": Uncaught exception!" )
3942 main.cleanup()
3943 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07003944
3945 def transactionalMapGet( self, keyName, inMemory=False ):
3946 """
3947 CLI command to get the value of a key in a consistent map using
3948 transactions. This a test function and can only get keys from the
3949 test map hard coded into the cli command
3950 Required arguments:
3951 keyName - The name of the key to get
3952 Optional arguments:
3953 inMemory - use in memory map for the counter
3954 returns:
3955 The string value of the key or
3956 None on Error
3957 """
3958 try:
3959 keyName = str( keyName )
3960 cmdStr = "transactional-map-test-get "
3961 if inMemory:
3962 cmdStr += "-i "
3963 cmdStr += keyName
3964 output = self.sendline( cmdStr )
3965 try:
3966 # TODO: Maybe make this less hardcoded
3967 # ConsistentMap Exceptions
3968 assert "org.onosproject.store.service" not in output
3969 # Node not leader
3970 assert "java.lang.IllegalStateException" not in output
3971 except AssertionError:
3972 main.log.error( "Error in processing '" + cmdStr + "' " +
3973 "command: " + str( output ) )
3974 return None
3975 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
3976 if "Key " + keyName + " not found." in output:
3977 return None
3978 else:
3979 match = re.search( pattern, output )
3980 if match:
3981 return match.groupdict()[ 'value' ]
3982 else:
3983 main.log.error( self.name + ": transactionlMapGet did not" +
3984 " match expected output." )
3985 main.log.debug( self.name + " expected: " + pattern )
3986 main.log.debug( self.name + " actual: " + repr( output ) )
3987 return None
3988 except TypeError:
3989 main.log.exception( self.name + ": Object not as expected" )
3990 return None
3991 except pexpect.EOF:
3992 main.log.error( self.name + ": EOF exception found" )
3993 main.log.error( self.name + ": " + self.handle.before )
3994 main.cleanup()
3995 main.exit()
3996 except Exception:
3997 main.log.exception( self.name + ": Uncaught exception!" )
3998 main.cleanup()
3999 main.exit()
4000
4001 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4002 """
4003 CLI command to put a value into 'numKeys' number of keys in a
4004 consistent map using transactions. This a test function and can only
4005 put into keys named 'Key#' of the test map hard coded into the cli command
4006 Required arguments:
4007 numKeys - Number of keys to add the value to
4008 value - The string value to put into the keys
4009 Optional arguments:
4010 inMemory - use in memory map for the counter
4011 returns:
4012 A dictionary whose keys are the name of the keys put into the map
4013 and the values of the keys are dictionaries whose key-values are
4014 'value': value put into map and optionaly
4015 'oldValue': Previous value in the key or
4016 None on Error
4017
4018 Example output
4019 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4020 'Key2': {'value': 'Testing'} }
4021 """
4022 try:
4023 numKeys = str( numKeys )
4024 value = str( value )
4025 cmdStr = "transactional-map-test-put "
4026 if inMemory:
4027 cmdStr += "-i "
4028 cmdStr += numKeys + " " + value
4029 output = self.sendline( cmdStr )
4030 try:
4031 # TODO: Maybe make this less hardcoded
4032 # ConsistentMap Exceptions
4033 assert "org.onosproject.store.service" not in output
4034 # Node not leader
4035 assert "java.lang.IllegalStateException" not in output
4036 except AssertionError:
4037 main.log.error( "Error in processing '" + cmdStr + "' " +
4038 "command: " + str( output ) )
4039 return None
4040 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4041 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4042 results = {}
4043 for line in output.splitlines():
4044 new = re.search( newPattern, line )
4045 updated = re.search( updatedPattern, line )
4046 if new:
4047 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4048 elif updated:
4049 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
4050 'oldValue': updated.groupdict()[ 'oldValue' ] }
4051 else:
4052 main.log.error( self.name + ": transactionlMapGet did not" +
4053 " match expected output." )
4054 main.log.debug( self.name + " expected: " + pattern )
4055 main.log.debug( self.name + " actual: " + repr( output ) )
4056 return results
4057 except TypeError:
4058 main.log.exception( self.name + ": Object not as expected" )
4059 return None
4060 except pexpect.EOF:
4061 main.log.error( self.name + ": EOF exception found" )
4062 main.log.error( self.name + ": " + self.handle.before )
4063 main.cleanup()
4064 main.exit()
4065 except Exception:
4066 main.log.exception( self.name + ": Uncaught exception!" )
4067 main.cleanup()
4068 main.exit()
acsmarsdaea66c2015-09-03 11:44:06 -07004069 def maps( self, jsonFormat=True ):
4070 """
4071 Description: Returns result of onos:maps
4072 Optional:
4073 * jsonFormat: enable json formatting of output
4074 """
4075 try:
4076 cmdStr = "maps"
4077 if jsonFormat:
4078 cmdStr += " -j"
4079 handle = self.sendline( cmdStr )
4080 return handle
4081 except TypeError:
4082 main.log.exception( self.name + ": Object not as expected" )
4083 return None
4084 except pexpect.EOF:
4085 main.log.error( self.name + ": EOF exception found" )
4086 main.log.error( self.name + ": " + self.handle.before )
4087 main.cleanup()
4088 main.exit()
4089 except Exception:
4090 main.log.exception( self.name + ": Uncaught exception!" )
4091 main.cleanup()
4092 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004093
4094 def getSwController( self, uri, jsonFormat=True ):
4095 """
4096 Descrition: Gets the controller information from the device
4097 """
4098 try:
4099 cmd = "device-controllers "
4100 if jsonFormat:
4101 cmd += "-j "
4102 response = self.sendline( cmd + uri )
4103 return response
4104 except TypeError:
4105 main.log.exception( self.name + ": Object not as expected" )
4106 return None
4107 except pexpect.EOF:
4108 main.log.error( self.name + ": EOF exception found" )
4109 main.log.error( self.name + ": " + self.handle.before )
4110 main.cleanup()
4111 main.exit()
4112 except Exception:
4113 main.log.exception( self.name + ": Uncaught exception!" )
4114 main.cleanup()
4115 main.exit()
4116
4117 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4118 """
4119 Descrition: sets the controller(s) for the specified device
4120
4121 Parameters:
4122 Required: uri - String: The uri of the device(switch).
4123 ip - String or List: The ip address of the controller.
4124 This parameter can be formed in a couple of different ways.
4125 VALID:
4126 10.0.0.1 - just the ip address
4127 tcp:10.0.0.1 - the protocol and the ip address
4128 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4129 so that you can add controllers with different
4130 protocols and ports
4131 INVALID:
4132 10.0.0.1:6653 - this is not supported by ONOS
4133
4134 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4135 port - The port number.
4136 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4137
4138 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4139 """
4140 try:
4141 cmd = "device-setcontrollers"
4142
4143 if jsonFormat:
4144 cmd += " -j"
4145 cmd += " " + uri
4146 if isinstance( ip, str ):
4147 ip = [ip]
4148 for item in ip:
4149 if ":" in item:
4150 sitem = item.split( ":" )
4151 if len(sitem) == 3:
4152 cmd += " " + item
4153 elif "." in sitem[1]:
4154 cmd += " {}:{}".format(item, port)
4155 else:
4156 main.log.error( "Malformed entry: " + item )
4157 raise TypeError
4158 else:
4159 cmd += " {}:{}:{}".format( proto, item, port )
4160
4161 response = self.sendline( cmd )
4162
4163 if "Error" in response:
4164 main.log.error( response )
4165 return main.FALSE
4166
GlennRC050596c2015-11-18 17:06:41 -08004167 return main.TRUE
4168
4169 except TypeError:
4170 main.log.exception( self.name + ": Object not as expected" )
4171 return main.FALSE
4172 except pexpect.EOF:
4173 main.log.error( self.name + ": EOF exception found" )
4174 main.log.error( self.name + ": " + self.handle.before )
4175 main.cleanup()
4176 main.exit()
4177 except Exception:
4178 main.log.exception( self.name + ": Uncaught exception!" )
4179 main.cleanup()
4180 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004181
4182 def removeDevice( self, device ):
4183 '''
4184 Description:
4185 Remove a device from ONOS by passing the uri of the device(s).
4186 Parameters:
4187 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4188 Returns:
4189 Returns main.FALSE if an exception is thrown or an error is present
4190 in the response. Otherwise, returns main.TRUE.
4191 NOTE:
4192 If a host cannot be removed, then this function will return main.FALSE
4193 '''
4194 try:
4195 if type( device ) is str:
4196 device = list( device )
4197
4198 for d in device:
4199 time.sleep( 1 )
4200 response = self.sendline( "device-remove {}".format( d ) )
4201 if "Error" in response:
4202 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4203 return main.FALSE
4204
4205 return main.TRUE
4206
4207 except TypeError:
4208 main.log.exception( self.name + ": Object not as expected" )
4209 return main.FALSE
4210 except pexpect.EOF:
4211 main.log.error( self.name + ": EOF exception found" )
4212 main.log.error( self.name + ": " + self.handle.before )
4213 main.cleanup()
4214 main.exit()
4215 except Exception:
4216 main.log.exception( self.name + ": Uncaught exception!" )
4217 main.cleanup()
4218 main.exit()
4219
4220 def removeHost( self, host ):
4221 '''
4222 Description:
4223 Remove a host from ONOS by passing the id of the host(s)
4224 Parameters:
4225 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4226 Returns:
4227 Returns main.FALSE if an exception is thrown or an error is present
4228 in the response. Otherwise, returns main.TRUE.
4229 NOTE:
4230 If a host cannot be removed, then this function will return main.FALSE
4231 '''
4232 try:
4233 if type( host ) is str:
4234 host = list( host )
4235
4236 for h in host:
4237 time.sleep( 1 )
4238 response = self.sendline( "host-remove {}".format( h ) )
4239 if "Error" in response:
4240 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4241 return main.FALSE
4242
4243 return main.TRUE
4244
4245 except TypeError:
4246 main.log.exception( self.name + ": Object not as expected" )
4247 return main.FALSE
4248 except pexpect.EOF:
4249 main.log.error( self.name + ": EOF exception found" )
4250 main.log.error( self.name + ": " + self.handle.before )
4251 main.cleanup()
4252 main.exit()
4253 except Exception:
4254 main.log.exception( self.name + ": Uncaught exception!" )
4255 main.cleanup()
4256 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004257
4258 def link( self, begin, end, state):
4259 '''
4260 Description:
4261 Bring link down or up in the null-provider.
4262 params:
4263 begin - (string) One end of a device or switch.
4264 end - (string) the other end of the device or switch
4265 returns:
4266 main.TRUE if no exceptions were thrown and no Errors are
4267 present in the resoponse. Otherwise, returns main.FALSE
4268 '''
4269 try:
4270 cmd = "null-link null:{} null:{} {}".format(begin, end, state)
4271 response = self.sendline( cmd, showResponse=True )
4272
4273 if "Error" in response or "Failure" in response:
4274 main.log.error( response )
4275 return main.FALSE
4276
4277 return main.TRUE
4278 except TypeError:
4279 main.log.exception( self.name + ": Object not as expected" )
4280 return main.FALSE
4281 except pexpect.EOF:
4282 main.log.error( self.name + ": EOF exception found" )
4283 main.log.error( self.name + ": " + self.handle.before )
4284 main.cleanup()
4285 main.exit()
4286 except Exception:
4287 main.log.exception( self.name + ": Uncaught exception!" )
4288 main.cleanup()
4289 main.exit()
4290