blob: 63fc296d0baf6c2f009b9c162de13a426b9a732e [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:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 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" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700154 try:
155 self.handle.expect( "\$" )
156 except pexpect.TIMEOUT:
157 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700158 return main.TRUE
159 else: # some other output
160 main.log.warn( "Unknown repsonse to logout command: '{}'",
161 repr( self.handle.before ) )
162 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700163 elif i == 1: # not in CLI
164 return main.TRUE
165 elif i == 3: # Timeout
166 return main.FALSE
167 else:
andrewonlab9627f432014-11-14 12:45:10 -0500168 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800169 except TypeError:
170 main.log.exception( self.name + ": Object not as expected" )
171 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800173 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700174 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500175 main.cleanup()
176 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700177 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700178 main.log.error( self.name +
179 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800180 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800181 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
184
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800186 """
andrewonlab95ce8322014-10-13 14:12:04 -0400187 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800188
andrewonlab95ce8322014-10-13 14:12:04 -0400189 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800190 """
andrewonlab95ce8322014-10-13 14:12:04 -0400191 try:
192 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800193 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400194 main.cleanup()
195 main.exit()
196 else:
kelvin8ec71442015-01-15 16:57:00 -0800197 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800199 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400200 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800201 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800202 handleBefore = self.handle.before
203 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800204 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800205 self.handle.sendline("")
206 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800207 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400208
kelvin-onlabd3b64892015-01-20 13:26:24 -0800209 main.log.info( "Cell call returned: " + handleBefore +
210 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400211
212 return main.TRUE
213
Jon Halld4d4b372015-01-28 16:02:41 -0800214 except TypeError:
215 main.log.exception( self.name + ": Object not as expected" )
216 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400217 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800218 main.log.error( self.name + ": eof exception found" )
219 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400220 main.cleanup()
221 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800222 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800223 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400224 main.cleanup()
225 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800226
pingping-lin57a56ce2015-05-20 16:43:48 -0700227 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800228 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800229 """
Jon Hallefbd9792015-03-05 16:11:36 -0800230 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 by user would be used to set the current karaf shell idle timeout.
232 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800233 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 Below is an example to start a session with 60 seconds idle timeout
235 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800236
Hari Krishna25d42f72015-01-05 15:08:28 -0800237 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800239
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 Note: karafTimeout is left as str so that this could be read
241 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800242 """
You Wangf69ab392016-01-26 16:34:38 -0800243 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400244 try:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline( "" )
246 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700247 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500248
249 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800250 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500251 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400252
kelvin8ec71442015-01-15 16:57:00 -0800253 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800255 i = self.handle.expect( [
256 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700257 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400258
259 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800261 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800262 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800263 "config:property-set -p org.apache.karaf.shell\
264 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800265 karafTimeout )
266 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800268 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400269 return main.TRUE
270 else:
kelvin8ec71442015-01-15 16:57:00 -0800271 # If failed, send ctrl+c to process and try again
272 main.log.info( "Starting CLI failed. Retrying..." )
273 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800275 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
276 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400277 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800279 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800280 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800281 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 "config:property-set -p org.apache.karaf.shell\
283 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800284 karafTimeout )
285 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400288 return main.TRUE
289 else:
kelvin8ec71442015-01-15 16:57:00 -0800290 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400292 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400293
Jon Halld4d4b372015-01-28 16:02:41 -0800294 except TypeError:
295 main.log.exception( self.name + ": Object not as expected" )
296 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800298 main.log.error( self.name + ": EOF exception found" )
299 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400300 main.cleanup()
301 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800303 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400304 main.cleanup()
305 main.exit()
306
suibin zhang116647a2016-05-06 16:30:09 -0700307 def startCellCli( self, karafTimeout="",
308 commandlineTimeout=10, onosStartTimeout=60 ):
309 """
310 Start CLI on onos ecll handle.
311
312 karafTimeout is an optional argument. karafTimeout value passed
313 by user would be used to set the current karaf shell idle timeout.
314 Note that when ever this property is modified the shell will exit and
315 the subsequent login would reflect new idle timeout.
316 Below is an example to start a session with 60 seconds idle timeout
317 ( input value is in milliseconds ):
318
319 tValue = "60000"
320
321 Note: karafTimeout is left as str so that this could be read
322 and passed to startOnosCli from PARAMS file as str.
323 """
324
325 try:
326 self.handle.sendline( "" )
327 x = self.handle.expect( [
328 "\$", "onos>" ], commandlineTimeout)
329
330 if x == 1:
331 main.log.info( "ONOS cli is already running" )
332 return main.TRUE
333
334 # Wait for onos start ( -w ) and enter onos cli
335 self.handle.sendline( "/opt/onos/bin/onos" )
336 i = self.handle.expect( [
337 "onos>",
338 pexpect.TIMEOUT ], onosStartTimeout )
339
340 if i == 0:
341 main.log.info( self.name + " CLI Started successfully" )
342 if karafTimeout:
343 self.handle.sendline(
344 "config:property-set -p org.apache.karaf.shell\
345 sshIdleTimeout " +
346 karafTimeout )
347 self.handle.expect( "\$" )
348 self.handle.sendline( "/opt/onos/bin/onos" )
349 self.handle.expect( "onos>" )
350 return main.TRUE
351 else:
352 # If failed, send ctrl+c to process and try again
353 main.log.info( "Starting CLI failed. Retrying..." )
354 self.handle.send( "\x03" )
355 self.handle.sendline( "/opt/onos/bin/onos" )
356 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
357 timeout=30 )
358 if i == 0:
359 main.log.info( self.name + " CLI Started " +
360 "successfully after retry attempt" )
361 if karafTimeout:
362 self.handle.sendline(
363 "config:property-set -p org.apache.karaf.shell\
364 sshIdleTimeout " +
365 karafTimeout )
366 self.handle.expect( "\$" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 self.handle.expect( "onos>" )
369 return main.TRUE
370 else:
371 main.log.error( "Connection to CLI " +
372 self.name + " timeout" )
373 return main.FALSE
374
375 except TypeError:
376 main.log.exception( self.name + ": Object not as expected" )
377 return None
378 except pexpect.EOF:
379 main.log.error( self.name + ": EOF exception found" )
380 main.log.error( self.name + ": " + self.handle.before )
381 main.cleanup()
382 main.exit()
383 except Exception:
384 main.log.exception( self.name + ": Uncaught exception!" )
385 main.cleanup()
386 main.exit()
387
YPZhangebf9eb52016-05-12 15:20:24 -0700388 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800389 """
390 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800391 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800392 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700393 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800394 Available level: DEBUG, TRACE, INFO, WARN, ERROR
395 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800396 """
397 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800398 lvlStr = ""
399 if level:
400 lvlStr = "--level=" + level
401
kelvin-onlab338f5512015-02-06 10:53:16 -0800402 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700403 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800404 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800405
kelvin-onlab9f541032015-02-04 16:19:53 -0800406 response = self.handle.before
407 if re.search( "Error", response ):
408 return main.FALSE
409 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700410 except pexpect.TIMEOUT:
411 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700412 if noExit:
413 main.cleanup()
414 return None
415 else:
416 main.cleanup()
417 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 except pexpect.EOF:
419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700421 if noExit:
422 main.cleanup()
423 return None
424 else:
425 main.cleanup()
426 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800427 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800428 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700429 if noExit:
430 main.cleanup()
431 return None
432 else:
433 main.cleanup()
434 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400435
YPZhangebf9eb52016-05-12 15:20:24 -0700436 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800437 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800438 Send a completely user specified string to
439 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400440 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800441
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit is True, TestON will not exit, but clean up
443
andrewonlaba18f6bf2014-10-13 19:31:54 -0400444 Warning: There are no sanity checking to commands
445 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800446
kelvin8ec71442015-01-15 16:57:00 -0800447 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400448 try:
Jon Halla495f562016-05-16 18:03:26 -0700449 # Try to reconnect if disconnected from cli
450 self.handle.sendline( "" )
451 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
452 if i == 1:
453 main.log.error( self.name + ": onos cli session closed. ")
454 if self.onosIp:
455 main.log.warn( "Trying to reconnect " + self.onosIp )
456 reconnectResult = self.startOnosCli( self.onosIp )
457 if reconnectResult:
458 main.log.info( self.name + ": onos cli session reconnected." )
459 else:
460 main.log.error( self.name + ": reconnection failed." )
461 main.cleanup()
462 main.exit()
463 else:
464 main.cleanup()
465 main.exit()
466 if i == 2:
467 self.handle.sendline( "" )
468 self.handle.expect( "onos>" )
469
Jon Hall14a03b52016-05-11 12:07:30 -0700470 if debug:
471 # NOTE: This adds and average of .4 seconds per call
472 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700473 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800475 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800476 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800477 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800478 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
479 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700480 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700481 main.log.debug( self.name + ": Raw output" )
482 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483
484 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800486 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700487 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700488 main.log.debug( self.name + ": ansiEscape output" )
489 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490
kelvin-onlabfb521662015-02-27 09:52:40 -0800491 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800492 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700493 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700494 main.log.debug( self.name + ": Removed extra returns " +
495 "from output" )
496 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497
498 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800499 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700501 main.log.debug( self.name + ": parsed and stripped output" )
502 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503
Jon Hall63604932015-02-26 17:09:50 -0800504 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 output = response.split( cmdStr.strip(), 1 )
506 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700507 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700509 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800510 output = output[1].strip()
511 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800512 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800513 return output
GlennRCed771242016-01-13 17:02:47 -0800514 except pexpect.TIMEOUT:
515 main.log.error( self.name + ":ONOS timeout" )
516 if debug:
517 main.log.debug( self.handle.before )
518 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700519 except IndexError:
520 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700521 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800523 except TypeError:
524 main.log.exception( self.name + ": Object not as expected" )
525 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400526 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800527 main.log.error( self.name + ": EOF exception found" )
528 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700529 if noExit:
530 main.cleanup()
531 return None
532 else:
533 main.cleanup()
534 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800536 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700537 if noExit:
538 main.cleanup()
539 return None
540 else:
541 main.cleanup()
542 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400543
kelvin8ec71442015-01-15 16:57:00 -0800544 # IMPORTANT NOTE:
545 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 # the cli command changing 'a:b' with 'aB'.
547 # Ex ) onos:topology > onosTopology
548 # onos:links > onosLinks
549 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800552 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 Adds a new cluster node by ID and address information.
554 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 * nodeId
556 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400557 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800559 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400560 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800561 cmdStr = "add-node " + str( nodeId ) + " " +\
562 str( ONOSIp ) + " " + str( tcpPort )
563 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700564 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800565 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800566 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error( "Error in adding node" )
568 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800569 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400570 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800573 except AssertionError:
574 main.log.exception( "" )
575 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800576 except TypeError:
577 main.log.exception( self.name + ": Object not as expected" )
578 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error( self.name + ": EOF exception found" )
581 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 main.cleanup()
583 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800584 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800585 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 main.cleanup()
587 main.exit()
588
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlab86dc3082014-10-13 18:18:38 -0400591 Removes a cluster by ID
592 Issues command: 'remove-node [<node-id>]'
593 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800595 """
andrewonlab86dc3082014-10-13 18:18:38 -0400596 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700599 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700600 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800601 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700602 if re.search( "Error", handle ):
603 main.log.error( "Error in removing node" )
604 main.log.error( handle )
605 return main.FALSE
606 else:
607 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800608 except AssertionError:
609 main.log.exception( "" )
610 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800611 except TypeError:
612 main.log.exception( self.name + ": Object not as expected" )
613 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800615 main.log.error( self.name + ": EOF exception found" )
616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400617 main.cleanup()
618 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400621 main.cleanup()
622 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400623
Jon Hall61282e32015-03-19 11:34:11 -0700624 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800625 """
andrewonlab7c211572014-10-15 16:45:20 -0400626 List the nodes currently visible
627 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700628 Optional argument:
629 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800630 """
andrewonlab7c211572014-10-15 16:45:20 -0400631 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700632 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700633 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 cmdStr += " -j"
635 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700636 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800637 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 return output
Jon Hallc6793552016-01-19 14:18:37 -0800639 except AssertionError:
640 main.log.exception( "" )
641 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800642 except TypeError:
643 main.log.exception( self.name + ": Object not as expected" )
644 return None
andrewonlab7c211572014-10-15 16:45:20 -0400645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": EOF exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800651 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400652 main.cleanup()
653 main.exit()
654
kelvin8ec71442015-01-15 16:57:00 -0800655 def topology( self ):
656 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700657 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700658 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700659 Return:
660 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800661 """
andrewonlab95ce8322014-10-13 14:12:04 -0400662 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700663 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800665 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700666 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400667 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800668 except AssertionError:
669 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800670 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400674 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400677 main.cleanup()
678 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800679 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800680 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400681 main.cleanup()
682 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800683
jenkins7ead5a82015-03-13 10:28:21 -0700684 def deviceRemove( self, deviceId ):
685 """
686 Removes particular device from storage
687
688 TODO: refactor this function
689 """
690 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr = "device-remove " + str( deviceId )
692 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800693 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700694 if re.search( "Error", handle ):
695 main.log.error( "Error in removing device" )
696 main.log.error( handle )
697 return main.FALSE
698 else:
699 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800700 except AssertionError:
701 main.log.exception( "" )
702 return None
jenkins7ead5a82015-03-13 10:28:21 -0700703 except TypeError:
704 main.log.exception( self.name + ": Object not as expected" )
705 return None
706 except pexpect.EOF:
707 main.log.error( self.name + ": EOF exception found" )
708 main.log.error( self.name + ": " + self.handle.before )
709 main.cleanup()
710 main.exit()
711 except Exception:
712 main.log.exception( self.name + ": Uncaught exception!" )
713 main.cleanup()
714 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700715
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800717 """
Jon Hall7b02d952014-10-17 20:14:54 -0400718 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400719 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800721 """
andrewonlab86dc3082014-10-13 18:18:38 -0400722 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700723 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr += " -j"
726 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800727 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700728 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800729 except AssertionError:
730 main.log.exception( "" )
731 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800732 except TypeError:
733 main.log.exception( self.name + ": Object not as expected" )
734 return None
andrewonlab7c211572014-10-15 16:45:20 -0400735 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800736 main.log.error( self.name + ": EOF exception found" )
737 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400738 main.cleanup()
739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800741 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400742 main.cleanup()
743 main.exit()
744
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800746 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800747 This balances the devices across all controllers
748 by issuing command: 'onos> onos:balance-masters'
749 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800750 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800751 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800754 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 if re.search( "Error", handle ):
756 main.log.error( "Error in balancing masters" )
757 main.log.error( handle )
758 return main.FALSE
759 else:
760 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800761 except AssertionError:
762 main.log.exception( "" )
763 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800764 except TypeError:
765 main.log.exception( self.name + ": Object not as expected" )
766 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800768 main.log.error( self.name + ": EOF exception found" )
769 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800770 main.cleanup()
771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800773 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800774 main.cleanup()
775 main.exit()
776
Jon Hallc6793552016-01-19 14:18:37 -0800777 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700778 """
779 Returns the output of the masters command.
780 Optional argument:
781 * jsonFormat - boolean indicating if you want output in json
782 """
783 try:
784 cmdStr = "onos:masters"
785 if jsonFormat:
786 cmdStr += " -j"
787 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700788 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800789 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700790 return output
Jon Hallc6793552016-01-19 14:18:37 -0800791 except AssertionError:
792 main.log.exception( "" )
793 return None
acsmars24950022015-07-30 18:00:43 -0700794 except TypeError:
795 main.log.exception( self.name + ": Object not as expected" )
796 return None
797 except pexpect.EOF:
798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
800 main.cleanup()
801 main.exit()
802 except Exception:
803 main.log.exception( self.name + ": Uncaught exception!" )
804 main.cleanup()
805 main.exit()
806
Jon Hallc6793552016-01-19 14:18:37 -0800807 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700808 """
809 Uses the master command to check that the devices' leadership
810 is evenly divided
811
812 Dependencies: checkMasters() and summary()
813
814 Returns main.True if the devices are balanced
815 Returns main.False if the devices are unbalanced
816 Exits on Exception
817 Returns None on TypeError
818 """
819 try:
Jon Hallc6793552016-01-19 14:18:37 -0800820 summaryOutput = self.summary()
821 totalDevices = json.loads( summaryOutput )[ "devices" ]
822 except ( TypeError, ValueError ):
823 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
824 return None
825 try:
acsmars24950022015-07-30 18:00:43 -0700826 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800827 mastersOutput = self.checkMasters()
828 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700829 first = masters[ 0 ][ "size" ]
830 for master in masters:
831 totalOwnedDevices += master[ "size" ]
832 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
833 main.log.error( "Mastership not balanced" )
834 main.log.info( "\n" + self.checkMasters( False ) )
835 return main.FALSE
836 main.log.info( "Mastership balanced between " \
837 + str( len(masters) ) + " masters" )
838 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800839 except ( TypeError, ValueError ):
840 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700841 return None
842 except pexpect.EOF:
843 main.log.error( self.name + ": EOF exception found" )
844 main.log.error( self.name + ": " + self.handle.before )
845 main.cleanup()
846 main.exit()
847 except Exception:
848 main.log.exception( self.name + ": Uncaught exception!" )
849 main.cleanup()
850 main.exit()
851
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800853 """
Jon Halle8217482014-10-17 13:49:14 -0400854 Lists all core links
855 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800857 """
Jon Halle8217482014-10-17 13:49:14 -0400858 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700859 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 cmdStr += " -j"
862 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800863 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700864 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800865 except AssertionError:
866 main.log.exception( "" )
867 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800868 except TypeError:
869 main.log.exception( self.name + ": Object not as expected" )
870 return None
Jon Halle8217482014-10-17 13:49:14 -0400871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800872 main.log.error( self.name + ": EOF exception found" )
873 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400874 main.cleanup()
875 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800876 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800877 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400878 main.cleanup()
879 main.exit()
880
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800882 """
Jon Halle8217482014-10-17 13:49:14 -0400883 Lists all ports
884 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800886 """
Jon Halle8217482014-10-17 13:49:14 -0400887 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700888 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700890 cmdStr += " -j"
891 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800892 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700893 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800894 except AssertionError:
895 main.log.exception( "" )
896 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800897 except TypeError:
898 main.log.exception( self.name + ": Object not as expected" )
899 return None
Jon Halle8217482014-10-17 13:49:14 -0400900 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400903 main.cleanup()
904 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800905 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800906 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400907 main.cleanup()
908 main.exit()
909
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800911 """
Jon Hall983a1702014-10-28 18:44:22 -0400912 Lists all devices and the controllers with roles assigned to them
913 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800915 """
andrewonlab7c211572014-10-15 16:45:20 -0400916 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700917 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700919 cmdStr += " -j"
920 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800921 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800923 except AssertionError:
924 main.log.exception( "" )
925 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800926 except TypeError:
927 main.log.exception( self.name + ": Object not as expected" )
928 return None
Jon Hall983a1702014-10-28 18:44:22 -0400929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400932 main.cleanup()
933 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800935 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400936 main.cleanup()
937 main.exit()
938
kelvin-onlabd3b64892015-01-20 13:26:24 -0800939 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800940 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800941 Given the a string containing the json representation of the "roles"
942 cli command and a partial or whole device id, returns a json object
943 containing the roles output for the first device whose id contains
944 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400945
946 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800947 A dict of the role assignments for the given device or
948 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800949 """
Jon Hall983a1702014-10-28 18:44:22 -0400950 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400952 return None
953 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 rawRoles = self.roles()
955 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800956 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800958 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400960 return device
961 return None
Jon Hallc6793552016-01-19 14:18:37 -0800962 except ( TypeError, ValueError ):
963 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800964 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400965 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400968 main.cleanup()
969 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800970 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800971 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400972 main.cleanup()
973 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800974
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800976 """
Jon Hall94fd0472014-12-08 11:52:42 -0800977 Iterates through each device and checks if there is a master assigned
978 Returns: main.TRUE if each device has a master
979 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800980 """
Jon Hall94fd0472014-12-08 11:52:42 -0800981 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 rawRoles = self.roles()
983 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800984 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800986 # print device
987 if device[ 'master' ] == "none":
988 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800989 return main.FALSE
990 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800991 except ( TypeError, ValueError ):
992 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800993 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.error( self.name + ": EOF exception found" )
996 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800997 main.cleanup()
998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001000 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 main.cleanup()
1002 main.exit()
1003
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001005 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001006 Returns string of paths, and the cost.
1007 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001008 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001009 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1011 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001012 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001013 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.error( "Error in getting paths" )
1015 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 else:
kelvin8ec71442015-01-15 16:57:00 -08001017 path = handle.split( ";" )[ 0 ]
1018 cost = handle.split( ";" )[ 1 ]
1019 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001020 except AssertionError:
1021 main.log.exception( "" )
1022 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001023 except TypeError:
1024 main.log.exception( self.name + ": Object not as expected" )
1025 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 main.cleanup()
1030 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001031 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001032 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001033 main.cleanup()
1034 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001035
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001037 """
Jon Hallffb386d2014-11-21 13:43:38 -08001038 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001039 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001040 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001041 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001042 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001043 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001045 cmdStr += " -j"
1046 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001047 if handle:
1048 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001049 # TODO: Maybe make this less hardcoded
1050 # ConsistentMap Exceptions
1051 assert "org.onosproject.store.service" not in handle
1052 # Node not leader
1053 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001055 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001057 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -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
Jon Hall42db6dc2014-10-24 19:03:48 -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 )
Jon Hall42db6dc2014-10-24 19:03:48 -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!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001074 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001075
Jon Hallefbd9792015-03-05 16:11:36 -08001076 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001077 partial mac address
1078
Jon Hall42db6dc2014-10-24 19:03:48 -04001079 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 try:
kelvin8ec71442015-01-15 16:57:00 -08001082 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001083 return None
1084 else:
1085 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 rawHosts = self.hosts()
1087 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001088 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001090 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001091 if not host:
1092 pass
1093 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001094 return host
1095 return None
Jon Hallc6793552016-01-19 14:18:37 -08001096 except ( TypeError, ValueError ):
1097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001102 main.cleanup()
1103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001105 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 main.cleanup()
1107 main.exit()
1108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001110 """
1111 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001112 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001113
andrewonlab3f0a4af2014-10-17 12:25:14 -04001114 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 IMPORTANT:
1117 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001118 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Furthermore, it assumes that value of VLAN is '-1'
1120 Description:
kelvin8ec71442015-01-15 16:57:00 -08001121 Converts mininet hosts ( h1, h2, h3... ) into
1122 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1123 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001128 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 hostHex = hex( int( host ) ).zfill( 12 )
1130 hostHex = str( hostHex ).replace( 'x', '0' )
1131 i = iter( str( hostHex ) )
1132 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1133 hostHex = hostHex + "/-1"
1134 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137
Jon Halld4d4b372015-01-28 16:02:41 -08001138 except TypeError:
1139 main.log.exception( self.name + ": Object not as expected" )
1140 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001142 main.log.error( self.name + ": EOF exception found" )
1143 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144 main.cleanup()
1145 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001146 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001147 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 main.cleanup()
1149 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001150
Jeremy Songster832f9e92016-05-05 14:30:49 -07001151 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001152 """
andrewonlabe6745342014-10-17 14:29:13 -04001153 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 * hostIdOne: ONOS host id for host1
1155 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001156 Optional:
1157 * vlanId: specify a VLAN id for the intent
andrewonlabe6745342014-10-17 14:29:13 -04001158 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001159 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001160 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001161 Returns:
1162 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001163 """
andrewonlabe6745342014-10-17 14:29:13 -04001164 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001165 cmdStr = "add-host-intent "
1166 if vlanId:
1167 cmdStr += "-v " + str( vlanId ) + " "
1168 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001170 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001171 if re.search( "Error", handle ):
1172 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001173 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001174 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001175 else:
1176 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001177 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1178 match = re.search('id=0x([\da-f]+),', handle)
1179 if match:
1180 return match.group()[3:-1]
1181 else:
1182 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001183 main.log.debug( "Response from ONOS was: " +
1184 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 return None
Jon Hallc6793552016-01-19 14:18:37 -08001186 except AssertionError:
1187 main.log.exception( "" )
1188 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001189 except TypeError:
1190 main.log.exception( self.name + ": Object not as expected" )
1191 return None
andrewonlabe6745342014-10-17 14:29:13 -04001192 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001193 main.log.error( self.name + ": EOF exception found" )
1194 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001195 main.cleanup()
1196 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001197 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001198 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001199 main.cleanup()
1200 main.exit()
1201
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001203 """
andrewonlab7b31d232014-10-24 13:31:47 -04001204 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 * ingressDevice: device id of ingress device
1206 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001207 Optional:
1208 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001209 Description:
1210 Adds an optical intent by specifying an ingress and egress device
1211 Returns:
1212 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001213 """
andrewonlab7b31d232014-10-24 13:31:47 -04001214 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1216 " " + str( egressDevice )
1217 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001218 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001219 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001220 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001221 main.log.error( "Error in adding Optical intent" )
1222 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001223 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001224 main.log.info( "Optical intent installed between " +
1225 str( ingressDevice ) + " and " +
1226 str( egressDevice ) )
1227 match = re.search('id=0x([\da-f]+),', handle)
1228 if match:
1229 return match.group()[3:-1]
1230 else:
1231 main.log.error( "Error, intent ID not found" )
1232 return None
Jon Hallc6793552016-01-19 14:18:37 -08001233 except AssertionError:
1234 main.log.exception( "" )
1235 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001236 except TypeError:
1237 main.log.exception( self.name + ": Object not as expected" )
1238 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001239 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001240 main.log.error( self.name + ": EOF exception found" )
1241 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001242 main.cleanup()
1243 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001244 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001245 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001246 main.cleanup()
1247 main.exit()
1248
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001250 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001251 ingressDevice,
1252 egressDevice,
1253 portIngress="",
1254 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001255 ethType="",
1256 ethSrc="",
1257 ethDst="",
1258 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001260 ipProto="",
1261 ipSrc="",
1262 ipDst="",
1263 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001264 tcpDst="",
1265 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001266 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001267 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 * ingressDevice: device id of ingress device
1269 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001270 Optional:
1271 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001272 * ethSrc: specify ethSrc ( i.e. src mac addr )
1273 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001274 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001275 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001276 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001277 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001278 * ipSrc: specify ip source address
1279 * ipDst: specify ip destination address
1280 * tcpSrc: specify tcp source port
1281 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001282 * vlanId: specify vlan ID
andrewonlab4dbb4d82014-10-17 18:22:31 -04001283 Description:
kelvin8ec71442015-01-15 16:57:00 -08001284 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001285 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001286 Returns:
1287 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001288
Jon Halle3f39ff2015-01-13 11:50:53 -08001289 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001290 options developers provide for point-to-point
1291 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001292 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001293 try:
kelvin8ec71442015-01-15 16:57:00 -08001294 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001295 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001297 and not ipProto and not ipSrc and not ipDst \
1298 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001299 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001300
andrewonlab289e4b72014-10-21 21:24:18 -04001301 else:
andrewonlab36af3822014-11-18 17:48:18 -05001302 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001303
andrewonlab0c0a6772014-10-22 12:31:18 -04001304 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001305 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001306 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001307 cmd += " --ethSrc " + str( ethSrc )
1308 if ethDst:
1309 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001310 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001311 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001312 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001313 cmd += " --lambda "
1314 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001315 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001316 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001317 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001318 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001319 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001320 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001321 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001322 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001323 cmd += " --tcpDst " + str( tcpDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001324 if vlanId:
1325 cmd += " -v " + str( vlanId )
andrewonlab289e4b72014-10-21 21:24:18 -04001326
kelvin8ec71442015-01-15 16:57:00 -08001327 # Check whether the user appended the port
1328 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 if "/" in ingressDevice:
1330 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001331 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001332 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001333 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001334 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001335 # Would it make sense to throw an exception and exit
1336 # the test?
1337 return None
andrewonlab36af3822014-11-18 17:48:18 -05001338
kelvin8ec71442015-01-15 16:57:00 -08001339 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 str( ingressDevice ) + "/" +\
1341 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001342
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 if "/" in egressDevice:
1344 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001345 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001347 main.log.error( "You must specify the egress port" )
1348 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001349
kelvin8ec71442015-01-15 16:57:00 -08001350 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 str( egressDevice ) + "/" +\
1352 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001353
kelvin-onlab898a6c62015-01-16 14:13:53 -08001354 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001355 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001356 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001357 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001358 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001360 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001361 # TODO: print out all the options in this message?
1362 main.log.info( "Point-to-point intent installed between " +
1363 str( ingressDevice ) + " and " +
1364 str( egressDevice ) )
1365 match = re.search('id=0x([\da-f]+),', handle)
1366 if match:
1367 return match.group()[3:-1]
1368 else:
1369 main.log.error( "Error, intent ID not found" )
1370 return None
Jon Hallc6793552016-01-19 14:18:37 -08001371 except AssertionError:
1372 main.log.exception( "" )
1373 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001374 except TypeError:
1375 main.log.exception( self.name + ": Object not as expected" )
1376 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001377 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001378 main.log.error( self.name + ": EOF exception found" )
1379 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001380 main.cleanup()
1381 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001382 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001383 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001384 main.cleanup()
1385 main.exit()
1386
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001388 self,
shahshreyac2f97072015-03-19 17:04:29 -07001389 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001391 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001392 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001393 ethType="",
1394 ethSrc="",
1395 ethDst="",
1396 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 ipProto="",
1399 ipSrc="",
1400 ipDst="",
1401 tcpSrc="",
1402 tcpDst="",
1403 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001404 setEthDst="",
1405 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001406 """
shahshreyad0c80432014-12-04 16:56:05 -08001407 Note:
shahshreya70622b12015-03-19 17:19:00 -07001408 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001409 is same. That is, all ingress devices include port numbers
1410 with a "/" or all ingress devices could specify device
1411 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001412 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001413 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001414 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001416 Optional:
1417 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001418 * ethSrc: specify ethSrc ( i.e. src mac addr )
1419 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001420 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001422 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001423 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001424 * ipSrc: specify ip source address
1425 * ipDst: specify ip destination address
1426 * tcpSrc: specify tcp source port
1427 * tcpDst: specify tcp destination port
1428 * setEthSrc: action to Rewrite Source MAC Address
1429 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001430 * vlanId: specify vlan Id
shahshreyad0c80432014-12-04 16:56:05 -08001431 Description:
kelvin8ec71442015-01-15 16:57:00 -08001432 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001433 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001434 Returns:
1435 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001436
Jon Halle3f39ff2015-01-13 11:50:53 -08001437 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001438 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001439 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001440 """
shahshreyad0c80432014-12-04 16:56:05 -08001441 try:
kelvin8ec71442015-01-15 16:57:00 -08001442 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001443 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001444 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001445 and not ipProto and not ipSrc and not ipDst\
1446 and not tcpSrc and not tcpDst and not setEthSrc\
1447 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001448 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001449
1450 else:
1451 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001452
shahshreyad0c80432014-12-04 16:56:05 -08001453 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001454 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001455 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001456 cmd += " --ethSrc " + str( ethSrc )
1457 if ethDst:
1458 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001459 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001460 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001462 cmd += " --lambda "
1463 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001464 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001465 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001466 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001467 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001468 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001469 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001470 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001471 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001472 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001473 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001474 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001475 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001476 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001477 if vlanId:
1478 cmd += " -v " + str( vlanId )
shahshreyad0c80432014-12-04 16:56:05 -08001479
kelvin8ec71442015-01-15 16:57:00 -08001480 # Check whether the user appended the port
1481 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001482
1483 if portIngressList is None:
1484 for ingressDevice in ingressDeviceList:
1485 if "/" in ingressDevice:
1486 cmd += " " + str( ingressDevice )
1487 else:
1488 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001489 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001490 # TODO: perhaps more meaningful return
1491 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001492 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001493 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001494 for ingressDevice, portIngress in zip( ingressDeviceList,
1495 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001496 cmd += " " + \
1497 str( ingressDevice ) + "/" +\
1498 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001499 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001500 main.log.error( "Device list and port list does not " +
1501 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001502 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 if "/" in egressDevice:
1504 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001505 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001507 main.log.error( "You must specify " +
1508 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001509 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001510
kelvin8ec71442015-01-15 16:57:00 -08001511 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 str( egressDevice ) + "/" +\
1513 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001514 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001515 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001516 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001517 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001518 main.log.error( "Error in adding multipoint-to-singlepoint " +
1519 "intent" )
1520 return None
shahshreyad0c80432014-12-04 16:56:05 -08001521 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001522 match = re.search('id=0x([\da-f]+),', handle)
1523 if match:
1524 return match.group()[3:-1]
1525 else:
1526 main.log.error( "Error, intent ID not found" )
1527 return None
Jon Hallc6793552016-01-19 14:18:37 -08001528 except AssertionError:
1529 main.log.exception( "" )
1530 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001531 except TypeError:
1532 main.log.exception( self.name + ": Object not as expected" )
1533 return None
1534 except pexpect.EOF:
1535 main.log.error( self.name + ": EOF exception found" )
1536 main.log.error( self.name + ": " + self.handle.before )
1537 main.cleanup()
1538 main.exit()
1539 except Exception:
1540 main.log.exception( self.name + ": Uncaught exception!" )
1541 main.cleanup()
1542 main.exit()
1543
1544 def addSinglepointToMultipointIntent(
1545 self,
1546 ingressDevice,
1547 egressDeviceList,
1548 portIngress="",
1549 portEgressList=None,
1550 ethType="",
1551 ethSrc="",
1552 ethDst="",
1553 bandwidth="",
1554 lambdaAlloc=False,
1555 ipProto="",
1556 ipSrc="",
1557 ipDst="",
1558 tcpSrc="",
1559 tcpDst="",
1560 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001561 setEthDst="",
1562 vlanId="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001563 """
1564 Note:
1565 This function assumes the format of all egress devices
1566 is same. That is, all egress devices include port numbers
1567 with a "/" or all egress devices could specify device
1568 ids and port numbers seperately.
1569 Required:
1570 * EgressDeviceList: List of device ids of egress device
1571 ( Atleast 2 eress devices required in the list )
1572 * ingressDevice: device id of ingress device
1573 Optional:
1574 * ethType: specify ethType
1575 * ethSrc: specify ethSrc ( i.e. src mac addr )
1576 * ethDst: specify ethDst ( i.e. dst mac addr )
1577 * bandwidth: specify bandwidth capacity of link
1578 * lambdaAlloc: if True, intent will allocate lambda
1579 for the specified intent
1580 * ipProto: specify ip protocol
1581 * ipSrc: specify ip source address
1582 * ipDst: specify ip destination address
1583 * tcpSrc: specify tcp source port
1584 * tcpDst: specify tcp destination port
1585 * setEthSrc: action to Rewrite Source MAC Address
1586 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001587 * vlanId: specify vlan Id
kelvin-onlabb9408212015-04-01 13:34:04 -07001588 Description:
1589 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1590 specifying device id's and optional fields
1591 Returns:
1592 A string of the intent id or None on error
1593
1594 NOTE: This function may change depending on the
1595 options developers provide for singlepoint-to-multipoint
1596 intent via cli
1597 """
1598 try:
1599 # If there are no optional arguments
1600 if not ethType and not ethSrc and not ethDst\
1601 and not bandwidth and not lambdaAlloc\
1602 and not ipProto and not ipSrc and not ipDst\
1603 and not tcpSrc and not tcpDst and not setEthSrc\
1604 and not setEthDst:
1605 cmd = "add-single-to-multi-intent"
1606
1607 else:
1608 cmd = "add-single-to-multi-intent"
1609
1610 if ethType:
1611 cmd += " --ethType " + str( ethType )
1612 if ethSrc:
1613 cmd += " --ethSrc " + str( ethSrc )
1614 if ethDst:
1615 cmd += " --ethDst " + str( ethDst )
1616 if bandwidth:
1617 cmd += " --bandwidth " + str( bandwidth )
1618 if lambdaAlloc:
1619 cmd += " --lambda "
1620 if ipProto:
1621 cmd += " --ipProto " + str( ipProto )
1622 if ipSrc:
1623 cmd += " --ipSrc " + str( ipSrc )
1624 if ipDst:
1625 cmd += " --ipDst " + str( ipDst )
1626 if tcpSrc:
1627 cmd += " --tcpSrc " + str( tcpSrc )
1628 if tcpDst:
1629 cmd += " --tcpDst " + str( tcpDst )
1630 if setEthSrc:
1631 cmd += " --setEthSrc " + str( setEthSrc )
1632 if setEthDst:
1633 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001634 if vlanId:
1635 cmd += " -v " + str( vlanId )
kelvin-onlabb9408212015-04-01 13:34:04 -07001636
1637 # Check whether the user appended the port
1638 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001639
kelvin-onlabb9408212015-04-01 13:34:04 -07001640 if "/" in ingressDevice:
1641 cmd += " " + str( ingressDevice )
1642 else:
1643 if not portIngress:
1644 main.log.error( "You must specify " +
1645 "the Ingress port" )
1646 return main.FALSE
1647
1648 cmd += " " +\
1649 str( ingressDevice ) + "/" +\
1650 str( portIngress )
1651
1652 if portEgressList is None:
1653 for egressDevice in egressDeviceList:
1654 if "/" in egressDevice:
1655 cmd += " " + str( egressDevice )
1656 else:
1657 main.log.error( "You must specify " +
1658 "the egress port" )
1659 # TODO: perhaps more meaningful return
1660 return main.FALSE
1661 else:
1662 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001663 for egressDevice, portEgress in zip( egressDeviceList,
1664 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001665 cmd += " " + \
1666 str( egressDevice ) + "/" +\
1667 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001668 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001669 main.log.error( "Device list and port list does not " +
1670 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001671 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001672 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001673 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001674 # If error, return error message
1675 if re.search( "Error", handle ):
1676 main.log.error( "Error in adding singlepoint-to-multipoint " +
1677 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001678 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 else:
1680 match = re.search('id=0x([\da-f]+),', handle)
1681 if match:
1682 return match.group()[3:-1]
1683 else:
1684 main.log.error( "Error, intent ID not found" )
1685 return None
Jon Hallc6793552016-01-19 14:18:37 -08001686 except AssertionError:
1687 main.log.exception( "" )
1688 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001689 except TypeError:
1690 main.log.exception( self.name + ": Object not as expected" )
1691 return None
shahshreyad0c80432014-12-04 16:56:05 -08001692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001693 main.log.error( self.name + ": EOF exception found" )
1694 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001695 main.cleanup()
1696 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001697 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001698 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001699 main.cleanup()
1700 main.exit()
1701
Hari Krishna9e232602015-04-13 17:29:08 -07001702 def addMplsIntent(
1703 self,
1704 ingressDevice,
1705 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001706 ingressPort="",
1707 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001708 ethType="",
1709 ethSrc="",
1710 ethDst="",
1711 bandwidth="",
1712 lambdaAlloc=False,
1713 ipProto="",
1714 ipSrc="",
1715 ipDst="",
1716 tcpSrc="",
1717 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001718 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001719 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001720 priority=""):
1721 """
1722 Required:
1723 * ingressDevice: device id of ingress device
1724 * egressDevice: device id of egress device
1725 Optional:
1726 * ethType: specify ethType
1727 * ethSrc: specify ethSrc ( i.e. src mac addr )
1728 * ethDst: specify ethDst ( i.e. dst mac addr )
1729 * bandwidth: specify bandwidth capacity of link
1730 * lambdaAlloc: if True, intent will allocate lambda
1731 for the specified intent
1732 * ipProto: specify ip protocol
1733 * ipSrc: specify ip source address
1734 * ipDst: specify ip destination address
1735 * tcpSrc: specify tcp source port
1736 * tcpDst: specify tcp destination port
1737 * ingressLabel: Ingress MPLS label
1738 * egressLabel: Egress MPLS label
1739 Description:
1740 Adds MPLS intent by
1741 specifying device id's and optional fields
1742 Returns:
1743 A string of the intent id or None on error
1744
1745 NOTE: This function may change depending on the
1746 options developers provide for MPLS
1747 intent via cli
1748 """
1749 try:
1750 # If there are no optional arguments
1751 if not ethType and not ethSrc and not ethDst\
1752 and not bandwidth and not lambdaAlloc \
1753 and not ipProto and not ipSrc and not ipDst \
1754 and not tcpSrc and not tcpDst and not ingressLabel \
1755 and not egressLabel:
1756 cmd = "add-mpls-intent"
1757
1758 else:
1759 cmd = "add-mpls-intent"
1760
1761 if ethType:
1762 cmd += " --ethType " + str( ethType )
1763 if ethSrc:
1764 cmd += " --ethSrc " + str( ethSrc )
1765 if ethDst:
1766 cmd += " --ethDst " + str( ethDst )
1767 if bandwidth:
1768 cmd += " --bandwidth " + str( bandwidth )
1769 if lambdaAlloc:
1770 cmd += " --lambda "
1771 if ipProto:
1772 cmd += " --ipProto " + str( ipProto )
1773 if ipSrc:
1774 cmd += " --ipSrc " + str( ipSrc )
1775 if ipDst:
1776 cmd += " --ipDst " + str( ipDst )
1777 if tcpSrc:
1778 cmd += " --tcpSrc " + str( tcpSrc )
1779 if tcpDst:
1780 cmd += " --tcpDst " + str( tcpDst )
1781 if ingressLabel:
1782 cmd += " --ingressLabel " + str( ingressLabel )
1783 if egressLabel:
1784 cmd += " --egressLabel " + str( egressLabel )
1785 if priority:
1786 cmd += " --priority " + str( priority )
1787
1788 # Check whether the user appended the port
1789 # or provided it as an input
1790 if "/" in ingressDevice:
1791 cmd += " " + str( ingressDevice )
1792 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001793 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001794 main.log.error( "You must specify the ingress port" )
1795 return None
1796
1797 cmd += " " + \
1798 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001799 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001800
1801 if "/" in egressDevice:
1802 cmd += " " + str( egressDevice )
1803 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001804 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001805 main.log.error( "You must specify the egress port" )
1806 return None
1807
1808 cmd += " " +\
1809 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001810 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001811
1812 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001813 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001814 # If error, return error message
1815 if re.search( "Error", handle ):
1816 main.log.error( "Error in adding mpls intent" )
1817 return None
1818 else:
1819 # TODO: print out all the options in this message?
1820 main.log.info( "MPLS intent installed between " +
1821 str( ingressDevice ) + " and " +
1822 str( egressDevice ) )
1823 match = re.search('id=0x([\da-f]+),', handle)
1824 if match:
1825 return match.group()[3:-1]
1826 else:
1827 main.log.error( "Error, intent ID not found" )
1828 return None
Jon Hallc6793552016-01-19 14:18:37 -08001829 except AssertionError:
1830 main.log.exception( "" )
1831 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001832 except TypeError:
1833 main.log.exception( self.name + ": Object not as expected" )
1834 return None
1835 except pexpect.EOF:
1836 main.log.error( self.name + ": EOF exception found" )
1837 main.log.error( self.name + ": " + self.handle.before )
1838 main.cleanup()
1839 main.exit()
1840 except Exception:
1841 main.log.exception( self.name + ": Uncaught exception!" )
1842 main.cleanup()
1843 main.exit()
1844
Jon Hallefbd9792015-03-05 16:11:36 -08001845 def removeIntent( self, intentId, app='org.onosproject.cli',
1846 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001847 """
shahshreya1c818fc2015-02-26 13:44:08 -08001848 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001849 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001850 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001851 -p or --purge: Purge the intent from the store after removal
1852
Jon Halle3f39ff2015-01-13 11:50:53 -08001853 Returns:
1854 main.False on error and
1855 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001856 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001857 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001858 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001859 if purge:
1860 cmdStr += " -p"
1861 if sync:
1862 cmdStr += " -s"
1863
1864 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001866 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001867 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001868 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001869 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001870 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 # TODO: Should this be main.TRUE
1872 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001873 except AssertionError:
1874 main.log.exception( "" )
1875 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001876 except TypeError:
1877 main.log.exception( self.name + ": Object not as expected" )
1878 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001879 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001880 main.log.error( self.name + ": EOF exception found" )
1881 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001882 main.cleanup()
1883 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001884 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001885 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001886 main.cleanup()
1887 main.exit()
1888
Jeremy42df2e72016-02-23 16:37:46 -08001889 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1890 """
1891 Description:
1892 Remove all the intents
1893 Optional args:-
1894 -s or --sync: Waits for the removal before returning
1895 -p or --purge: Purge the intent from the store after removal
1896 Returns:
1897 Returns main.TRUE if all intents are removed, otherwise returns
1898 main.FALSE; Returns None for exception
1899 """
1900 try:
1901 cmdStr = "remove-intent"
1902 if purge:
1903 cmdStr += " -p"
1904 if sync:
1905 cmdStr += " -s"
1906
1907 cmdStr += " " + app
1908 handle = self.sendline( cmdStr )
1909 assert "Command not found:" not in handle, handle
1910 if re.search( "Error", handle ):
1911 main.log.error( "Error in removing intent" )
1912 return main.FALSE
1913 else:
1914 return main.TRUE
1915 except AssertionError:
1916 main.log.exception( "" )
1917 return None
1918 except TypeError:
1919 main.log.exception( self.name + ": Object not as expected" )
1920 return None
1921 except pexpect.EOF:
1922 main.log.error( self.name + ": EOF exception found" )
1923 main.log.error( self.name + ": " + self.handle.before )
1924 main.cleanup()
1925 main.exit()
1926 except Exception:
1927 main.log.exception( self.name + ": Uncaught exception!" )
1928 main.cleanup()
1929 main.exit()
1930
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001931 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 """
1933 Purges all WITHDRAWN Intents
1934 """
1935 try:
1936 cmdStr = "purge-intents"
1937 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001938 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001939 if re.search( "Error", handle ):
1940 main.log.error( "Error in purging intents" )
1941 return main.FALSE
1942 else:
1943 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001944 except AssertionError:
1945 main.log.exception( "" )
1946 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001947 except TypeError:
1948 main.log.exception( self.name + ": Object not as expected" )
1949 return None
1950 except pexpect.EOF:
1951 main.log.error( self.name + ": EOF exception found" )
1952 main.log.error( self.name + ": " + self.handle.before )
1953 main.cleanup()
1954 main.exit()
1955 except Exception:
1956 main.log.exception( self.name + ": Uncaught exception!" )
1957 main.cleanup()
1958 main.exit()
1959
kelvin-onlabd3b64892015-01-20 13:26:24 -08001960 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001961 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001962 NOTE: This method should be used after installing application:
1963 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001964 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001965 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001966 Description:
1967 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001968 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001969 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001970 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001971 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001972 cmdStr += " -j"
1973 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001974 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001976 except AssertionError:
1977 main.log.exception( "" )
1978 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001985 main.cleanup()
1986 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001987 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001988 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001989 main.cleanup()
1990 main.exit()
1991
pingping-lin54b03372015-08-13 14:43:10 -07001992 def ipv4RouteNumber( self ):
1993 """
1994 NOTE: This method should be used after installing application:
1995 onos-app-sdnip
1996 Description:
1997 Obtain the total IPv4 routes number in the system
1998 """
1999 try:
2000 cmdStr = "routes -s -j"
2001 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002002 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002003 jsonResult = json.loads( handle )
2004 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002005 except AssertionError:
2006 main.log.exception( "" )
2007 return None
2008 except ( TypeError, ValueError ):
2009 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002010 return None
2011 except pexpect.EOF:
2012 main.log.error( self.name + ": EOF exception found" )
2013 main.log.error( self.name + ": " + self.handle.before )
2014 main.cleanup()
2015 main.exit()
2016 except Exception:
2017 main.log.exception( self.name + ": Uncaught exception!" )
2018 main.cleanup()
2019 main.exit()
2020
pingping-lin8244a3b2015-09-16 13:36:56 -07002021 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002022 """
andrewonlabe6745342014-10-17 14:29:13 -04002023 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002024 Obtain intents from the ONOS cli.
2025 Optional:
2026 * jsonFormat: Enable output formatting in json, default to True
2027 * summary: Whether only output the intent summary, defaults to False
2028 * type: Only output a certain type of intent. This options is valid
2029 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002030 """
andrewonlabe6745342014-10-17 14:29:13 -04002031 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002032 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002033 if summary:
2034 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002036 cmdStr += " -j"
2037 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002038 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002040 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002041 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002042 else:
Jon Hallff566d52016-01-15 14:45:36 -08002043 intentType = ""
2044 # IF we want the summary of a specific intent type
2045 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002046 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002047 if intentType in jsonResult.keys():
2048 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002049 else:
Jon Hallff566d52016-01-15 14:45:36 -08002050 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002051 return handle
2052 else:
2053 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002054 except AssertionError:
2055 main.log.exception( "" )
2056 return None
2057 except ( TypeError, ValueError ):
2058 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002059 return None
2060 except pexpect.EOF:
2061 main.log.error( self.name + ": EOF exception found" )
2062 main.log.error( self.name + ": " + self.handle.before )
2063 main.cleanup()
2064 main.exit()
2065 except Exception:
2066 main.log.exception( self.name + ": Uncaught exception!" )
2067 main.cleanup()
2068 main.exit()
2069
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 def getIntentState(self, intentsId, intentsJson=None):
2071 """
You Wangfdcbfc42016-05-16 12:16:53 -07002072 Description:
2073 Gets intent state. Accepts a single intent ID (string type) or a
2074 list of intent IDs.
2075 Parameters:
2076 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002078 Returns:
2079 Returns the state (string type) of the ID if a single intent ID is
2080 accepted.
2081 Returns a list of dictionaries if a list of intent IDs is accepted,
2082 and each dictionary maps 'id' to the Intent ID and 'state' to
2083 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002084 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002085 try:
2086 state = "State is Undefined"
2087 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002088 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 else:
Jon Hallc6793552016-01-19 14:18:37 -08002090 rawJson = intentsJson
2091 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002092 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002093 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002094 if intentsId == intent[ 'id' ]:
2095 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002096 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002097 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2098 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002099 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002100 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002101 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002102 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002103 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002104 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002105 if intentsId[ i ] == intents[ 'id' ]:
2106 stateDict[ 'state' ] = intents[ 'state' ]
2107 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002108 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002109 break
Jon Hallefbd9792015-03-05 16:11:36 -08002110 if len( intentsId ) != len( dictList ):
2111 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002112 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002113 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002114 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002115 return None
Jon Hallc6793552016-01-19 14:18:37 -08002116 except ( TypeError, ValueError ):
2117 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002118 return None
2119 except pexpect.EOF:
2120 main.log.error( self.name + ": EOF exception found" )
2121 main.log.error( self.name + ": " + self.handle.before )
2122 main.cleanup()
2123 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002124 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002125 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002126 main.cleanup()
2127 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002128
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002130 """
2131 Description:
2132 Check intents state
2133 Required:
2134 intentsId - List of intents ID to be checked
2135 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002136 expectedState - Check the expected state(s) of each intents
2137 state in the list.
2138 *NOTE: You can pass in a list of expected state,
2139 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002140 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002141 Returns main.TRUE only if all intent are the same as expected states
2142 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 """
2144 try:
2145 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002146 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002147 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002148 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002149 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002150 "getting intents state" )
2151 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002152
2153 if isinstance( expectedState, types.StringType ):
2154 for intents in intentsDict:
2155 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002156 main.log.debug( self.name + " : Intent ID - " +
2157 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002158 " actual state = " +
2159 intents.get( 'state' )
2160 + " does not equal expected state = "
2161 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002162 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002163
2164 elif isinstance( expectedState, types.ListType ):
2165 for intents in intentsDict:
2166 if not any( state == intents.get( 'state' ) for state in
2167 expectedState ):
2168 main.log.debug( self.name + " : Intent ID - " +
2169 intents.get( 'id' ) +
2170 " actual state = " +
2171 intents.get( 'state' ) +
2172 " does not equal expected states = "
2173 + str( expectedState ) )
2174 returnValue = main.FALSE
2175
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002176 if returnValue == main.TRUE:
2177 main.log.info( self.name + ": All " +
2178 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002179 " intents are in " + str( expectedState ) +
2180 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002181 return returnValue
2182 except TypeError:
2183 main.log.exception( self.name + ": Object not as expected" )
2184 return None
2185 except pexpect.EOF:
2186 main.log.error( self.name + ": EOF exception found" )
2187 main.log.error( self.name + ": " + self.handle.before )
2188 main.cleanup()
2189 main.exit()
2190 except Exception:
2191 main.log.exception( self.name + ": Uncaught exception!" )
2192 main.cleanup()
2193 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002194
You Wang66518af2016-05-16 15:32:59 -07002195 def compareIntent( self, intentDict ):
2196 """
2197 Description:
2198 Compare the intent ids and states provided in the argument with all intents in ONOS
2199 Return:
2200 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2201 Arguments:
2202 intentDict: a dictionary which maps intent ids to intent states
2203 """
2204 try:
2205 intentsRaw = self.intents()
2206 intentsJson = json.loads( intentsRaw )
2207 intentDictONOS = {}
2208 for intent in intentsJson:
2209 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2210 if len( intentDict ) != len( intentDictONOS ):
2211 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2212 str( len( intentDict ) ) + " expected and " +
2213 str( len( intentDictONOS ) ) + " actual" )
2214 return main.FALSE
2215 returnValue = main.TRUE
2216 for intentID in intentDict.keys():
2217 if not intentID in intentDictONOS.keys():
2218 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2219 returnValue = main.FALSE
2220 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2221 main.log.debug( self.name + ": intent ID - " + intentID +
2222 " expected state is " + intentDict[ intentID ] +
2223 " but actual state is " + intentDictONOS[ intentID ] )
2224 returnValue = main.FALSE
2225 if returnValue == main.TRUE:
2226 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2227 return returnValue
2228 except ( TypeError, ValueError ):
2229 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
2230 return None
2231 except pexpect.EOF:
2232 main.log.error( self.name + ": EOF exception found" )
2233 main.log.error( self.name + ": " + self.handle.before )
2234 main.cleanup()
2235 main.exit()
2236 except Exception:
2237 main.log.exception( self.name + ": Uncaught exception!" )
2238 main.cleanup()
2239 main.exit()
2240
GlennRCed771242016-01-13 17:02:47 -08002241 def checkIntentSummary( self, timeout=60 ):
2242 """
2243 Description:
2244 Check the number of installed intents.
2245 Optional:
2246 timeout - the timeout for pexcept
2247 Return:
2248 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2249 , otherwise, returns main.FALSE.
2250 """
2251
2252 try:
2253 cmd = "intents -s -j"
2254
2255 # Check response if something wrong
2256 response = self.sendline( cmd, timeout=timeout )
2257 if response == None:
2258 return main.False
2259 response = json.loads( response )
2260
2261 # get total and installed number, see if they are match
2262 allState = response.get( 'all' )
2263 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002264 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002265 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002266 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002267 return main.FALSE
2268
Jon Hallc6793552016-01-19 14:18:37 -08002269 except ( TypeError, ValueError ):
2270 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002271 return None
2272 except pexpect.EOF:
2273 main.log.error( self.name + ": EOF exception found" )
2274 main.log.error( self.name + ": " + self.handle.before )
2275 main.cleanup()
2276 main.exit()
2277 except Exception:
2278 main.log.exception( self.name + ": Uncaught exception!" )
2279 main.cleanup()
2280 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002281 except pexpect.TIMEOUT:
2282 main.log.error( self.name + ": ONOS timeout" )
2283 return None
GlennRCed771242016-01-13 17:02:47 -08002284
YPZhangebf9eb52016-05-12 15:20:24 -07002285 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002286 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002287 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002288 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002289 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002290 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002291 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002292 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002293 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002294 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002295 cmdStr += " -j "
2296 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002297 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002298 assert "Command not found:" not in handle, handle
2299 if re.search( "Error:", handle ):
2300 main.log.error( self.name + ": flows() response: " +
2301 str( handle ) )
2302 return handle
2303 except AssertionError:
2304 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002305 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002306 except TypeError:
2307 main.log.exception( self.name + ": Object not as expected" )
2308 return None
Jon Hallc6793552016-01-19 14:18:37 -08002309 except pexpect.TIMEOUT:
2310 main.log.error( self.name + ": ONOS timeout" )
2311 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002312 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002313 main.log.error( self.name + ": EOF exception found" )
2314 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002315 main.cleanup()
2316 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002317 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002318 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002319 main.cleanup()
2320 main.exit()
2321
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002322 def checkFlowCount(self, min=0, timeout=60 ):
2323 count = int(self.getTotalFlowsNum( timeout=timeout ))
2324 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002325
YPZhangebf9eb52016-05-12 15:20:24 -07002326 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002327 """
2328 Description:
GlennRCed771242016-01-13 17:02:47 -08002329 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002330 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2331 if the count of those states is 0, which means all current flows
2332 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002333 Optional:
GlennRCed771242016-01-13 17:02:47 -08002334 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002335 Return:
2336 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002337 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002338 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002339 """
2340 try:
GlennRCed771242016-01-13 17:02:47 -08002341 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2342 checkedStates = []
2343 statesCount = [0, 0, 0, 0]
2344 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002345 rawFlows = self.flows( state=s, timeout = timeout )
2346 checkedStates.append( json.loads( rawFlows ) )
2347 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002348 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002349 try:
2350 statesCount[i] += int( c.get( "flowCount" ) )
2351 except TypeError:
2352 main.log.exception( "Json object not as expected" )
2353 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002354
GlennRCed771242016-01-13 17:02:47 -08002355 # We want to count PENDING_ADD if isPENDING is true
2356 if isPENDING:
2357 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2358 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002359 else:
GlennRCed771242016-01-13 17:02:47 -08002360 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2361 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002362 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002363 except ( TypeError, ValueError ):
2364 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002365 return None
2366 except pexpect.EOF:
2367 main.log.error( self.name + ": EOF exception found" )
2368 main.log.error( self.name + ": " + self.handle.before )
2369 main.cleanup()
2370 main.exit()
2371 except Exception:
2372 main.log.exception( self.name + ": Uncaught exception!" )
2373 main.cleanup()
2374 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002375 except pexpect.TIMEOUT:
2376 main.log.error( self.name + ": ONOS timeout" )
2377 return None
2378
kelvin-onlab4df89f22015-04-13 18:10:23 -07002379
GlennRCed771242016-01-13 17:02:47 -08002380 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002381 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002382 """
andrewonlab87852b02014-11-19 18:44:19 -05002383 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002384 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002385 a specific point-to-point intent definition
2386 Required:
GlennRCed771242016-01-13 17:02:47 -08002387 * ingress: specify source dpid
2388 * egress: specify destination dpid
2389 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002390 Optional:
GlennRCed771242016-01-13 17:02:47 -08002391 * offset: the keyOffset is where the next batch of intents
2392 will be installed
2393 Returns: If failed to push test intents, it will returen None,
2394 if successful, return true.
2395 Timeout expection will return None,
2396 TypeError will return false
2397 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002398 """
andrewonlab87852b02014-11-19 18:44:19 -05002399 try:
GlennRCed771242016-01-13 17:02:47 -08002400 if background:
2401 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002402 else:
GlennRCed771242016-01-13 17:02:47 -08002403 back = ""
2404 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002405 ingress,
2406 egress,
2407 batchSize,
2408 offset,
2409 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002410 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002411 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002412 main.log.info( response )
2413 if response == None:
2414 return None
2415
2416 # TODO: We should handle if there is failure in installation
2417 return main.TRUE
2418
Jon Hallc6793552016-01-19 14:18:37 -08002419 except AssertionError:
2420 main.log.exception( "" )
2421 return None
GlennRCed771242016-01-13 17:02:47 -08002422 except pexpect.TIMEOUT:
2423 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002424 return None
andrewonlab87852b02014-11-19 18:44:19 -05002425 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002426 main.log.error( self.name + ": EOF exception found" )
2427 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002428 main.cleanup()
2429 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002430 except TypeError:
2431 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002432 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002433 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002434 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002435 main.cleanup()
2436 main.exit()
2437
YPZhangebf9eb52016-05-12 15:20:24 -07002438 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002439 """
2440 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002441 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002442 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002443 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002444 """
YPZhange3109a72016-02-02 11:25:37 -08002445
YPZhangb5d3f832016-01-23 22:54:26 -08002446 try:
YPZhange3109a72016-02-02 11:25:37 -08002447 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002448 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002449 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002450
2451 if totalFlows == None:
2452 # if timeout, we will get total number of all flows, and subtract other states
2453 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2454 checkedStates = []
2455 totalFlows = 0
2456 statesCount = [0, 0, 0, 0]
2457
2458 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002459 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002460 totalFlows = int( response.get("flows") )
2461
2462 for s in states:
2463 rawFlows = self.flows( state=s, timeout = timeout )
2464 if rawFlows == None:
2465 # if timeout, return the total flows number from summary command
2466 return totalFlows
2467 checkedStates.append( json.loads( rawFlows ) )
2468
2469 # Calculate ADDED flows number, equal total subtracts others
2470 for i in range( len( states ) ):
2471 for c in checkedStates[i]:
2472 try:
2473 statesCount[i] += int( c.get( "flowCount" ) )
2474 except TypeError:
2475 main.log.exception( "Json object not as expected" )
2476 totalFlows = totalFlows - int( statesCount[i] )
2477 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2478
2479 return totalFlows
2480
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002481 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002482
You Wangd3cb2ce2016-05-16 14:01:24 -07002483 except ( TypeError, ValueError ):
2484 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002485 return None
2486 except pexpect.EOF:
2487 main.log.error( self.name + ": EOF exception found" )
2488 main.log.error( self.name + ": " + self.handle.before )
2489 main.cleanup()
2490 main.exit()
2491 except Exception:
2492 main.log.exception( self.name + ": Uncaught exception!" )
2493 main.cleanup()
2494 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002495 except pexpect.TIMEOUT:
2496 main.log.error( self.name + ": ONOS timeout" )
2497 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002498
YPZhangebf9eb52016-05-12 15:20:24 -07002499 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002500 """
2501 Description:
2502 Get the total number of intents, include every states.
2503 Return:
2504 The number of intents
2505 """
2506 try:
2507 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002508 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002509 if response == None:
2510 return -1
2511 response = json.loads( response )
2512 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002513 except ( TypeError, ValueError ):
2514 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002515 return None
2516 except pexpect.EOF:
2517 main.log.error( self.name + ": EOF exception found" )
2518 main.log.error( self.name + ": " + self.handle.before )
2519 main.cleanup()
2520 main.exit()
2521 except Exception:
2522 main.log.exception( self.name + ": Uncaught exception!" )
2523 main.cleanup()
2524 main.exit()
2525
kelvin-onlabd3b64892015-01-20 13:26:24 -08002526 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002527 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002528 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002529 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002531 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002532 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002533 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002534 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002535 cmdStr += " -j"
2536 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002537 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002538 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002539 except AssertionError:
2540 main.log.exception( "" )
2541 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002542 except TypeError:
2543 main.log.exception( self.name + ": Object not as expected" )
2544 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002545 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002546 main.log.error( self.name + ": EOF exception found" )
2547 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002548 main.cleanup()
2549 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002550 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002551 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002552 main.cleanup()
2553 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002554
kelvin-onlabd3b64892015-01-20 13:26:24 -08002555 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002556 """
2557 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002558 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002559 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002560 """
andrewonlab867212a2014-10-22 20:13:38 -04002561 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002562 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002563 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002564 cmdStr += " -j"
2565 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002566 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002567 if handle:
2568 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002569 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002570 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002571 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002572 else:
2573 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002574 except AssertionError:
2575 main.log.exception( "" )
2576 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002577 except TypeError:
2578 main.log.exception( self.name + ": Object not as expected" )
2579 return None
andrewonlab867212a2014-10-22 20:13:38 -04002580 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002581 main.log.error( self.name + ": EOF exception found" )
2582 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002583 main.cleanup()
2584 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002585 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002586 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002587 main.cleanup()
2588 main.exit()
2589
kelvin8ec71442015-01-15 16:57:00 -08002590 # Wrapper functions ****************
2591 # Wrapper functions use existing driver
2592 # functions and extends their use case.
2593 # For example, we may use the output of
2594 # a normal driver function, and parse it
2595 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002596
kelvin-onlabd3b64892015-01-20 13:26:24 -08002597 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002598 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002599 Description:
2600 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002601 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002602 try:
kelvin8ec71442015-01-15 16:57:00 -08002603 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002604 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002605 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002606
kelvin8ec71442015-01-15 16:57:00 -08002607 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002608 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2609 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002610 match = re.search('id=0x([\da-f]+),', intents)
2611 if match:
2612 tmpId = match.group()[3:-1]
2613 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002614 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002615
Jon Halld4d4b372015-01-28 16:02:41 -08002616 except TypeError:
2617 main.log.exception( self.name + ": Object not as expected" )
2618 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002619 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002620 main.log.error( self.name + ": EOF exception found" )
2621 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002622 main.cleanup()
2623 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002624 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002625 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002626 main.cleanup()
2627 main.exit()
2628
Jon Hall30b82fa2015-03-04 17:15:43 -08002629 def FlowAddedCount( self, deviceId ):
2630 """
2631 Determine the number of flow rules for the given device id that are
2632 in the added state
2633 """
2634 try:
2635 cmdStr = "flows any " + str( deviceId ) + " | " +\
2636 "grep 'state=ADDED' | wc -l"
2637 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002638 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002639 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002640 except AssertionError:
2641 main.log.exception( "" )
2642 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002643 except pexpect.EOF:
2644 main.log.error( self.name + ": EOF exception found" )
2645 main.log.error( self.name + ": " + self.handle.before )
2646 main.cleanup()
2647 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002648 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002649 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002650 main.cleanup()
2651 main.exit()
2652
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002654 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002655 Use 'devices' function to obtain list of all devices
2656 and parse the result to obtain a list of all device
2657 id's. Returns this list. Returns empty list if no
2658 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002659 List is ordered sequentially
2660
andrewonlab3e15ead2014-10-15 14:21:34 -04002661 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002662 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002663 the ids. By obtaining the list of device ids on the fly,
2664 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002665 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002666 try:
kelvin8ec71442015-01-15 16:57:00 -08002667 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002668 devicesStr = self.devices( jsonFormat=False )
2669 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002670
kelvin-onlabd3b64892015-01-20 13:26:24 -08002671 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002672 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002673 return idList
kelvin8ec71442015-01-15 16:57:00 -08002674
2675 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002676 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002677 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002678 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002679 # Split list further into arguments before and after string
2680 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002681 # append to idList
2682 for arg in tempList:
2683 idList.append( arg.split( "id=" )[ 1 ] )
2684 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002685
Jon Halld4d4b372015-01-28 16:02:41 -08002686 except TypeError:
2687 main.log.exception( self.name + ": Object not as expected" )
2688 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002689 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002690 main.log.error( self.name + ": EOF exception found" )
2691 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002692 main.cleanup()
2693 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002694 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002695 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002696 main.cleanup()
2697 main.exit()
2698
kelvin-onlabd3b64892015-01-20 13:26:24 -08002699 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002700 """
andrewonlab7c211572014-10-15 16:45:20 -04002701 Uses 'nodes' function to obtain list of all nodes
2702 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002703 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002704 Returns:
2705 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002706 """
andrewonlab7c211572014-10-15 16:45:20 -04002707 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002708 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002709 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002710 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002711 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002713 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002714 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002715 nodesJson = json.loads( nodesStr )
2716 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002717 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002718 except ( TypeError, ValueError ):
2719 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002720 return None
andrewonlab7c211572014-10-15 16:45:20 -04002721 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002722 main.log.error( self.name + ": EOF exception found" )
2723 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002724 main.cleanup()
2725 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002726 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002727 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002728 main.cleanup()
2729 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002730
kelvin-onlabd3b64892015-01-20 13:26:24 -08002731 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002732 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002733 Return the first device from the devices api whose 'id' contains 'dpid'
2734 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002735 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002736 try:
kelvin8ec71442015-01-15 16:57:00 -08002737 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002738 return None
2739 else:
kelvin8ec71442015-01-15 16:57:00 -08002740 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002741 rawDevices = self.devices()
2742 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002743 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002744 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002745 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2746 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002747 return device
2748 return None
Jon Hallc6793552016-01-19 14:18:37 -08002749 except ( TypeError, ValueError ):
2750 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002751 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002752 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002753 main.log.error( self.name + ": EOF exception found" )
2754 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002755 main.cleanup()
2756 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002757 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002758 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002759 main.cleanup()
2760 main.exit()
2761
You Wang24139872016-05-03 11:48:47 -07002762 def getTopology( self, topologyOutput ):
2763 """
2764 Definition:
2765 Loads a json topology output
2766 Return:
2767 topology = current ONOS topology
2768 """
2769 import json
2770 try:
2771 # either onos:topology or 'topology' will work in CLI
2772 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002773 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002774 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002775 except ( TypeError, ValueError ):
2776 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2777 return None
You Wang24139872016-05-03 11:48:47 -07002778 except pexpect.EOF:
2779 main.log.error( self.name + ": EOF exception found" )
2780 main.log.error( self.name + ": " + self.handle.before )
2781 main.cleanup()
2782 main.exit()
2783 except Exception:
2784 main.log.exception( self.name + ": Uncaught exception!" )
2785 main.cleanup()
2786 main.exit()
2787
2788 def checkStatus(
2789 self,
2790 topologyResult,
2791 numoswitch,
2792 numolink,
2793 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002794 """
Jon Hallefbd9792015-03-05 16:11:36 -08002795 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002796 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002797 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002798
You Wang24139872016-05-03 11:48:47 -07002799 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002800 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002801 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002802 logLevel = level to log to.
2803 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002804
Jon Hallefbd9792015-03-05 16:11:36 -08002805 Returns: main.TRUE if the number of switches and links are correct,
2806 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002807 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002808 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002809 try:
You Wang24139872016-05-03 11:48:47 -07002810 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002811 if topology == {}:
2812 return main.ERROR
2813 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002814 # Is the number of switches is what we expected
2815 devices = topology.get( 'devices', False )
2816 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002817 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002818 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002819 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002820 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002822 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002823 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002824 output = output + "The number of links and switches match "\
2825 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002826 result = main.TRUE
2827 else:
You Wang24139872016-05-03 11:48:47 -07002828 output = output + \
2829 "The number of links and switches does not match " + \
2830 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002831 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002832 output = output + "\n ONOS sees %i devices" % int( devices )
2833 output = output + " (%i expected) " % int( numoswitch )
2834 output = output + "and %i links " % int( links )
2835 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002836 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002837 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002838 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002839 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002840 else:
You Wang24139872016-05-03 11:48:47 -07002841 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002842 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002843 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002844 main.log.error( self.name + ": EOF exception found" )
2845 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002846 main.cleanup()
2847 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002848 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002849 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002850 main.cleanup()
2851 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002852
kelvin-onlabd3b64892015-01-20 13:26:24 -08002853 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002854 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002855 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002856 deviceId must be the id of a device as seen in the onos devices command
2857 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002858 role must be either master, standby, or none
2859
Jon Halle3f39ff2015-01-13 11:50:53 -08002860 Returns:
2861 main.TRUE or main.FALSE based on argument verification and
2862 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002863 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002864 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002865 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002866 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002867 cmdStr = "device-role " +\
2868 str( deviceId ) + " " +\
2869 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002870 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002872 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002873 if re.search( "Error", handle ):
2874 # end color output to escape any colours
2875 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002876 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002877 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002878 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002879 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002880 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002881 main.log.error( "Invalid 'role' given to device_role(). " +
2882 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002883 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002884 except AssertionError:
2885 main.log.exception( "" )
2886 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002887 except TypeError:
2888 main.log.exception( self.name + ": Object not as expected" )
2889 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002891 main.log.error( self.name + ": EOF exception found" )
2892 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002893 main.cleanup()
2894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002896 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002897 main.cleanup()
2898 main.exit()
2899
kelvin-onlabd3b64892015-01-20 13:26:24 -08002900 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002901 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002902 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002903 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002904 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002905 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002906 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002907 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002908 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002909 cmdStr += " -j"
2910 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002911 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002912 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002913 except AssertionError:
2914 main.log.exception( "" )
2915 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002916 except TypeError:
2917 main.log.exception( self.name + ": Object not as expected" )
2918 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002920 main.log.error( self.name + ": EOF exception found" )
2921 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002922 main.cleanup()
2923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002925 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002926 main.cleanup()
2927 main.exit()
2928
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002930 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002931 CLI command to get the current leader for the Election test application
2932 NOTE: Requires installation of the onos-app-election feature
2933 Returns: Node IP of the leader if one exists
2934 None if none exists
2935 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002936 """
Jon Hall94fd0472014-12-08 11:52:42 -08002937 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002938 cmdStr = "election-test-leader"
2939 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002940 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002941 # Leader
2942 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002943 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002944 nodeSearch = re.search( leaderPattern, response )
2945 if nodeSearch:
2946 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002947 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002948 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002949 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002950 # no leader
2951 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002952 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002953 nullSearch = re.search( nullPattern, response )
2954 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002955 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002956 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002957 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002958 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002959 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002960 if re.search( errorPattern, response ):
2961 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002962 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002963 return main.FALSE
2964 else:
Jon Hall390696c2015-05-05 17:13:41 -07002965 main.log.error( "Error in electionTestLeader on " + self.name +
2966 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002967 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002968 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002969 except AssertionError:
2970 main.log.exception( "" )
2971 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002972 except TypeError:
2973 main.log.exception( self.name + ": Object not as expected" )
2974 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002975 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002976 main.log.error( self.name + ": EOF exception found" )
2977 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002978 main.cleanup()
2979 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002981 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002982 main.cleanup()
2983 main.exit()
2984
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002986 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002987 CLI command to run for leadership of the Election test application.
2988 NOTE: Requires installation of the onos-app-election feature
2989 Returns: Main.TRUE on success
2990 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002991 """
Jon Hall94fd0472014-12-08 11:52:42 -08002992 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 cmdStr = "election-test-run"
2994 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002995 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002996 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002997 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002998 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002999 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003000 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003001 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003002 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003003 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003004 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 errorPattern = "Command\snot\sfound"
3006 if re.search( errorPattern, response ):
3007 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003008 return main.FALSE
3009 else:
Jon Hall390696c2015-05-05 17:13:41 -07003010 main.log.error( "Error in electionTestRun on " + self.name +
3011 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003012 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003013 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003014 except AssertionError:
3015 main.log.exception( "" )
3016 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003017 except TypeError:
3018 main.log.exception( self.name + ": Object not as expected" )
3019 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003021 main.log.error( self.name + ": EOF exception found" )
3022 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003023 main.cleanup()
3024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003026 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003027 main.cleanup()
3028 main.exit()
3029
kelvin-onlabd3b64892015-01-20 13:26:24 -08003030 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003031 """
Jon Hall94fd0472014-12-08 11:52:42 -08003032 * CLI command to withdraw the local node from leadership election for
3033 * the Election test application.
3034 #NOTE: Requires installation of the onos-app-election feature
3035 Returns: Main.TRUE on success
3036 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003037 """
Jon Hall94fd0472014-12-08 11:52:42 -08003038 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003039 cmdStr = "election-test-withdraw"
3040 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003041 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003042 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003043 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003044 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003045 if re.search( successPattern, response ):
3046 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003048 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003049 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003050 errorPattern = "Command\snot\sfound"
3051 if re.search( errorPattern, response ):
3052 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003053 return main.FALSE
3054 else:
Jon Hall390696c2015-05-05 17:13:41 -07003055 main.log.error( "Error in electionTestWithdraw on " +
3056 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003057 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003058 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003059 except AssertionError:
3060 main.log.exception( "" )
3061 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003062 except TypeError:
3063 main.log.exception( self.name + ": Object not as expected" )
3064 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003066 main.log.error( self.name + ": EOF exception found" )
3067 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003068 main.cleanup()
3069 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003070 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003071 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003072 main.cleanup()
3073 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003074
kelvin8ec71442015-01-15 16:57:00 -08003075 def getDevicePortsEnabledCount( self, dpid ):
3076 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003077 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003078 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003079 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003080 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003081 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3082 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003083 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003084 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003085 if re.search( "No such device", output ):
3086 main.log.error( "Error in getting ports" )
3087 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003088 return output
Jon Hallc6793552016-01-19 14:18:37 -08003089 except AssertionError:
3090 main.log.exception( "" )
3091 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003092 except TypeError:
3093 main.log.exception( self.name + ": Object not as expected" )
3094 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003095 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003096 main.log.error( self.name + ": EOF exception found" )
3097 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003098 main.cleanup()
3099 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003100 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003101 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003102 main.cleanup()
3103 main.exit()
3104
kelvin8ec71442015-01-15 16:57:00 -08003105 def getDeviceLinksActiveCount( self, dpid ):
3106 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003107 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003108 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003109 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003110 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003111 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3112 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003113 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003114 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003115 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003116 main.log.error( "Error in getting ports " )
3117 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003118 return output
Jon Hallc6793552016-01-19 14:18:37 -08003119 except AssertionError:
3120 main.log.exception( "" )
3121 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003122 except TypeError:
3123 main.log.exception( self.name + ": Object not as expected" )
3124 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003125 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003126 main.log.error( self.name + ": EOF exception found" )
3127 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003128 main.cleanup()
3129 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003131 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003132 main.cleanup()
3133 main.exit()
3134
kelvin8ec71442015-01-15 16:57:00 -08003135 def getAllIntentIds( self ):
3136 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003138 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003139 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003140 cmdStr = "onos:intents | grep id="
3141 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003142 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003143 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003144 if re.search( "Error", output ):
3145 main.log.error( "Error in getting ports" )
3146 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003147 return output
Jon Hallc6793552016-01-19 14:18:37 -08003148 except AssertionError:
3149 main.log.exception( "" )
3150 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003151 except TypeError:
3152 main.log.exception( self.name + ": Object not as expected" )
3153 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003155 main.log.error( self.name + ": EOF exception found" )
3156 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003157 main.cleanup()
3158 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003160 main.log.exception( self.name + ": Uncaught exception!" )
3161 main.cleanup()
3162 main.exit()
3163
Jon Hall73509952015-02-24 16:42:56 -08003164 def intentSummary( self ):
3165 """
Jon Hallefbd9792015-03-05 16:11:36 -08003166 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003167 """
3168 try:
3169 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003170 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003171 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003172 states.append( intent.get( 'state', None ) )
3173 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003174 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003175 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003176 except ( TypeError, ValueError ):
3177 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003178 return None
3179 except pexpect.EOF:
3180 main.log.error( self.name + ": EOF exception found" )
3181 main.log.error( self.name + ": " + self.handle.before )
3182 main.cleanup()
3183 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003184 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003185 main.log.exception( self.name + ": Uncaught exception!" )
3186 main.cleanup()
3187 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003188
Jon Hall61282e32015-03-19 11:34:11 -07003189 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003190 """
3191 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003192 Optional argument:
3193 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003194 """
Jon Hall63604932015-02-26 17:09:50 -08003195 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003196 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003197 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003198 cmdStr += " -j"
3199 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003200 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003201 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003202 return output
Jon Hallc6793552016-01-19 14:18:37 -08003203 except AssertionError:
3204 main.log.exception( "" )
3205 return None
Jon Hall63604932015-02-26 17:09:50 -08003206 except TypeError:
3207 main.log.exception( self.name + ": Object not as expected" )
3208 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003209 except pexpect.EOF:
3210 main.log.error( self.name + ": EOF exception found" )
3211 main.log.error( self.name + ": " + self.handle.before )
3212 main.cleanup()
3213 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003214 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003215 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003216 main.cleanup()
3217 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003218
acsmarsa4a4d1e2015-07-10 16:01:24 -07003219 def leaderCandidates( self, jsonFormat=True ):
3220 """
3221 Returns the output of the leaders -c command.
3222 Optional argument:
3223 * jsonFormat - boolean indicating if you want output in json
3224 """
3225 try:
3226 cmdStr = "onos:leaders -c"
3227 if jsonFormat:
3228 cmdStr += " -j"
3229 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003230 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003231 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003232 return output
Jon Hallc6793552016-01-19 14:18:37 -08003233 except AssertionError:
3234 main.log.exception( "" )
3235 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003236 except TypeError:
3237 main.log.exception( self.name + ": Object not as expected" )
3238 return None
3239 except pexpect.EOF:
3240 main.log.error( self.name + ": EOF exception found" )
3241 main.log.error( self.name + ": " + self.handle.before )
3242 main.cleanup()
3243 main.exit()
3244 except Exception:
3245 main.log.exception( self.name + ": Uncaught exception!" )
3246 main.cleanup()
3247 main.exit()
3248
Jon Hallc6793552016-01-19 14:18:37 -08003249 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003250 """
3251 Returns a list in format [leader,candidate1,candidate2,...] for a given
3252 topic parameter and an empty list if the topic doesn't exist
3253 If no leader is elected leader in the returned list will be "none"
3254 Returns None if there is a type error processing the json object
3255 """
3256 try:
Jon Hall6e709752016-02-01 13:38:46 -08003257 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003258 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003259 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003260 assert "Command not found:" not in rawOutput, rawOutput
3261 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003262 results = []
3263 for dict in output:
3264 if dict["topic"] == topic:
3265 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003266 candidates = re.split( ", ", dict["candidates"][1:-1] )
3267 results.append( leader )
3268 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003269 return results
Jon Hallc6793552016-01-19 14:18:37 -08003270 except AssertionError:
3271 main.log.exception( "" )
3272 return None
3273 except ( TypeError, ValueError ):
3274 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003275 return None
3276 except pexpect.EOF:
3277 main.log.error( self.name + ": EOF exception found" )
3278 main.log.error( self.name + ": " + self.handle.before )
3279 main.cleanup()
3280 main.exit()
3281 except Exception:
3282 main.log.exception( self.name + ": Uncaught exception!" )
3283 main.cleanup()
3284 main.exit()
3285
Jon Hall61282e32015-03-19 11:34:11 -07003286 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003287 """
3288 Returns the output of the intent Pending map.
3289 """
Jon Hall63604932015-02-26 17:09:50 -08003290 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003291 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003292 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003293 cmdStr += " -j"
3294 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003295 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003296 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003297 return output
Jon Hallc6793552016-01-19 14:18:37 -08003298 except AssertionError:
3299 main.log.exception( "" )
3300 return None
Jon Hall63604932015-02-26 17:09:50 -08003301 except TypeError:
3302 main.log.exception( self.name + ": Object not as expected" )
3303 return None
3304 except pexpect.EOF:
3305 main.log.error( self.name + ": EOF exception found" )
3306 main.log.error( self.name + ": " + self.handle.before )
3307 main.cleanup()
3308 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003309 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003310 main.log.exception( self.name + ": Uncaught exception!" )
3311 main.cleanup()
3312 main.exit()
3313
Jon Hall61282e32015-03-19 11:34:11 -07003314 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003315 """
3316 Returns the output of the raft partitions command for ONOS.
3317 """
Jon Hall61282e32015-03-19 11:34:11 -07003318 # Sample JSON
3319 # {
3320 # "leader": "tcp://10.128.30.11:7238",
3321 # "members": [
3322 # "tcp://10.128.30.11:7238",
3323 # "tcp://10.128.30.17:7238",
3324 # "tcp://10.128.30.13:7238",
3325 # ],
3326 # "name": "p1",
3327 # "term": 3
3328 # },
Jon Hall63604932015-02-26 17:09:50 -08003329 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003330 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003331 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 cmdStr += " -j"
3333 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003334 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003335 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003336 return output
Jon Hallc6793552016-01-19 14:18:37 -08003337 except AssertionError:
3338 main.log.exception( "" )
3339 return None
Jon Hall63604932015-02-26 17:09:50 -08003340 except TypeError:
3341 main.log.exception( self.name + ": Object not as expected" )
3342 return None
3343 except pexpect.EOF:
3344 main.log.error( self.name + ": EOF exception found" )
3345 main.log.error( self.name + ": " + self.handle.before )
3346 main.cleanup()
3347 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003348 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003349 main.log.exception( self.name + ": Uncaught exception!" )
3350 main.cleanup()
3351 main.exit()
3352
Jon Hallbe379602015-03-24 13:39:32 -07003353 def apps( self, jsonFormat=True ):
3354 """
3355 Returns the output of the apps command for ONOS. This command lists
3356 information about installed ONOS applications
3357 """
3358 # Sample JSON object
3359 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3360 # "description":"ONOS OpenFlow protocol southbound providers",
3361 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3362 # "features":"[onos-openflow]","state":"ACTIVE"}]
3363 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003364 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003365 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003366 cmdStr += " -j"
3367 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003368 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003369 assert "Command not found:" not in output, output
3370 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003371 return output
Jon Hallbe379602015-03-24 13:39:32 -07003372 # FIXME: look at specific exceptions/Errors
3373 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003374 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003375 return None
3376 except TypeError:
3377 main.log.exception( self.name + ": Object not as expected" )
3378 return None
3379 except pexpect.EOF:
3380 main.log.error( self.name + ": EOF exception found" )
3381 main.log.error( self.name + ": " + self.handle.before )
3382 main.cleanup()
3383 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003384 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003385 main.log.exception( self.name + ": Uncaught exception!" )
3386 main.cleanup()
3387 main.exit()
3388
Jon Hall146f1522015-03-24 15:33:24 -07003389 def appStatus( self, appName ):
3390 """
3391 Uses the onos:apps cli command to return the status of an application.
3392 Returns:
3393 "ACTIVE" - If app is installed and activated
3394 "INSTALLED" - If app is installed and deactivated
3395 "UNINSTALLED" - If app is not installed
3396 None - on error
3397 """
Jon Hall146f1522015-03-24 15:33:24 -07003398 try:
3399 if not isinstance( appName, types.StringType ):
3400 main.log.error( self.name + ".appStatus(): appName must be" +
3401 " a string" )
3402 return None
3403 output = self.apps( jsonFormat=True )
3404 appsJson = json.loads( output )
3405 state = None
3406 for app in appsJson:
3407 if appName == app.get('name'):
3408 state = app.get('state')
3409 break
3410 if state == "ACTIVE" or state == "INSTALLED":
3411 return state
3412 elif state is None:
3413 return "UNINSTALLED"
3414 elif state:
3415 main.log.error( "Unexpected state from 'onos:apps': " +
3416 str( state ) )
3417 return state
Jon Hallc6793552016-01-19 14:18:37 -08003418 except ( TypeError, ValueError ):
3419 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003420 return None
3421 except pexpect.EOF:
3422 main.log.error( self.name + ": EOF exception found" )
3423 main.log.error( self.name + ": " + self.handle.before )
3424 main.cleanup()
3425 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003426 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003427 main.log.exception( self.name + ": Uncaught exception!" )
3428 main.cleanup()
3429 main.exit()
3430
Jon Hallbe379602015-03-24 13:39:32 -07003431 def app( self, appName, option ):
3432 """
3433 Interacts with the app command for ONOS. This command manages
3434 application inventory.
3435 """
Jon Hallbe379602015-03-24 13:39:32 -07003436 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003437 # Validate argument types
3438 valid = True
3439 if not isinstance( appName, types.StringType ):
3440 main.log.error( self.name + ".app(): appName must be a " +
3441 "string" )
3442 valid = False
3443 if not isinstance( option, types.StringType ):
3444 main.log.error( self.name + ".app(): option must be a string" )
3445 valid = False
3446 if not valid:
3447 return main.FALSE
3448 # Validate Option
3449 option = option.lower()
3450 # NOTE: Install may become a valid option
3451 if option == "activate":
3452 pass
3453 elif option == "deactivate":
3454 pass
3455 elif option == "uninstall":
3456 pass
3457 else:
3458 # Invalid option
3459 main.log.error( "The ONOS app command argument only takes " +
3460 "the values: (activate|deactivate|uninstall)" +
3461 "; was given '" + option + "'")
3462 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003463 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003464 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003465 if "Error executing command" in output:
3466 main.log.error( "Error in processing onos:app command: " +
3467 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003468 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003469 elif "No such application" in output:
3470 main.log.error( "The application '" + appName +
3471 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003472 return main.FALSE
3473 elif "Command not found:" in output:
3474 main.log.error( "Error in processing onos:app command: " +
3475 str( output ) )
3476 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003477 elif "Unsupported command:" in output:
3478 main.log.error( "Incorrect command given to 'app': " +
3479 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003480 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003481 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003482 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003483 return main.TRUE
3484 except TypeError:
3485 main.log.exception( self.name + ": Object not as expected" )
3486 return main.ERROR
3487 except pexpect.EOF:
3488 main.log.error( self.name + ": EOF exception found" )
3489 main.log.error( self.name + ": " + self.handle.before )
3490 main.cleanup()
3491 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003492 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003493 main.log.exception( self.name + ": Uncaught exception!" )
3494 main.cleanup()
3495 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003496
Jon Hallbd16b922015-03-26 17:53:15 -07003497 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003498 """
3499 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003500 appName is the hierarchical app name, not the feature name
3501 If check is True, method will check the status of the app after the
3502 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003503 Returns main.TRUE if the command was successfully sent
3504 main.FALSE if the cli responded with an error or given
3505 incorrect input
3506 """
3507 try:
3508 if not isinstance( appName, types.StringType ):
3509 main.log.error( self.name + ".activateApp(): appName must be" +
3510 " a string" )
3511 return main.FALSE
3512 status = self.appStatus( appName )
3513 if status == "INSTALLED":
3514 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003515 if check and response == main.TRUE:
3516 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003517 status = self.appStatus( appName )
3518 if status == "ACTIVE":
3519 return main.TRUE
3520 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003521 main.log.debug( "The state of application " +
3522 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003523 time.sleep( 1 )
3524 return main.FALSE
3525 else: # not 'check' or command didn't succeed
3526 return response
Jon Hall146f1522015-03-24 15:33:24 -07003527 elif status == "ACTIVE":
3528 return main.TRUE
3529 elif status == "UNINSTALLED":
3530 main.log.error( self.name + ": Tried to activate the " +
3531 "application '" + appName + "' which is not " +
3532 "installed." )
3533 else:
3534 main.log.error( "Unexpected return value from appStatus: " +
3535 str( status ) )
3536 return main.ERROR
3537 except TypeError:
3538 main.log.exception( self.name + ": Object not as expected" )
3539 return main.ERROR
3540 except pexpect.EOF:
3541 main.log.error( self.name + ": EOF exception found" )
3542 main.log.error( self.name + ": " + self.handle.before )
3543 main.cleanup()
3544 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003545 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003546 main.log.exception( self.name + ": Uncaught exception!" )
3547 main.cleanup()
3548 main.exit()
3549
Jon Hallbd16b922015-03-26 17:53:15 -07003550 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003551 """
3552 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003553 appName is the hierarchical app name, not the feature name
3554 If check is True, method will check the status of the app after the
3555 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003556 Returns main.TRUE if the command was successfully sent
3557 main.FALSE if the cli responded with an error or given
3558 incorrect input
3559 """
3560 try:
3561 if not isinstance( appName, types.StringType ):
3562 main.log.error( self.name + ".deactivateApp(): appName must " +
3563 "be a string" )
3564 return main.FALSE
3565 status = self.appStatus( appName )
3566 if status == "INSTALLED":
3567 return main.TRUE
3568 elif status == "ACTIVE":
3569 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003570 if check and response == main.TRUE:
3571 for i in range(10): # try 10 times then give up
3572 status = self.appStatus( appName )
3573 if status == "INSTALLED":
3574 return main.TRUE
3575 else:
3576 time.sleep( 1 )
3577 return main.FALSE
3578 else: # not check or command didn't succeed
3579 return response
Jon Hall146f1522015-03-24 15:33:24 -07003580 elif status == "UNINSTALLED":
3581 main.log.warn( self.name + ": Tried to deactivate the " +
3582 "application '" + appName + "' which is not " +
3583 "installed." )
3584 return main.TRUE
3585 else:
3586 main.log.error( "Unexpected return value from appStatus: " +
3587 str( status ) )
3588 return main.ERROR
3589 except TypeError:
3590 main.log.exception( self.name + ": Object not as expected" )
3591 return main.ERROR
3592 except pexpect.EOF:
3593 main.log.error( self.name + ": EOF exception found" )
3594 main.log.error( self.name + ": " + self.handle.before )
3595 main.cleanup()
3596 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003597 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003598 main.log.exception( self.name + ": Uncaught exception!" )
3599 main.cleanup()
3600 main.exit()
3601
Jon Hallbd16b922015-03-26 17:53:15 -07003602 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003603 """
3604 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003605 appName is the hierarchical app name, not the feature name
3606 If check is True, method will check the status of the app after the
3607 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003608 Returns main.TRUE if the command was successfully sent
3609 main.FALSE if the cli responded with an error or given
3610 incorrect input
3611 """
3612 # TODO: check with Thomas about the state machine for apps
3613 try:
3614 if not isinstance( appName, types.StringType ):
3615 main.log.error( self.name + ".uninstallApp(): appName must " +
3616 "be a string" )
3617 return main.FALSE
3618 status = self.appStatus( appName )
3619 if status == "INSTALLED":
3620 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003621 if check and response == main.TRUE:
3622 for i in range(10): # try 10 times then give up
3623 status = self.appStatus( appName )
3624 if status == "UNINSTALLED":
3625 return main.TRUE
3626 else:
3627 time.sleep( 1 )
3628 return main.FALSE
3629 else: # not check or command didn't succeed
3630 return response
Jon Hall146f1522015-03-24 15:33:24 -07003631 elif status == "ACTIVE":
3632 main.log.warn( self.name + ": Tried to uninstall the " +
3633 "application '" + appName + "' which is " +
3634 "currently active." )
3635 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003636 if check and response == main.TRUE:
3637 for i in range(10): # try 10 times then give up
3638 status = self.appStatus( appName )
3639 if status == "UNINSTALLED":
3640 return main.TRUE
3641 else:
3642 time.sleep( 1 )
3643 return main.FALSE
3644 else: # not check or command didn't succeed
3645 return response
Jon Hall146f1522015-03-24 15:33:24 -07003646 elif status == "UNINSTALLED":
3647 return main.TRUE
3648 else:
3649 main.log.error( "Unexpected return value from appStatus: " +
3650 str( status ) )
3651 return main.ERROR
3652 except TypeError:
3653 main.log.exception( self.name + ": Object not as expected" )
3654 return main.ERROR
3655 except pexpect.EOF:
3656 main.log.error( self.name + ": EOF exception found" )
3657 main.log.error( self.name + ": " + self.handle.before )
3658 main.cleanup()
3659 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003660 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003661 main.log.exception( self.name + ": Uncaught exception!" )
3662 main.cleanup()
3663 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003664
3665 def appIDs( self, jsonFormat=True ):
3666 """
3667 Show the mappings between app id and app names given by the 'app-ids'
3668 cli command
3669 """
3670 try:
3671 cmdStr = "app-ids"
3672 if jsonFormat:
3673 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003674 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003675 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003676 assert "Command not found:" not in output, output
3677 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003678 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003679 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003680 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003681 return None
3682 except TypeError:
3683 main.log.exception( self.name + ": Object not as expected" )
3684 return None
3685 except pexpect.EOF:
3686 main.log.error( self.name + ": EOF exception found" )
3687 main.log.error( self.name + ": " + self.handle.before )
3688 main.cleanup()
3689 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003690 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003691 main.log.exception( self.name + ": Uncaught exception!" )
3692 main.cleanup()
3693 main.exit()
3694
3695 def appToIDCheck( self ):
3696 """
3697 This method will check that each application's ID listed in 'apps' is
3698 the same as the ID listed in 'app-ids'. The check will also check that
3699 there are no duplicate IDs issued. Note that an app ID should be
3700 a globaly unique numerical identifier for app/app-like features. Once
3701 an ID is registered, the ID is never freed up so that if an app is
3702 reinstalled it will have the same ID.
3703
3704 Returns: main.TRUE if the check passes and
3705 main.FALSE if the check fails or
3706 main.ERROR if there is some error in processing the test
3707 """
3708 try:
Jon Hall390696c2015-05-05 17:13:41 -07003709 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003710 rawJson = self.appIDs( jsonFormat=True )
3711 if rawJson:
3712 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003713 else:
Jon Hallc6793552016-01-19 14:18:37 -08003714 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003715 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003716 rawJson = self.apps( jsonFormat=True )
3717 if rawJson:
3718 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003719 else:
Jon Hallc6793552016-01-19 14:18:37 -08003720 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003721 bail = True
3722 if bail:
3723 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003724 result = main.TRUE
3725 for app in apps:
3726 appID = app.get( 'id' )
3727 if appID is None:
3728 main.log.error( "Error parsing app: " + str( app ) )
3729 result = main.FALSE
3730 appName = app.get( 'name' )
3731 if appName is None:
3732 main.log.error( "Error parsing app: " + str( app ) )
3733 result = main.FALSE
3734 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003735 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003736 # main.log.debug( "Comparing " + str( app ) + " to " +
3737 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003738 if not current: # if ids doesn't have this id
3739 result = main.FALSE
3740 main.log.error( "'app-ids' does not have the ID for " +
3741 str( appName ) + " that apps does." )
3742 elif len( current ) > 1:
3743 # there is more than one app with this ID
3744 result = main.FALSE
3745 # We will log this later in the method
3746 elif not current[0][ 'name' ] == appName:
3747 currentName = current[0][ 'name' ]
3748 result = main.FALSE
3749 main.log.error( "'app-ids' has " + str( currentName ) +
3750 " registered under id:" + str( appID ) +
3751 " but 'apps' has " + str( appName ) )
3752 else:
3753 pass # id and name match!
3754 # now make sure that app-ids has no duplicates
3755 idsList = []
3756 namesList = []
3757 for item in ids:
3758 idsList.append( item[ 'id' ] )
3759 namesList.append( item[ 'name' ] )
3760 if len( idsList ) != len( set( idsList ) ) or\
3761 len( namesList ) != len( set( namesList ) ):
3762 main.log.error( "'app-ids' has some duplicate entries: \n"
3763 + json.dumps( ids,
3764 sort_keys=True,
3765 indent=4,
3766 separators=( ',', ': ' ) ) )
3767 result = main.FALSE
3768 return result
Jon Hallc6793552016-01-19 14:18:37 -08003769 except ( TypeError, ValueError ):
3770 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003771 return main.ERROR
3772 except pexpect.EOF:
3773 main.log.error( self.name + ": EOF exception found" )
3774 main.log.error( self.name + ": " + self.handle.before )
3775 main.cleanup()
3776 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003777 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003778 main.log.exception( self.name + ": Uncaught exception!" )
3779 main.cleanup()
3780 main.exit()
3781
Jon Hallfb760a02015-04-13 15:35:03 -07003782 def getCfg( self, component=None, propName=None, short=False,
3783 jsonFormat=True ):
3784 """
3785 Get configuration settings from onos cli
3786 Optional arguments:
3787 component - Optionally only list configurations for a specific
3788 component. If None, all components with configurations
3789 are displayed. Case Sensitive string.
3790 propName - If component is specified, propName option will show
3791 only this specific configuration from that component.
3792 Case Sensitive string.
3793 jsonFormat - Returns output as json. Note that this will override
3794 the short option
3795 short - Short, less verbose, version of configurations.
3796 This is overridden by the json option
3797 returns:
3798 Output from cli as a string or None on error
3799 """
3800 try:
3801 baseStr = "cfg"
3802 cmdStr = " get"
3803 componentStr = ""
3804 if component:
3805 componentStr += " " + component
3806 if propName:
3807 componentStr += " " + propName
3808 if jsonFormat:
3809 baseStr += " -j"
3810 elif short:
3811 baseStr += " -s"
3812 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003813 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003814 assert "Command not found:" not in output, output
3815 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003816 return output
3817 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003818 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003819 return None
3820 except TypeError:
3821 main.log.exception( self.name + ": Object not as expected" )
3822 return None
3823 except pexpect.EOF:
3824 main.log.error( self.name + ": EOF exception found" )
3825 main.log.error( self.name + ": " + self.handle.before )
3826 main.cleanup()
3827 main.exit()
3828 except Exception:
3829 main.log.exception( self.name + ": Uncaught exception!" )
3830 main.cleanup()
3831 main.exit()
3832
3833 def setCfg( self, component, propName, value=None, check=True ):
3834 """
3835 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003836 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003837 component - The case sensitive name of the component whose
3838 property is to be set
3839 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003840 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003841 value - The value to set the property to. If None, will unset the
3842 property and revert it to it's default value(if applicable)
3843 check - Boolean, Check whether the option was successfully set this
3844 only applies when a value is given.
3845 returns:
3846 main.TRUE on success or main.FALSE on failure. If check is False,
3847 will return main.TRUE unless there is an error
3848 """
3849 try:
3850 baseStr = "cfg"
3851 cmdStr = " set " + str( component ) + " " + str( propName )
3852 if value is not None:
3853 cmdStr += " " + str( value )
3854 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003855 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003856 assert "Command not found:" not in output, output
3857 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003858 if value and check:
3859 results = self.getCfg( component=str( component ),
3860 propName=str( propName ),
3861 jsonFormat=True )
3862 # Check if current value is what we just set
3863 try:
3864 jsonOutput = json.loads( results )
3865 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003866 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003867 main.log.exception( "Error parsing cfg output" )
3868 main.log.error( "output:" + repr( results ) )
3869 return main.FALSE
3870 if current == str( value ):
3871 return main.TRUE
3872 return main.FALSE
3873 return main.TRUE
3874 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003875 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003876 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003877 except ( TypeError, ValueError ):
3878 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003879 return main.FALSE
3880 except pexpect.EOF:
3881 main.log.error( self.name + ": EOF exception found" )
3882 main.log.error( self.name + ": " + self.handle.before )
3883 main.cleanup()
3884 main.exit()
3885 except Exception:
3886 main.log.exception( self.name + ": Uncaught exception!" )
3887 main.cleanup()
3888 main.exit()
3889
Jon Hall390696c2015-05-05 17:13:41 -07003890 def setTestAdd( self, setName, values ):
3891 """
3892 CLI command to add elements to a distributed set.
3893 Arguments:
3894 setName - The name of the set to add to.
3895 values - The value(s) to add to the set, space seperated.
3896 Example usages:
3897 setTestAdd( "set1", "a b c" )
3898 setTestAdd( "set2", "1" )
3899 returns:
3900 main.TRUE on success OR
3901 main.FALSE if elements were already in the set OR
3902 main.ERROR on error
3903 """
3904 try:
3905 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3906 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003907 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003908 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003909 try:
3910 # TODO: Maybe make this less hardcoded
3911 # ConsistentMap Exceptions
3912 assert "org.onosproject.store.service" not in output
3913 # Node not leader
3914 assert "java.lang.IllegalStateException" not in output
3915 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003916 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003917 "command: " + str( output ) )
3918 retryTime = 30 # Conservative time, given by Madan
3919 main.log.info( "Waiting " + str( retryTime ) +
3920 "seconds before retrying." )
3921 time.sleep( retryTime ) # Due to change in mastership
3922 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003923 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003924 assert "Error executing command" not in output
3925 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3926 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3927 main.log.info( self.name + ": " + output )
3928 if re.search( positiveMatch, output):
3929 return main.TRUE
3930 elif re.search( negativeMatch, output):
3931 return main.FALSE
3932 else:
3933 main.log.error( self.name + ": setTestAdd did not" +
3934 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003935 main.log.debug( self.name + " actual: " + repr( output ) )
3936 return main.ERROR
3937 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003938 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003939 return main.ERROR
3940 except TypeError:
3941 main.log.exception( self.name + ": Object not as expected" )
3942 return main.ERROR
3943 except pexpect.EOF:
3944 main.log.error( self.name + ": EOF exception found" )
3945 main.log.error( self.name + ": " + self.handle.before )
3946 main.cleanup()
3947 main.exit()
3948 except Exception:
3949 main.log.exception( self.name + ": Uncaught exception!" )
3950 main.cleanup()
3951 main.exit()
3952
3953 def setTestRemove( self, setName, values, clear=False, retain=False ):
3954 """
3955 CLI command to remove elements from a distributed set.
3956 Required arguments:
3957 setName - The name of the set to remove from.
3958 values - The value(s) to remove from the set, space seperated.
3959 Optional arguments:
3960 clear - Clear all elements from the set
3961 retain - Retain only the given values. (intersection of the
3962 original set and the given set)
3963 returns:
3964 main.TRUE on success OR
3965 main.FALSE if the set was not changed OR
3966 main.ERROR on error
3967 """
3968 try:
3969 cmdStr = "set-test-remove "
3970 if clear:
3971 cmdStr += "-c " + str( setName )
3972 elif retain:
3973 cmdStr += "-r " + str( setName ) + " " + str( values )
3974 else:
3975 cmdStr += str( setName ) + " " + str( values )
3976 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003977 try:
Jon Halla495f562016-05-16 18:03:26 -07003978 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003979 # TODO: Maybe make this less hardcoded
3980 # ConsistentMap Exceptions
3981 assert "org.onosproject.store.service" not in output
3982 # Node not leader
3983 assert "java.lang.IllegalStateException" not in output
3984 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003985 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003986 "command: " + str( output ) )
3987 retryTime = 30 # Conservative time, given by Madan
3988 main.log.info( "Waiting " + str( retryTime ) +
3989 "seconds before retrying." )
3990 time.sleep( retryTime ) # Due to change in mastership
3991 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003992 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003993 assert "Command not found:" not in output, output
3994 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003995 main.log.info( self.name + ": " + output )
3996 if clear:
3997 pattern = "Set " + str( setName ) + " cleared"
3998 if re.search( pattern, output ):
3999 return main.TRUE
4000 elif retain:
4001 positivePattern = str( setName ) + " was pruned to contain " +\
4002 "only elements of set \[(.*)\]"
4003 negativePattern = str( setName ) + " was not changed by " +\
4004 "retaining only elements of the set " +\
4005 "\[(.*)\]"
4006 if re.search( positivePattern, output ):
4007 return main.TRUE
4008 elif re.search( negativePattern, output ):
4009 return main.FALSE
4010 else:
4011 positivePattern = "\[(.*)\] was removed from the set " +\
4012 str( setName )
4013 if ( len( values.split() ) == 1 ):
4014 negativePattern = "\[(.*)\] was not in set " +\
4015 str( setName )
4016 else:
4017 negativePattern = "No element of \[(.*)\] was in set " +\
4018 str( setName )
4019 if re.search( positivePattern, output ):
4020 return main.TRUE
4021 elif re.search( negativePattern, output ):
4022 return main.FALSE
4023 main.log.error( self.name + ": setTestRemove did not" +
4024 " match expected output" )
4025 main.log.debug( self.name + " expected: " + pattern )
4026 main.log.debug( self.name + " actual: " + repr( output ) )
4027 return main.ERROR
4028 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004029 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004030 return main.ERROR
4031 except TypeError:
4032 main.log.exception( self.name + ": Object not as expected" )
4033 return main.ERROR
4034 except pexpect.EOF:
4035 main.log.error( self.name + ": EOF exception found" )
4036 main.log.error( self.name + ": " + self.handle.before )
4037 main.cleanup()
4038 main.exit()
4039 except Exception:
4040 main.log.exception( self.name + ": Uncaught exception!" )
4041 main.cleanup()
4042 main.exit()
4043
4044 def setTestGet( self, setName, values="" ):
4045 """
4046 CLI command to get the elements in a distributed set.
4047 Required arguments:
4048 setName - The name of the set to remove from.
4049 Optional arguments:
4050 values - The value(s) to check if in the set, space seperated.
4051 returns:
4052 main.ERROR on error OR
4053 A list of elements in the set if no optional arguments are
4054 supplied OR
4055 A tuple containing the list then:
4056 main.FALSE if the given values are not in the set OR
4057 main.TRUE if the given values are in the set OR
4058 """
4059 try:
4060 values = str( values ).strip()
4061 setName = str( setName ).strip()
4062 length = len( values.split() )
4063 containsCheck = None
4064 # Patterns to match
4065 setPattern = "\[(.*)\]"
4066 pattern = "Items in set " + setName + ":\n" + setPattern
4067 containsTrue = "Set " + setName + " contains the value " + values
4068 containsFalse = "Set " + setName + " did not contain the value " +\
4069 values
4070 containsAllTrue = "Set " + setName + " contains the the subset " +\
4071 setPattern
4072 containsAllFalse = "Set " + setName + " did not contain the the" +\
4073 " subset " + setPattern
4074
4075 cmdStr = "set-test-get "
4076 cmdStr += setName + " " + values
4077 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004078 try:
Jon Halla495f562016-05-16 18:03:26 -07004079 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004080 # TODO: Maybe make this less hardcoded
4081 # ConsistentMap Exceptions
4082 assert "org.onosproject.store.service" not in output
4083 # Node not leader
4084 assert "java.lang.IllegalStateException" not in output
4085 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004086 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004087 "command: " + str( output ) )
4088 retryTime = 30 # Conservative time, given by Madan
4089 main.log.info( "Waiting " + str( retryTime ) +
4090 "seconds before retrying." )
4091 time.sleep( retryTime ) # Due to change in mastership
4092 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004093 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004094 assert "Command not found:" not in output, output
4095 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004096 main.log.info( self.name + ": " + output )
4097
4098 if length == 0:
4099 match = re.search( pattern, output )
4100 else: # if given values
4101 if length == 1: # Contains output
4102 patternTrue = pattern + "\n" + containsTrue
4103 patternFalse = pattern + "\n" + containsFalse
4104 else: # ContainsAll output
4105 patternTrue = pattern + "\n" + containsAllTrue
4106 patternFalse = pattern + "\n" + containsAllFalse
4107 matchTrue = re.search( patternTrue, output )
4108 matchFalse = re.search( patternFalse, output )
4109 if matchTrue:
4110 containsCheck = main.TRUE
4111 match = matchTrue
4112 elif matchFalse:
4113 containsCheck = main.FALSE
4114 match = matchFalse
4115 else:
4116 main.log.error( self.name + " setTestGet did not match " +\
4117 "expected output" )
4118 main.log.debug( self.name + " expected: " + pattern )
4119 main.log.debug( self.name + " actual: " + repr( output ) )
4120 match = None
4121 if match:
4122 setMatch = match.group( 1 )
4123 if setMatch == '':
4124 setList = []
4125 else:
4126 setList = setMatch.split( ", " )
4127 if length > 0:
4128 return ( setList, containsCheck )
4129 else:
4130 return setList
4131 else: # no match
4132 main.log.error( self.name + ": setTestGet did not" +
4133 " match expected output" )
4134 main.log.debug( self.name + " expected: " + pattern )
4135 main.log.debug( self.name + " actual: " + repr( output ) )
4136 return main.ERROR
4137 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004138 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004139 return main.ERROR
4140 except TypeError:
4141 main.log.exception( self.name + ": Object not as expected" )
4142 return main.ERROR
4143 except pexpect.EOF:
4144 main.log.error( self.name + ": EOF exception found" )
4145 main.log.error( self.name + ": " + self.handle.before )
4146 main.cleanup()
4147 main.exit()
4148 except Exception:
4149 main.log.exception( self.name + ": Uncaught exception!" )
4150 main.cleanup()
4151 main.exit()
4152
4153 def setTestSize( self, setName ):
4154 """
4155 CLI command to get the elements in a distributed set.
4156 Required arguments:
4157 setName - The name of the set to remove from.
4158 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004159 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004160 None on error
4161 """
4162 try:
4163 # TODO: Should this check against the number of elements returned
4164 # and then return true/false based on that?
4165 setName = str( setName ).strip()
4166 # Patterns to match
4167 setPattern = "\[(.*)\]"
4168 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4169 setPattern
4170 cmdStr = "set-test-get -s "
4171 cmdStr += setName
4172 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004173 try:
Jon Halla495f562016-05-16 18:03:26 -07004174 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004175 # TODO: Maybe make this less hardcoded
4176 # ConsistentMap Exceptions
4177 assert "org.onosproject.store.service" not in output
4178 # Node not leader
4179 assert "java.lang.IllegalStateException" not in output
4180 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004181 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004182 "command: " + str( output ) )
4183 retryTime = 30 # Conservative time, given by Madan
4184 main.log.info( "Waiting " + str( retryTime ) +
4185 "seconds before retrying." )
4186 time.sleep( retryTime ) # Due to change in mastership
4187 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004188 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004189 assert "Command not found:" not in output, output
4190 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004191 main.log.info( self.name + ": " + output )
4192 match = re.search( pattern, output )
4193 if match:
4194 setSize = int( match.group( 1 ) )
4195 setMatch = match.group( 2 )
4196 if len( setMatch.split() ) == setSize:
4197 main.log.info( "The size returned by " + self.name +
4198 " matches the number of elements in " +
4199 "the returned set" )
4200 else:
4201 main.log.error( "The size returned by " + self.name +
4202 " does not match the number of " +
4203 "elements in the returned set." )
4204 return setSize
4205 else: # no match
4206 main.log.error( self.name + ": setTestGet did not" +
4207 " match expected output" )
4208 main.log.debug( self.name + " expected: " + pattern )
4209 main.log.debug( self.name + " actual: " + repr( output ) )
4210 return None
4211 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004212 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004213 return None
Jon Hall390696c2015-05-05 17:13:41 -07004214 except TypeError:
4215 main.log.exception( self.name + ": Object not as expected" )
4216 return None
4217 except pexpect.EOF:
4218 main.log.error( self.name + ": EOF exception found" )
4219 main.log.error( self.name + ": " + self.handle.before )
4220 main.cleanup()
4221 main.exit()
4222 except Exception:
4223 main.log.exception( self.name + ": Uncaught exception!" )
4224 main.cleanup()
4225 main.exit()
4226
Jon Hall80daded2015-05-27 16:07:00 -07004227 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004228 """
4229 Command to list the various counters in the system.
4230 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004231 if jsonFormat, a string of the json object returned by the cli
4232 command
4233 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004234 None on error
4235 """
Jon Hall390696c2015-05-05 17:13:41 -07004236 try:
4237 counters = {}
4238 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004239 if jsonFormat:
4240 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004241 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004242 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004243 assert "Command not found:" not in output, output
4244 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004245 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004246 return output
Jon Hall390696c2015-05-05 17:13:41 -07004247 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004248 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004249 return None
Jon Hall390696c2015-05-05 17:13:41 -07004250 except TypeError:
4251 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004252 return None
Jon Hall390696c2015-05-05 17:13:41 -07004253 except pexpect.EOF:
4254 main.log.error( self.name + ": EOF exception found" )
4255 main.log.error( self.name + ": " + self.handle.before )
4256 main.cleanup()
4257 main.exit()
4258 except Exception:
4259 main.log.exception( self.name + ": Uncaught exception!" )
4260 main.cleanup()
4261 main.exit()
4262
Jon Hall935db192016-04-19 00:22:04 -07004263 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004264 """
Jon Halle1a3b752015-07-22 13:02:46 -07004265 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004266 Required arguments:
4267 counter - The name of the counter to increment.
4268 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004269 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004270 returns:
4271 integer value of the counter or
4272 None on Error
4273 """
4274 try:
4275 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004276 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004277 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004278 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004279 if delta != 1:
4280 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004281 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004282 try:
Jon Halla495f562016-05-16 18:03:26 -07004283 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004284 # TODO: Maybe make this less hardcoded
4285 # ConsistentMap Exceptions
4286 assert "org.onosproject.store.service" not in output
4287 # Node not leader
4288 assert "java.lang.IllegalStateException" not in output
4289 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004290 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004291 "command: " + str( output ) )
4292 retryTime = 30 # Conservative time, given by Madan
4293 main.log.info( "Waiting " + str( retryTime ) +
4294 "seconds before retrying." )
4295 time.sleep( retryTime ) # Due to change in mastership
4296 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004297 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004298 assert "Command not found:" not in output, output
4299 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004300 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004301 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004302 match = re.search( pattern, output )
4303 if match:
4304 return int( match.group( 1 ) )
4305 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004306 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004307 " match expected output." )
4308 main.log.debug( self.name + " expected: " + pattern )
4309 main.log.debug( self.name + " actual: " + repr( output ) )
4310 return None
4311 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004312 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004313 return None
4314 except TypeError:
4315 main.log.exception( self.name + ": Object not as expected" )
4316 return None
4317 except pexpect.EOF:
4318 main.log.error( self.name + ": EOF exception found" )
4319 main.log.error( self.name + ": " + self.handle.before )
4320 main.cleanup()
4321 main.exit()
4322 except Exception:
4323 main.log.exception( self.name + ": Uncaught exception!" )
4324 main.cleanup()
4325 main.exit()
4326
Jon Hall935db192016-04-19 00:22:04 -07004327 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004328 """
4329 CLI command to get a distributed counter then add a delta to it.
4330 Required arguments:
4331 counter - The name of the counter to increment.
4332 Optional arguments:
4333 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004334 returns:
4335 integer value of the counter or
4336 None on Error
4337 """
4338 try:
4339 counter = str( counter )
4340 delta = int( delta )
4341 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004342 cmdStr += counter
4343 if delta != 1:
4344 cmdStr += " " + str( delta )
4345 output = self.sendline( cmdStr )
4346 try:
Jon Halla495f562016-05-16 18:03:26 -07004347 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004348 # TODO: Maybe make this less hardcoded
4349 # ConsistentMap Exceptions
4350 assert "org.onosproject.store.service" not in output
4351 # Node not leader
4352 assert "java.lang.IllegalStateException" not in output
4353 except AssertionError:
4354 main.log.error( "Error in processing '" + cmdStr + "' " +
4355 "command: " + str( output ) )
4356 retryTime = 30 # Conservative time, given by Madan
4357 main.log.info( "Waiting " + str( retryTime ) +
4358 "seconds before retrying." )
4359 time.sleep( retryTime ) # Due to change in mastership
4360 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004361 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004362 assert "Command not found:" not in output, output
4363 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004364 main.log.info( self.name + ": " + output )
4365 pattern = counter + " was updated to (-?\d+)"
4366 match = re.search( pattern, output )
4367 if match:
4368 return int( match.group( 1 ) )
4369 else:
4370 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4371 " match expected output." )
4372 main.log.debug( self.name + " expected: " + pattern )
4373 main.log.debug( self.name + " actual: " + repr( output ) )
4374 return None
4375 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004376 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004377 return None
4378 except TypeError:
4379 main.log.exception( self.name + ": Object not as expected" )
4380 return None
4381 except pexpect.EOF:
4382 main.log.error( self.name + ": EOF exception found" )
4383 main.log.error( self.name + ": " + self.handle.before )
4384 main.cleanup()
4385 main.exit()
4386 except Exception:
4387 main.log.exception( self.name + ": Uncaught exception!" )
4388 main.cleanup()
4389 main.exit()
4390
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004391 def summary( self, jsonFormat=True ):
4392 """
4393 Description: Execute summary command in onos
4394 Returns: json object ( summary -j ), returns main.FALSE if there is
4395 no output
4396
4397 """
4398 try:
4399 cmdStr = "summary"
4400 if jsonFormat:
4401 cmdStr += " -j"
4402 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004403 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004404 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004405 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004406 if not handle:
4407 main.log.error( self.name + ": There is no output in " +
4408 "summary command" )
4409 return main.FALSE
4410 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004411 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004412 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004413 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004414 except TypeError:
4415 main.log.exception( self.name + ": Object not as expected" )
4416 return None
4417 except pexpect.EOF:
4418 main.log.error( self.name + ": EOF exception found" )
4419 main.log.error( self.name + ": " + self.handle.before )
4420 main.cleanup()
4421 main.exit()
4422 except Exception:
4423 main.log.exception( self.name + ": Uncaught exception!" )
4424 main.cleanup()
4425 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004426
Jon Hall935db192016-04-19 00:22:04 -07004427 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004428 """
4429 CLI command to get the value of a key in a consistent map using
4430 transactions. This a test function and can only get keys from the
4431 test map hard coded into the cli command
4432 Required arguments:
4433 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004434 returns:
4435 The string value of the key or
4436 None on Error
4437 """
4438 try:
4439 keyName = str( keyName )
4440 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004441 cmdStr += keyName
4442 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004443 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004444 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004445 try:
4446 # TODO: Maybe make this less hardcoded
4447 # ConsistentMap Exceptions
4448 assert "org.onosproject.store.service" not in output
4449 # Node not leader
4450 assert "java.lang.IllegalStateException" not in output
4451 except AssertionError:
4452 main.log.error( "Error in processing '" + cmdStr + "' " +
4453 "command: " + str( output ) )
4454 return None
4455 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4456 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004457 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004458 return None
4459 else:
4460 match = re.search( pattern, output )
4461 if match:
4462 return match.groupdict()[ 'value' ]
4463 else:
4464 main.log.error( self.name + ": transactionlMapGet did not" +
4465 " match expected output." )
4466 main.log.debug( self.name + " expected: " + pattern )
4467 main.log.debug( self.name + " actual: " + repr( output ) )
4468 return None
Jon Hallc6793552016-01-19 14:18:37 -08004469 except AssertionError:
4470 main.log.exception( "" )
4471 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004472 except TypeError:
4473 main.log.exception( self.name + ": Object not as expected" )
4474 return None
4475 except pexpect.EOF:
4476 main.log.error( self.name + ": EOF exception found" )
4477 main.log.error( self.name + ": " + self.handle.before )
4478 main.cleanup()
4479 main.exit()
4480 except Exception:
4481 main.log.exception( self.name + ": Uncaught exception!" )
4482 main.cleanup()
4483 main.exit()
4484
Jon Hall935db192016-04-19 00:22:04 -07004485 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004486 """
4487 CLI command to put a value into 'numKeys' number of keys in a
4488 consistent map using transactions. This a test function and can only
4489 put into keys named 'Key#' of the test map hard coded into the cli command
4490 Required arguments:
4491 numKeys - Number of keys to add the value to
4492 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004493 returns:
4494 A dictionary whose keys are the name of the keys put into the map
4495 and the values of the keys are dictionaries whose key-values are
4496 'value': value put into map and optionaly
4497 'oldValue': Previous value in the key or
4498 None on Error
4499
4500 Example output
4501 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4502 'Key2': {'value': 'Testing'} }
4503 """
4504 try:
4505 numKeys = str( numKeys )
4506 value = str( value )
4507 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004508 cmdStr += numKeys + " " + value
4509 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004510 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004511 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004512 try:
4513 # TODO: Maybe make this less hardcoded
4514 # ConsistentMap Exceptions
4515 assert "org.onosproject.store.service" not in output
4516 # Node not leader
4517 assert "java.lang.IllegalStateException" not in output
4518 except AssertionError:
4519 main.log.error( "Error in processing '" + cmdStr + "' " +
4520 "command: " + str( output ) )
4521 return None
4522 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4523 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4524 results = {}
4525 for line in output.splitlines():
4526 new = re.search( newPattern, line )
4527 updated = re.search( updatedPattern, line )
4528 if new:
4529 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4530 elif updated:
4531 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004532 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004533 else:
4534 main.log.error( self.name + ": transactionlMapGet did not" +
4535 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004536 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4537 newPattern,
4538 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004539 main.log.debug( self.name + " actual: " + repr( output ) )
4540 return results
Jon Hallc6793552016-01-19 14:18:37 -08004541 except AssertionError:
4542 main.log.exception( "" )
4543 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004544 except TypeError:
4545 main.log.exception( self.name + ": Object not as expected" )
4546 return None
4547 except pexpect.EOF:
4548 main.log.error( self.name + ": EOF exception found" )
4549 main.log.error( self.name + ": " + self.handle.before )
4550 main.cleanup()
4551 main.exit()
4552 except Exception:
4553 main.log.exception( self.name + ": Uncaught exception!" )
4554 main.cleanup()
4555 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004556
acsmarsdaea66c2015-09-03 11:44:06 -07004557 def maps( self, jsonFormat=True ):
4558 """
4559 Description: Returns result of onos:maps
4560 Optional:
4561 * jsonFormat: enable json formatting of output
4562 """
4563 try:
4564 cmdStr = "maps"
4565 if jsonFormat:
4566 cmdStr += " -j"
4567 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004568 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004569 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004570 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004571 except AssertionError:
4572 main.log.exception( "" )
4573 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004574 except TypeError:
4575 main.log.exception( self.name + ": Object not as expected" )
4576 return None
4577 except pexpect.EOF:
4578 main.log.error( self.name + ": EOF exception found" )
4579 main.log.error( self.name + ": " + self.handle.before )
4580 main.cleanup()
4581 main.exit()
4582 except Exception:
4583 main.log.exception( self.name + ": Uncaught exception!" )
4584 main.cleanup()
4585 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004586
4587 def getSwController( self, uri, jsonFormat=True ):
4588 """
4589 Descrition: Gets the controller information from the device
4590 """
4591 try:
4592 cmd = "device-controllers "
4593 if jsonFormat:
4594 cmd += "-j "
4595 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004596 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004597 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004598 return response
Jon Hallc6793552016-01-19 14:18:37 -08004599 except AssertionError:
4600 main.log.exception( "" )
4601 return None
GlennRC050596c2015-11-18 17:06:41 -08004602 except TypeError:
4603 main.log.exception( self.name + ": Object not as expected" )
4604 return None
4605 except pexpect.EOF:
4606 main.log.error( self.name + ": EOF exception found" )
4607 main.log.error( self.name + ": " + self.handle.before )
4608 main.cleanup()
4609 main.exit()
4610 except Exception:
4611 main.log.exception( self.name + ": Uncaught exception!" )
4612 main.cleanup()
4613 main.exit()
4614
4615 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4616 """
4617 Descrition: sets the controller(s) for the specified device
4618
4619 Parameters:
4620 Required: uri - String: The uri of the device(switch).
4621 ip - String or List: The ip address of the controller.
4622 This parameter can be formed in a couple of different ways.
4623 VALID:
4624 10.0.0.1 - just the ip address
4625 tcp:10.0.0.1 - the protocol and the ip address
4626 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4627 so that you can add controllers with different
4628 protocols and ports
4629 INVALID:
4630 10.0.0.1:6653 - this is not supported by ONOS
4631
4632 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4633 port - The port number.
4634 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4635
4636 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4637 """
4638 try:
4639 cmd = "device-setcontrollers"
4640
4641 if jsonFormat:
4642 cmd += " -j"
4643 cmd += " " + uri
4644 if isinstance( ip, str ):
4645 ip = [ip]
4646 for item in ip:
4647 if ":" in item:
4648 sitem = item.split( ":" )
4649 if len(sitem) == 3:
4650 cmd += " " + item
4651 elif "." in sitem[1]:
4652 cmd += " {}:{}".format(item, port)
4653 else:
4654 main.log.error( "Malformed entry: " + item )
4655 raise TypeError
4656 else:
4657 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004658 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004659 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004660 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004661 if "Error" in response:
4662 main.log.error( response )
4663 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004664 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004665 except AssertionError:
4666 main.log.exception( "" )
4667 return None
GlennRC050596c2015-11-18 17:06:41 -08004668 except TypeError:
4669 main.log.exception( self.name + ": Object not as expected" )
4670 return main.FALSE
4671 except pexpect.EOF:
4672 main.log.error( self.name + ": EOF exception found" )
4673 main.log.error( self.name + ": " + self.handle.before )
4674 main.cleanup()
4675 main.exit()
4676 except Exception:
4677 main.log.exception( self.name + ": Uncaught exception!" )
4678 main.cleanup()
4679 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004680
4681 def removeDevice( self, device ):
4682 '''
4683 Description:
4684 Remove a device from ONOS by passing the uri of the device(s).
4685 Parameters:
4686 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4687 Returns:
4688 Returns main.FALSE if an exception is thrown or an error is present
4689 in the response. Otherwise, returns main.TRUE.
4690 NOTE:
4691 If a host cannot be removed, then this function will return main.FALSE
4692 '''
4693 try:
4694 if type( device ) is str:
4695 device = list( device )
4696
4697 for d in device:
4698 time.sleep( 1 )
4699 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004700 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004701 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004702 if "Error" in response:
4703 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4704 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004705 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004706 except AssertionError:
4707 main.log.exception( "" )
4708 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004709 except TypeError:
4710 main.log.exception( self.name + ": Object not as expected" )
4711 return main.FALSE
4712 except pexpect.EOF:
4713 main.log.error( self.name + ": EOF exception found" )
4714 main.log.error( self.name + ": " + self.handle.before )
4715 main.cleanup()
4716 main.exit()
4717 except Exception:
4718 main.log.exception( self.name + ": Uncaught exception!" )
4719 main.cleanup()
4720 main.exit()
4721
4722 def removeHost( self, host ):
4723 '''
4724 Description:
4725 Remove a host from ONOS by passing the id of the host(s)
4726 Parameters:
4727 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4728 Returns:
4729 Returns main.FALSE if an exception is thrown or an error is present
4730 in the response. Otherwise, returns main.TRUE.
4731 NOTE:
4732 If a host cannot be removed, then this function will return main.FALSE
4733 '''
4734 try:
4735 if type( host ) is str:
4736 host = list( host )
4737
4738 for h in host:
4739 time.sleep( 1 )
4740 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004741 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004742 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004743 if "Error" in response:
4744 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4745 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004746 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004747 except AssertionError:
4748 main.log.exception( "" )
4749 return None
GlennRC20fc6522015-12-23 23:26:57 -08004750 except TypeError:
4751 main.log.exception( self.name + ": Object not as expected" )
4752 return main.FALSE
4753 except pexpect.EOF:
4754 main.log.error( self.name + ": EOF exception found" )
4755 main.log.error( self.name + ": " + self.handle.before )
4756 main.cleanup()
4757 main.exit()
4758 except Exception:
4759 main.log.exception( self.name + ": Uncaught exception!" )
4760 main.cleanup()
4761 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004762
Jon Hallc6793552016-01-19 14:18:37 -08004763 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004764 '''
4765 Description:
4766 Bring link down or up in the null-provider.
4767 params:
4768 begin - (string) One end of a device or switch.
4769 end - (string) the other end of the device or switch
4770 returns:
4771 main.TRUE if no exceptions were thrown and no Errors are
4772 present in the resoponse. Otherwise, returns main.FALSE
4773 '''
4774 try:
Jon Hallc6793552016-01-19 14:18:37 -08004775 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004776 response = self.sendline( cmd, showResponse=True )
Jon Halla495f562016-05-16 18:03:26 -07004777 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004778 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004779 if "Error" in response or "Failure" in response:
4780 main.log.error( response )
4781 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004782 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004783 except AssertionError:
4784 main.log.exception( "" )
4785 return None
GlennRCed771242016-01-13 17:02:47 -08004786 except TypeError:
4787 main.log.exception( self.name + ": Object not as expected" )
4788 return main.FALSE
4789 except pexpect.EOF:
4790 main.log.error( self.name + ": EOF exception found" )
4791 main.log.error( self.name + ": " + self.handle.before )
4792 main.cleanup()
4793 main.exit()
4794 except Exception:
4795 main.log.exception( self.name + ": Uncaught exception!" )
4796 main.cleanup()
4797 main.exit()
4798