blob: 123535301671c9a345df98bdd0164eea79d734f7 [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 Songsterff553672016-05-12 17:06:23 -07001151 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
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
Jeremy Songsterff553672016-05-12 17:06:23 -07001158 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001159 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001160 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001161 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001162 Returns:
1163 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlabe6745342014-10-17 14:29:13 -04001165 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001166 cmdStr = "add-host-intent "
1167 if vlanId:
1168 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001169 if setVlan:
1170 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001171 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001173 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001174 if re.search( "Error", handle ):
1175 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001176 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001177 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001178 else:
1179 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001180 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1181 match = re.search('id=0x([\da-f]+),', handle)
1182 if match:
1183 return match.group()[3:-1]
1184 else:
1185 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001186 main.log.debug( "Response from ONOS was: " +
1187 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 return None
Jon Hallc6793552016-01-19 14:18:37 -08001189 except AssertionError:
1190 main.log.exception( "" )
1191 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001192 except TypeError:
1193 main.log.exception( self.name + ": Object not as expected" )
1194 return None
andrewonlabe6745342014-10-17 14:29:13 -04001195 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001196 main.log.error( self.name + ": EOF exception found" )
1197 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001198 main.cleanup()
1199 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001200 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001201 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001202 main.cleanup()
1203 main.exit()
1204
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001206 """
andrewonlab7b31d232014-10-24 13:31:47 -04001207 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 * ingressDevice: device id of ingress device
1209 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001210 Optional:
1211 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001212 Description:
1213 Adds an optical intent by specifying an ingress and egress device
1214 Returns:
1215 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001216 """
andrewonlab7b31d232014-10-24 13:31:47 -04001217 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1219 " " + str( egressDevice )
1220 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001221 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001223 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001224 main.log.error( "Error in adding Optical intent" )
1225 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001226 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 main.log.info( "Optical intent installed between " +
1228 str( ingressDevice ) + " and " +
1229 str( egressDevice ) )
1230 match = re.search('id=0x([\da-f]+),', handle)
1231 if match:
1232 return match.group()[3:-1]
1233 else:
1234 main.log.error( "Error, intent ID not found" )
1235 return None
Jon Hallc6793552016-01-19 14:18:37 -08001236 except AssertionError:
1237 main.log.exception( "" )
1238 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001239 except TypeError:
1240 main.log.exception( self.name + ": Object not as expected" )
1241 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001243 main.log.error( self.name + ": EOF exception found" )
1244 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001245 main.cleanup()
1246 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001247 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001248 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001249 main.cleanup()
1250 main.exit()
1251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 ingressDevice,
1255 egressDevice,
1256 portIngress="",
1257 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 ethType="",
1259 ethSrc="",
1260 ethDst="",
1261 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 ipProto="",
1264 ipSrc="",
1265 ipDst="",
1266 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001267 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001268 vlanId="",
1269 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001270 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001271 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 * ingressDevice: device id of ingress device
1273 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001274 Optional:
1275 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001276 * ethSrc: specify ethSrc ( i.e. src mac addr )
1277 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001278 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001280 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001281 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001282 * ipSrc: specify ip source address
1283 * ipDst: specify ip destination address
1284 * tcpSrc: specify tcp source port
1285 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001286 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001287 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001288 Description:
kelvin8ec71442015-01-15 16:57:00 -08001289 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001290 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 Returns:
1292 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001293
Jon Halle3f39ff2015-01-13 11:50:53 -08001294 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001295 options developers provide for point-to-point
1296 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001297 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001298 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001299 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001300
Jeremy Songsterff553672016-05-12 17:06:23 -07001301 if ethType:
1302 cmd += " --ethType " + str( ethType )
1303 if ethSrc:
1304 cmd += " --ethSrc " + str( ethSrc )
1305 if ethDst:
1306 cmd += " --ethDst " + str( ethDst )
1307 if bandwidth:
1308 cmd += " --bandwidth " + str( bandwidth )
1309 if lambdaAlloc:
1310 cmd += " --lambda "
1311 if ipProto:
1312 cmd += " --ipProto " + str( ipProto )
1313 if ipSrc:
1314 cmd += " --ipSrc " + str( ipSrc )
1315 if ipDst:
1316 cmd += " --ipDst " + str( ipDst )
1317 if tcpSrc:
1318 cmd += " --tcpSrc " + str( tcpSrc )
1319 if tcpDst:
1320 cmd += " --tcpDst " + str( tcpDst )
1321 if vlanId:
1322 cmd += " -v " + str( vlanId )
1323 if setVlan:
1324 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001325
kelvin8ec71442015-01-15 16:57:00 -08001326 # Check whether the user appended the port
1327 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 if "/" in ingressDevice:
1329 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001330 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001331 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001332 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001333 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 # Would it make sense to throw an exception and exit
1335 # the test?
1336 return None
andrewonlab36af3822014-11-18 17:48:18 -05001337
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 str( ingressDevice ) + "/" +\
1340 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001341
kelvin-onlabd3b64892015-01-20 13:26:24 -08001342 if "/" in egressDevice:
1343 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001344 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 main.log.error( "You must specify the egress port" )
1347 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001348
kelvin8ec71442015-01-15 16:57:00 -08001349 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001350 str( egressDevice ) + "/" +\
1351 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001352
kelvin-onlab898a6c62015-01-16 14:13:53 -08001353 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001354 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001355 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001356 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001357 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001359 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001360 # TODO: print out all the options in this message?
1361 main.log.info( "Point-to-point intent installed between " +
1362 str( ingressDevice ) + " and " +
1363 str( egressDevice ) )
1364 match = re.search('id=0x([\da-f]+),', handle)
1365 if match:
1366 return match.group()[3:-1]
1367 else:
1368 main.log.error( "Error, intent ID not found" )
1369 return None
Jon Hallc6793552016-01-19 14:18:37 -08001370 except AssertionError:
1371 main.log.exception( "" )
1372 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001373 except TypeError:
1374 main.log.exception( self.name + ": Object not as expected" )
1375 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001376 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001377 main.log.error( self.name + ": EOF exception found" )
1378 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001379 main.cleanup()
1380 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001381 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001382 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001383 main.cleanup()
1384 main.exit()
1385
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001387 self,
shahshreyac2f97072015-03-19 17:04:29 -07001388 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001390 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001392 ethType="",
1393 ethSrc="",
1394 ethDst="",
1395 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001397 ipProto="",
1398 ipSrc="",
1399 ipDst="",
1400 tcpSrc="",
1401 tcpDst="",
1402 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001403 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001404 vlanId="",
1405 setVlan="" ):
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
Jeremy Songsterff553672016-05-12 17:06:23 -07001431 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001432 Description:
kelvin8ec71442015-01-15 16:57:00 -08001433 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001434 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001435 Returns:
1436 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001437
Jon Halle3f39ff2015-01-13 11:50:53 -08001438 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001439 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001440 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001441 """
shahshreyad0c80432014-12-04 16:56:05 -08001442 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001443 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001444
Jeremy Songsterff553672016-05-12 17:06:23 -07001445 if ethType:
1446 cmd += " --ethType " + str( ethType )
1447 if ethSrc:
1448 cmd += " --ethSrc " + str( ethSrc )
1449 if ethDst:
1450 cmd += " --ethDst " + str( ethDst )
1451 if bandwidth:
1452 cmd += " --bandwidth " + str( bandwidth )
1453 if lambdaAlloc:
1454 cmd += " --lambda "
1455 if ipProto:
1456 cmd += " --ipProto " + str( ipProto )
1457 if ipSrc:
1458 cmd += " --ipSrc " + str( ipSrc )
1459 if ipDst:
1460 cmd += " --ipDst " + str( ipDst )
1461 if tcpSrc:
1462 cmd += " --tcpSrc " + str( tcpSrc )
1463 if tcpDst:
1464 cmd += " --tcpDst " + str( tcpDst )
1465 if setEthSrc:
1466 cmd += " --setEthSrc " + str( setEthSrc )
1467 if setEthDst:
1468 cmd += " --setEthDst " + str( setEthDst )
1469 if vlanId:
1470 cmd += " -v " + str( vlanId )
1471 if setVlan:
1472 cmd += " --setVlan " + str( setVlan )
shahshreyad0c80432014-12-04 16:56:05 -08001473
kelvin8ec71442015-01-15 16:57:00 -08001474 # Check whether the user appended the port
1475 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001476
1477 if portIngressList is None:
1478 for ingressDevice in ingressDeviceList:
1479 if "/" in ingressDevice:
1480 cmd += " " + str( ingressDevice )
1481 else:
1482 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001483 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001484 # TODO: perhaps more meaningful return
1485 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001486 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001487 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001488 for ingressDevice, portIngress in zip( ingressDeviceList,
1489 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001490 cmd += " " + \
1491 str( ingressDevice ) + "/" +\
1492 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001493 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001494 main.log.error( "Device list and port list does not " +
1495 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001496 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 if "/" in egressDevice:
1498 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001499 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001501 main.log.error( "You must specify " +
1502 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001503 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001504
kelvin8ec71442015-01-15 16:57:00 -08001505 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 str( egressDevice ) + "/" +\
1507 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001508 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001509 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001510 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001511 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001512 main.log.error( "Error in adding multipoint-to-singlepoint " +
1513 "intent" )
1514 return None
shahshreyad0c80432014-12-04 16:56:05 -08001515 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001516 match = re.search('id=0x([\da-f]+),', handle)
1517 if match:
1518 return match.group()[3:-1]
1519 else:
1520 main.log.error( "Error, intent ID not found" )
1521 return None
Jon Hallc6793552016-01-19 14:18:37 -08001522 except AssertionError:
1523 main.log.exception( "" )
1524 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001525 except TypeError:
1526 main.log.exception( self.name + ": Object not as expected" )
1527 return None
1528 except pexpect.EOF:
1529 main.log.error( self.name + ": EOF exception found" )
1530 main.log.error( self.name + ": " + self.handle.before )
1531 main.cleanup()
1532 main.exit()
1533 except Exception:
1534 main.log.exception( self.name + ": Uncaught exception!" )
1535 main.cleanup()
1536 main.exit()
1537
1538 def addSinglepointToMultipointIntent(
1539 self,
1540 ingressDevice,
1541 egressDeviceList,
1542 portIngress="",
1543 portEgressList=None,
1544 ethType="",
1545 ethSrc="",
1546 ethDst="",
1547 bandwidth="",
1548 lambdaAlloc=False,
1549 ipProto="",
1550 ipSrc="",
1551 ipDst="",
1552 tcpSrc="",
1553 tcpDst="",
1554 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001555 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001556 vlanId="",
1557 setVlan="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001558 """
1559 Note:
1560 This function assumes the format of all egress devices
1561 is same. That is, all egress devices include port numbers
1562 with a "/" or all egress devices could specify device
1563 ids and port numbers seperately.
1564 Required:
1565 * EgressDeviceList: List of device ids of egress device
1566 ( Atleast 2 eress devices required in the list )
1567 * ingressDevice: device id of ingress device
1568 Optional:
1569 * ethType: specify ethType
1570 * ethSrc: specify ethSrc ( i.e. src mac addr )
1571 * ethDst: specify ethDst ( i.e. dst mac addr )
1572 * bandwidth: specify bandwidth capacity of link
1573 * lambdaAlloc: if True, intent will allocate lambda
1574 for the specified intent
1575 * ipProto: specify ip protocol
1576 * ipSrc: specify ip source address
1577 * ipDst: specify ip destination address
1578 * tcpSrc: specify tcp source port
1579 * tcpDst: specify tcp destination port
1580 * setEthSrc: action to Rewrite Source MAC Address
1581 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001582 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001583 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001584 Description:
1585 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1586 specifying device id's and optional fields
1587 Returns:
1588 A string of the intent id or None on error
1589
1590 NOTE: This function may change depending on the
1591 options developers provide for singlepoint-to-multipoint
1592 intent via cli
1593 """
1594 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001595 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001596
Jeremy Songsterff553672016-05-12 17:06:23 -07001597 if ethType:
1598 cmd += " --ethType " + str( ethType )
1599 if ethSrc:
1600 cmd += " --ethSrc " + str( ethSrc )
1601 if ethDst:
1602 cmd += " --ethDst " + str( ethDst )
1603 if bandwidth:
1604 cmd += " --bandwidth " + str( bandwidth )
1605 if lambdaAlloc:
1606 cmd += " --lambda "
1607 if ipProto:
1608 cmd += " --ipProto " + str( ipProto )
1609 if ipSrc:
1610 cmd += " --ipSrc " + str( ipSrc )
1611 if ipDst:
1612 cmd += " --ipDst " + str( ipDst )
1613 if tcpSrc:
1614 cmd += " --tcpSrc " + str( tcpSrc )
1615 if tcpDst:
1616 cmd += " --tcpDst " + str( tcpDst )
1617 if setEthSrc:
1618 cmd += " --setEthSrc " + str( setEthSrc )
1619 if setEthDst:
1620 cmd += " --setEthDst " + str( setEthDst )
1621 if vlanId:
1622 cmd += " -v " + str( vlanId )
1623 if setVlan:
1624 cmd += " --setVlan " + str( setVlan )
kelvin-onlabb9408212015-04-01 13:34:04 -07001625
1626 # Check whether the user appended the port
1627 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001628
kelvin-onlabb9408212015-04-01 13:34:04 -07001629 if "/" in ingressDevice:
1630 cmd += " " + str( ingressDevice )
1631 else:
1632 if not portIngress:
1633 main.log.error( "You must specify " +
1634 "the Ingress port" )
1635 return main.FALSE
1636
1637 cmd += " " +\
1638 str( ingressDevice ) + "/" +\
1639 str( portIngress )
1640
1641 if portEgressList is None:
1642 for egressDevice in egressDeviceList:
1643 if "/" in egressDevice:
1644 cmd += " " + str( egressDevice )
1645 else:
1646 main.log.error( "You must specify " +
1647 "the egress port" )
1648 # TODO: perhaps more meaningful return
1649 return main.FALSE
1650 else:
1651 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001652 for egressDevice, portEgress in zip( egressDeviceList,
1653 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 cmd += " " + \
1655 str( egressDevice ) + "/" +\
1656 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001657 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001658 main.log.error( "Device list and port list does not " +
1659 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001660 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001661 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001662 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001663 # If error, return error message
1664 if re.search( "Error", handle ):
1665 main.log.error( "Error in adding singlepoint-to-multipoint " +
1666 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001667 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001668 else:
1669 match = re.search('id=0x([\da-f]+),', handle)
1670 if match:
1671 return match.group()[3:-1]
1672 else:
1673 main.log.error( "Error, intent ID not found" )
1674 return None
Jon Hallc6793552016-01-19 14:18:37 -08001675 except AssertionError:
1676 main.log.exception( "" )
1677 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001678 except TypeError:
1679 main.log.exception( self.name + ": Object not as expected" )
1680 return None
shahshreyad0c80432014-12-04 16:56:05 -08001681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001682 main.log.error( self.name + ": EOF exception found" )
1683 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001684 main.cleanup()
1685 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001686 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001687 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001688 main.cleanup()
1689 main.exit()
1690
Hari Krishna9e232602015-04-13 17:29:08 -07001691 def addMplsIntent(
1692 self,
1693 ingressDevice,
1694 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001695 ingressPort="",
1696 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001697 ethType="",
1698 ethSrc="",
1699 ethDst="",
1700 bandwidth="",
1701 lambdaAlloc=False,
1702 ipProto="",
1703 ipSrc="",
1704 ipDst="",
1705 tcpSrc="",
1706 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001707 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001708 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001709 priority=""):
1710 """
1711 Required:
1712 * ingressDevice: device id of ingress device
1713 * egressDevice: device id of egress device
1714 Optional:
1715 * ethType: specify ethType
1716 * ethSrc: specify ethSrc ( i.e. src mac addr )
1717 * ethDst: specify ethDst ( i.e. dst mac addr )
1718 * bandwidth: specify bandwidth capacity of link
1719 * lambdaAlloc: if True, intent will allocate lambda
1720 for the specified intent
1721 * ipProto: specify ip protocol
1722 * ipSrc: specify ip source address
1723 * ipDst: specify ip destination address
1724 * tcpSrc: specify tcp source port
1725 * tcpDst: specify tcp destination port
1726 * ingressLabel: Ingress MPLS label
1727 * egressLabel: Egress MPLS label
1728 Description:
1729 Adds MPLS intent by
1730 specifying device id's and optional fields
1731 Returns:
1732 A string of the intent id or None on error
1733
1734 NOTE: This function may change depending on the
1735 options developers provide for MPLS
1736 intent via cli
1737 """
1738 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001739 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001740
Jeremy Songsterff553672016-05-12 17:06:23 -07001741 if ethType:
1742 cmd += " --ethType " + str( ethType )
1743 if ethSrc:
1744 cmd += " --ethSrc " + str( ethSrc )
1745 if ethDst:
1746 cmd += " --ethDst " + str( ethDst )
1747 if bandwidth:
1748 cmd += " --bandwidth " + str( bandwidth )
1749 if lambdaAlloc:
1750 cmd += " --lambda "
1751 if ipProto:
1752 cmd += " --ipProto " + str( ipProto )
1753 if ipSrc:
1754 cmd += " --ipSrc " + str( ipSrc )
1755 if ipDst:
1756 cmd += " --ipDst " + str( ipDst )
1757 if tcpSrc:
1758 cmd += " --tcpSrc " + str( tcpSrc )
1759 if tcpDst:
1760 cmd += " --tcpDst " + str( tcpDst )
1761 if ingressLabel:
1762 cmd += " --ingressLabel " + str( ingressLabel )
1763 if egressLabel:
1764 cmd += " --egressLabel " + str( egressLabel )
1765 if priority:
1766 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001767
1768 # Check whether the user appended the port
1769 # or provided it as an input
1770 if "/" in ingressDevice:
1771 cmd += " " + str( ingressDevice )
1772 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001773 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001774 main.log.error( "You must specify the ingress port" )
1775 return None
1776
1777 cmd += " " + \
1778 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001779 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001780
1781 if "/" in egressDevice:
1782 cmd += " " + str( egressDevice )
1783 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001784 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001785 main.log.error( "You must specify the egress port" )
1786 return None
1787
1788 cmd += " " +\
1789 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001790 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001791
1792 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001793 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001794 # If error, return error message
1795 if re.search( "Error", handle ):
1796 main.log.error( "Error in adding mpls intent" )
1797 return None
1798 else:
1799 # TODO: print out all the options in this message?
1800 main.log.info( "MPLS intent installed between " +
1801 str( ingressDevice ) + " and " +
1802 str( egressDevice ) )
1803 match = re.search('id=0x([\da-f]+),', handle)
1804 if match:
1805 return match.group()[3:-1]
1806 else:
1807 main.log.error( "Error, intent ID not found" )
1808 return None
Jon Hallc6793552016-01-19 14:18:37 -08001809 except AssertionError:
1810 main.log.exception( "" )
1811 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001812 except TypeError:
1813 main.log.exception( self.name + ": Object not as expected" )
1814 return None
1815 except pexpect.EOF:
1816 main.log.error( self.name + ": EOF exception found" )
1817 main.log.error( self.name + ": " + self.handle.before )
1818 main.cleanup()
1819 main.exit()
1820 except Exception:
1821 main.log.exception( self.name + ": Uncaught exception!" )
1822 main.cleanup()
1823 main.exit()
1824
Jon Hallefbd9792015-03-05 16:11:36 -08001825 def removeIntent( self, intentId, app='org.onosproject.cli',
1826 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001827 """
shahshreya1c818fc2015-02-26 13:44:08 -08001828 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001829 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001830 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001831 -p or --purge: Purge the intent from the store after removal
1832
Jon Halle3f39ff2015-01-13 11:50:53 -08001833 Returns:
1834 main.False on error and
1835 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001836 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001837 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001838 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001839 if purge:
1840 cmdStr += " -p"
1841 if sync:
1842 cmdStr += " -s"
1843
1844 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001846 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001847 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001848 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001849 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001850 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001851 # TODO: Should this be main.TRUE
1852 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001853 except AssertionError:
1854 main.log.exception( "" )
1855 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001856 except TypeError:
1857 main.log.exception( self.name + ": Object not as expected" )
1858 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001859 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001860 main.log.error( self.name + ": EOF exception found" )
1861 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001862 main.cleanup()
1863 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001864 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001865 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001866 main.cleanup()
1867 main.exit()
1868
Jeremy42df2e72016-02-23 16:37:46 -08001869 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1870 """
1871 Description:
1872 Remove all the intents
1873 Optional args:-
1874 -s or --sync: Waits for the removal before returning
1875 -p or --purge: Purge the intent from the store after removal
1876 Returns:
1877 Returns main.TRUE if all intents are removed, otherwise returns
1878 main.FALSE; Returns None for exception
1879 """
1880 try:
1881 cmdStr = "remove-intent"
1882 if purge:
1883 cmdStr += " -p"
1884 if sync:
1885 cmdStr += " -s"
1886
1887 cmdStr += " " + app
1888 handle = self.sendline( cmdStr )
1889 assert "Command not found:" not in handle, handle
1890 if re.search( "Error", handle ):
1891 main.log.error( "Error in removing intent" )
1892 return main.FALSE
1893 else:
1894 return main.TRUE
1895 except AssertionError:
1896 main.log.exception( "" )
1897 return None
1898 except TypeError:
1899 main.log.exception( self.name + ": Object not as expected" )
1900 return None
1901 except pexpect.EOF:
1902 main.log.error( self.name + ": EOF exception found" )
1903 main.log.error( self.name + ": " + self.handle.before )
1904 main.cleanup()
1905 main.exit()
1906 except Exception:
1907 main.log.exception( self.name + ": Uncaught exception!" )
1908 main.cleanup()
1909 main.exit()
1910
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001911 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001912 """
1913 Purges all WITHDRAWN Intents
1914 """
1915 try:
1916 cmdStr = "purge-intents"
1917 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001918 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001919 if re.search( "Error", handle ):
1920 main.log.error( "Error in purging intents" )
1921 return main.FALSE
1922 else:
1923 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001924 except AssertionError:
1925 main.log.exception( "" )
1926 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001927 except TypeError:
1928 main.log.exception( self.name + ": Object not as expected" )
1929 return None
1930 except pexpect.EOF:
1931 main.log.error( self.name + ": EOF exception found" )
1932 main.log.error( self.name + ": " + self.handle.before )
1933 main.cleanup()
1934 main.exit()
1935 except Exception:
1936 main.log.exception( self.name + ": Uncaught exception!" )
1937 main.cleanup()
1938 main.exit()
1939
kelvin-onlabd3b64892015-01-20 13:26:24 -08001940 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001941 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001942 NOTE: This method should be used after installing application:
1943 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001944 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001945 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001946 Description:
1947 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001948 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001949 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001950 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001951 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001952 cmdStr += " -j"
1953 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001954 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001955 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001956 except AssertionError:
1957 main.log.exception( "" )
1958 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001959 except TypeError:
1960 main.log.exception( self.name + ": Object not as expected" )
1961 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001963 main.log.error( self.name + ": EOF exception found" )
1964 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001965 main.cleanup()
1966 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001968 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001969 main.cleanup()
1970 main.exit()
1971
pingping-lin54b03372015-08-13 14:43:10 -07001972 def ipv4RouteNumber( self ):
1973 """
1974 NOTE: This method should be used after installing application:
1975 onos-app-sdnip
1976 Description:
1977 Obtain the total IPv4 routes number in the system
1978 """
1979 try:
1980 cmdStr = "routes -s -j"
1981 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001982 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001983 jsonResult = json.loads( handle )
1984 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001985 except AssertionError:
1986 main.log.exception( "" )
1987 return None
1988 except ( TypeError, ValueError ):
1989 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001990 return None
1991 except pexpect.EOF:
1992 main.log.error( self.name + ": EOF exception found" )
1993 main.log.error( self.name + ": " + self.handle.before )
1994 main.cleanup()
1995 main.exit()
1996 except Exception:
1997 main.log.exception( self.name + ": Uncaught exception!" )
1998 main.cleanup()
1999 main.exit()
2000
pingping-lin8244a3b2015-09-16 13:36:56 -07002001 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002002 """
andrewonlabe6745342014-10-17 14:29:13 -04002003 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002004 Obtain intents from the ONOS cli.
2005 Optional:
2006 * jsonFormat: Enable output formatting in json, default to True
2007 * summary: Whether only output the intent summary, defaults to False
2008 * type: Only output a certain type of intent. This options is valid
2009 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002010 """
andrewonlabe6745342014-10-17 14:29:13 -04002011 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002012 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002013 if summary:
2014 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002015 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002016 cmdStr += " -j"
2017 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002018 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002019 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002020 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002021 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002022 else:
Jon Hallff566d52016-01-15 14:45:36 -08002023 intentType = ""
2024 # IF we want the summary of a specific intent type
2025 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002026 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002027 if intentType in jsonResult.keys():
2028 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002029 else:
Jon Hallff566d52016-01-15 14:45:36 -08002030 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002031 return handle
2032 else:
2033 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002034 except AssertionError:
2035 main.log.exception( "" )
2036 return None
2037 except ( TypeError, ValueError ):
2038 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002039 return None
2040 except pexpect.EOF:
2041 main.log.error( self.name + ": EOF exception found" )
2042 main.log.error( self.name + ": " + self.handle.before )
2043 main.cleanup()
2044 main.exit()
2045 except Exception:
2046 main.log.exception( self.name + ": Uncaught exception!" )
2047 main.cleanup()
2048 main.exit()
2049
kelvin-onlab54400a92015-02-26 18:05:51 -08002050 def getIntentState(self, intentsId, intentsJson=None):
2051 """
You Wangfdcbfc42016-05-16 12:16:53 -07002052 Description:
2053 Gets intent state. Accepts a single intent ID (string type) or a
2054 list of intent IDs.
2055 Parameters:
2056 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002057 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002058 Returns:
2059 Returns the state (string type) of the ID if a single intent ID is
2060 accepted.
2061 Returns a list of dictionaries if a list of intent IDs is accepted,
2062 and each dictionary maps 'id' to the Intent ID and 'state' to
2063 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002064 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002065 try:
2066 state = "State is Undefined"
2067 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002068 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002069 else:
Jon Hallc6793552016-01-19 14:18:37 -08002070 rawJson = intentsJson
2071 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002072 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002073 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002074 if intentsId == intent[ 'id' ]:
2075 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002076 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002077 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2078 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002079 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002080 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002081 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002082 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002083 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002084 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002085 if intentsId[ i ] == intents[ 'id' ]:
2086 stateDict[ 'state' ] = intents[ 'state' ]
2087 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002088 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 break
Jon Hallefbd9792015-03-05 16:11:36 -08002090 if len( intentsId ) != len( dictList ):
2091 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002092 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002093 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002094 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002095 return None
Jon Hallc6793552016-01-19 14:18:37 -08002096 except ( TypeError, ValueError ):
2097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002098 return None
2099 except pexpect.EOF:
2100 main.log.error( self.name + ": EOF exception found" )
2101 main.log.error( self.name + ": " + self.handle.before )
2102 main.cleanup()
2103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002104 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002105 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002106 main.cleanup()
2107 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002108
kelvin-onlabf512e942015-06-08 19:42:59 -07002109 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002110 """
2111 Description:
2112 Check intents state
2113 Required:
2114 intentsId - List of intents ID to be checked
2115 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002116 expectedState - Check the expected state(s) of each intents
2117 state in the list.
2118 *NOTE: You can pass in a list of expected state,
2119 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002120 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002121 Returns main.TRUE only if all intent are the same as expected states
2122 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 """
2124 try:
2125 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002126 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002127 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002128 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002129 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002130 "getting intents state" )
2131 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002132
2133 if isinstance( expectedState, types.StringType ):
2134 for intents in intentsDict:
2135 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002136 main.log.debug( self.name + " : Intent ID - " +
2137 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002138 " actual state = " +
2139 intents.get( 'state' )
2140 + " does not equal expected state = "
2141 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002142 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002143
2144 elif isinstance( expectedState, types.ListType ):
2145 for intents in intentsDict:
2146 if not any( state == intents.get( 'state' ) for state in
2147 expectedState ):
2148 main.log.debug( self.name + " : Intent ID - " +
2149 intents.get( 'id' ) +
2150 " actual state = " +
2151 intents.get( 'state' ) +
2152 " does not equal expected states = "
2153 + str( expectedState ) )
2154 returnValue = main.FALSE
2155
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002156 if returnValue == main.TRUE:
2157 main.log.info( self.name + ": All " +
2158 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002159 " intents are in " + str( expectedState ) +
2160 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002161 return returnValue
2162 except TypeError:
2163 main.log.exception( self.name + ": Object not as expected" )
2164 return None
2165 except pexpect.EOF:
2166 main.log.error( self.name + ": EOF exception found" )
2167 main.log.error( self.name + ": " + self.handle.before )
2168 main.cleanup()
2169 main.exit()
2170 except Exception:
2171 main.log.exception( self.name + ": Uncaught exception!" )
2172 main.cleanup()
2173 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002174
You Wang66518af2016-05-16 15:32:59 -07002175 def compareIntent( self, intentDict ):
2176 """
2177 Description:
2178 Compare the intent ids and states provided in the argument with all intents in ONOS
2179 Return:
2180 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2181 Arguments:
2182 intentDict: a dictionary which maps intent ids to intent states
2183 """
2184 try:
2185 intentsRaw = self.intents()
2186 intentsJson = json.loads( intentsRaw )
2187 intentDictONOS = {}
2188 for intent in intentsJson:
2189 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2190 if len( intentDict ) != len( intentDictONOS ):
2191 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2192 str( len( intentDict ) ) + " expected and " +
2193 str( len( intentDictONOS ) ) + " actual" )
2194 return main.FALSE
2195 returnValue = main.TRUE
2196 for intentID in intentDict.keys():
2197 if not intentID in intentDictONOS.keys():
2198 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2199 returnValue = main.FALSE
2200 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2201 main.log.debug( self.name + ": intent ID - " + intentID +
2202 " expected state is " + intentDict[ intentID ] +
2203 " but actual state is " + intentDictONOS[ intentID ] )
2204 returnValue = main.FALSE
2205 if returnValue == main.TRUE:
2206 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2207 return returnValue
2208 except ( TypeError, ValueError ):
2209 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
2210 return None
2211 except pexpect.EOF:
2212 main.log.error( self.name + ": EOF exception found" )
2213 main.log.error( self.name + ": " + self.handle.before )
2214 main.cleanup()
2215 main.exit()
2216 except Exception:
2217 main.log.exception( self.name + ": Uncaught exception!" )
2218 main.cleanup()
2219 main.exit()
2220
GlennRCed771242016-01-13 17:02:47 -08002221 def checkIntentSummary( self, timeout=60 ):
2222 """
2223 Description:
2224 Check the number of installed intents.
2225 Optional:
2226 timeout - the timeout for pexcept
2227 Return:
2228 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2229 , otherwise, returns main.FALSE.
2230 """
2231
2232 try:
2233 cmd = "intents -s -j"
2234
2235 # Check response if something wrong
2236 response = self.sendline( cmd, timeout=timeout )
2237 if response == None:
2238 return main.False
2239 response = json.loads( response )
2240
2241 # get total and installed number, see if they are match
2242 allState = response.get( 'all' )
2243 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002244 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002245 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002246 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002247 return main.FALSE
2248
Jon Hallc6793552016-01-19 14:18:37 -08002249 except ( TypeError, ValueError ):
2250 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002251 return None
2252 except pexpect.EOF:
2253 main.log.error( self.name + ": EOF exception found" )
2254 main.log.error( self.name + ": " + self.handle.before )
2255 main.cleanup()
2256 main.exit()
2257 except Exception:
2258 main.log.exception( self.name + ": Uncaught exception!" )
2259 main.cleanup()
2260 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002261 except pexpect.TIMEOUT:
2262 main.log.error( self.name + ": ONOS timeout" )
2263 return None
GlennRCed771242016-01-13 17:02:47 -08002264
YPZhangebf9eb52016-05-12 15:20:24 -07002265 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002266 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002267 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002268 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002269 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002270 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002271 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002272 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002273 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002274 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002275 cmdStr += " -j "
2276 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002277 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002278 assert "Command not found:" not in handle, handle
2279 if re.search( "Error:", handle ):
2280 main.log.error( self.name + ": flows() response: " +
2281 str( handle ) )
2282 return handle
2283 except AssertionError:
2284 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002285 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002286 except TypeError:
2287 main.log.exception( self.name + ": Object not as expected" )
2288 return None
Jon Hallc6793552016-01-19 14:18:37 -08002289 except pexpect.TIMEOUT:
2290 main.log.error( self.name + ": ONOS timeout" )
2291 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002292 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002293 main.log.error( self.name + ": EOF exception found" )
2294 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002295 main.cleanup()
2296 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002297 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002298 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002299 main.cleanup()
2300 main.exit()
2301
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002302 def checkFlowCount(self, min=0, timeout=60 ):
2303 count = int(self.getTotalFlowsNum( timeout=timeout ))
2304 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002305
YPZhangebf9eb52016-05-12 15:20:24 -07002306 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002307 """
2308 Description:
GlennRCed771242016-01-13 17:02:47 -08002309 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002310 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2311 if the count of those states is 0, which means all current flows
2312 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002313 Optional:
GlennRCed771242016-01-13 17:02:47 -08002314 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002315 Return:
2316 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002317 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002318 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002319 """
2320 try:
GlennRCed771242016-01-13 17:02:47 -08002321 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2322 checkedStates = []
2323 statesCount = [0, 0, 0, 0]
2324 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002325 rawFlows = self.flows( state=s, timeout = timeout )
2326 checkedStates.append( json.loads( rawFlows ) )
2327 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002328 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002329 try:
2330 statesCount[i] += int( c.get( "flowCount" ) )
2331 except TypeError:
2332 main.log.exception( "Json object not as expected" )
2333 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002334
GlennRCed771242016-01-13 17:02:47 -08002335 # We want to count PENDING_ADD if isPENDING is true
2336 if isPENDING:
2337 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2338 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002339 else:
GlennRCed771242016-01-13 17:02:47 -08002340 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2341 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002342 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002343 except ( TypeError, ValueError ):
2344 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002345 return None
2346 except pexpect.EOF:
2347 main.log.error( self.name + ": EOF exception found" )
2348 main.log.error( self.name + ": " + self.handle.before )
2349 main.cleanup()
2350 main.exit()
2351 except Exception:
2352 main.log.exception( self.name + ": Uncaught exception!" )
2353 main.cleanup()
2354 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002355 except pexpect.TIMEOUT:
2356 main.log.error( self.name + ": ONOS timeout" )
2357 return None
2358
kelvin-onlab4df89f22015-04-13 18:10:23 -07002359
GlennRCed771242016-01-13 17:02:47 -08002360 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002361 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002362 """
andrewonlab87852b02014-11-19 18:44:19 -05002363 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002364 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002365 a specific point-to-point intent definition
2366 Required:
GlennRCed771242016-01-13 17:02:47 -08002367 * ingress: specify source dpid
2368 * egress: specify destination dpid
2369 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002370 Optional:
GlennRCed771242016-01-13 17:02:47 -08002371 * offset: the keyOffset is where the next batch of intents
2372 will be installed
2373 Returns: If failed to push test intents, it will returen None,
2374 if successful, return true.
2375 Timeout expection will return None,
2376 TypeError will return false
2377 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002378 """
andrewonlab87852b02014-11-19 18:44:19 -05002379 try:
GlennRCed771242016-01-13 17:02:47 -08002380 if background:
2381 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002382 else:
GlennRCed771242016-01-13 17:02:47 -08002383 back = ""
2384 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002385 ingress,
2386 egress,
2387 batchSize,
2388 offset,
2389 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002390 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002391 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002392 main.log.info( response )
2393 if response == None:
2394 return None
2395
2396 # TODO: We should handle if there is failure in installation
2397 return main.TRUE
2398
Jon Hallc6793552016-01-19 14:18:37 -08002399 except AssertionError:
2400 main.log.exception( "" )
2401 return None
GlennRCed771242016-01-13 17:02:47 -08002402 except pexpect.TIMEOUT:
2403 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002404 return None
andrewonlab87852b02014-11-19 18:44:19 -05002405 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002406 main.log.error( self.name + ": EOF exception found" )
2407 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002408 main.cleanup()
2409 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002410 except TypeError:
2411 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002412 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002413 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002414 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002415 main.cleanup()
2416 main.exit()
2417
YPZhangebf9eb52016-05-12 15:20:24 -07002418 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002419 """
2420 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002421 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002422 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002423 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002424 """
YPZhange3109a72016-02-02 11:25:37 -08002425
YPZhangb5d3f832016-01-23 22:54:26 -08002426 try:
YPZhange3109a72016-02-02 11:25:37 -08002427 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002428 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002429 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002430
2431 if totalFlows == None:
2432 # if timeout, we will get total number of all flows, and subtract other states
2433 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2434 checkedStates = []
2435 totalFlows = 0
2436 statesCount = [0, 0, 0, 0]
2437
2438 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002439 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002440 totalFlows = int( response.get("flows") )
2441
2442 for s in states:
2443 rawFlows = self.flows( state=s, timeout = timeout )
2444 if rawFlows == None:
2445 # if timeout, return the total flows number from summary command
2446 return totalFlows
2447 checkedStates.append( json.loads( rawFlows ) )
2448
2449 # Calculate ADDED flows number, equal total subtracts others
2450 for i in range( len( states ) ):
2451 for c in checkedStates[i]:
2452 try:
2453 statesCount[i] += int( c.get( "flowCount" ) )
2454 except TypeError:
2455 main.log.exception( "Json object not as expected" )
2456 totalFlows = totalFlows - int( statesCount[i] )
2457 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2458
2459 return totalFlows
2460
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002461 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002462
You Wangd3cb2ce2016-05-16 14:01:24 -07002463 except ( TypeError, ValueError ):
2464 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002465 return None
2466 except pexpect.EOF:
2467 main.log.error( self.name + ": EOF exception found" )
2468 main.log.error( self.name + ": " + self.handle.before )
2469 main.cleanup()
2470 main.exit()
2471 except Exception:
2472 main.log.exception( self.name + ": Uncaught exception!" )
2473 main.cleanup()
2474 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002475 except pexpect.TIMEOUT:
2476 main.log.error( self.name + ": ONOS timeout" )
2477 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002478
YPZhangebf9eb52016-05-12 15:20:24 -07002479 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002480 """
2481 Description:
2482 Get the total number of intents, include every states.
2483 Return:
2484 The number of intents
2485 """
2486 try:
2487 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002488 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002489 if response == None:
2490 return -1
2491 response = json.loads( response )
2492 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002493 except ( TypeError, ValueError ):
2494 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002495 return None
2496 except pexpect.EOF:
2497 main.log.error( self.name + ": EOF exception found" )
2498 main.log.error( self.name + ": " + self.handle.before )
2499 main.cleanup()
2500 main.exit()
2501 except Exception:
2502 main.log.exception( self.name + ": Uncaught exception!" )
2503 main.cleanup()
2504 main.exit()
2505
kelvin-onlabd3b64892015-01-20 13:26:24 -08002506 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002507 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002508 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002509 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002511 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002512 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002513 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002514 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002515 cmdStr += " -j"
2516 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002517 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002518 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002519 except AssertionError:
2520 main.log.exception( "" )
2521 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002522 except TypeError:
2523 main.log.exception( self.name + ": Object not as expected" )
2524 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002525 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002526 main.log.error( self.name + ": EOF exception found" )
2527 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002528 main.cleanup()
2529 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002530 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002531 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002532 main.cleanup()
2533 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002534
kelvin-onlabd3b64892015-01-20 13:26:24 -08002535 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002536 """
2537 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002538 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002539 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002540 """
andrewonlab867212a2014-10-22 20:13:38 -04002541 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002542 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002543 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002544 cmdStr += " -j"
2545 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002546 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002547 if handle:
2548 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002549 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002550 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002551 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002552 else:
2553 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002554 except AssertionError:
2555 main.log.exception( "" )
2556 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002557 except TypeError:
2558 main.log.exception( self.name + ": Object not as expected" )
2559 return None
andrewonlab867212a2014-10-22 20:13:38 -04002560 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002561 main.log.error( self.name + ": EOF exception found" )
2562 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002563 main.cleanup()
2564 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002565 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002566 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002567 main.cleanup()
2568 main.exit()
2569
kelvin8ec71442015-01-15 16:57:00 -08002570 # Wrapper functions ****************
2571 # Wrapper functions use existing driver
2572 # functions and extends their use case.
2573 # For example, we may use the output of
2574 # a normal driver function, and parse it
2575 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002576
kelvin-onlabd3b64892015-01-20 13:26:24 -08002577 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002578 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002579 Description:
2580 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002581 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002582 try:
kelvin8ec71442015-01-15 16:57:00 -08002583 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002584 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002585 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002586
kelvin8ec71442015-01-15 16:57:00 -08002587 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002588 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2589 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002590 match = re.search('id=0x([\da-f]+),', intents)
2591 if match:
2592 tmpId = match.group()[3:-1]
2593 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002594 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002595
Jon Halld4d4b372015-01-28 16:02:41 -08002596 except TypeError:
2597 main.log.exception( self.name + ": Object not as expected" )
2598 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002599 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002600 main.log.error( self.name + ": EOF exception found" )
2601 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002602 main.cleanup()
2603 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002604 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002605 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002606 main.cleanup()
2607 main.exit()
2608
Jon Hall30b82fa2015-03-04 17:15:43 -08002609 def FlowAddedCount( self, deviceId ):
2610 """
2611 Determine the number of flow rules for the given device id that are
2612 in the added state
2613 """
2614 try:
2615 cmdStr = "flows any " + str( deviceId ) + " | " +\
2616 "grep 'state=ADDED' | wc -l"
2617 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002618 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002619 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002620 except AssertionError:
2621 main.log.exception( "" )
2622 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002623 except pexpect.EOF:
2624 main.log.error( self.name + ": EOF exception found" )
2625 main.log.error( self.name + ": " + self.handle.before )
2626 main.cleanup()
2627 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002628 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002629 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002630 main.cleanup()
2631 main.exit()
2632
kelvin-onlabd3b64892015-01-20 13:26:24 -08002633 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002634 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002635 Use 'devices' function to obtain list of all devices
2636 and parse the result to obtain a list of all device
2637 id's. Returns this list. Returns empty list if no
2638 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002639 List is ordered sequentially
2640
andrewonlab3e15ead2014-10-15 14:21:34 -04002641 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002642 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002643 the ids. By obtaining the list of device ids on the fly,
2644 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002645 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002646 try:
kelvin8ec71442015-01-15 16:57:00 -08002647 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002648 devicesStr = self.devices( jsonFormat=False )
2649 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002650
kelvin-onlabd3b64892015-01-20 13:26:24 -08002651 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002652 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 return idList
kelvin8ec71442015-01-15 16:57:00 -08002654
2655 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002656 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002657 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002658 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002659 # Split list further into arguments before and after string
2660 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002661 # append to idList
2662 for arg in tempList:
2663 idList.append( arg.split( "id=" )[ 1 ] )
2664 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002665
Jon Halld4d4b372015-01-28 16:02:41 -08002666 except TypeError:
2667 main.log.exception( self.name + ": Object not as expected" )
2668 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002669 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002670 main.log.error( self.name + ": EOF exception found" )
2671 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002672 main.cleanup()
2673 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002674 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002675 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002676 main.cleanup()
2677 main.exit()
2678
kelvin-onlabd3b64892015-01-20 13:26:24 -08002679 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002680 """
andrewonlab7c211572014-10-15 16:45:20 -04002681 Uses 'nodes' function to obtain list of all nodes
2682 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002683 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002684 Returns:
2685 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002686 """
andrewonlab7c211572014-10-15 16:45:20 -04002687 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002688 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002689 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002690 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002691 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002692 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002693 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002694 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002695 nodesJson = json.loads( nodesStr )
2696 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002698 except ( TypeError, ValueError ):
2699 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002700 return None
andrewonlab7c211572014-10-15 16:45:20 -04002701 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002702 main.log.error( self.name + ": EOF exception found" )
2703 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002704 main.cleanup()
2705 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002706 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002707 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002708 main.cleanup()
2709 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002710
kelvin-onlabd3b64892015-01-20 13:26:24 -08002711 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002712 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002713 Return the first device from the devices api whose 'id' contains 'dpid'
2714 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002715 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002716 try:
kelvin8ec71442015-01-15 16:57:00 -08002717 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002718 return None
2719 else:
kelvin8ec71442015-01-15 16:57:00 -08002720 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 rawDevices = self.devices()
2722 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002723 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002724 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002725 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2726 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002727 return device
2728 return None
Jon Hallc6793552016-01-19 14:18:37 -08002729 except ( TypeError, ValueError ):
2730 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002731 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002735 main.cleanup()
2736 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002737 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002738 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002739 main.cleanup()
2740 main.exit()
2741
You Wang24139872016-05-03 11:48:47 -07002742 def getTopology( self, topologyOutput ):
2743 """
2744 Definition:
2745 Loads a json topology output
2746 Return:
2747 topology = current ONOS topology
2748 """
2749 import json
2750 try:
2751 # either onos:topology or 'topology' will work in CLI
2752 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002753 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002754 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002755 except ( TypeError, ValueError ):
2756 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2757 return None
You Wang24139872016-05-03 11:48:47 -07002758 except pexpect.EOF:
2759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
2761 main.cleanup()
2762 main.exit()
2763 except Exception:
2764 main.log.exception( self.name + ": Uncaught exception!" )
2765 main.cleanup()
2766 main.exit()
2767
2768 def checkStatus(
2769 self,
2770 topologyResult,
2771 numoswitch,
2772 numolink,
2773 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002774 """
Jon Hallefbd9792015-03-05 16:11:36 -08002775 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002776 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002777 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002778
You Wang24139872016-05-03 11:48:47 -07002779 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002780 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002781 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002782 logLevel = level to log to.
2783 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002784
Jon Hallefbd9792015-03-05 16:11:36 -08002785 Returns: main.TRUE if the number of switches and links are correct,
2786 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002787 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002788 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002789 try:
You Wang24139872016-05-03 11:48:47 -07002790 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002791 if topology == {}:
2792 return main.ERROR
2793 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002794 # Is the number of switches is what we expected
2795 devices = topology.get( 'devices', False )
2796 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002797 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002798 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002799 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002800 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002801 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002802 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002803 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002804 output = output + "The number of links and switches match "\
2805 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002806 result = main.TRUE
2807 else:
You Wang24139872016-05-03 11:48:47 -07002808 output = output + \
2809 "The number of links and switches does not match " + \
2810 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002811 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002812 output = output + "\n ONOS sees %i devices" % int( devices )
2813 output = output + " (%i expected) " % int( numoswitch )
2814 output = output + "and %i links " % int( links )
2815 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002817 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002818 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002819 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002820 else:
You Wang24139872016-05-03 11:48:47 -07002821 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002822 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002823 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002824 main.log.error( self.name + ": EOF exception found" )
2825 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002826 main.cleanup()
2827 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002828 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002829 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002830 main.cleanup()
2831 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002832
kelvin-onlabd3b64892015-01-20 13:26:24 -08002833 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002834 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002835 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002836 deviceId must be the id of a device as seen in the onos devices command
2837 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002838 role must be either master, standby, or none
2839
Jon Halle3f39ff2015-01-13 11:50:53 -08002840 Returns:
2841 main.TRUE or main.FALSE based on argument verification and
2842 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002843 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002844 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002845 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002846 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002847 cmdStr = "device-role " +\
2848 str( deviceId ) + " " +\
2849 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002850 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002852 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002853 if re.search( "Error", handle ):
2854 # end color output to escape any colours
2855 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002856 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002857 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002858 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002859 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002860 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002861 main.log.error( "Invalid 'role' given to device_role(). " +
2862 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002863 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002864 except AssertionError:
2865 main.log.exception( "" )
2866 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002867 except TypeError:
2868 main.log.exception( self.name + ": Object not as expected" )
2869 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002870 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002871 main.log.error( self.name + ": EOF exception found" )
2872 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002873 main.cleanup()
2874 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002875 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002876 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002877 main.cleanup()
2878 main.exit()
2879
kelvin-onlabd3b64892015-01-20 13:26:24 -08002880 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002881 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002882 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002883 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002884 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002885 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002886 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002887 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002888 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002889 cmdStr += " -j"
2890 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002891 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002892 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002893 except AssertionError:
2894 main.log.exception( "" )
2895 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002896 except TypeError:
2897 main.log.exception( self.name + ": Object not as expected" )
2898 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002902 main.cleanup()
2903 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002904 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002905 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002906 main.cleanup()
2907 main.exit()
2908
kelvin-onlabd3b64892015-01-20 13:26:24 -08002909 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002910 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002911 CLI command to get the current leader for the Election test application
2912 NOTE: Requires installation of the onos-app-election feature
2913 Returns: Node IP of the leader if one exists
2914 None if none exists
2915 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002916 """
Jon Hall94fd0472014-12-08 11:52:42 -08002917 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 cmdStr = "election-test-leader"
2919 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002920 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002921 # Leader
2922 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002923 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002924 nodeSearch = re.search( leaderPattern, response )
2925 if nodeSearch:
2926 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002927 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002928 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002929 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002930 # no leader
2931 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002932 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002933 nullSearch = re.search( nullPattern, response )
2934 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002935 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002936 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002937 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002938 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002939 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002940 if re.search( errorPattern, response ):
2941 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002942 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002943 return main.FALSE
2944 else:
Jon Hall390696c2015-05-05 17:13:41 -07002945 main.log.error( "Error in electionTestLeader on " + self.name +
2946 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002947 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002948 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002949 except AssertionError:
2950 main.log.exception( "" )
2951 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002952 except TypeError:
2953 main.log.exception( self.name + ": Object not as expected" )
2954 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002956 main.log.error( self.name + ": EOF exception found" )
2957 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002958 main.cleanup()
2959 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002961 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002962 main.cleanup()
2963 main.exit()
2964
kelvin-onlabd3b64892015-01-20 13:26:24 -08002965 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002966 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002967 CLI command to run for leadership of the Election test application.
2968 NOTE: Requires installation of the onos-app-election feature
2969 Returns: Main.TRUE on success
2970 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002971 """
Jon Hall94fd0472014-12-08 11:52:42 -08002972 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002973 cmdStr = "election-test-run"
2974 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002975 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002976 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002977 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002978 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002979 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002980 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002981 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002982 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002983 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002984 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002985 errorPattern = "Command\snot\sfound"
2986 if re.search( errorPattern, response ):
2987 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002988 return main.FALSE
2989 else:
Jon Hall390696c2015-05-05 17:13:41 -07002990 main.log.error( "Error in electionTestRun on " + self.name +
2991 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002992 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002993 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002994 except AssertionError:
2995 main.log.exception( "" )
2996 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002997 except TypeError:
2998 main.log.exception( self.name + ": Object not as expected" )
2999 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003000 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003001 main.log.error( self.name + ": EOF exception found" )
3002 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003003 main.cleanup()
3004 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003005 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003006 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003007 main.cleanup()
3008 main.exit()
3009
kelvin-onlabd3b64892015-01-20 13:26:24 -08003010 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003011 """
Jon Hall94fd0472014-12-08 11:52:42 -08003012 * CLI command to withdraw the local node from leadership election for
3013 * the Election test application.
3014 #NOTE: Requires installation of the onos-app-election feature
3015 Returns: Main.TRUE on success
3016 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003017 """
Jon Hall94fd0472014-12-08 11:52:42 -08003018 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003019 cmdStr = "election-test-withdraw"
3020 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003021 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003022 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003023 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003024 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003025 if re.search( successPattern, response ):
3026 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003027 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003028 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003029 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003030 errorPattern = "Command\snot\sfound"
3031 if re.search( errorPattern, response ):
3032 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003033 return main.FALSE
3034 else:
Jon Hall390696c2015-05-05 17:13:41 -07003035 main.log.error( "Error in electionTestWithdraw on " +
3036 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003037 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003038 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003039 except AssertionError:
3040 main.log.exception( "" )
3041 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003042 except TypeError:
3043 main.log.exception( self.name + ": Object not as expected" )
3044 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003045 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003046 main.log.error( self.name + ": EOF exception found" )
3047 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003048 main.cleanup()
3049 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003050 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003051 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003052 main.cleanup()
3053 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003054
kelvin8ec71442015-01-15 16:57:00 -08003055 def getDevicePortsEnabledCount( self, dpid ):
3056 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003057 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003058 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003059 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003060 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003061 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3062 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003063 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003064 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003065 if re.search( "No such device", output ):
3066 main.log.error( "Error in getting ports" )
3067 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003068 return output
Jon Hallc6793552016-01-19 14:18:37 -08003069 except AssertionError:
3070 main.log.exception( "" )
3071 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003072 except TypeError:
3073 main.log.exception( self.name + ": Object not as expected" )
3074 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003075 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003076 main.log.error( self.name + ": EOF exception found" )
3077 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003078 main.cleanup()
3079 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003080 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003081 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003082 main.cleanup()
3083 main.exit()
3084
kelvin8ec71442015-01-15 16:57:00 -08003085 def getDeviceLinksActiveCount( self, dpid ):
3086 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003087 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003088 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003089 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003090 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003091 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3092 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003093 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003094 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003095 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003096 main.log.error( "Error in getting ports " )
3097 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003098 return output
Jon Hallc6793552016-01-19 14:18:37 -08003099 except AssertionError:
3100 main.log.exception( "" )
3101 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003102 except TypeError:
3103 main.log.exception( self.name + ": Object not as expected" )
3104 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003106 main.log.error( self.name + ": EOF exception found" )
3107 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003108 main.cleanup()
3109 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003111 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003112 main.cleanup()
3113 main.exit()
3114
kelvin8ec71442015-01-15 16:57:00 -08003115 def getAllIntentIds( self ):
3116 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003117 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003118 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003119 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 cmdStr = "onos:intents | grep id="
3121 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003122 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003123 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003124 if re.search( "Error", output ):
3125 main.log.error( "Error in getting ports" )
3126 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003127 return output
Jon Hallc6793552016-01-19 14:18:37 -08003128 except AssertionError:
3129 main.log.exception( "" )
3130 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003131 except TypeError:
3132 main.log.exception( self.name + ": Object not as expected" )
3133 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003135 main.log.error( self.name + ": EOF exception found" )
3136 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 main.cleanup()
3138 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003139 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003140 main.log.exception( self.name + ": Uncaught exception!" )
3141 main.cleanup()
3142 main.exit()
3143
Jon Hall73509952015-02-24 16:42:56 -08003144 def intentSummary( self ):
3145 """
Jon Hallefbd9792015-03-05 16:11:36 -08003146 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003147 """
3148 try:
3149 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003150 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003151 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003152 states.append( intent.get( 'state', None ) )
3153 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003154 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003155 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003156 except ( TypeError, ValueError ):
3157 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003158 return None
3159 except pexpect.EOF:
3160 main.log.error( self.name + ": EOF exception found" )
3161 main.log.error( self.name + ": " + self.handle.before )
3162 main.cleanup()
3163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003164 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003165 main.log.exception( self.name + ": Uncaught exception!" )
3166 main.cleanup()
3167 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003168
Jon Hall61282e32015-03-19 11:34:11 -07003169 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003170 """
3171 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003172 Optional argument:
3173 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003174 """
Jon Hall63604932015-02-26 17:09:50 -08003175 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003176 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003177 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003178 cmdStr += " -j"
3179 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003180 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003181 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003182 return output
Jon Hallc6793552016-01-19 14:18:37 -08003183 except AssertionError:
3184 main.log.exception( "" )
3185 return None
Jon Hall63604932015-02-26 17:09:50 -08003186 except TypeError:
3187 main.log.exception( self.name + ": Object not as expected" )
3188 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003189 except pexpect.EOF:
3190 main.log.error( self.name + ": EOF exception found" )
3191 main.log.error( self.name + ": " + self.handle.before )
3192 main.cleanup()
3193 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003194 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003195 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003196 main.cleanup()
3197 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003198
acsmarsa4a4d1e2015-07-10 16:01:24 -07003199 def leaderCandidates( self, jsonFormat=True ):
3200 """
3201 Returns the output of the leaders -c command.
3202 Optional argument:
3203 * jsonFormat - boolean indicating if you want output in json
3204 """
3205 try:
3206 cmdStr = "onos:leaders -c"
3207 if jsonFormat:
3208 cmdStr += " -j"
3209 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003210 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003211 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003212 return output
Jon Hallc6793552016-01-19 14:18:37 -08003213 except AssertionError:
3214 main.log.exception( "" )
3215 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003216 except TypeError:
3217 main.log.exception( self.name + ": Object not as expected" )
3218 return None
3219 except pexpect.EOF:
3220 main.log.error( self.name + ": EOF exception found" )
3221 main.log.error( self.name + ": " + self.handle.before )
3222 main.cleanup()
3223 main.exit()
3224 except Exception:
3225 main.log.exception( self.name + ": Uncaught exception!" )
3226 main.cleanup()
3227 main.exit()
3228
Jon Hallc6793552016-01-19 14:18:37 -08003229 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003230 """
3231 Returns a list in format [leader,candidate1,candidate2,...] for a given
3232 topic parameter and an empty list if the topic doesn't exist
3233 If no leader is elected leader in the returned list will be "none"
3234 Returns None if there is a type error processing the json object
3235 """
3236 try:
Jon Hall6e709752016-02-01 13:38:46 -08003237 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003238 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003239 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003240 assert "Command not found:" not in rawOutput, rawOutput
3241 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003242 results = []
3243 for dict in output:
3244 if dict["topic"] == topic:
3245 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003246 candidates = re.split( ", ", dict["candidates"][1:-1] )
3247 results.append( leader )
3248 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003249 return results
Jon Hallc6793552016-01-19 14:18:37 -08003250 except AssertionError:
3251 main.log.exception( "" )
3252 return None
3253 except ( TypeError, ValueError ):
3254 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003255 return None
3256 except pexpect.EOF:
3257 main.log.error( self.name + ": EOF exception found" )
3258 main.log.error( self.name + ": " + self.handle.before )
3259 main.cleanup()
3260 main.exit()
3261 except Exception:
3262 main.log.exception( self.name + ": Uncaught exception!" )
3263 main.cleanup()
3264 main.exit()
3265
Jon Hall61282e32015-03-19 11:34:11 -07003266 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003267 """
3268 Returns the output of the intent Pending map.
3269 """
Jon Hall63604932015-02-26 17:09:50 -08003270 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003271 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003272 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003273 cmdStr += " -j"
3274 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003275 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003276 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003277 return output
Jon Hallc6793552016-01-19 14:18:37 -08003278 except AssertionError:
3279 main.log.exception( "" )
3280 return None
Jon Hall63604932015-02-26 17:09:50 -08003281 except TypeError:
3282 main.log.exception( self.name + ": Object not as expected" )
3283 return None
3284 except pexpect.EOF:
3285 main.log.error( self.name + ": EOF exception found" )
3286 main.log.error( self.name + ": " + self.handle.before )
3287 main.cleanup()
3288 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003289 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003290 main.log.exception( self.name + ": Uncaught exception!" )
3291 main.cleanup()
3292 main.exit()
3293
Jon Hall61282e32015-03-19 11:34:11 -07003294 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003295 """
3296 Returns the output of the raft partitions command for ONOS.
3297 """
Jon Hall61282e32015-03-19 11:34:11 -07003298 # Sample JSON
3299 # {
3300 # "leader": "tcp://10.128.30.11:7238",
3301 # "members": [
3302 # "tcp://10.128.30.11:7238",
3303 # "tcp://10.128.30.17:7238",
3304 # "tcp://10.128.30.13:7238",
3305 # ],
3306 # "name": "p1",
3307 # "term": 3
3308 # },
Jon Hall63604932015-02-26 17:09:50 -08003309 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003310 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003311 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003312 cmdStr += " -j"
3313 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003314 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003315 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003316 return output
Jon Hallc6793552016-01-19 14:18:37 -08003317 except AssertionError:
3318 main.log.exception( "" )
3319 return None
Jon Hall63604932015-02-26 17:09:50 -08003320 except TypeError:
3321 main.log.exception( self.name + ": Object not as expected" )
3322 return None
3323 except pexpect.EOF:
3324 main.log.error( self.name + ": EOF exception found" )
3325 main.log.error( self.name + ": " + self.handle.before )
3326 main.cleanup()
3327 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003328 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003329 main.log.exception( self.name + ": Uncaught exception!" )
3330 main.cleanup()
3331 main.exit()
3332
Jon Hallbe379602015-03-24 13:39:32 -07003333 def apps( self, jsonFormat=True ):
3334 """
3335 Returns the output of the apps command for ONOS. This command lists
3336 information about installed ONOS applications
3337 """
3338 # Sample JSON object
3339 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3340 # "description":"ONOS OpenFlow protocol southbound providers",
3341 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3342 # "features":"[onos-openflow]","state":"ACTIVE"}]
3343 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003344 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003345 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003346 cmdStr += " -j"
3347 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003348 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003349 assert "Command not found:" not in output, output
3350 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003351 return output
Jon Hallbe379602015-03-24 13:39:32 -07003352 # FIXME: look at specific exceptions/Errors
3353 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003354 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003355 return None
3356 except TypeError:
3357 main.log.exception( self.name + ": Object not as expected" )
3358 return None
3359 except pexpect.EOF:
3360 main.log.error( self.name + ": EOF exception found" )
3361 main.log.error( self.name + ": " + self.handle.before )
3362 main.cleanup()
3363 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003364 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003365 main.log.exception( self.name + ": Uncaught exception!" )
3366 main.cleanup()
3367 main.exit()
3368
Jon Hall146f1522015-03-24 15:33:24 -07003369 def appStatus( self, appName ):
3370 """
3371 Uses the onos:apps cli command to return the status of an application.
3372 Returns:
3373 "ACTIVE" - If app is installed and activated
3374 "INSTALLED" - If app is installed and deactivated
3375 "UNINSTALLED" - If app is not installed
3376 None - on error
3377 """
Jon Hall146f1522015-03-24 15:33:24 -07003378 try:
3379 if not isinstance( appName, types.StringType ):
3380 main.log.error( self.name + ".appStatus(): appName must be" +
3381 " a string" )
3382 return None
3383 output = self.apps( jsonFormat=True )
3384 appsJson = json.loads( output )
3385 state = None
3386 for app in appsJson:
3387 if appName == app.get('name'):
3388 state = app.get('state')
3389 break
3390 if state == "ACTIVE" or state == "INSTALLED":
3391 return state
3392 elif state is None:
3393 return "UNINSTALLED"
3394 elif state:
3395 main.log.error( "Unexpected state from 'onos:apps': " +
3396 str( state ) )
3397 return state
Jon Hallc6793552016-01-19 14:18:37 -08003398 except ( TypeError, ValueError ):
3399 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003400 return None
3401 except pexpect.EOF:
3402 main.log.error( self.name + ": EOF exception found" )
3403 main.log.error( self.name + ": " + self.handle.before )
3404 main.cleanup()
3405 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003406 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003407 main.log.exception( self.name + ": Uncaught exception!" )
3408 main.cleanup()
3409 main.exit()
3410
Jon Hallbe379602015-03-24 13:39:32 -07003411 def app( self, appName, option ):
3412 """
3413 Interacts with the app command for ONOS. This command manages
3414 application inventory.
3415 """
Jon Hallbe379602015-03-24 13:39:32 -07003416 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003417 # Validate argument types
3418 valid = True
3419 if not isinstance( appName, types.StringType ):
3420 main.log.error( self.name + ".app(): appName must be a " +
3421 "string" )
3422 valid = False
3423 if not isinstance( option, types.StringType ):
3424 main.log.error( self.name + ".app(): option must be a string" )
3425 valid = False
3426 if not valid:
3427 return main.FALSE
3428 # Validate Option
3429 option = option.lower()
3430 # NOTE: Install may become a valid option
3431 if option == "activate":
3432 pass
3433 elif option == "deactivate":
3434 pass
3435 elif option == "uninstall":
3436 pass
3437 else:
3438 # Invalid option
3439 main.log.error( "The ONOS app command argument only takes " +
3440 "the values: (activate|deactivate|uninstall)" +
3441 "; was given '" + option + "'")
3442 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003443 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003444 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003445 if "Error executing command" in output:
3446 main.log.error( "Error in processing onos:app command: " +
3447 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003448 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003449 elif "No such application" in output:
3450 main.log.error( "The application '" + appName +
3451 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003452 return main.FALSE
3453 elif "Command not found:" in output:
3454 main.log.error( "Error in processing onos:app command: " +
3455 str( output ) )
3456 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003457 elif "Unsupported command:" in output:
3458 main.log.error( "Incorrect command given to 'app': " +
3459 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003460 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003461 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003462 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003463 return main.TRUE
3464 except TypeError:
3465 main.log.exception( self.name + ": Object not as expected" )
3466 return main.ERROR
3467 except pexpect.EOF:
3468 main.log.error( self.name + ": EOF exception found" )
3469 main.log.error( self.name + ": " + self.handle.before )
3470 main.cleanup()
3471 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003472 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003473 main.log.exception( self.name + ": Uncaught exception!" )
3474 main.cleanup()
3475 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003476
Jon Hallbd16b922015-03-26 17:53:15 -07003477 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003478 """
3479 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003480 appName is the hierarchical app name, not the feature name
3481 If check is True, method will check the status of the app after the
3482 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003483 Returns main.TRUE if the command was successfully sent
3484 main.FALSE if the cli responded with an error or given
3485 incorrect input
3486 """
3487 try:
3488 if not isinstance( appName, types.StringType ):
3489 main.log.error( self.name + ".activateApp(): appName must be" +
3490 " a string" )
3491 return main.FALSE
3492 status = self.appStatus( appName )
3493 if status == "INSTALLED":
3494 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003495 if check and response == main.TRUE:
3496 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003497 status = self.appStatus( appName )
3498 if status == "ACTIVE":
3499 return main.TRUE
3500 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003501 main.log.debug( "The state of application " +
3502 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003503 time.sleep( 1 )
3504 return main.FALSE
3505 else: # not 'check' or command didn't succeed
3506 return response
Jon Hall146f1522015-03-24 15:33:24 -07003507 elif status == "ACTIVE":
3508 return main.TRUE
3509 elif status == "UNINSTALLED":
3510 main.log.error( self.name + ": Tried to activate the " +
3511 "application '" + appName + "' which is not " +
3512 "installed." )
3513 else:
3514 main.log.error( "Unexpected return value from appStatus: " +
3515 str( status ) )
3516 return main.ERROR
3517 except TypeError:
3518 main.log.exception( self.name + ": Object not as expected" )
3519 return main.ERROR
3520 except pexpect.EOF:
3521 main.log.error( self.name + ": EOF exception found" )
3522 main.log.error( self.name + ": " + self.handle.before )
3523 main.cleanup()
3524 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003525 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003526 main.log.exception( self.name + ": Uncaught exception!" )
3527 main.cleanup()
3528 main.exit()
3529
Jon Hallbd16b922015-03-26 17:53:15 -07003530 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003531 """
3532 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003533 appName is the hierarchical app name, not the feature name
3534 If check is True, method will check the status of the app after the
3535 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003536 Returns main.TRUE if the command was successfully sent
3537 main.FALSE if the cli responded with an error or given
3538 incorrect input
3539 """
3540 try:
3541 if not isinstance( appName, types.StringType ):
3542 main.log.error( self.name + ".deactivateApp(): appName must " +
3543 "be a string" )
3544 return main.FALSE
3545 status = self.appStatus( appName )
3546 if status == "INSTALLED":
3547 return main.TRUE
3548 elif status == "ACTIVE":
3549 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003550 if check and response == main.TRUE:
3551 for i in range(10): # try 10 times then give up
3552 status = self.appStatus( appName )
3553 if status == "INSTALLED":
3554 return main.TRUE
3555 else:
3556 time.sleep( 1 )
3557 return main.FALSE
3558 else: # not check or command didn't succeed
3559 return response
Jon Hall146f1522015-03-24 15:33:24 -07003560 elif status == "UNINSTALLED":
3561 main.log.warn( self.name + ": Tried to deactivate the " +
3562 "application '" + appName + "' which is not " +
3563 "installed." )
3564 return main.TRUE
3565 else:
3566 main.log.error( "Unexpected return value from appStatus: " +
3567 str( status ) )
3568 return main.ERROR
3569 except TypeError:
3570 main.log.exception( self.name + ": Object not as expected" )
3571 return main.ERROR
3572 except pexpect.EOF:
3573 main.log.error( self.name + ": EOF exception found" )
3574 main.log.error( self.name + ": " + self.handle.before )
3575 main.cleanup()
3576 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003577 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003578 main.log.exception( self.name + ": Uncaught exception!" )
3579 main.cleanup()
3580 main.exit()
3581
Jon Hallbd16b922015-03-26 17:53:15 -07003582 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003583 """
3584 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003585 appName is the hierarchical app name, not the feature name
3586 If check is True, method will check the status of the app after the
3587 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003588 Returns main.TRUE if the command was successfully sent
3589 main.FALSE if the cli responded with an error or given
3590 incorrect input
3591 """
3592 # TODO: check with Thomas about the state machine for apps
3593 try:
3594 if not isinstance( appName, types.StringType ):
3595 main.log.error( self.name + ".uninstallApp(): appName must " +
3596 "be a string" )
3597 return main.FALSE
3598 status = self.appStatus( appName )
3599 if status == "INSTALLED":
3600 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003601 if check and response == main.TRUE:
3602 for i in range(10): # try 10 times then give up
3603 status = self.appStatus( appName )
3604 if status == "UNINSTALLED":
3605 return main.TRUE
3606 else:
3607 time.sleep( 1 )
3608 return main.FALSE
3609 else: # not check or command didn't succeed
3610 return response
Jon Hall146f1522015-03-24 15:33:24 -07003611 elif status == "ACTIVE":
3612 main.log.warn( self.name + ": Tried to uninstall the " +
3613 "application '" + appName + "' which is " +
3614 "currently active." )
3615 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003616 if check and response == main.TRUE:
3617 for i in range(10): # try 10 times then give up
3618 status = self.appStatus( appName )
3619 if status == "UNINSTALLED":
3620 return main.TRUE
3621 else:
3622 time.sleep( 1 )
3623 return main.FALSE
3624 else: # not check or command didn't succeed
3625 return response
Jon Hall146f1522015-03-24 15:33:24 -07003626 elif status == "UNINSTALLED":
3627 return main.TRUE
3628 else:
3629 main.log.error( "Unexpected return value from appStatus: " +
3630 str( status ) )
3631 return main.ERROR
3632 except TypeError:
3633 main.log.exception( self.name + ": Object not as expected" )
3634 return main.ERROR
3635 except pexpect.EOF:
3636 main.log.error( self.name + ": EOF exception found" )
3637 main.log.error( self.name + ": " + self.handle.before )
3638 main.cleanup()
3639 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003640 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003641 main.log.exception( self.name + ": Uncaught exception!" )
3642 main.cleanup()
3643 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003644
3645 def appIDs( self, jsonFormat=True ):
3646 """
3647 Show the mappings between app id and app names given by the 'app-ids'
3648 cli command
3649 """
3650 try:
3651 cmdStr = "app-ids"
3652 if jsonFormat:
3653 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003654 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003655 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003656 assert "Command not found:" not in output, output
3657 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003658 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003659 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003660 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003661 return None
3662 except TypeError:
3663 main.log.exception( self.name + ": Object not as expected" )
3664 return None
3665 except pexpect.EOF:
3666 main.log.error( self.name + ": EOF exception found" )
3667 main.log.error( self.name + ": " + self.handle.before )
3668 main.cleanup()
3669 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003670 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003671 main.log.exception( self.name + ": Uncaught exception!" )
3672 main.cleanup()
3673 main.exit()
3674
3675 def appToIDCheck( self ):
3676 """
3677 This method will check that each application's ID listed in 'apps' is
3678 the same as the ID listed in 'app-ids'. The check will also check that
3679 there are no duplicate IDs issued. Note that an app ID should be
3680 a globaly unique numerical identifier for app/app-like features. Once
3681 an ID is registered, the ID is never freed up so that if an app is
3682 reinstalled it will have the same ID.
3683
3684 Returns: main.TRUE if the check passes and
3685 main.FALSE if the check fails or
3686 main.ERROR if there is some error in processing the test
3687 """
3688 try:
Jon Hall390696c2015-05-05 17:13:41 -07003689 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003690 rawJson = self.appIDs( jsonFormat=True )
3691 if rawJson:
3692 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003693 else:
Jon Hallc6793552016-01-19 14:18:37 -08003694 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003695 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003696 rawJson = self.apps( jsonFormat=True )
3697 if rawJson:
3698 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003699 else:
Jon Hallc6793552016-01-19 14:18:37 -08003700 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003701 bail = True
3702 if bail:
3703 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003704 result = main.TRUE
3705 for app in apps:
3706 appID = app.get( 'id' )
3707 if appID is None:
3708 main.log.error( "Error parsing app: " + str( app ) )
3709 result = main.FALSE
3710 appName = app.get( 'name' )
3711 if appName is None:
3712 main.log.error( "Error parsing app: " + str( app ) )
3713 result = main.FALSE
3714 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003715 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003716 # main.log.debug( "Comparing " + str( app ) + " to " +
3717 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003718 if not current: # if ids doesn't have this id
3719 result = main.FALSE
3720 main.log.error( "'app-ids' does not have the ID for " +
3721 str( appName ) + " that apps does." )
3722 elif len( current ) > 1:
3723 # there is more than one app with this ID
3724 result = main.FALSE
3725 # We will log this later in the method
3726 elif not current[0][ 'name' ] == appName:
3727 currentName = current[0][ 'name' ]
3728 result = main.FALSE
3729 main.log.error( "'app-ids' has " + str( currentName ) +
3730 " registered under id:" + str( appID ) +
3731 " but 'apps' has " + str( appName ) )
3732 else:
3733 pass # id and name match!
3734 # now make sure that app-ids has no duplicates
3735 idsList = []
3736 namesList = []
3737 for item in ids:
3738 idsList.append( item[ 'id' ] )
3739 namesList.append( item[ 'name' ] )
3740 if len( idsList ) != len( set( idsList ) ) or\
3741 len( namesList ) != len( set( namesList ) ):
3742 main.log.error( "'app-ids' has some duplicate entries: \n"
3743 + json.dumps( ids,
3744 sort_keys=True,
3745 indent=4,
3746 separators=( ',', ': ' ) ) )
3747 result = main.FALSE
3748 return result
Jon Hallc6793552016-01-19 14:18:37 -08003749 except ( TypeError, ValueError ):
3750 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003751 return main.ERROR
3752 except pexpect.EOF:
3753 main.log.error( self.name + ": EOF exception found" )
3754 main.log.error( self.name + ": " + self.handle.before )
3755 main.cleanup()
3756 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003757 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003758 main.log.exception( self.name + ": Uncaught exception!" )
3759 main.cleanup()
3760 main.exit()
3761
Jon Hallfb760a02015-04-13 15:35:03 -07003762 def getCfg( self, component=None, propName=None, short=False,
3763 jsonFormat=True ):
3764 """
3765 Get configuration settings from onos cli
3766 Optional arguments:
3767 component - Optionally only list configurations for a specific
3768 component. If None, all components with configurations
3769 are displayed. Case Sensitive string.
3770 propName - If component is specified, propName option will show
3771 only this specific configuration from that component.
3772 Case Sensitive string.
3773 jsonFormat - Returns output as json. Note that this will override
3774 the short option
3775 short - Short, less verbose, version of configurations.
3776 This is overridden by the json option
3777 returns:
3778 Output from cli as a string or None on error
3779 """
3780 try:
3781 baseStr = "cfg"
3782 cmdStr = " get"
3783 componentStr = ""
3784 if component:
3785 componentStr += " " + component
3786 if propName:
3787 componentStr += " " + propName
3788 if jsonFormat:
3789 baseStr += " -j"
3790 elif short:
3791 baseStr += " -s"
3792 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003793 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003794 assert "Command not found:" not in output, output
3795 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003796 return output
3797 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003798 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003799 return None
3800 except TypeError:
3801 main.log.exception( self.name + ": Object not as expected" )
3802 return None
3803 except pexpect.EOF:
3804 main.log.error( self.name + ": EOF exception found" )
3805 main.log.error( self.name + ": " + self.handle.before )
3806 main.cleanup()
3807 main.exit()
3808 except Exception:
3809 main.log.exception( self.name + ": Uncaught exception!" )
3810 main.cleanup()
3811 main.exit()
3812
3813 def setCfg( self, component, propName, value=None, check=True ):
3814 """
3815 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003816 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003817 component - The case sensitive name of the component whose
3818 property is to be set
3819 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003820 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003821 value - The value to set the property to. If None, will unset the
3822 property and revert it to it's default value(if applicable)
3823 check - Boolean, Check whether the option was successfully set this
3824 only applies when a value is given.
3825 returns:
3826 main.TRUE on success or main.FALSE on failure. If check is False,
3827 will return main.TRUE unless there is an error
3828 """
3829 try:
3830 baseStr = "cfg"
3831 cmdStr = " set " + str( component ) + " " + str( propName )
3832 if value is not None:
3833 cmdStr += " " + str( value )
3834 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003835 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003836 assert "Command not found:" not in output, output
3837 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003838 if value and check:
3839 results = self.getCfg( component=str( component ),
3840 propName=str( propName ),
3841 jsonFormat=True )
3842 # Check if current value is what we just set
3843 try:
3844 jsonOutput = json.loads( results )
3845 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003846 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003847 main.log.exception( "Error parsing cfg output" )
3848 main.log.error( "output:" + repr( results ) )
3849 return main.FALSE
3850 if current == str( value ):
3851 return main.TRUE
3852 return main.FALSE
3853 return main.TRUE
3854 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003855 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003856 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003857 except ( TypeError, ValueError ):
3858 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003859 return main.FALSE
3860 except pexpect.EOF:
3861 main.log.error( self.name + ": EOF exception found" )
3862 main.log.error( self.name + ": " + self.handle.before )
3863 main.cleanup()
3864 main.exit()
3865 except Exception:
3866 main.log.exception( self.name + ": Uncaught exception!" )
3867 main.cleanup()
3868 main.exit()
3869
Jon Hall390696c2015-05-05 17:13:41 -07003870 def setTestAdd( self, setName, values ):
3871 """
3872 CLI command to add elements to a distributed set.
3873 Arguments:
3874 setName - The name of the set to add to.
3875 values - The value(s) to add to the set, space seperated.
3876 Example usages:
3877 setTestAdd( "set1", "a b c" )
3878 setTestAdd( "set2", "1" )
3879 returns:
3880 main.TRUE on success OR
3881 main.FALSE if elements were already in the set OR
3882 main.ERROR on error
3883 """
3884 try:
3885 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3886 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003887 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003888 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003889 try:
3890 # TODO: Maybe make this less hardcoded
3891 # ConsistentMap Exceptions
3892 assert "org.onosproject.store.service" not in output
3893 # Node not leader
3894 assert "java.lang.IllegalStateException" not in output
3895 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003896 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003897 "command: " + str( output ) )
3898 retryTime = 30 # Conservative time, given by Madan
3899 main.log.info( "Waiting " + str( retryTime ) +
3900 "seconds before retrying." )
3901 time.sleep( retryTime ) # Due to change in mastership
3902 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003903 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003904 assert "Error executing command" not in output
3905 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3906 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3907 main.log.info( self.name + ": " + output )
3908 if re.search( positiveMatch, output):
3909 return main.TRUE
3910 elif re.search( negativeMatch, output):
3911 return main.FALSE
3912 else:
3913 main.log.error( self.name + ": setTestAdd did not" +
3914 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003915 main.log.debug( self.name + " actual: " + repr( output ) )
3916 return main.ERROR
3917 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003918 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003919 return main.ERROR
3920 except TypeError:
3921 main.log.exception( self.name + ": Object not as expected" )
3922 return main.ERROR
3923 except pexpect.EOF:
3924 main.log.error( self.name + ": EOF exception found" )
3925 main.log.error( self.name + ": " + self.handle.before )
3926 main.cleanup()
3927 main.exit()
3928 except Exception:
3929 main.log.exception( self.name + ": Uncaught exception!" )
3930 main.cleanup()
3931 main.exit()
3932
3933 def setTestRemove( self, setName, values, clear=False, retain=False ):
3934 """
3935 CLI command to remove elements from a distributed set.
3936 Required arguments:
3937 setName - The name of the set to remove from.
3938 values - The value(s) to remove from the set, space seperated.
3939 Optional arguments:
3940 clear - Clear all elements from the set
3941 retain - Retain only the given values. (intersection of the
3942 original set and the given set)
3943 returns:
3944 main.TRUE on success OR
3945 main.FALSE if the set was not changed OR
3946 main.ERROR on error
3947 """
3948 try:
3949 cmdStr = "set-test-remove "
3950 if clear:
3951 cmdStr += "-c " + str( setName )
3952 elif retain:
3953 cmdStr += "-r " + str( setName ) + " " + str( values )
3954 else:
3955 cmdStr += str( setName ) + " " + str( values )
3956 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003957 try:
Jon Halla495f562016-05-16 18:03:26 -07003958 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003959 # TODO: Maybe make this less hardcoded
3960 # ConsistentMap Exceptions
3961 assert "org.onosproject.store.service" not in output
3962 # Node not leader
3963 assert "java.lang.IllegalStateException" not in output
3964 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003965 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003966 "command: " + str( output ) )
3967 retryTime = 30 # Conservative time, given by Madan
3968 main.log.info( "Waiting " + str( retryTime ) +
3969 "seconds before retrying." )
3970 time.sleep( retryTime ) # Due to change in mastership
3971 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003972 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003973 assert "Command not found:" not in output, output
3974 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003975 main.log.info( self.name + ": " + output )
3976 if clear:
3977 pattern = "Set " + str( setName ) + " cleared"
3978 if re.search( pattern, output ):
3979 return main.TRUE
3980 elif retain:
3981 positivePattern = str( setName ) + " was pruned to contain " +\
3982 "only elements of set \[(.*)\]"
3983 negativePattern = str( setName ) + " was not changed by " +\
3984 "retaining only elements of the set " +\
3985 "\[(.*)\]"
3986 if re.search( positivePattern, output ):
3987 return main.TRUE
3988 elif re.search( negativePattern, output ):
3989 return main.FALSE
3990 else:
3991 positivePattern = "\[(.*)\] was removed from the set " +\
3992 str( setName )
3993 if ( len( values.split() ) == 1 ):
3994 negativePattern = "\[(.*)\] was not in set " +\
3995 str( setName )
3996 else:
3997 negativePattern = "No element of \[(.*)\] was in set " +\
3998 str( setName )
3999 if re.search( positivePattern, output ):
4000 return main.TRUE
4001 elif re.search( negativePattern, output ):
4002 return main.FALSE
4003 main.log.error( self.name + ": setTestRemove did not" +
4004 " match expected output" )
4005 main.log.debug( self.name + " expected: " + pattern )
4006 main.log.debug( self.name + " actual: " + repr( output ) )
4007 return main.ERROR
4008 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004009 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004010 return main.ERROR
4011 except TypeError:
4012 main.log.exception( self.name + ": Object not as expected" )
4013 return main.ERROR
4014 except pexpect.EOF:
4015 main.log.error( self.name + ": EOF exception found" )
4016 main.log.error( self.name + ": " + self.handle.before )
4017 main.cleanup()
4018 main.exit()
4019 except Exception:
4020 main.log.exception( self.name + ": Uncaught exception!" )
4021 main.cleanup()
4022 main.exit()
4023
4024 def setTestGet( self, setName, values="" ):
4025 """
4026 CLI command to get the elements in a distributed set.
4027 Required arguments:
4028 setName - The name of the set to remove from.
4029 Optional arguments:
4030 values - The value(s) to check if in the set, space seperated.
4031 returns:
4032 main.ERROR on error OR
4033 A list of elements in the set if no optional arguments are
4034 supplied OR
4035 A tuple containing the list then:
4036 main.FALSE if the given values are not in the set OR
4037 main.TRUE if the given values are in the set OR
4038 """
4039 try:
4040 values = str( values ).strip()
4041 setName = str( setName ).strip()
4042 length = len( values.split() )
4043 containsCheck = None
4044 # Patterns to match
4045 setPattern = "\[(.*)\]"
4046 pattern = "Items in set " + setName + ":\n" + setPattern
4047 containsTrue = "Set " + setName + " contains the value " + values
4048 containsFalse = "Set " + setName + " did not contain the value " +\
4049 values
4050 containsAllTrue = "Set " + setName + " contains the the subset " +\
4051 setPattern
4052 containsAllFalse = "Set " + setName + " did not contain the the" +\
4053 " subset " + setPattern
4054
4055 cmdStr = "set-test-get "
4056 cmdStr += setName + " " + values
4057 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004058 try:
Jon Halla495f562016-05-16 18:03:26 -07004059 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004060 # TODO: Maybe make this less hardcoded
4061 # ConsistentMap Exceptions
4062 assert "org.onosproject.store.service" not in output
4063 # Node not leader
4064 assert "java.lang.IllegalStateException" not in output
4065 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004066 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004067 "command: " + str( output ) )
4068 retryTime = 30 # Conservative time, given by Madan
4069 main.log.info( "Waiting " + str( retryTime ) +
4070 "seconds before retrying." )
4071 time.sleep( retryTime ) # Due to change in mastership
4072 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004073 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004074 assert "Command not found:" not in output, output
4075 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004076 main.log.info( self.name + ": " + output )
4077
4078 if length == 0:
4079 match = re.search( pattern, output )
4080 else: # if given values
4081 if length == 1: # Contains output
4082 patternTrue = pattern + "\n" + containsTrue
4083 patternFalse = pattern + "\n" + containsFalse
4084 else: # ContainsAll output
4085 patternTrue = pattern + "\n" + containsAllTrue
4086 patternFalse = pattern + "\n" + containsAllFalse
4087 matchTrue = re.search( patternTrue, output )
4088 matchFalse = re.search( patternFalse, output )
4089 if matchTrue:
4090 containsCheck = main.TRUE
4091 match = matchTrue
4092 elif matchFalse:
4093 containsCheck = main.FALSE
4094 match = matchFalse
4095 else:
4096 main.log.error( self.name + " setTestGet did not match " +\
4097 "expected output" )
4098 main.log.debug( self.name + " expected: " + pattern )
4099 main.log.debug( self.name + " actual: " + repr( output ) )
4100 match = None
4101 if match:
4102 setMatch = match.group( 1 )
4103 if setMatch == '':
4104 setList = []
4105 else:
4106 setList = setMatch.split( ", " )
4107 if length > 0:
4108 return ( setList, containsCheck )
4109 else:
4110 return setList
4111 else: # no match
4112 main.log.error( self.name + ": setTestGet did not" +
4113 " match expected output" )
4114 main.log.debug( self.name + " expected: " + pattern )
4115 main.log.debug( self.name + " actual: " + repr( output ) )
4116 return main.ERROR
4117 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004118 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004119 return main.ERROR
4120 except TypeError:
4121 main.log.exception( self.name + ": Object not as expected" )
4122 return main.ERROR
4123 except pexpect.EOF:
4124 main.log.error( self.name + ": EOF exception found" )
4125 main.log.error( self.name + ": " + self.handle.before )
4126 main.cleanup()
4127 main.exit()
4128 except Exception:
4129 main.log.exception( self.name + ": Uncaught exception!" )
4130 main.cleanup()
4131 main.exit()
4132
4133 def setTestSize( self, setName ):
4134 """
4135 CLI command to get the elements in a distributed set.
4136 Required arguments:
4137 setName - The name of the set to remove from.
4138 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004139 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004140 None on error
4141 """
4142 try:
4143 # TODO: Should this check against the number of elements returned
4144 # and then return true/false based on that?
4145 setName = str( setName ).strip()
4146 # Patterns to match
4147 setPattern = "\[(.*)\]"
4148 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4149 setPattern
4150 cmdStr = "set-test-get -s "
4151 cmdStr += setName
4152 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004153 try:
Jon Halla495f562016-05-16 18:03:26 -07004154 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004155 # TODO: Maybe make this less hardcoded
4156 # ConsistentMap Exceptions
4157 assert "org.onosproject.store.service" not in output
4158 # Node not leader
4159 assert "java.lang.IllegalStateException" not in output
4160 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004161 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004162 "command: " + str( output ) )
4163 retryTime = 30 # Conservative time, given by Madan
4164 main.log.info( "Waiting " + str( retryTime ) +
4165 "seconds before retrying." )
4166 time.sleep( retryTime ) # Due to change in mastership
4167 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004168 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004169 assert "Command not found:" not in output, output
4170 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004171 main.log.info( self.name + ": " + output )
4172 match = re.search( pattern, output )
4173 if match:
4174 setSize = int( match.group( 1 ) )
4175 setMatch = match.group( 2 )
4176 if len( setMatch.split() ) == setSize:
4177 main.log.info( "The size returned by " + self.name +
4178 " matches the number of elements in " +
4179 "the returned set" )
4180 else:
4181 main.log.error( "The size returned by " + self.name +
4182 " does not match the number of " +
4183 "elements in the returned set." )
4184 return setSize
4185 else: # no match
4186 main.log.error( self.name + ": setTestGet did not" +
4187 " match expected output" )
4188 main.log.debug( self.name + " expected: " + pattern )
4189 main.log.debug( self.name + " actual: " + repr( output ) )
4190 return None
4191 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004192 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004193 return None
Jon Hall390696c2015-05-05 17:13:41 -07004194 except TypeError:
4195 main.log.exception( self.name + ": Object not as expected" )
4196 return None
4197 except pexpect.EOF:
4198 main.log.error( self.name + ": EOF exception found" )
4199 main.log.error( self.name + ": " + self.handle.before )
4200 main.cleanup()
4201 main.exit()
4202 except Exception:
4203 main.log.exception( self.name + ": Uncaught exception!" )
4204 main.cleanup()
4205 main.exit()
4206
Jon Hall80daded2015-05-27 16:07:00 -07004207 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004208 """
4209 Command to list the various counters in the system.
4210 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004211 if jsonFormat, a string of the json object returned by the cli
4212 command
4213 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004214 None on error
4215 """
Jon Hall390696c2015-05-05 17:13:41 -07004216 try:
4217 counters = {}
4218 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004219 if jsonFormat:
4220 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004221 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004222 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004223 assert "Command not found:" not in output, output
4224 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004225 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004226 return output
Jon Hall390696c2015-05-05 17:13:41 -07004227 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004228 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004229 return None
Jon Hall390696c2015-05-05 17:13:41 -07004230 except TypeError:
4231 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004232 return None
Jon Hall390696c2015-05-05 17:13:41 -07004233 except pexpect.EOF:
4234 main.log.error( self.name + ": EOF exception found" )
4235 main.log.error( self.name + ": " + self.handle.before )
4236 main.cleanup()
4237 main.exit()
4238 except Exception:
4239 main.log.exception( self.name + ": Uncaught exception!" )
4240 main.cleanup()
4241 main.exit()
4242
Jon Hall935db192016-04-19 00:22:04 -07004243 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004244 """
Jon Halle1a3b752015-07-22 13:02:46 -07004245 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004246 Required arguments:
4247 counter - The name of the counter to increment.
4248 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004249 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004250 returns:
4251 integer value of the counter or
4252 None on Error
4253 """
4254 try:
4255 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004256 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004257 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004258 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004259 if delta != 1:
4260 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004261 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004262 try:
Jon Halla495f562016-05-16 18:03:26 -07004263 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004264 # TODO: Maybe make this less hardcoded
4265 # ConsistentMap Exceptions
4266 assert "org.onosproject.store.service" not in output
4267 # Node not leader
4268 assert "java.lang.IllegalStateException" not in output
4269 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004270 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004271 "command: " + str( output ) )
4272 retryTime = 30 # Conservative time, given by Madan
4273 main.log.info( "Waiting " + str( retryTime ) +
4274 "seconds before retrying." )
4275 time.sleep( retryTime ) # Due to change in mastership
4276 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004277 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004278 assert "Command not found:" not in output, output
4279 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004280 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004281 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004282 match = re.search( pattern, output )
4283 if match:
4284 return int( match.group( 1 ) )
4285 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004286 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004287 " match expected output." )
4288 main.log.debug( self.name + " expected: " + pattern )
4289 main.log.debug( self.name + " actual: " + repr( output ) )
4290 return None
4291 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004292 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004293 return None
4294 except TypeError:
4295 main.log.exception( self.name + ": Object not as expected" )
4296 return None
4297 except pexpect.EOF:
4298 main.log.error( self.name + ": EOF exception found" )
4299 main.log.error( self.name + ": " + self.handle.before )
4300 main.cleanup()
4301 main.exit()
4302 except Exception:
4303 main.log.exception( self.name + ": Uncaught exception!" )
4304 main.cleanup()
4305 main.exit()
4306
Jon Hall935db192016-04-19 00:22:04 -07004307 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004308 """
4309 CLI command to get a distributed counter then add a delta to it.
4310 Required arguments:
4311 counter - The name of the counter to increment.
4312 Optional arguments:
4313 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004314 returns:
4315 integer value of the counter or
4316 None on Error
4317 """
4318 try:
4319 counter = str( counter )
4320 delta = int( delta )
4321 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004322 cmdStr += counter
4323 if delta != 1:
4324 cmdStr += " " + str( delta )
4325 output = self.sendline( cmdStr )
4326 try:
Jon Halla495f562016-05-16 18:03:26 -07004327 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004328 # TODO: Maybe make this less hardcoded
4329 # ConsistentMap Exceptions
4330 assert "org.onosproject.store.service" not in output
4331 # Node not leader
4332 assert "java.lang.IllegalStateException" not in output
4333 except AssertionError:
4334 main.log.error( "Error in processing '" + cmdStr + "' " +
4335 "command: " + str( output ) )
4336 retryTime = 30 # Conservative time, given by Madan
4337 main.log.info( "Waiting " + str( retryTime ) +
4338 "seconds before retrying." )
4339 time.sleep( retryTime ) # Due to change in mastership
4340 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004341 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004342 assert "Command not found:" not in output, output
4343 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004344 main.log.info( self.name + ": " + output )
4345 pattern = counter + " was updated to (-?\d+)"
4346 match = re.search( pattern, output )
4347 if match:
4348 return int( match.group( 1 ) )
4349 else:
4350 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4351 " match expected output." )
4352 main.log.debug( self.name + " expected: " + pattern )
4353 main.log.debug( self.name + " actual: " + repr( output ) )
4354 return None
4355 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004356 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004357 return None
4358 except TypeError:
4359 main.log.exception( self.name + ": Object not as expected" )
4360 return None
4361 except pexpect.EOF:
4362 main.log.error( self.name + ": EOF exception found" )
4363 main.log.error( self.name + ": " + self.handle.before )
4364 main.cleanup()
4365 main.exit()
4366 except Exception:
4367 main.log.exception( self.name + ": Uncaught exception!" )
4368 main.cleanup()
4369 main.exit()
4370
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004371 def summary( self, jsonFormat=True ):
4372 """
4373 Description: Execute summary command in onos
4374 Returns: json object ( summary -j ), returns main.FALSE if there is
4375 no output
4376
4377 """
4378 try:
4379 cmdStr = "summary"
4380 if jsonFormat:
4381 cmdStr += " -j"
4382 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004383 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004384 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004385 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004386 if not handle:
4387 main.log.error( self.name + ": There is no output in " +
4388 "summary command" )
4389 return main.FALSE
4390 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004391 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004392 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004393 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004394 except TypeError:
4395 main.log.exception( self.name + ": Object not as expected" )
4396 return None
4397 except pexpect.EOF:
4398 main.log.error( self.name + ": EOF exception found" )
4399 main.log.error( self.name + ": " + self.handle.before )
4400 main.cleanup()
4401 main.exit()
4402 except Exception:
4403 main.log.exception( self.name + ": Uncaught exception!" )
4404 main.cleanup()
4405 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004406
Jon Hall935db192016-04-19 00:22:04 -07004407 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004408 """
4409 CLI command to get the value of a key in a consistent map using
4410 transactions. This a test function and can only get keys from the
4411 test map hard coded into the cli command
4412 Required arguments:
4413 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004414 returns:
4415 The string value of the key or
4416 None on Error
4417 """
4418 try:
4419 keyName = str( keyName )
4420 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004421 cmdStr += keyName
4422 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004423 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004424 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004425 try:
4426 # TODO: Maybe make this less hardcoded
4427 # ConsistentMap Exceptions
4428 assert "org.onosproject.store.service" not in output
4429 # Node not leader
4430 assert "java.lang.IllegalStateException" not in output
4431 except AssertionError:
4432 main.log.error( "Error in processing '" + cmdStr + "' " +
4433 "command: " + str( output ) )
4434 return None
4435 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4436 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004437 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004438 return None
4439 else:
4440 match = re.search( pattern, output )
4441 if match:
4442 return match.groupdict()[ 'value' ]
4443 else:
4444 main.log.error( self.name + ": transactionlMapGet did not" +
4445 " match expected output." )
4446 main.log.debug( self.name + " expected: " + pattern )
4447 main.log.debug( self.name + " actual: " + repr( output ) )
4448 return None
Jon Hallc6793552016-01-19 14:18:37 -08004449 except AssertionError:
4450 main.log.exception( "" )
4451 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004452 except TypeError:
4453 main.log.exception( self.name + ": Object not as expected" )
4454 return None
4455 except pexpect.EOF:
4456 main.log.error( self.name + ": EOF exception found" )
4457 main.log.error( self.name + ": " + self.handle.before )
4458 main.cleanup()
4459 main.exit()
4460 except Exception:
4461 main.log.exception( self.name + ": Uncaught exception!" )
4462 main.cleanup()
4463 main.exit()
4464
Jon Hall935db192016-04-19 00:22:04 -07004465 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004466 """
4467 CLI command to put a value into 'numKeys' number of keys in a
4468 consistent map using transactions. This a test function and can only
4469 put into keys named 'Key#' of the test map hard coded into the cli command
4470 Required arguments:
4471 numKeys - Number of keys to add the value to
4472 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004473 returns:
4474 A dictionary whose keys are the name of the keys put into the map
4475 and the values of the keys are dictionaries whose key-values are
4476 'value': value put into map and optionaly
4477 'oldValue': Previous value in the key or
4478 None on Error
4479
4480 Example output
4481 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4482 'Key2': {'value': 'Testing'} }
4483 """
4484 try:
4485 numKeys = str( numKeys )
4486 value = str( value )
4487 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004488 cmdStr += numKeys + " " + value
4489 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004490 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004491 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004492 try:
4493 # TODO: Maybe make this less hardcoded
4494 # ConsistentMap Exceptions
4495 assert "org.onosproject.store.service" not in output
4496 # Node not leader
4497 assert "java.lang.IllegalStateException" not in output
4498 except AssertionError:
4499 main.log.error( "Error in processing '" + cmdStr + "' " +
4500 "command: " + str( output ) )
4501 return None
4502 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4503 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4504 results = {}
4505 for line in output.splitlines():
4506 new = re.search( newPattern, line )
4507 updated = re.search( updatedPattern, line )
4508 if new:
4509 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4510 elif updated:
4511 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004512 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004513 else:
4514 main.log.error( self.name + ": transactionlMapGet did not" +
4515 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004516 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4517 newPattern,
4518 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004519 main.log.debug( self.name + " actual: " + repr( output ) )
4520 return results
Jon Hallc6793552016-01-19 14:18:37 -08004521 except AssertionError:
4522 main.log.exception( "" )
4523 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004524 except TypeError:
4525 main.log.exception( self.name + ": Object not as expected" )
4526 return None
4527 except pexpect.EOF:
4528 main.log.error( self.name + ": EOF exception found" )
4529 main.log.error( self.name + ": " + self.handle.before )
4530 main.cleanup()
4531 main.exit()
4532 except Exception:
4533 main.log.exception( self.name + ": Uncaught exception!" )
4534 main.cleanup()
4535 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004536
acsmarsdaea66c2015-09-03 11:44:06 -07004537 def maps( self, jsonFormat=True ):
4538 """
4539 Description: Returns result of onos:maps
4540 Optional:
4541 * jsonFormat: enable json formatting of output
4542 """
4543 try:
4544 cmdStr = "maps"
4545 if jsonFormat:
4546 cmdStr += " -j"
4547 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004548 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004549 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004550 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004551 except AssertionError:
4552 main.log.exception( "" )
4553 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004554 except TypeError:
4555 main.log.exception( self.name + ": Object not as expected" )
4556 return None
4557 except pexpect.EOF:
4558 main.log.error( self.name + ": EOF exception found" )
4559 main.log.error( self.name + ": " + self.handle.before )
4560 main.cleanup()
4561 main.exit()
4562 except Exception:
4563 main.log.exception( self.name + ": Uncaught exception!" )
4564 main.cleanup()
4565 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004566
4567 def getSwController( self, uri, jsonFormat=True ):
4568 """
4569 Descrition: Gets the controller information from the device
4570 """
4571 try:
4572 cmd = "device-controllers "
4573 if jsonFormat:
4574 cmd += "-j "
4575 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004576 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004577 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004578 return response
Jon Hallc6793552016-01-19 14:18:37 -08004579 except AssertionError:
4580 main.log.exception( "" )
4581 return None
GlennRC050596c2015-11-18 17:06:41 -08004582 except TypeError:
4583 main.log.exception( self.name + ": Object not as expected" )
4584 return None
4585 except pexpect.EOF:
4586 main.log.error( self.name + ": EOF exception found" )
4587 main.log.error( self.name + ": " + self.handle.before )
4588 main.cleanup()
4589 main.exit()
4590 except Exception:
4591 main.log.exception( self.name + ": Uncaught exception!" )
4592 main.cleanup()
4593 main.exit()
4594
4595 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4596 """
4597 Descrition: sets the controller(s) for the specified device
4598
4599 Parameters:
4600 Required: uri - String: The uri of the device(switch).
4601 ip - String or List: The ip address of the controller.
4602 This parameter can be formed in a couple of different ways.
4603 VALID:
4604 10.0.0.1 - just the ip address
4605 tcp:10.0.0.1 - the protocol and the ip address
4606 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4607 so that you can add controllers with different
4608 protocols and ports
4609 INVALID:
4610 10.0.0.1:6653 - this is not supported by ONOS
4611
4612 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4613 port - The port number.
4614 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4615
4616 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4617 """
4618 try:
4619 cmd = "device-setcontrollers"
4620
4621 if jsonFormat:
4622 cmd += " -j"
4623 cmd += " " + uri
4624 if isinstance( ip, str ):
4625 ip = [ip]
4626 for item in ip:
4627 if ":" in item:
4628 sitem = item.split( ":" )
4629 if len(sitem) == 3:
4630 cmd += " " + item
4631 elif "." in sitem[1]:
4632 cmd += " {}:{}".format(item, port)
4633 else:
4634 main.log.error( "Malformed entry: " + item )
4635 raise TypeError
4636 else:
4637 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004638 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004639 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004640 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004641 if "Error" in response:
4642 main.log.error( response )
4643 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004644 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004645 except AssertionError:
4646 main.log.exception( "" )
4647 return None
GlennRC050596c2015-11-18 17:06:41 -08004648 except TypeError:
4649 main.log.exception( self.name + ": Object not as expected" )
4650 return main.FALSE
4651 except pexpect.EOF:
4652 main.log.error( self.name + ": EOF exception found" )
4653 main.log.error( self.name + ": " + self.handle.before )
4654 main.cleanup()
4655 main.exit()
4656 except Exception:
4657 main.log.exception( self.name + ": Uncaught exception!" )
4658 main.cleanup()
4659 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004660
4661 def removeDevice( self, device ):
4662 '''
4663 Description:
4664 Remove a device from ONOS by passing the uri of the device(s).
4665 Parameters:
4666 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4667 Returns:
4668 Returns main.FALSE if an exception is thrown or an error is present
4669 in the response. Otherwise, returns main.TRUE.
4670 NOTE:
4671 If a host cannot be removed, then this function will return main.FALSE
4672 '''
4673 try:
4674 if type( device ) is str:
4675 device = list( device )
4676
4677 for d in device:
4678 time.sleep( 1 )
4679 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004680 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004681 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004682 if "Error" in response:
4683 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4684 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004685 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004686 except AssertionError:
4687 main.log.exception( "" )
4688 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004689 except TypeError:
4690 main.log.exception( self.name + ": Object not as expected" )
4691 return main.FALSE
4692 except pexpect.EOF:
4693 main.log.error( self.name + ": EOF exception found" )
4694 main.log.error( self.name + ": " + self.handle.before )
4695 main.cleanup()
4696 main.exit()
4697 except Exception:
4698 main.log.exception( self.name + ": Uncaught exception!" )
4699 main.cleanup()
4700 main.exit()
4701
4702 def removeHost( self, host ):
4703 '''
4704 Description:
4705 Remove a host from ONOS by passing the id of the host(s)
4706 Parameters:
4707 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4708 Returns:
4709 Returns main.FALSE if an exception is thrown or an error is present
4710 in the response. Otherwise, returns main.TRUE.
4711 NOTE:
4712 If a host cannot be removed, then this function will return main.FALSE
4713 '''
4714 try:
4715 if type( host ) is str:
4716 host = list( host )
4717
4718 for h in host:
4719 time.sleep( 1 )
4720 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004721 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004722 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004723 if "Error" in response:
4724 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4725 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004726 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004727 except AssertionError:
4728 main.log.exception( "" )
4729 return None
GlennRC20fc6522015-12-23 23:26:57 -08004730 except TypeError:
4731 main.log.exception( self.name + ": Object not as expected" )
4732 return main.FALSE
4733 except pexpect.EOF:
4734 main.log.error( self.name + ": EOF exception found" )
4735 main.log.error( self.name + ": " + self.handle.before )
4736 main.cleanup()
4737 main.exit()
4738 except Exception:
4739 main.log.exception( self.name + ": Uncaught exception!" )
4740 main.cleanup()
4741 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004742
Jon Hallc6793552016-01-19 14:18:37 -08004743 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004744 '''
4745 Description:
4746 Bring link down or up in the null-provider.
4747 params:
4748 begin - (string) One end of a device or switch.
4749 end - (string) the other end of the device or switch
4750 returns:
4751 main.TRUE if no exceptions were thrown and no Errors are
4752 present in the resoponse. Otherwise, returns main.FALSE
4753 '''
4754 try:
Jon Hallc6793552016-01-19 14:18:37 -08004755 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004756 response = self.sendline( cmd, showResponse=True )
Jon Halla495f562016-05-16 18:03:26 -07004757 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004758 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004759 if "Error" in response or "Failure" in response:
4760 main.log.error( response )
4761 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004762 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004763 except AssertionError:
4764 main.log.exception( "" )
4765 return None
GlennRCed771242016-01-13 17:02:47 -08004766 except TypeError:
4767 main.log.exception( self.name + ": Object not as expected" )
4768 return main.FALSE
4769 except pexpect.EOF:
4770 main.log.error( self.name + ": EOF exception found" )
4771 main.log.error( self.name + ": " + self.handle.before )
4772 main.cleanup()
4773 main.exit()
4774 except Exception:
4775 main.log.exception( self.name + ": Uncaught exception!" )
4776 main.cleanup()
4777 main.exit()
4778