blob: a0cb7ea1b2a9c6e3437ac7286e56f38997a0b4ea [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-onlab9f541032015-02-04 16:19:53 -0800402 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800403 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700404 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800405 main.log.error( self.name + ": onos cli session closed. ")
406 if self.onosIp:
407 main.log.warn( "Trying to reconnect " + self.onosIp )
408 reconnectResult = self.startOnosCli( self.onosIp )
409 if reconnectResult:
410 main.log.info( self.name + ": onos cli session reconnected." )
411 else:
412 main.log.error( self.name + ": reconnection failed." )
413 main.cleanup()
414 main.exit()
415 else:
416 main.cleanup()
417 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700418 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700419 self.handle.sendline( "" )
420 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800421 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700422 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800423 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800424
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 response = self.handle.before
426 if re.search( "Error", response ):
427 return main.FALSE
428 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700429 except pexpect.TIMEOUT:
430 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700431 if noExit:
432 main.cleanup()
433 return None
434 else:
435 main.cleanup()
436 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800437 except pexpect.EOF:
438 main.log.error( self.name + ": EOF exception found" )
439 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700440 if noExit:
441 main.cleanup()
442 return None
443 else:
444 main.cleanup()
445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800446 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800447 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700448 if noExit:
449 main.cleanup()
450 return None
451 else:
452 main.cleanup()
453 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400454
YPZhangebf9eb52016-05-12 15:20:24 -0700455 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800456 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800457 Send a completely user specified string to
458 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400459 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800460
YPZhangebf9eb52016-05-12 15:20:24 -0700461 if noExit is True, TestON will not exit, but clean up
462
andrewonlaba18f6bf2014-10-13 19:31:54 -0400463 Warning: There are no sanity checking to commands
464 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800465
kelvin8ec71442015-01-15 16:57:00 -0800466 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 try:
Jon Hall14a03b52016-05-11 12:07:30 -0700468 if debug:
469 # NOTE: This adds and average of .4 seconds per call
470 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700471 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800473 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800474 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800475 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800476 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
477 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700478 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700479 main.log.debug( self.name + ": Raw output" )
480 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700481
482 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800483 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800484 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700485 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700486 main.log.debug( self.name + ": ansiEscape output" )
487 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700488
kelvin-onlabfb521662015-02-27 09:52:40 -0800489 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800490 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700491 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700492 main.log.debug( self.name + ": Removed extra returns " +
493 "from output" )
494 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700495
496 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800497 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700498 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700499 main.log.debug( self.name + ": parsed and stripped output" )
500 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700501
Jon Hall63604932015-02-26 17:09:50 -0800502 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 output = response.split( cmdStr.strip(), 1 )
504 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700505 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700506 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700507 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800508 output = output[1].strip()
509 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800510 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800511 return output
GlennRCed771242016-01-13 17:02:47 -0800512 except pexpect.TIMEOUT:
513 main.log.error( self.name + ":ONOS timeout" )
514 if debug:
515 main.log.debug( self.handle.before )
516 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700517 except IndexError:
518 main.log.exception( self.name + ": Object not as expected" )
519 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800520 except TypeError:
521 main.log.exception( self.name + ": Object not as expected" )
522 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400523 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800524 main.log.error( self.name + ": EOF exception found" )
525 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700526 if noExit:
527 main.cleanup()
528 return None
529 else:
530 main.cleanup()
531 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800532 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800533 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700534 if noExit:
535 main.cleanup()
536 return None
537 else:
538 main.cleanup()
539 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400540
kelvin8ec71442015-01-15 16:57:00 -0800541 # IMPORTANT NOTE:
542 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800543 # the cli command changing 'a:b' with 'aB'.
544 # Ex ) onos:topology > onosTopology
545 # onos:links > onosLinks
546 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800547
kelvin-onlabd3b64892015-01-20 13:26:24 -0800548 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800549 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400550 Adds a new cluster node by ID and address information.
551 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 * nodeId
553 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400554 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800556 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400557 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 cmdStr = "add-node " + str( nodeId ) + " " +\
559 str( ONOSIp ) + " " + str( tcpPort )
560 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800561 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800562 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800563 main.log.error( "Error in adding node" )
564 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800565 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400568 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800569 except AssertionError:
570 main.log.exception( "" )
571 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800572 except TypeError:
573 main.log.exception( self.name + ": Object not as expected" )
574 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400575 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800576 main.log.error( self.name + ": EOF exception found" )
577 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400578 main.cleanup()
579 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800580 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800581 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 main.cleanup()
583 main.exit()
584
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800586 """
andrewonlab86dc3082014-10-13 18:18:38 -0400587 Removes a cluster by ID
588 Issues command: 'remove-node [<node-id>]'
589 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800590 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800591 """
andrewonlab86dc3082014-10-13 18:18:38 -0400592 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400593
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700595 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700597 if re.search( "Error", handle ):
598 main.log.error( "Error in removing node" )
599 main.log.error( handle )
600 return main.FALSE
601 else:
602 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800603 except AssertionError:
604 main.log.exception( "" )
605 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800606 except TypeError:
607 main.log.exception( self.name + ": Object not as expected" )
608 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800610 main.log.error( self.name + ": EOF exception found" )
611 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400612 main.cleanup()
613 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400616 main.cleanup()
617 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400618
Jon Hall61282e32015-03-19 11:34:11 -0700619 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800620 """
andrewonlab7c211572014-10-15 16:45:20 -0400621 List the nodes currently visible
622 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700623 Optional argument:
624 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800625 """
andrewonlab7c211572014-10-15 16:45:20 -0400626 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700627 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700628 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 cmdStr += " -j"
630 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800631 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700632 return output
Jon Hallc6793552016-01-19 14:18:37 -0800633 except AssertionError:
634 main.log.exception( "" )
635 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
andrewonlab7c211572014-10-15 16:45:20 -0400639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400646 main.cleanup()
647 main.exit()
648
kelvin8ec71442015-01-15 16:57:00 -0800649 def topology( self ):
650 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700651 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700652 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700653 Return:
654 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800655 """
andrewonlab95ce8322014-10-13 14:12:04 -0400656 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700657 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800659 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400661 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800662 except AssertionError:
663 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800664 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800665 except TypeError:
666 main.log.exception( self.name + ": Object not as expected" )
667 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400668 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800669 main.log.error( self.name + ": EOF exception found" )
670 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400671 main.cleanup()
672 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800673 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800674 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400675 main.cleanup()
676 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800677
jenkins7ead5a82015-03-13 10:28:21 -0700678 def deviceRemove( self, deviceId ):
679 """
680 Removes particular device from storage
681
682 TODO: refactor this function
683 """
684 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700685 cmdStr = "device-remove " + str( deviceId )
686 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800687 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700688 if re.search( "Error", handle ):
689 main.log.error( "Error in removing device" )
690 main.log.error( handle )
691 return main.FALSE
692 else:
693 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
696 return None
jenkins7ead5a82015-03-13 10:28:21 -0700697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
700 except pexpect.EOF:
701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
703 main.cleanup()
704 main.exit()
705 except Exception:
706 main.log.exception( self.name + ": Uncaught exception!" )
707 main.cleanup()
708 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800711 """
Jon Hall7b02d952014-10-17 20:14:54 -0400712 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400713 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800715 """
andrewonlab86dc3082014-10-13 18:18:38 -0400716 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700717 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 cmdStr += " -j"
720 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800721 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700722 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800723 except AssertionError:
724 main.log.exception( "" )
725 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800726 except TypeError:
727 main.log.exception( self.name + ": Object not as expected" )
728 return None
andrewonlab7c211572014-10-15 16:45:20 -0400729 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400732 main.cleanup()
733 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800735 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400736 main.cleanup()
737 main.exit()
738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800741 This balances the devices across all controllers
742 by issuing command: 'onos> onos:balance-masters'
743 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800744 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800745 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800748 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700749 if re.search( "Error", handle ):
750 main.log.error( "Error in balancing masters" )
751 main.log.error( handle )
752 return main.FALSE
753 else:
754 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800755 except AssertionError:
756 main.log.exception( "" )
757 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800758 except TypeError:
759 main.log.exception( self.name + ": Object not as expected" )
760 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800764 main.cleanup()
765 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800766 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800767 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800768 main.cleanup()
769 main.exit()
770
Jon Hallc6793552016-01-19 14:18:37 -0800771 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700772 """
773 Returns the output of the masters command.
774 Optional argument:
775 * jsonFormat - boolean indicating if you want output in json
776 """
777 try:
778 cmdStr = "onos:masters"
779 if jsonFormat:
780 cmdStr += " -j"
781 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800782 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700783 return output
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
acsmars24950022015-07-30 18:00:43 -0700787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
790 except pexpect.EOF:
791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
793 main.cleanup()
794 main.exit()
795 except Exception:
796 main.log.exception( self.name + ": Uncaught exception!" )
797 main.cleanup()
798 main.exit()
799
Jon Hallc6793552016-01-19 14:18:37 -0800800 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700801 """
802 Uses the master command to check that the devices' leadership
803 is evenly divided
804
805 Dependencies: checkMasters() and summary()
806
807 Returns main.True if the devices are balanced
808 Returns main.False if the devices are unbalanced
809 Exits on Exception
810 Returns None on TypeError
811 """
812 try:
Jon Hallc6793552016-01-19 14:18:37 -0800813 summaryOutput = self.summary()
814 totalDevices = json.loads( summaryOutput )[ "devices" ]
815 except ( TypeError, ValueError ):
816 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
817 return None
818 try:
acsmars24950022015-07-30 18:00:43 -0700819 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800820 mastersOutput = self.checkMasters()
821 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700822 first = masters[ 0 ][ "size" ]
823 for master in masters:
824 totalOwnedDevices += master[ "size" ]
825 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
826 main.log.error( "Mastership not balanced" )
827 main.log.info( "\n" + self.checkMasters( False ) )
828 return main.FALSE
829 main.log.info( "Mastership balanced between " \
830 + str( len(masters) ) + " masters" )
831 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800832 except ( TypeError, ValueError ):
833 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700834 return None
835 except pexpect.EOF:
836 main.log.error( self.name + ": EOF exception found" )
837 main.log.error( self.name + ": " + self.handle.before )
838 main.cleanup()
839 main.exit()
840 except Exception:
841 main.log.exception( self.name + ": Uncaught exception!" )
842 main.cleanup()
843 main.exit()
844
kelvin-onlabd3b64892015-01-20 13:26:24 -0800845 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800846 """
Jon Halle8217482014-10-17 13:49:14 -0400847 Lists all core links
848 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800850 """
Jon Halle8217482014-10-17 13:49:14 -0400851 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700852 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700854 cmdStr += " -j"
855 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800856 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700857 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800858 except AssertionError:
859 main.log.exception( "" )
860 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800861 except TypeError:
862 main.log.exception( self.name + ": Object not as expected" )
863 return None
Jon Halle8217482014-10-17 13:49:14 -0400864 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800865 main.log.error( self.name + ": EOF exception found" )
866 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400867 main.cleanup()
868 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800869 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800870 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400871 main.cleanup()
872 main.exit()
873
kelvin-onlabd3b64892015-01-20 13:26:24 -0800874 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800875 """
Jon Halle8217482014-10-17 13:49:14 -0400876 Lists all ports
877 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800878 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800879 """
Jon Halle8217482014-10-17 13:49:14 -0400880 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700883 cmdStr += " -j"
884 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800885 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700886 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800887 except AssertionError:
888 main.log.exception( "" )
889 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800890 except TypeError:
891 main.log.exception( self.name + ": Object not as expected" )
892 return None
Jon Halle8217482014-10-17 13:49:14 -0400893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.error( self.name + ": EOF exception found" )
895 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400896 main.cleanup()
897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800898 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800899 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400900 main.cleanup()
901 main.exit()
902
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800904 """
Jon Hall983a1702014-10-28 18:44:22 -0400905 Lists all devices and the controllers with roles assigned to them
906 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800908 """
andrewonlab7c211572014-10-15 16:45:20 -0400909 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700912 cmdStr += " -j"
913 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800914 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700915 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800916 except AssertionError:
917 main.log.exception( "" )
918 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800919 except TypeError:
920 main.log.exception( self.name + ": Object not as expected" )
921 return None
Jon Hall983a1702014-10-28 18:44:22 -0400922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400925 main.cleanup()
926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800927 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800928 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400929 main.cleanup()
930 main.exit()
931
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800933 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800934 Given the a string containing the json representation of the "roles"
935 cli command and a partial or whole device id, returns a json object
936 containing the roles output for the first device whose id contains
937 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400938
939 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800940 A dict of the role assignments for the given device or
941 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800942 """
Jon Hall983a1702014-10-28 18:44:22 -0400943 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400945 return None
946 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 rawRoles = self.roles()
948 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800949 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800951 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400953 return device
954 return None
Jon Hallc6793552016-01-19 14:18:37 -0800955 except ( TypeError, ValueError ):
956 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800957 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400961 main.cleanup()
962 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800963 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800964 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400965 main.cleanup()
966 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800967
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800969 """
Jon Hall94fd0472014-12-08 11:52:42 -0800970 Iterates through each device and checks if there is a master assigned
971 Returns: main.TRUE if each device has a master
972 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800973 """
Jon Hall94fd0472014-12-08 11:52:42 -0800974 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 rawRoles = self.roles()
976 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800977 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800979 # print device
980 if device[ 'master' ] == "none":
981 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800982 return main.FALSE
983 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800984 except ( TypeError, ValueError ):
985 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800986 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800988 main.log.error( self.name + ": EOF exception found" )
989 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800990 main.cleanup()
991 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800992 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800993 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800994 main.cleanup()
995 main.exit()
996
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800998 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400999 Returns string of paths, and the cost.
1000 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001001 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001002 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1004 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001005 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001006 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( "Error in getting paths" )
1008 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001009 else:
kelvin8ec71442015-01-15 16:57:00 -08001010 path = handle.split( ";" )[ 0 ]
1011 cost = handle.split( ";" )[ 1 ]
1012 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001013 except AssertionError:
1014 main.log.exception( "" )
1015 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001016 except TypeError:
1017 main.log.exception( self.name + ": Object not as expected" )
1018 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001022 main.cleanup()
1023 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001025 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 main.cleanup()
1027 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001028
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001030 """
Jon Hallffb386d2014-11-21 13:43:38 -08001031 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001032 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001034 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001035 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001036 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001038 cmdStr += " -j"
1039 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001040 if handle:
1041 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001042 # TODO: Maybe make this less hardcoded
1043 # ConsistentMap Exceptions
1044 assert "org.onosproject.store.service" not in handle
1045 # Node not leader
1046 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001047 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001048 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001049 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001050 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001051 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001052 except TypeError:
1053 main.log.exception( self.name + ": Object not as expected" )
1054 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001055 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001056 main.log.error( self.name + ": EOF exception found" )
1057 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001058 main.cleanup()
1059 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001060 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001061 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001062 main.cleanup()
1063 main.exit()
1064
kelvin-onlabd3b64892015-01-20 13:26:24 -08001065 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001066 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001067 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001068
Jon Hallefbd9792015-03-05 16:11:36 -08001069 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001070 partial mac address
1071
Jon Hall42db6dc2014-10-24 19:03:48 -04001072 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001073 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001074 try:
kelvin8ec71442015-01-15 16:57:00 -08001075 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001076 return None
1077 else:
1078 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 rawHosts = self.hosts()
1080 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001081 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001083 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001084 if not host:
1085 pass
1086 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 return host
1088 return None
Jon Hallc6793552016-01-19 14:18:37 -08001089 except ( TypeError, ValueError ):
1090 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001091 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001093 main.log.error( self.name + ": EOF exception found" )
1094 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001095 main.cleanup()
1096 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001098 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 main.cleanup()
1100 main.exit()
1101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001103 """
1104 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001105 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001106
andrewonlab3f0a4af2014-10-17 12:25:14 -04001107 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001109 IMPORTANT:
1110 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001111 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001112 Furthermore, it assumes that value of VLAN is '-1'
1113 Description:
kelvin8ec71442015-01-15 16:57:00 -08001114 Converts mininet hosts ( h1, h2, h3... ) into
1115 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1116 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001121 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 hostHex = hex( int( host ) ).zfill( 12 )
1123 hostHex = str( hostHex ).replace( 'x', '0' )
1124 i = iter( str( hostHex ) )
1125 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1126 hostHex = hostHex + "/-1"
1127 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001130
Jon Halld4d4b372015-01-28 16:02:41 -08001131 except TypeError:
1132 main.log.exception( self.name + ": Object not as expected" )
1133 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001135 main.log.error( self.name + ": EOF exception found" )
1136 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137 main.cleanup()
1138 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001139 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001140 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141 main.cleanup()
1142 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001143
Jeremy Songster832f9e92016-05-05 14:30:49 -07001144 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001145 """
andrewonlabe6745342014-10-17 14:29:13 -04001146 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001147 * hostIdOne: ONOS host id for host1
1148 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001149 Optional:
1150 * vlanId: specify a VLAN id for the intent
andrewonlabe6745342014-10-17 14:29:13 -04001151 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001152 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001153 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001154 Returns:
1155 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001156 """
andrewonlabe6745342014-10-17 14:29:13 -04001157 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001158 cmdStr = "add-host-intent "
1159 if vlanId:
1160 cmdStr += "-v " + str( vlanId ) + " "
1161 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001163 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001164 if re.search( "Error", handle ):
1165 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001166 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001167 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001168 else:
1169 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001170 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1171 match = re.search('id=0x([\da-f]+),', handle)
1172 if match:
1173 return match.group()[3:-1]
1174 else:
1175 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001176 main.log.debug( "Response from ONOS was: " +
1177 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001178 return None
Jon Hallc6793552016-01-19 14:18:37 -08001179 except AssertionError:
1180 main.log.exception( "" )
1181 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001182 except TypeError:
1183 main.log.exception( self.name + ": Object not as expected" )
1184 return None
andrewonlabe6745342014-10-17 14:29:13 -04001185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001188 main.cleanup()
1189 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001190 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001191 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001192 main.cleanup()
1193 main.exit()
1194
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001196 """
andrewonlab7b31d232014-10-24 13:31:47 -04001197 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 * ingressDevice: device id of ingress device
1199 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001200 Optional:
1201 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001202 Description:
1203 Adds an optical intent by specifying an ingress and egress device
1204 Returns:
1205 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001206 """
andrewonlab7b31d232014-10-24 13:31:47 -04001207 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1209 " " + str( egressDevice )
1210 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001211 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001212 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001213 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 main.log.error( "Error in adding Optical intent" )
1215 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001216 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001217 main.log.info( "Optical intent installed between " +
1218 str( ingressDevice ) + " and " +
1219 str( egressDevice ) )
1220 match = re.search('id=0x([\da-f]+),', handle)
1221 if match:
1222 return match.group()[3:-1]
1223 else:
1224 main.log.error( "Error, intent ID not found" )
1225 return None
Jon Hallc6793552016-01-19 14:18:37 -08001226 except AssertionError:
1227 main.log.exception( "" )
1228 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001229 except TypeError:
1230 main.log.exception( self.name + ": Object not as expected" )
1231 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001232 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.error( self.name + ": EOF exception found" )
1234 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001235 main.cleanup()
1236 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001237 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001238 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001239 main.cleanup()
1240 main.exit()
1241
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001243 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 ingressDevice,
1245 egressDevice,
1246 portIngress="",
1247 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001248 ethType="",
1249 ethSrc="",
1250 ethDst="",
1251 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 ipProto="",
1254 ipSrc="",
1255 ipDst="",
1256 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001257 tcpDst="",
1258 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001259 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001260 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 * ingressDevice: device id of ingress device
1262 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001263 Optional:
1264 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001265 * ethSrc: specify ethSrc ( i.e. src mac addr )
1266 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001267 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001269 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001270 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001271 * ipSrc: specify ip source address
1272 * ipDst: specify ip destination address
1273 * tcpSrc: specify tcp source port
1274 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001275 * vlanId: specify vlan ID
andrewonlab4dbb4d82014-10-17 18:22:31 -04001276 Description:
kelvin8ec71442015-01-15 16:57:00 -08001277 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001278 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001279 Returns:
1280 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001281
Jon Halle3f39ff2015-01-13 11:50:53 -08001282 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001283 options developers provide for point-to-point
1284 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001285 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001286 try:
kelvin8ec71442015-01-15 16:57:00 -08001287 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001288 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001290 and not ipProto and not ipSrc and not ipDst \
1291 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001292 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001293
andrewonlab289e4b72014-10-21 21:24:18 -04001294 else:
andrewonlab36af3822014-11-18 17:48:18 -05001295 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001296
andrewonlab0c0a6772014-10-22 12:31:18 -04001297 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001298 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001299 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001300 cmd += " --ethSrc " + str( ethSrc )
1301 if ethDst:
1302 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001303 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001304 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001306 cmd += " --lambda "
1307 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001308 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001309 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001310 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001311 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001312 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001313 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001314 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001315 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001316 cmd += " --tcpDst " + str( tcpDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001317 if vlanId:
1318 cmd += " -v " + str( vlanId )
andrewonlab289e4b72014-10-21 21:24:18 -04001319
kelvin8ec71442015-01-15 16:57:00 -08001320 # Check whether the user appended the port
1321 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 if "/" in ingressDevice:
1323 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001324 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001326 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001327 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001328 # Would it make sense to throw an exception and exit
1329 # the test?
1330 return None
andrewonlab36af3822014-11-18 17:48:18 -05001331
kelvin8ec71442015-01-15 16:57:00 -08001332 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 str( ingressDevice ) + "/" +\
1334 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001335
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 if "/" in egressDevice:
1337 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001338 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001340 main.log.error( "You must specify the egress port" )
1341 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001342
kelvin8ec71442015-01-15 16:57:00 -08001343 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 str( egressDevice ) + "/" +\
1345 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001346
kelvin-onlab898a6c62015-01-16 14:13:53 -08001347 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001348 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001349 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001350 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001351 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001352 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001353 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001354 # TODO: print out all the options in this message?
1355 main.log.info( "Point-to-point intent installed between " +
1356 str( ingressDevice ) + " and " +
1357 str( egressDevice ) )
1358 match = re.search('id=0x([\da-f]+),', handle)
1359 if match:
1360 return match.group()[3:-1]
1361 else:
1362 main.log.error( "Error, intent ID not found" )
1363 return None
Jon Hallc6793552016-01-19 14:18:37 -08001364 except AssertionError:
1365 main.log.exception( "" )
1366 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001367 except TypeError:
1368 main.log.exception( self.name + ": Object not as expected" )
1369 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001370 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001371 main.log.error( self.name + ": EOF exception found" )
1372 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001373 main.cleanup()
1374 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001375 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001376 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001377 main.cleanup()
1378 main.exit()
1379
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001381 self,
shahshreyac2f97072015-03-19 17:04:29 -07001382 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001384 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001385 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001386 ethType="",
1387 ethSrc="",
1388 ethDst="",
1389 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001391 ipProto="",
1392 ipSrc="",
1393 ipDst="",
1394 tcpSrc="",
1395 tcpDst="",
1396 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001397 setEthDst="",
1398 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001399 """
shahshreyad0c80432014-12-04 16:56:05 -08001400 Note:
shahshreya70622b12015-03-19 17:19:00 -07001401 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001402 is same. That is, all ingress devices include port numbers
1403 with a "/" or all ingress devices could specify device
1404 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001405 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001406 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001407 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001409 Optional:
1410 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001411 * ethSrc: specify ethSrc ( i.e. src mac addr )
1412 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001413 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001414 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001415 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001416 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001417 * ipSrc: specify ip source address
1418 * ipDst: specify ip destination address
1419 * tcpSrc: specify tcp source port
1420 * tcpDst: specify tcp destination port
1421 * setEthSrc: action to Rewrite Source MAC Address
1422 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001423 * vlanId: specify vlan Id
shahshreyad0c80432014-12-04 16:56:05 -08001424 Description:
kelvin8ec71442015-01-15 16:57:00 -08001425 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001426 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001427 Returns:
1428 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001429
Jon Halle3f39ff2015-01-13 11:50:53 -08001430 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001431 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001432 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001433 """
shahshreyad0c80432014-12-04 16:56:05 -08001434 try:
kelvin8ec71442015-01-15 16:57:00 -08001435 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001436 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001438 and not ipProto and not ipSrc and not ipDst\
1439 and not tcpSrc and not tcpDst and not setEthSrc\
1440 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001441 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001442
1443 else:
1444 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001445
shahshreyad0c80432014-12-04 16:56:05 -08001446 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001447 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001448 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001449 cmd += " --ethSrc " + str( ethSrc )
1450 if ethDst:
1451 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001452 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001453 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001455 cmd += " --lambda "
1456 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001457 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001458 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001459 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001460 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001461 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001462 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001463 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001464 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001465 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001466 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001467 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001468 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001469 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001470 if vlanId:
1471 cmd += " -v " + str( vlanId )
shahshreyad0c80432014-12-04 16:56:05 -08001472
kelvin8ec71442015-01-15 16:57:00 -08001473 # Check whether the user appended the port
1474 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001475
1476 if portIngressList is None:
1477 for ingressDevice in ingressDeviceList:
1478 if "/" in ingressDevice:
1479 cmd += " " + str( ingressDevice )
1480 else:
1481 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001482 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001483 # TODO: perhaps more meaningful return
1484 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001485 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001486 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001487 for ingressDevice, portIngress in zip( ingressDeviceList,
1488 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001489 cmd += " " + \
1490 str( ingressDevice ) + "/" +\
1491 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001492 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001493 main.log.error( "Device list and port list does not " +
1494 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001495 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 if "/" in egressDevice:
1497 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001498 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001499 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001500 main.log.error( "You must specify " +
1501 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001502 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001503
kelvin8ec71442015-01-15 16:57:00 -08001504 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 str( egressDevice ) + "/" +\
1506 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001507 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001508 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001509 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001510 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001511 main.log.error( "Error in adding multipoint-to-singlepoint " +
1512 "intent" )
1513 return None
shahshreyad0c80432014-12-04 16:56:05 -08001514 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001515 match = re.search('id=0x([\da-f]+),', handle)
1516 if match:
1517 return match.group()[3:-1]
1518 else:
1519 main.log.error( "Error, intent ID not found" )
1520 return None
Jon Hallc6793552016-01-19 14:18:37 -08001521 except AssertionError:
1522 main.log.exception( "" )
1523 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001524 except TypeError:
1525 main.log.exception( self.name + ": Object not as expected" )
1526 return None
1527 except pexpect.EOF:
1528 main.log.error( self.name + ": EOF exception found" )
1529 main.log.error( self.name + ": " + self.handle.before )
1530 main.cleanup()
1531 main.exit()
1532 except Exception:
1533 main.log.exception( self.name + ": Uncaught exception!" )
1534 main.cleanup()
1535 main.exit()
1536
1537 def addSinglepointToMultipointIntent(
1538 self,
1539 ingressDevice,
1540 egressDeviceList,
1541 portIngress="",
1542 portEgressList=None,
1543 ethType="",
1544 ethSrc="",
1545 ethDst="",
1546 bandwidth="",
1547 lambdaAlloc=False,
1548 ipProto="",
1549 ipSrc="",
1550 ipDst="",
1551 tcpSrc="",
1552 tcpDst="",
1553 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001554 setEthDst="",
1555 vlanId="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001556 """
1557 Note:
1558 This function assumes the format of all egress devices
1559 is same. That is, all egress devices include port numbers
1560 with a "/" or all egress devices could specify device
1561 ids and port numbers seperately.
1562 Required:
1563 * EgressDeviceList: List of device ids of egress device
1564 ( Atleast 2 eress devices required in the list )
1565 * ingressDevice: device id of ingress device
1566 Optional:
1567 * ethType: specify ethType
1568 * ethSrc: specify ethSrc ( i.e. src mac addr )
1569 * ethDst: specify ethDst ( i.e. dst mac addr )
1570 * bandwidth: specify bandwidth capacity of link
1571 * lambdaAlloc: if True, intent will allocate lambda
1572 for the specified intent
1573 * ipProto: specify ip protocol
1574 * ipSrc: specify ip source address
1575 * ipDst: specify ip destination address
1576 * tcpSrc: specify tcp source port
1577 * tcpDst: specify tcp destination port
1578 * setEthSrc: action to Rewrite Source MAC Address
1579 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001580 * vlanId: specify vlan Id
kelvin-onlabb9408212015-04-01 13:34:04 -07001581 Description:
1582 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1583 specifying device id's and optional fields
1584 Returns:
1585 A string of the intent id or None on error
1586
1587 NOTE: This function may change depending on the
1588 options developers provide for singlepoint-to-multipoint
1589 intent via cli
1590 """
1591 try:
1592 # If there are no optional arguments
1593 if not ethType and not ethSrc and not ethDst\
1594 and not bandwidth and not lambdaAlloc\
1595 and not ipProto and not ipSrc and not ipDst\
1596 and not tcpSrc and not tcpDst and not setEthSrc\
1597 and not setEthDst:
1598 cmd = "add-single-to-multi-intent"
1599
1600 else:
1601 cmd = "add-single-to-multi-intent"
1602
1603 if ethType:
1604 cmd += " --ethType " + str( ethType )
1605 if ethSrc:
1606 cmd += " --ethSrc " + str( ethSrc )
1607 if ethDst:
1608 cmd += " --ethDst " + str( ethDst )
1609 if bandwidth:
1610 cmd += " --bandwidth " + str( bandwidth )
1611 if lambdaAlloc:
1612 cmd += " --lambda "
1613 if ipProto:
1614 cmd += " --ipProto " + str( ipProto )
1615 if ipSrc:
1616 cmd += " --ipSrc " + str( ipSrc )
1617 if ipDst:
1618 cmd += " --ipDst " + str( ipDst )
1619 if tcpSrc:
1620 cmd += " --tcpSrc " + str( tcpSrc )
1621 if tcpDst:
1622 cmd += " --tcpDst " + str( tcpDst )
1623 if setEthSrc:
1624 cmd += " --setEthSrc " + str( setEthSrc )
1625 if setEthDst:
1626 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001627 if vlanId:
1628 cmd += " -v " + str( vlanId )
kelvin-onlabb9408212015-04-01 13:34:04 -07001629
1630 # Check whether the user appended the port
1631 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001632
kelvin-onlabb9408212015-04-01 13:34:04 -07001633 if "/" in ingressDevice:
1634 cmd += " " + str( ingressDevice )
1635 else:
1636 if not portIngress:
1637 main.log.error( "You must specify " +
1638 "the Ingress port" )
1639 return main.FALSE
1640
1641 cmd += " " +\
1642 str( ingressDevice ) + "/" +\
1643 str( portIngress )
1644
1645 if portEgressList is None:
1646 for egressDevice in egressDeviceList:
1647 if "/" in egressDevice:
1648 cmd += " " + str( egressDevice )
1649 else:
1650 main.log.error( "You must specify " +
1651 "the egress port" )
1652 # TODO: perhaps more meaningful return
1653 return main.FALSE
1654 else:
1655 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001656 for egressDevice, portEgress in zip( egressDeviceList,
1657 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001658 cmd += " " + \
1659 str( egressDevice ) + "/" +\
1660 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001661 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001662 main.log.error( "Device list and port list does not " +
1663 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001664 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001665 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001666 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001667 # If error, return error message
1668 if re.search( "Error", handle ):
1669 main.log.error( "Error in adding singlepoint-to-multipoint " +
1670 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001671 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001672 else:
1673 match = re.search('id=0x([\da-f]+),', handle)
1674 if match:
1675 return match.group()[3:-1]
1676 else:
1677 main.log.error( "Error, intent ID not found" )
1678 return None
Jon Hallc6793552016-01-19 14:18:37 -08001679 except AssertionError:
1680 main.log.exception( "" )
1681 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001682 except TypeError:
1683 main.log.exception( self.name + ": Object not as expected" )
1684 return None
shahshreyad0c80432014-12-04 16:56:05 -08001685 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( self.name + ": EOF exception found" )
1687 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001688 main.cleanup()
1689 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001690 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001691 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001692 main.cleanup()
1693 main.exit()
1694
Hari Krishna9e232602015-04-13 17:29:08 -07001695 def addMplsIntent(
1696 self,
1697 ingressDevice,
1698 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001699 ingressPort="",
1700 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001701 ethType="",
1702 ethSrc="",
1703 ethDst="",
1704 bandwidth="",
1705 lambdaAlloc=False,
1706 ipProto="",
1707 ipSrc="",
1708 ipDst="",
1709 tcpSrc="",
1710 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001711 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001712 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001713 priority=""):
1714 """
1715 Required:
1716 * ingressDevice: device id of ingress device
1717 * egressDevice: device id of egress device
1718 Optional:
1719 * ethType: specify ethType
1720 * ethSrc: specify ethSrc ( i.e. src mac addr )
1721 * ethDst: specify ethDst ( i.e. dst mac addr )
1722 * bandwidth: specify bandwidth capacity of link
1723 * lambdaAlloc: if True, intent will allocate lambda
1724 for the specified intent
1725 * ipProto: specify ip protocol
1726 * ipSrc: specify ip source address
1727 * ipDst: specify ip destination address
1728 * tcpSrc: specify tcp source port
1729 * tcpDst: specify tcp destination port
1730 * ingressLabel: Ingress MPLS label
1731 * egressLabel: Egress MPLS label
1732 Description:
1733 Adds MPLS intent by
1734 specifying device id's and optional fields
1735 Returns:
1736 A string of the intent id or None on error
1737
1738 NOTE: This function may change depending on the
1739 options developers provide for MPLS
1740 intent via cli
1741 """
1742 try:
1743 # If there are no optional arguments
1744 if not ethType and not ethSrc and not ethDst\
1745 and not bandwidth and not lambdaAlloc \
1746 and not ipProto and not ipSrc and not ipDst \
1747 and not tcpSrc and not tcpDst and not ingressLabel \
1748 and not egressLabel:
1749 cmd = "add-mpls-intent"
1750
1751 else:
1752 cmd = "add-mpls-intent"
1753
1754 if ethType:
1755 cmd += " --ethType " + str( ethType )
1756 if ethSrc:
1757 cmd += " --ethSrc " + str( ethSrc )
1758 if ethDst:
1759 cmd += " --ethDst " + str( ethDst )
1760 if bandwidth:
1761 cmd += " --bandwidth " + str( bandwidth )
1762 if lambdaAlloc:
1763 cmd += " --lambda "
1764 if ipProto:
1765 cmd += " --ipProto " + str( ipProto )
1766 if ipSrc:
1767 cmd += " --ipSrc " + str( ipSrc )
1768 if ipDst:
1769 cmd += " --ipDst " + str( ipDst )
1770 if tcpSrc:
1771 cmd += " --tcpSrc " + str( tcpSrc )
1772 if tcpDst:
1773 cmd += " --tcpDst " + str( tcpDst )
1774 if ingressLabel:
1775 cmd += " --ingressLabel " + str( ingressLabel )
1776 if egressLabel:
1777 cmd += " --egressLabel " + str( egressLabel )
1778 if priority:
1779 cmd += " --priority " + str( priority )
1780
1781 # Check whether the user appended the port
1782 # or provided it as an input
1783 if "/" in ingressDevice:
1784 cmd += " " + str( ingressDevice )
1785 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001786 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001787 main.log.error( "You must specify the ingress port" )
1788 return None
1789
1790 cmd += " " + \
1791 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001792 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001793
1794 if "/" in egressDevice:
1795 cmd += " " + str( egressDevice )
1796 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001797 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001798 main.log.error( "You must specify the egress port" )
1799 return None
1800
1801 cmd += " " +\
1802 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001803 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001806 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001807 # If error, return error message
1808 if re.search( "Error", handle ):
1809 main.log.error( "Error in adding mpls intent" )
1810 return None
1811 else:
1812 # TODO: print out all the options in this message?
1813 main.log.info( "MPLS intent installed between " +
1814 str( ingressDevice ) + " and " +
1815 str( egressDevice ) )
1816 match = re.search('id=0x([\da-f]+),', handle)
1817 if match:
1818 return match.group()[3:-1]
1819 else:
1820 main.log.error( "Error, intent ID not found" )
1821 return None
Jon Hallc6793552016-01-19 14:18:37 -08001822 except AssertionError:
1823 main.log.exception( "" )
1824 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001825 except TypeError:
1826 main.log.exception( self.name + ": Object not as expected" )
1827 return None
1828 except pexpect.EOF:
1829 main.log.error( self.name + ": EOF exception found" )
1830 main.log.error( self.name + ": " + self.handle.before )
1831 main.cleanup()
1832 main.exit()
1833 except Exception:
1834 main.log.exception( self.name + ": Uncaught exception!" )
1835 main.cleanup()
1836 main.exit()
1837
Jon Hallefbd9792015-03-05 16:11:36 -08001838 def removeIntent( self, intentId, app='org.onosproject.cli',
1839 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001840 """
shahshreya1c818fc2015-02-26 13:44:08 -08001841 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001842 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001843 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001844 -p or --purge: Purge the intent from the store after removal
1845
Jon Halle3f39ff2015-01-13 11:50:53 -08001846 Returns:
1847 main.False on error and
1848 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001850 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001851 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001852 if purge:
1853 cmdStr += " -p"
1854 if sync:
1855 cmdStr += " -s"
1856
1857 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001859 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001860 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001862 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001863 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 # TODO: Should this be main.TRUE
1865 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001866 except AssertionError:
1867 main.log.exception( "" )
1868 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001875 main.cleanup()
1876 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001879 main.cleanup()
1880 main.exit()
1881
Jeremy42df2e72016-02-23 16:37:46 -08001882 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1883 """
1884 Description:
1885 Remove all the intents
1886 Optional args:-
1887 -s or --sync: Waits for the removal before returning
1888 -p or --purge: Purge the intent from the store after removal
1889 Returns:
1890 Returns main.TRUE if all intents are removed, otherwise returns
1891 main.FALSE; Returns None for exception
1892 """
1893 try:
1894 cmdStr = "remove-intent"
1895 if purge:
1896 cmdStr += " -p"
1897 if sync:
1898 cmdStr += " -s"
1899
1900 cmdStr += " " + app
1901 handle = self.sendline( cmdStr )
1902 assert "Command not found:" not in handle, handle
1903 if re.search( "Error", handle ):
1904 main.log.error( "Error in removing intent" )
1905 return main.FALSE
1906 else:
1907 return main.TRUE
1908 except AssertionError:
1909 main.log.exception( "" )
1910 return None
1911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
1914 except pexpect.EOF:
1915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
1917 main.cleanup()
1918 main.exit()
1919 except Exception:
1920 main.log.exception( self.name + ": Uncaught exception!" )
1921 main.cleanup()
1922 main.exit()
1923
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001924 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001925 """
1926 Purges all WITHDRAWN Intents
1927 """
1928 try:
1929 cmdStr = "purge-intents"
1930 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001931 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 if re.search( "Error", handle ):
1933 main.log.error( "Error in purging intents" )
1934 return main.FALSE
1935 else:
1936 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001937 except AssertionError:
1938 main.log.exception( "" )
1939 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 except TypeError:
1941 main.log.exception( self.name + ": Object not as expected" )
1942 return None
1943 except pexpect.EOF:
1944 main.log.error( self.name + ": EOF exception found" )
1945 main.log.error( self.name + ": " + self.handle.before )
1946 main.cleanup()
1947 main.exit()
1948 except Exception:
1949 main.log.exception( self.name + ": Uncaught exception!" )
1950 main.cleanup()
1951 main.exit()
1952
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001954 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001955 NOTE: This method should be used after installing application:
1956 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001957 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001959 Description:
1960 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001961 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001963 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001965 cmdStr += " -j"
1966 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001967 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001969 except AssertionError:
1970 main.log.exception( "" )
1971 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001972 except TypeError:
1973 main.log.exception( self.name + ": Object not as expected" )
1974 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001976 main.log.error( self.name + ": EOF exception found" )
1977 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001978 main.cleanup()
1979 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001981 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 main.cleanup()
1983 main.exit()
1984
pingping-lin54b03372015-08-13 14:43:10 -07001985 def ipv4RouteNumber( self ):
1986 """
1987 NOTE: This method should be used after installing application:
1988 onos-app-sdnip
1989 Description:
1990 Obtain the total IPv4 routes number in the system
1991 """
1992 try:
1993 cmdStr = "routes -s -j"
1994 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001995 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001996 jsonResult = json.loads( handle )
1997 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001998 except AssertionError:
1999 main.log.exception( "" )
2000 return None
2001 except ( TypeError, ValueError ):
2002 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002003 return None
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
2007 main.cleanup()
2008 main.exit()
2009 except Exception:
2010 main.log.exception( self.name + ": Uncaught exception!" )
2011 main.cleanup()
2012 main.exit()
2013
pingping-lin8244a3b2015-09-16 13:36:56 -07002014 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002015 """
andrewonlabe6745342014-10-17 14:29:13 -04002016 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002017 Obtain intents from the ONOS cli.
2018 Optional:
2019 * jsonFormat: Enable output formatting in json, default to True
2020 * summary: Whether only output the intent summary, defaults to False
2021 * type: Only output a certain type of intent. This options is valid
2022 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002023 """
andrewonlabe6745342014-10-17 14:29:13 -04002024 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002025 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002026 if summary:
2027 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002028 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002029 cmdStr += " -j"
2030 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002031 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002032 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002033 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002034 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002035 else:
Jon Hallff566d52016-01-15 14:45:36 -08002036 intentType = ""
2037 # IF we want the summary of a specific intent type
2038 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002040 if intentType in jsonResult.keys():
2041 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002042 else:
Jon Hallff566d52016-01-15 14:45:36 -08002043 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002044 return handle
2045 else:
2046 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002047 except AssertionError:
2048 main.log.exception( "" )
2049 return None
2050 except ( TypeError, ValueError ):
2051 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002052 return None
2053 except pexpect.EOF:
2054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
2056 main.cleanup()
2057 main.exit()
2058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
2060 main.cleanup()
2061 main.exit()
2062
kelvin-onlab54400a92015-02-26 18:05:51 -08002063 def getIntentState(self, intentsId, intentsJson=None):
2064 """
You Wangfdcbfc42016-05-16 12:16:53 -07002065 Description:
2066 Gets intent state. Accepts a single intent ID (string type) or a
2067 list of intent IDs.
2068 Parameters:
2069 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002071 Returns:
2072 Returns the state (string type) of the ID if a single intent ID is
2073 accepted.
2074 Returns a list of dictionaries if a list of intent IDs is accepted,
2075 and each dictionary maps 'id' to the Intent ID and 'state' to
2076 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002078 try:
2079 state = "State is Undefined"
2080 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002081 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002082 else:
Jon Hallc6793552016-01-19 14:18:37 -08002083 rawJson = intentsJson
2084 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002085 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002086 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002087 if intentsId == intent[ 'id' ]:
2088 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002090 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2091 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002092 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002093 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002094 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002095 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002096 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002097 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002098 if intentsId[ i ] == intents[ 'id' ]:
2099 stateDict[ 'state' ] = intents[ 'state' ]
2100 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002101 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 break
Jon Hallefbd9792015-03-05 16:11:36 -08002103 if len( intentsId ) != len( dictList ):
2104 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002105 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002107 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 return None
Jon Hallc6793552016-01-19 14:18:37 -08002109 except ( TypeError, ValueError ):
2110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002111 return None
2112 except pexpect.EOF:
2113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
2115 main.cleanup()
2116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002117 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002118 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002119 main.cleanup()
2120 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002121
kelvin-onlabf512e942015-06-08 19:42:59 -07002122 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 """
2124 Description:
2125 Check intents state
2126 Required:
2127 intentsId - List of intents ID to be checked
2128 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 expectedState - Check the expected state(s) of each intents
2130 state in the list.
2131 *NOTE: You can pass in a list of expected state,
2132 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002133 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002134 Returns main.TRUE only if all intent are the same as expected states
2135 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002136 """
2137 try:
2138 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002139 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002140 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002141 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002142 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 "getting intents state" )
2144 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002145
2146 if isinstance( expectedState, types.StringType ):
2147 for intents in intentsDict:
2148 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002149 main.log.debug( self.name + " : Intent ID - " +
2150 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002151 " actual state = " +
2152 intents.get( 'state' )
2153 + " does not equal expected state = "
2154 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002155 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002156
2157 elif isinstance( expectedState, types.ListType ):
2158 for intents in intentsDict:
2159 if not any( state == intents.get( 'state' ) for state in
2160 expectedState ):
2161 main.log.debug( self.name + " : Intent ID - " +
2162 intents.get( 'id' ) +
2163 " actual state = " +
2164 intents.get( 'state' ) +
2165 " does not equal expected states = "
2166 + str( expectedState ) )
2167 returnValue = main.FALSE
2168
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002169 if returnValue == main.TRUE:
2170 main.log.info( self.name + ": All " +
2171 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002172 " intents are in " + str( expectedState ) +
2173 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002174 return returnValue
2175 except TypeError:
2176 main.log.exception( self.name + ": Object not as expected" )
2177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
2181 main.cleanup()
2182 main.exit()
2183 except Exception:
2184 main.log.exception( self.name + ": Uncaught exception!" )
2185 main.cleanup()
2186 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002187
You Wang66518af2016-05-16 15:32:59 -07002188 def compareIntent( self, intentDict ):
2189 """
2190 Description:
2191 Compare the intent ids and states provided in the argument with all intents in ONOS
2192 Return:
2193 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2194 Arguments:
2195 intentDict: a dictionary which maps intent ids to intent states
2196 """
2197 try:
2198 intentsRaw = self.intents()
2199 intentsJson = json.loads( intentsRaw )
2200 intentDictONOS = {}
2201 for intent in intentsJson:
2202 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2203 if len( intentDict ) != len( intentDictONOS ):
2204 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2205 str( len( intentDict ) ) + " expected and " +
2206 str( len( intentDictONOS ) ) + " actual" )
2207 return main.FALSE
2208 returnValue = main.TRUE
2209 for intentID in intentDict.keys():
2210 if not intentID in intentDictONOS.keys():
2211 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2212 returnValue = main.FALSE
2213 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2214 main.log.debug( self.name + ": intent ID - " + intentID +
2215 " expected state is " + intentDict[ intentID ] +
2216 " but actual state is " + intentDictONOS[ intentID ] )
2217 returnValue = main.FALSE
2218 if returnValue == main.TRUE:
2219 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2220 return returnValue
2221 except ( TypeError, ValueError ):
2222 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
2223 return None
2224 except pexpect.EOF:
2225 main.log.error( self.name + ": EOF exception found" )
2226 main.log.error( self.name + ": " + self.handle.before )
2227 main.cleanup()
2228 main.exit()
2229 except Exception:
2230 main.log.exception( self.name + ": Uncaught exception!" )
2231 main.cleanup()
2232 main.exit()
2233
GlennRCed771242016-01-13 17:02:47 -08002234 def checkIntentSummary( self, timeout=60 ):
2235 """
2236 Description:
2237 Check the number of installed intents.
2238 Optional:
2239 timeout - the timeout for pexcept
2240 Return:
2241 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2242 , otherwise, returns main.FALSE.
2243 """
2244
2245 try:
2246 cmd = "intents -s -j"
2247
2248 # Check response if something wrong
2249 response = self.sendline( cmd, timeout=timeout )
2250 if response == None:
2251 return main.False
2252 response = json.loads( response )
2253
2254 # get total and installed number, see if they are match
2255 allState = response.get( 'all' )
2256 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002257 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002258 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002259 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002260 return main.FALSE
2261
Jon Hallc6793552016-01-19 14:18:37 -08002262 except ( TypeError, ValueError ):
2263 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002264 return None
2265 except pexpect.EOF:
2266 main.log.error( self.name + ": EOF exception found" )
2267 main.log.error( self.name + ": " + self.handle.before )
2268 main.cleanup()
2269 main.exit()
2270 except Exception:
2271 main.log.exception( self.name + ": Uncaught exception!" )
2272 main.cleanup()
2273 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002274 except pexpect.TIMEOUT:
2275 main.log.error( self.name + ": ONOS timeout" )
2276 return None
GlennRCed771242016-01-13 17:02:47 -08002277
YPZhangebf9eb52016-05-12 15:20:24 -07002278 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002279 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002280 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002281 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002282 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002283 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002284 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002285 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002286 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002287 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002288 cmdStr += " -j "
2289 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002290 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002291 assert "Command not found:" not in handle, handle
2292 if re.search( "Error:", handle ):
2293 main.log.error( self.name + ": flows() response: " +
2294 str( handle ) )
2295 return handle
2296 except AssertionError:
2297 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002298 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002299 except TypeError:
2300 main.log.exception( self.name + ": Object not as expected" )
2301 return None
Jon Hallc6793552016-01-19 14:18:37 -08002302 except pexpect.TIMEOUT:
2303 main.log.error( self.name + ": ONOS timeout" )
2304 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002305 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002306 main.log.error( self.name + ": EOF exception found" )
2307 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002308 main.cleanup()
2309 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002310 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002311 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002312 main.cleanup()
2313 main.exit()
2314
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002315 def checkFlowCount(self, min=0, timeout=60 ):
2316 count = int(self.getTotalFlowsNum( timeout=timeout ))
2317 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002318
YPZhangebf9eb52016-05-12 15:20:24 -07002319 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002320 """
2321 Description:
GlennRCed771242016-01-13 17:02:47 -08002322 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002323 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2324 if the count of those states is 0, which means all current flows
2325 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002326 Optional:
GlennRCed771242016-01-13 17:02:47 -08002327 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002328 Return:
2329 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002330 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002331 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002332 """
2333 try:
GlennRCed771242016-01-13 17:02:47 -08002334 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2335 checkedStates = []
2336 statesCount = [0, 0, 0, 0]
2337 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002338 rawFlows = self.flows( state=s, timeout = timeout )
2339 checkedStates.append( json.loads( rawFlows ) )
2340 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002341 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002342 try:
2343 statesCount[i] += int( c.get( "flowCount" ) )
2344 except TypeError:
2345 main.log.exception( "Json object not as expected" )
2346 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002347
GlennRCed771242016-01-13 17:02:47 -08002348 # We want to count PENDING_ADD if isPENDING is true
2349 if isPENDING:
2350 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2351 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002352 else:
GlennRCed771242016-01-13 17:02:47 -08002353 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2354 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002355 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002356 except ( TypeError, ValueError ):
2357 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002358 return None
2359 except pexpect.EOF:
2360 main.log.error( self.name + ": EOF exception found" )
2361 main.log.error( self.name + ": " + self.handle.before )
2362 main.cleanup()
2363 main.exit()
2364 except Exception:
2365 main.log.exception( self.name + ": Uncaught exception!" )
2366 main.cleanup()
2367 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002368 except pexpect.TIMEOUT:
2369 main.log.error( self.name + ": ONOS timeout" )
2370 return None
2371
kelvin-onlab4df89f22015-04-13 18:10:23 -07002372
GlennRCed771242016-01-13 17:02:47 -08002373 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002374 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002375 """
andrewonlab87852b02014-11-19 18:44:19 -05002376 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002377 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002378 a specific point-to-point intent definition
2379 Required:
GlennRCed771242016-01-13 17:02:47 -08002380 * ingress: specify source dpid
2381 * egress: specify destination dpid
2382 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002383 Optional:
GlennRCed771242016-01-13 17:02:47 -08002384 * offset: the keyOffset is where the next batch of intents
2385 will be installed
2386 Returns: If failed to push test intents, it will returen None,
2387 if successful, return true.
2388 Timeout expection will return None,
2389 TypeError will return false
2390 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002391 """
andrewonlab87852b02014-11-19 18:44:19 -05002392 try:
GlennRCed771242016-01-13 17:02:47 -08002393 if background:
2394 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002395 else:
GlennRCed771242016-01-13 17:02:47 -08002396 back = ""
2397 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002398 ingress,
2399 egress,
2400 batchSize,
2401 offset,
2402 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002403 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002404 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002405 main.log.info( response )
2406 if response == None:
2407 return None
2408
2409 # TODO: We should handle if there is failure in installation
2410 return main.TRUE
2411
Jon Hallc6793552016-01-19 14:18:37 -08002412 except AssertionError:
2413 main.log.exception( "" )
2414 return None
GlennRCed771242016-01-13 17:02:47 -08002415 except pexpect.TIMEOUT:
2416 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002417 return None
andrewonlab87852b02014-11-19 18:44:19 -05002418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002419 main.log.error( self.name + ": EOF exception found" )
2420 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002421 main.cleanup()
2422 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002423 except TypeError:
2424 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002425 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002426 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002427 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002428 main.cleanup()
2429 main.exit()
2430
YPZhangebf9eb52016-05-12 15:20:24 -07002431 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002432 """
2433 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002434 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002435 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002436 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002437 """
YPZhange3109a72016-02-02 11:25:37 -08002438
YPZhangb5d3f832016-01-23 22:54:26 -08002439 try:
YPZhange3109a72016-02-02 11:25:37 -08002440 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002441 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002442 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002443
2444 if totalFlows == None:
2445 # if timeout, we will get total number of all flows, and subtract other states
2446 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2447 checkedStates = []
2448 totalFlows = 0
2449 statesCount = [0, 0, 0, 0]
2450
2451 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002452 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002453 totalFlows = int( response.get("flows") )
2454
2455 for s in states:
2456 rawFlows = self.flows( state=s, timeout = timeout )
2457 if rawFlows == None:
2458 # if timeout, return the total flows number from summary command
2459 return totalFlows
2460 checkedStates.append( json.loads( rawFlows ) )
2461
2462 # Calculate ADDED flows number, equal total subtracts others
2463 for i in range( len( states ) ):
2464 for c in checkedStates[i]:
2465 try:
2466 statesCount[i] += int( c.get( "flowCount" ) )
2467 except TypeError:
2468 main.log.exception( "Json object not as expected" )
2469 totalFlows = totalFlows - int( statesCount[i] )
2470 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2471
2472 return totalFlows
2473
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002474 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002475
You Wangd3cb2ce2016-05-16 14:01:24 -07002476 except ( TypeError, ValueError ):
2477 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002478 return None
2479 except pexpect.EOF:
2480 main.log.error( self.name + ": EOF exception found" )
2481 main.log.error( self.name + ": " + self.handle.before )
2482 main.cleanup()
2483 main.exit()
2484 except Exception:
2485 main.log.exception( self.name + ": Uncaught exception!" )
2486 main.cleanup()
2487 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002488 except pexpect.TIMEOUT:
2489 main.log.error( self.name + ": ONOS timeout" )
2490 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002491
YPZhangebf9eb52016-05-12 15:20:24 -07002492 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002493 """
2494 Description:
2495 Get the total number of intents, include every states.
2496 Return:
2497 The number of intents
2498 """
2499 try:
2500 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002501 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002502 if response == None:
2503 return -1
2504 response = json.loads( response )
2505 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002506 except ( TypeError, ValueError ):
2507 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002508 return None
2509 except pexpect.EOF:
2510 main.log.error( self.name + ": EOF exception found" )
2511 main.log.error( self.name + ": " + self.handle.before )
2512 main.cleanup()
2513 main.exit()
2514 except Exception:
2515 main.log.exception( self.name + ": Uncaught exception!" )
2516 main.cleanup()
2517 main.exit()
2518
kelvin-onlabd3b64892015-01-20 13:26:24 -08002519 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002520 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002521 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002522 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002523 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002524 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002525 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002526 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002527 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002528 cmdStr += " -j"
2529 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002530 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002531 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002532 except AssertionError:
2533 main.log.exception( "" )
2534 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002535 except TypeError:
2536 main.log.exception( self.name + ": Object not as expected" )
2537 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002538 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002539 main.log.error( self.name + ": EOF exception found" )
2540 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002541 main.cleanup()
2542 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002543 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002544 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002545 main.cleanup()
2546 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002547
kelvin-onlabd3b64892015-01-20 13:26:24 -08002548 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002549 """
2550 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002551 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002552 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002553 """
andrewonlab867212a2014-10-22 20:13:38 -04002554 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002555 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002556 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002557 cmdStr += " -j"
2558 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002559 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002560 if handle:
2561 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002562 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002563 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002564 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002565 else:
2566 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002567 except AssertionError:
2568 main.log.exception( "" )
2569 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002570 except TypeError:
2571 main.log.exception( self.name + ": Object not as expected" )
2572 return None
andrewonlab867212a2014-10-22 20:13:38 -04002573 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002574 main.log.error( self.name + ": EOF exception found" )
2575 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002576 main.cleanup()
2577 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002578 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002579 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002580 main.cleanup()
2581 main.exit()
2582
kelvin8ec71442015-01-15 16:57:00 -08002583 # Wrapper functions ****************
2584 # Wrapper functions use existing driver
2585 # functions and extends their use case.
2586 # For example, we may use the output of
2587 # a normal driver function, and parse it
2588 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002589
kelvin-onlabd3b64892015-01-20 13:26:24 -08002590 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002591 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002592 Description:
2593 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002594 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002595 try:
kelvin8ec71442015-01-15 16:57:00 -08002596 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002597 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002598 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002599
kelvin8ec71442015-01-15 16:57:00 -08002600 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2602 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002603 match = re.search('id=0x([\da-f]+),', intents)
2604 if match:
2605 tmpId = match.group()[3:-1]
2606 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002607 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002608
Jon Halld4d4b372015-01-28 16:02:41 -08002609 except TypeError:
2610 main.log.exception( self.name + ": Object not as expected" )
2611 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002613 main.log.error( self.name + ": EOF exception found" )
2614 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002615 main.cleanup()
2616 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002617 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002618 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002619 main.cleanup()
2620 main.exit()
2621
Jon Hall30b82fa2015-03-04 17:15:43 -08002622 def FlowAddedCount( self, deviceId ):
2623 """
2624 Determine the number of flow rules for the given device id that are
2625 in the added state
2626 """
2627 try:
2628 cmdStr = "flows any " + str( deviceId ) + " | " +\
2629 "grep 'state=ADDED' | wc -l"
2630 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002631 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002632 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002633 except AssertionError:
2634 main.log.exception( "" )
2635 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002636 except pexpect.EOF:
2637 main.log.error( self.name + ": EOF exception found" )
2638 main.log.error( self.name + ": " + self.handle.before )
2639 main.cleanup()
2640 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002641 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002642 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002643 main.cleanup()
2644 main.exit()
2645
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002647 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002648 Use 'devices' function to obtain list of all devices
2649 and parse the result to obtain a list of all device
2650 id's. Returns this list. Returns empty list if no
2651 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002652 List is ordered sequentially
2653
andrewonlab3e15ead2014-10-15 14:21:34 -04002654 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002655 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002656 the ids. By obtaining the list of device ids on the fly,
2657 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002658 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002659 try:
kelvin8ec71442015-01-15 16:57:00 -08002660 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002661 devicesStr = self.devices( jsonFormat=False )
2662 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002663
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002665 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002666 return idList
kelvin8ec71442015-01-15 16:57:00 -08002667
2668 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002669 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002670 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002671 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002672 # Split list further into arguments before and after string
2673 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 # append to idList
2675 for arg in tempList:
2676 idList.append( arg.split( "id=" )[ 1 ] )
2677 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002678
Jon Halld4d4b372015-01-28 16:02:41 -08002679 except TypeError:
2680 main.log.exception( self.name + ": Object not as expected" )
2681 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002683 main.log.error( self.name + ": EOF exception found" )
2684 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002685 main.cleanup()
2686 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002687 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002688 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002689 main.cleanup()
2690 main.exit()
2691
kelvin-onlabd3b64892015-01-20 13:26:24 -08002692 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002693 """
andrewonlab7c211572014-10-15 16:45:20 -04002694 Uses 'nodes' function to obtain list of all nodes
2695 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002696 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002697 Returns:
2698 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002699 """
andrewonlab7c211572014-10-15 16:45:20 -04002700 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002701 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002702 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002703 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002704 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002705 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002706 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002707 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002708 nodesJson = json.loads( nodesStr )
2709 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002711 except ( TypeError, ValueError ):
2712 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002713 return None
andrewonlab7c211572014-10-15 16:45:20 -04002714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002715 main.log.error( self.name + ": EOF exception found" )
2716 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002717 main.cleanup()
2718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002720 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002721 main.cleanup()
2722 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002723
kelvin-onlabd3b64892015-01-20 13:26:24 -08002724 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002725 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002726 Return the first device from the devices api whose 'id' contains 'dpid'
2727 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002728 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002729 try:
kelvin8ec71442015-01-15 16:57:00 -08002730 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002731 return None
2732 else:
kelvin8ec71442015-01-15 16:57:00 -08002733 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002734 rawDevices = self.devices()
2735 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002736 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002737 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002738 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2739 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002740 return device
2741 return None
Jon Hallc6793552016-01-19 14:18:37 -08002742 except ( TypeError, ValueError ):
2743 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002744 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002745 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002746 main.log.error( self.name + ": EOF exception found" )
2747 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002748 main.cleanup()
2749 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002750 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002751 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002752 main.cleanup()
2753 main.exit()
2754
You Wang24139872016-05-03 11:48:47 -07002755 def getTopology( self, topologyOutput ):
2756 """
2757 Definition:
2758 Loads a json topology output
2759 Return:
2760 topology = current ONOS topology
2761 """
2762 import json
2763 try:
2764 # either onos:topology or 'topology' will work in CLI
2765 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002766 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002767 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002768 except ( TypeError, ValueError ):
2769 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2770 return None
You Wang24139872016-05-03 11:48:47 -07002771 except pexpect.EOF:
2772 main.log.error( self.name + ": EOF exception found" )
2773 main.log.error( self.name + ": " + self.handle.before )
2774 main.cleanup()
2775 main.exit()
2776 except Exception:
2777 main.log.exception( self.name + ": Uncaught exception!" )
2778 main.cleanup()
2779 main.exit()
2780
2781 def checkStatus(
2782 self,
2783 topologyResult,
2784 numoswitch,
2785 numolink,
2786 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002787 """
Jon Hallefbd9792015-03-05 16:11:36 -08002788 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002789 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002790 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002791
You Wang24139872016-05-03 11:48:47 -07002792 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002793 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002794 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002795 logLevel = level to log to.
2796 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002797
Jon Hallefbd9792015-03-05 16:11:36 -08002798 Returns: main.TRUE if the number of switches and links are correct,
2799 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002800 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002801 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002802 try:
You Wang24139872016-05-03 11:48:47 -07002803 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002804 if topology == {}:
2805 return main.ERROR
2806 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002807 # Is the number of switches is what we expected
2808 devices = topology.get( 'devices', False )
2809 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002810 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002811 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002812 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002813 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002815 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002816 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002817 output = output + "The number of links and switches match "\
2818 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002819 result = main.TRUE
2820 else:
You Wang24139872016-05-03 11:48:47 -07002821 output = output + \
2822 "The number of links and switches does not match " + \
2823 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002824 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002825 output = output + "\n ONOS sees %i devices" % int( devices )
2826 output = output + " (%i expected) " % int( numoswitch )
2827 output = output + "and %i links " % int( links )
2828 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002829 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002830 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002831 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002832 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002833 else:
You Wang24139872016-05-03 11:48:47 -07002834 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002835 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002836 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002837 main.log.error( self.name + ": EOF exception found" )
2838 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002839 main.cleanup()
2840 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002841 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002842 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002843 main.cleanup()
2844 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002845
kelvin-onlabd3b64892015-01-20 13:26:24 -08002846 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002847 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002848 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 deviceId must be the id of a device as seen in the onos devices command
2850 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002851 role must be either master, standby, or none
2852
Jon Halle3f39ff2015-01-13 11:50:53 -08002853 Returns:
2854 main.TRUE or main.FALSE based on argument verification and
2855 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002856 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002857 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002858 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002859 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002860 cmdStr = "device-role " +\
2861 str( deviceId ) + " " +\
2862 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002863 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002864 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002865 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002866 if re.search( "Error", handle ):
2867 # end color output to escape any colours
2868 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002869 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002870 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002871 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002872 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002873 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002874 main.log.error( "Invalid 'role' given to device_role(). " +
2875 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002876 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002877 except AssertionError:
2878 main.log.exception( "" )
2879 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002880 except TypeError:
2881 main.log.exception( self.name + ": Object not as expected" )
2882 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002883 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002884 main.log.error( self.name + ": EOF exception found" )
2885 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002886 main.cleanup()
2887 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002888 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002889 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002890 main.cleanup()
2891 main.exit()
2892
kelvin-onlabd3b64892015-01-20 13:26:24 -08002893 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002894 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002895 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002896 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002897 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002898 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002899 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002900 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002901 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002902 cmdStr += " -j"
2903 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002904 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002905 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002906 except AssertionError:
2907 main.log.exception( "" )
2908 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002909 except TypeError:
2910 main.log.exception( self.name + ": Object not as expected" )
2911 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002913 main.log.error( self.name + ": EOF exception found" )
2914 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002915 main.cleanup()
2916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002918 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002919 main.cleanup()
2920 main.exit()
2921
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002923 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002924 CLI command to get the current leader for the Election test application
2925 NOTE: Requires installation of the onos-app-election feature
2926 Returns: Node IP of the leader if one exists
2927 None if none exists
2928 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002929 """
Jon Hall94fd0472014-12-08 11:52:42 -08002930 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002931 cmdStr = "election-test-leader"
2932 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002933 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002934 # Leader
2935 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002936 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 nodeSearch = re.search( leaderPattern, response )
2938 if nodeSearch:
2939 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002940 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002941 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002942 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002943 # no leader
2944 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002945 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002946 nullSearch = re.search( nullPattern, response )
2947 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002949 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002950 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002951 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002952 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002953 if re.search( errorPattern, response ):
2954 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002955 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002956 return main.FALSE
2957 else:
Jon Hall390696c2015-05-05 17:13:41 -07002958 main.log.error( "Error in electionTestLeader on " + self.name +
2959 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002960 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002961 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002962 except AssertionError:
2963 main.log.exception( "" )
2964 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002965 except TypeError:
2966 main.log.exception( self.name + ": Object not as expected" )
2967 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002969 main.log.error( self.name + ": EOF exception found" )
2970 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002971 main.cleanup()
2972 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002973 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002974 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002975 main.cleanup()
2976 main.exit()
2977
kelvin-onlabd3b64892015-01-20 13:26:24 -08002978 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002979 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002980 CLI command to run for leadership of the Election test application.
2981 NOTE: Requires installation of the onos-app-election feature
2982 Returns: Main.TRUE on success
2983 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002984 """
Jon Hall94fd0472014-12-08 11:52:42 -08002985 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002986 cmdStr = "election-test-run"
2987 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002988 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002989 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002990 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002991 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002992 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002993 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002994 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002995 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002996 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002997 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002998 errorPattern = "Command\snot\sfound"
2999 if re.search( errorPattern, response ):
3000 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003001 return main.FALSE
3002 else:
Jon Hall390696c2015-05-05 17:13:41 -07003003 main.log.error( "Error in electionTestRun on " + self.name +
3004 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003006 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003007 except AssertionError:
3008 main.log.exception( "" )
3009 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003010 except TypeError:
3011 main.log.exception( self.name + ": Object not as expected" )
3012 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003013 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003014 main.log.error( self.name + ": EOF exception found" )
3015 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003016 main.cleanup()
3017 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003018 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003019 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003020 main.cleanup()
3021 main.exit()
3022
kelvin-onlabd3b64892015-01-20 13:26:24 -08003023 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003024 """
Jon Hall94fd0472014-12-08 11:52:42 -08003025 * CLI command to withdraw the local node from leadership election for
3026 * the Election test application.
3027 #NOTE: Requires installation of the onos-app-election feature
3028 Returns: Main.TRUE on success
3029 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003030 """
Jon Hall94fd0472014-12-08 11:52:42 -08003031 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003032 cmdStr = "election-test-withdraw"
3033 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003034 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003035 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003036 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003037 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003038 if re.search( successPattern, response ):
3039 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003040 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003041 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003042 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003043 errorPattern = "Command\snot\sfound"
3044 if re.search( errorPattern, response ):
3045 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003046 return main.FALSE
3047 else:
Jon Hall390696c2015-05-05 17:13:41 -07003048 main.log.error( "Error in electionTestWithdraw on " +
3049 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003050 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003051 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003052 except AssertionError:
3053 main.log.exception( "" )
3054 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003055 except TypeError:
3056 main.log.exception( self.name + ": Object not as expected" )
3057 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003058 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003059 main.log.error( self.name + ": EOF exception found" )
3060 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003061 main.cleanup()
3062 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003063 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003064 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003065 main.cleanup()
3066 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003067
kelvin8ec71442015-01-15 16:57:00 -08003068 def getDevicePortsEnabledCount( self, dpid ):
3069 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003070 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003071 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003072 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003073 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3075 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003076 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003077 if re.search( "No such device", output ):
3078 main.log.error( "Error in getting ports" )
3079 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003080 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003081 return output
Jon Hallc6793552016-01-19 14:18:37 -08003082 except AssertionError:
3083 main.log.exception( "" )
3084 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003085 except TypeError:
3086 main.log.exception( self.name + ": Object not as expected" )
3087 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003091 main.cleanup()
3092 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003093 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003094 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003095 main.cleanup()
3096 main.exit()
3097
kelvin8ec71442015-01-15 16:57:00 -08003098 def getDeviceLinksActiveCount( self, dpid ):
3099 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003100 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003101 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003102 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003103 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003104 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3105 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003106 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003107 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003108 main.log.error( "Error in getting ports " )
3109 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003110 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003111 return output
Jon Hallc6793552016-01-19 14:18:37 -08003112 except AssertionError:
3113 main.log.exception( "" )
3114 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003115 except TypeError:
3116 main.log.exception( self.name + ": Object not as expected" )
3117 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003118 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003121 main.cleanup()
3122 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003123 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003124 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003125 main.cleanup()
3126 main.exit()
3127
kelvin8ec71442015-01-15 16:57:00 -08003128 def getAllIntentIds( self ):
3129 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003131 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003132 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003133 cmdStr = "onos:intents | grep id="
3134 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003135 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003136 if re.search( "Error", output ):
3137 main.log.error( "Error in getting ports" )
3138 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003139 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003140 return output
Jon Hallc6793552016-01-19 14:18:37 -08003141 except AssertionError:
3142 main.log.exception( "" )
3143 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003144 except TypeError:
3145 main.log.exception( self.name + ": Object not as expected" )
3146 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003148 main.log.error( self.name + ": EOF exception found" )
3149 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003150 main.cleanup()
3151 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003152 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003153 main.log.exception( self.name + ": Uncaught exception!" )
3154 main.cleanup()
3155 main.exit()
3156
Jon Hall73509952015-02-24 16:42:56 -08003157 def intentSummary( self ):
3158 """
Jon Hallefbd9792015-03-05 16:11:36 -08003159 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003160 """
3161 try:
3162 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003163 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003164 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003165 states.append( intent.get( 'state', None ) )
3166 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003167 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003168 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003169 except ( TypeError, ValueError ):
3170 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003171 return None
3172 except pexpect.EOF:
3173 main.log.error( self.name + ": EOF exception found" )
3174 main.log.error( self.name + ": " + self.handle.before )
3175 main.cleanup()
3176 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003177 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003178 main.log.exception( self.name + ": Uncaught exception!" )
3179 main.cleanup()
3180 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003181
Jon Hall61282e32015-03-19 11:34:11 -07003182 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003183 """
3184 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003185 Optional argument:
3186 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003187 """
Jon Hall63604932015-02-26 17:09:50 -08003188 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003189 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003190 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003191 cmdStr += " -j"
3192 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003193 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003194 return output
Jon Hallc6793552016-01-19 14:18:37 -08003195 except AssertionError:
3196 main.log.exception( "" )
3197 return None
Jon Hall63604932015-02-26 17:09:50 -08003198 except TypeError:
3199 main.log.exception( self.name + ": Object not as expected" )
3200 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003201 except pexpect.EOF:
3202 main.log.error( self.name + ": EOF exception found" )
3203 main.log.error( self.name + ": " + self.handle.before )
3204 main.cleanup()
3205 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003206 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003207 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003208 main.cleanup()
3209 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003210
acsmarsa4a4d1e2015-07-10 16:01:24 -07003211 def leaderCandidates( self, jsonFormat=True ):
3212 """
3213 Returns the output of the leaders -c command.
3214 Optional argument:
3215 * jsonFormat - boolean indicating if you want output in json
3216 """
3217 try:
3218 cmdStr = "onos:leaders -c"
3219 if jsonFormat:
3220 cmdStr += " -j"
3221 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003222 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003223 return output
Jon Hallc6793552016-01-19 14:18:37 -08003224 except AssertionError:
3225 main.log.exception( "" )
3226 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003227 except TypeError:
3228 main.log.exception( self.name + ": Object not as expected" )
3229 return None
3230 except pexpect.EOF:
3231 main.log.error( self.name + ": EOF exception found" )
3232 main.log.error( self.name + ": " + self.handle.before )
3233 main.cleanup()
3234 main.exit()
3235 except Exception:
3236 main.log.exception( self.name + ": Uncaught exception!" )
3237 main.cleanup()
3238 main.exit()
3239
Jon Hallc6793552016-01-19 14:18:37 -08003240 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003241 """
3242 Returns a list in format [leader,candidate1,candidate2,...] for a given
3243 topic parameter and an empty list if the topic doesn't exist
3244 If no leader is elected leader in the returned list will be "none"
3245 Returns None if there is a type error processing the json object
3246 """
3247 try:
Jon Hall6e709752016-02-01 13:38:46 -08003248 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003249 rawOutput = self.sendline( cmdStr )
3250 assert "Command not found:" not in rawOutput, rawOutput
3251 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003252 results = []
3253 for dict in output:
3254 if dict["topic"] == topic:
3255 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003256 candidates = re.split( ", ", dict["candidates"][1:-1] )
3257 results.append( leader )
3258 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003259 return results
Jon Hallc6793552016-01-19 14:18:37 -08003260 except AssertionError:
3261 main.log.exception( "" )
3262 return None
3263 except ( TypeError, ValueError ):
3264 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003265 return None
3266 except pexpect.EOF:
3267 main.log.error( self.name + ": EOF exception found" )
3268 main.log.error( self.name + ": " + self.handle.before )
3269 main.cleanup()
3270 main.exit()
3271 except Exception:
3272 main.log.exception( self.name + ": Uncaught exception!" )
3273 main.cleanup()
3274 main.exit()
3275
Jon Hall61282e32015-03-19 11:34:11 -07003276 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003277 """
3278 Returns the output of the intent Pending map.
3279 """
Jon Hall63604932015-02-26 17:09:50 -08003280 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003281 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003282 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003283 cmdStr += " -j"
3284 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003285 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003286 return output
Jon Hallc6793552016-01-19 14:18:37 -08003287 except AssertionError:
3288 main.log.exception( "" )
3289 return None
Jon Hall63604932015-02-26 17:09:50 -08003290 except TypeError:
3291 main.log.exception( self.name + ": Object not as expected" )
3292 return None
3293 except pexpect.EOF:
3294 main.log.error( self.name + ": EOF exception found" )
3295 main.log.error( self.name + ": " + self.handle.before )
3296 main.cleanup()
3297 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003298 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003299 main.log.exception( self.name + ": Uncaught exception!" )
3300 main.cleanup()
3301 main.exit()
3302
Jon Hall61282e32015-03-19 11:34:11 -07003303 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003304 """
3305 Returns the output of the raft partitions command for ONOS.
3306 """
Jon Hall61282e32015-03-19 11:34:11 -07003307 # Sample JSON
3308 # {
3309 # "leader": "tcp://10.128.30.11:7238",
3310 # "members": [
3311 # "tcp://10.128.30.11:7238",
3312 # "tcp://10.128.30.17:7238",
3313 # "tcp://10.128.30.13:7238",
3314 # ],
3315 # "name": "p1",
3316 # "term": 3
3317 # },
Jon Hall63604932015-02-26 17:09:50 -08003318 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003319 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003320 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003321 cmdStr += " -j"
3322 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003323 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003324 return output
Jon Hallc6793552016-01-19 14:18:37 -08003325 except AssertionError:
3326 main.log.exception( "" )
3327 return None
Jon Hall63604932015-02-26 17:09:50 -08003328 except TypeError:
3329 main.log.exception( self.name + ": Object not as expected" )
3330 return None
3331 except pexpect.EOF:
3332 main.log.error( self.name + ": EOF exception found" )
3333 main.log.error( self.name + ": " + self.handle.before )
3334 main.cleanup()
3335 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003336 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003337 main.log.exception( self.name + ": Uncaught exception!" )
3338 main.cleanup()
3339 main.exit()
3340
Jon Hallbe379602015-03-24 13:39:32 -07003341 def apps( self, jsonFormat=True ):
3342 """
3343 Returns the output of the apps command for ONOS. This command lists
3344 information about installed ONOS applications
3345 """
3346 # Sample JSON object
3347 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3348 # "description":"ONOS OpenFlow protocol southbound providers",
3349 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3350 # "features":"[onos-openflow]","state":"ACTIVE"}]
3351 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003352 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003353 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003354 cmdStr += " -j"
3355 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003356 assert "Command not found:" not in output, output
3357 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003358 return output
Jon Hallbe379602015-03-24 13:39:32 -07003359 # FIXME: look at specific exceptions/Errors
3360 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003361 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003362 return None
3363 except TypeError:
3364 main.log.exception( self.name + ": Object not as expected" )
3365 return None
3366 except pexpect.EOF:
3367 main.log.error( self.name + ": EOF exception found" )
3368 main.log.error( self.name + ": " + self.handle.before )
3369 main.cleanup()
3370 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003371 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003372 main.log.exception( self.name + ": Uncaught exception!" )
3373 main.cleanup()
3374 main.exit()
3375
Jon Hall146f1522015-03-24 15:33:24 -07003376 def appStatus( self, appName ):
3377 """
3378 Uses the onos:apps cli command to return the status of an application.
3379 Returns:
3380 "ACTIVE" - If app is installed and activated
3381 "INSTALLED" - If app is installed and deactivated
3382 "UNINSTALLED" - If app is not installed
3383 None - on error
3384 """
Jon Hall146f1522015-03-24 15:33:24 -07003385 try:
3386 if not isinstance( appName, types.StringType ):
3387 main.log.error( self.name + ".appStatus(): appName must be" +
3388 " a string" )
3389 return None
3390 output = self.apps( jsonFormat=True )
3391 appsJson = json.loads( output )
3392 state = None
3393 for app in appsJson:
3394 if appName == app.get('name'):
3395 state = app.get('state')
3396 break
3397 if state == "ACTIVE" or state == "INSTALLED":
3398 return state
3399 elif state is None:
3400 return "UNINSTALLED"
3401 elif state:
3402 main.log.error( "Unexpected state from 'onos:apps': " +
3403 str( state ) )
3404 return state
Jon Hallc6793552016-01-19 14:18:37 -08003405 except ( TypeError, ValueError ):
3406 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003407 return None
3408 except pexpect.EOF:
3409 main.log.error( self.name + ": EOF exception found" )
3410 main.log.error( self.name + ": " + self.handle.before )
3411 main.cleanup()
3412 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003413 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003414 main.log.exception( self.name + ": Uncaught exception!" )
3415 main.cleanup()
3416 main.exit()
3417
Jon Hallbe379602015-03-24 13:39:32 -07003418 def app( self, appName, option ):
3419 """
3420 Interacts with the app command for ONOS. This command manages
3421 application inventory.
3422 """
Jon Hallbe379602015-03-24 13:39:32 -07003423 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003424 # Validate argument types
3425 valid = True
3426 if not isinstance( appName, types.StringType ):
3427 main.log.error( self.name + ".app(): appName must be a " +
3428 "string" )
3429 valid = False
3430 if not isinstance( option, types.StringType ):
3431 main.log.error( self.name + ".app(): option must be a string" )
3432 valid = False
3433 if not valid:
3434 return main.FALSE
3435 # Validate Option
3436 option = option.lower()
3437 # NOTE: Install may become a valid option
3438 if option == "activate":
3439 pass
3440 elif option == "deactivate":
3441 pass
3442 elif option == "uninstall":
3443 pass
3444 else:
3445 # Invalid option
3446 main.log.error( "The ONOS app command argument only takes " +
3447 "the values: (activate|deactivate|uninstall)" +
3448 "; was given '" + option + "'")
3449 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003450 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003451 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003452 if "Error executing command" in output:
3453 main.log.error( "Error in processing onos:app command: " +
3454 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003455 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003456 elif "No such application" in output:
3457 main.log.error( "The application '" + appName +
3458 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003459 return main.FALSE
3460 elif "Command not found:" in output:
3461 main.log.error( "Error in processing onos:app command: " +
3462 str( output ) )
3463 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003464 elif "Unsupported command:" in output:
3465 main.log.error( "Incorrect command given to 'app': " +
3466 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003467 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003468 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003469 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003470 return main.TRUE
3471 except TypeError:
3472 main.log.exception( self.name + ": Object not as expected" )
3473 return main.ERROR
3474 except pexpect.EOF:
3475 main.log.error( self.name + ": EOF exception found" )
3476 main.log.error( self.name + ": " + self.handle.before )
3477 main.cleanup()
3478 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003479 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003480 main.log.exception( self.name + ": Uncaught exception!" )
3481 main.cleanup()
3482 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003483
Jon Hallbd16b922015-03-26 17:53:15 -07003484 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003485 """
3486 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003487 appName is the hierarchical app name, not the feature name
3488 If check is True, method will check the status of the app after the
3489 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003490 Returns main.TRUE if the command was successfully sent
3491 main.FALSE if the cli responded with an error or given
3492 incorrect input
3493 """
3494 try:
3495 if not isinstance( appName, types.StringType ):
3496 main.log.error( self.name + ".activateApp(): appName must be" +
3497 " a string" )
3498 return main.FALSE
3499 status = self.appStatus( appName )
3500 if status == "INSTALLED":
3501 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003502 if check and response == main.TRUE:
3503 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003504 status = self.appStatus( appName )
3505 if status == "ACTIVE":
3506 return main.TRUE
3507 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003508 main.log.debug( "The state of application " +
3509 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003510 time.sleep( 1 )
3511 return main.FALSE
3512 else: # not 'check' or command didn't succeed
3513 return response
Jon Hall146f1522015-03-24 15:33:24 -07003514 elif status == "ACTIVE":
3515 return main.TRUE
3516 elif status == "UNINSTALLED":
3517 main.log.error( self.name + ": Tried to activate the " +
3518 "application '" + appName + "' which is not " +
3519 "installed." )
3520 else:
3521 main.log.error( "Unexpected return value from appStatus: " +
3522 str( status ) )
3523 return main.ERROR
3524 except TypeError:
3525 main.log.exception( self.name + ": Object not as expected" )
3526 return main.ERROR
3527 except pexpect.EOF:
3528 main.log.error( self.name + ": EOF exception found" )
3529 main.log.error( self.name + ": " + self.handle.before )
3530 main.cleanup()
3531 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003532 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003533 main.log.exception( self.name + ": Uncaught exception!" )
3534 main.cleanup()
3535 main.exit()
3536
Jon Hallbd16b922015-03-26 17:53:15 -07003537 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003538 """
3539 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003540 appName is the hierarchical app name, not the feature name
3541 If check is True, method will check the status of the app after the
3542 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003543 Returns main.TRUE if the command was successfully sent
3544 main.FALSE if the cli responded with an error or given
3545 incorrect input
3546 """
3547 try:
3548 if not isinstance( appName, types.StringType ):
3549 main.log.error( self.name + ".deactivateApp(): appName must " +
3550 "be a string" )
3551 return main.FALSE
3552 status = self.appStatus( appName )
3553 if status == "INSTALLED":
3554 return main.TRUE
3555 elif status == "ACTIVE":
3556 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003557 if check and response == main.TRUE:
3558 for i in range(10): # try 10 times then give up
3559 status = self.appStatus( appName )
3560 if status == "INSTALLED":
3561 return main.TRUE
3562 else:
3563 time.sleep( 1 )
3564 return main.FALSE
3565 else: # not check or command didn't succeed
3566 return response
Jon Hall146f1522015-03-24 15:33:24 -07003567 elif status == "UNINSTALLED":
3568 main.log.warn( self.name + ": Tried to deactivate the " +
3569 "application '" + appName + "' which is not " +
3570 "installed." )
3571 return main.TRUE
3572 else:
3573 main.log.error( "Unexpected return value from appStatus: " +
3574 str( status ) )
3575 return main.ERROR
3576 except TypeError:
3577 main.log.exception( self.name + ": Object not as expected" )
3578 return main.ERROR
3579 except pexpect.EOF:
3580 main.log.error( self.name + ": EOF exception found" )
3581 main.log.error( self.name + ": " + self.handle.before )
3582 main.cleanup()
3583 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003584 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003585 main.log.exception( self.name + ": Uncaught exception!" )
3586 main.cleanup()
3587 main.exit()
3588
Jon Hallbd16b922015-03-26 17:53:15 -07003589 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003590 """
3591 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003592 appName is the hierarchical app name, not the feature name
3593 If check is True, method will check the status of the app after the
3594 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003595 Returns main.TRUE if the command was successfully sent
3596 main.FALSE if the cli responded with an error or given
3597 incorrect input
3598 """
3599 # TODO: check with Thomas about the state machine for apps
3600 try:
3601 if not isinstance( appName, types.StringType ):
3602 main.log.error( self.name + ".uninstallApp(): appName must " +
3603 "be a string" )
3604 return main.FALSE
3605 status = self.appStatus( appName )
3606 if status == "INSTALLED":
3607 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003608 if check and response == main.TRUE:
3609 for i in range(10): # try 10 times then give up
3610 status = self.appStatus( appName )
3611 if status == "UNINSTALLED":
3612 return main.TRUE
3613 else:
3614 time.sleep( 1 )
3615 return main.FALSE
3616 else: # not check or command didn't succeed
3617 return response
Jon Hall146f1522015-03-24 15:33:24 -07003618 elif status == "ACTIVE":
3619 main.log.warn( self.name + ": Tried to uninstall the " +
3620 "application '" + appName + "' which is " +
3621 "currently active." )
3622 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003623 if check and response == main.TRUE:
3624 for i in range(10): # try 10 times then give up
3625 status = self.appStatus( appName )
3626 if status == "UNINSTALLED":
3627 return main.TRUE
3628 else:
3629 time.sleep( 1 )
3630 return main.FALSE
3631 else: # not check or command didn't succeed
3632 return response
Jon Hall146f1522015-03-24 15:33:24 -07003633 elif status == "UNINSTALLED":
3634 return main.TRUE
3635 else:
3636 main.log.error( "Unexpected return value from appStatus: " +
3637 str( status ) )
3638 return main.ERROR
3639 except TypeError:
3640 main.log.exception( self.name + ": Object not as expected" )
3641 return main.ERROR
3642 except pexpect.EOF:
3643 main.log.error( self.name + ": EOF exception found" )
3644 main.log.error( self.name + ": " + self.handle.before )
3645 main.cleanup()
3646 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003647 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003648 main.log.exception( self.name + ": Uncaught exception!" )
3649 main.cleanup()
3650 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003651
3652 def appIDs( self, jsonFormat=True ):
3653 """
3654 Show the mappings between app id and app names given by the 'app-ids'
3655 cli command
3656 """
3657 try:
3658 cmdStr = "app-ids"
3659 if jsonFormat:
3660 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003661 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003662 assert "Command not found:" not in output, output
3663 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003664 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003665 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003666 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003667 return None
3668 except TypeError:
3669 main.log.exception( self.name + ": Object not as expected" )
3670 return None
3671 except pexpect.EOF:
3672 main.log.error( self.name + ": EOF exception found" )
3673 main.log.error( self.name + ": " + self.handle.before )
3674 main.cleanup()
3675 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003676 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003677 main.log.exception( self.name + ": Uncaught exception!" )
3678 main.cleanup()
3679 main.exit()
3680
3681 def appToIDCheck( self ):
3682 """
3683 This method will check that each application's ID listed in 'apps' is
3684 the same as the ID listed in 'app-ids'. The check will also check that
3685 there are no duplicate IDs issued. Note that an app ID should be
3686 a globaly unique numerical identifier for app/app-like features. Once
3687 an ID is registered, the ID is never freed up so that if an app is
3688 reinstalled it will have the same ID.
3689
3690 Returns: main.TRUE if the check passes and
3691 main.FALSE if the check fails or
3692 main.ERROR if there is some error in processing the test
3693 """
3694 try:
Jon Hall390696c2015-05-05 17:13:41 -07003695 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003696 rawJson = self.appIDs( jsonFormat=True )
3697 if rawJson:
3698 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003699 else:
Jon Hallc6793552016-01-19 14:18:37 -08003700 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003701 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003702 rawJson = self.apps( jsonFormat=True )
3703 if rawJson:
3704 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003705 else:
Jon Hallc6793552016-01-19 14:18:37 -08003706 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003707 bail = True
3708 if bail:
3709 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003710 result = main.TRUE
3711 for app in apps:
3712 appID = app.get( 'id' )
3713 if appID is None:
3714 main.log.error( "Error parsing app: " + str( app ) )
3715 result = main.FALSE
3716 appName = app.get( 'name' )
3717 if appName is None:
3718 main.log.error( "Error parsing app: " + str( app ) )
3719 result = main.FALSE
3720 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003721 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003722 # main.log.debug( "Comparing " + str( app ) + " to " +
3723 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003724 if not current: # if ids doesn't have this id
3725 result = main.FALSE
3726 main.log.error( "'app-ids' does not have the ID for " +
3727 str( appName ) + " that apps does." )
3728 elif len( current ) > 1:
3729 # there is more than one app with this ID
3730 result = main.FALSE
3731 # We will log this later in the method
3732 elif not current[0][ 'name' ] == appName:
3733 currentName = current[0][ 'name' ]
3734 result = main.FALSE
3735 main.log.error( "'app-ids' has " + str( currentName ) +
3736 " registered under id:" + str( appID ) +
3737 " but 'apps' has " + str( appName ) )
3738 else:
3739 pass # id and name match!
3740 # now make sure that app-ids has no duplicates
3741 idsList = []
3742 namesList = []
3743 for item in ids:
3744 idsList.append( item[ 'id' ] )
3745 namesList.append( item[ 'name' ] )
3746 if len( idsList ) != len( set( idsList ) ) or\
3747 len( namesList ) != len( set( namesList ) ):
3748 main.log.error( "'app-ids' has some duplicate entries: \n"
3749 + json.dumps( ids,
3750 sort_keys=True,
3751 indent=4,
3752 separators=( ',', ': ' ) ) )
3753 result = main.FALSE
3754 return result
Jon Hallc6793552016-01-19 14:18:37 -08003755 except ( TypeError, ValueError ):
3756 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003757 return main.ERROR
3758 except pexpect.EOF:
3759 main.log.error( self.name + ": EOF exception found" )
3760 main.log.error( self.name + ": " + self.handle.before )
3761 main.cleanup()
3762 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003763 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003764 main.log.exception( self.name + ": Uncaught exception!" )
3765 main.cleanup()
3766 main.exit()
3767
Jon Hallfb760a02015-04-13 15:35:03 -07003768 def getCfg( self, component=None, propName=None, short=False,
3769 jsonFormat=True ):
3770 """
3771 Get configuration settings from onos cli
3772 Optional arguments:
3773 component - Optionally only list configurations for a specific
3774 component. If None, all components with configurations
3775 are displayed. Case Sensitive string.
3776 propName - If component is specified, propName option will show
3777 only this specific configuration from that component.
3778 Case Sensitive string.
3779 jsonFormat - Returns output as json. Note that this will override
3780 the short option
3781 short - Short, less verbose, version of configurations.
3782 This is overridden by the json option
3783 returns:
3784 Output from cli as a string or None on error
3785 """
3786 try:
3787 baseStr = "cfg"
3788 cmdStr = " get"
3789 componentStr = ""
3790 if component:
3791 componentStr += " " + component
3792 if propName:
3793 componentStr += " " + propName
3794 if jsonFormat:
3795 baseStr += " -j"
3796 elif short:
3797 baseStr += " -s"
3798 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003799 assert "Command not found:" not in output, output
3800 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003801 return output
3802 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003803 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003804 return None
3805 except TypeError:
3806 main.log.exception( self.name + ": Object not as expected" )
3807 return None
3808 except pexpect.EOF:
3809 main.log.error( self.name + ": EOF exception found" )
3810 main.log.error( self.name + ": " + self.handle.before )
3811 main.cleanup()
3812 main.exit()
3813 except Exception:
3814 main.log.exception( self.name + ": Uncaught exception!" )
3815 main.cleanup()
3816 main.exit()
3817
3818 def setCfg( self, component, propName, value=None, check=True ):
3819 """
3820 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003821 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003822 component - The case sensitive name of the component whose
3823 property is to be set
3824 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003825 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003826 value - The value to set the property to. If None, will unset the
3827 property and revert it to it's default value(if applicable)
3828 check - Boolean, Check whether the option was successfully set this
3829 only applies when a value is given.
3830 returns:
3831 main.TRUE on success or main.FALSE on failure. If check is False,
3832 will return main.TRUE unless there is an error
3833 """
3834 try:
3835 baseStr = "cfg"
3836 cmdStr = " set " + str( component ) + " " + str( propName )
3837 if value is not None:
3838 cmdStr += " " + str( value )
3839 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003840 assert "Command not found:" not in output, output
3841 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003842 if value and check:
3843 results = self.getCfg( component=str( component ),
3844 propName=str( propName ),
3845 jsonFormat=True )
3846 # Check if current value is what we just set
3847 try:
3848 jsonOutput = json.loads( results )
3849 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003850 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003851 main.log.exception( "Error parsing cfg output" )
3852 main.log.error( "output:" + repr( results ) )
3853 return main.FALSE
3854 if current == str( value ):
3855 return main.TRUE
3856 return main.FALSE
3857 return main.TRUE
3858 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003859 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003860 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003861 except ( TypeError, ValueError ):
3862 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003863 return main.FALSE
3864 except pexpect.EOF:
3865 main.log.error( self.name + ": EOF exception found" )
3866 main.log.error( self.name + ": " + self.handle.before )
3867 main.cleanup()
3868 main.exit()
3869 except Exception:
3870 main.log.exception( self.name + ": Uncaught exception!" )
3871 main.cleanup()
3872 main.exit()
3873
Jon Hall390696c2015-05-05 17:13:41 -07003874 def setTestAdd( self, setName, values ):
3875 """
3876 CLI command to add elements to a distributed set.
3877 Arguments:
3878 setName - The name of the set to add to.
3879 values - The value(s) to add to the set, space seperated.
3880 Example usages:
3881 setTestAdd( "set1", "a b c" )
3882 setTestAdd( "set2", "1" )
3883 returns:
3884 main.TRUE on success OR
3885 main.FALSE if elements were already in the set OR
3886 main.ERROR on error
3887 """
3888 try:
3889 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3890 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003891 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003892 try:
3893 # TODO: Maybe make this less hardcoded
3894 # ConsistentMap Exceptions
3895 assert "org.onosproject.store.service" not in output
3896 # Node not leader
3897 assert "java.lang.IllegalStateException" not in output
3898 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003899 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003900 "command: " + str( output ) )
3901 retryTime = 30 # Conservative time, given by Madan
3902 main.log.info( "Waiting " + str( retryTime ) +
3903 "seconds before retrying." )
3904 time.sleep( retryTime ) # Due to change in mastership
3905 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003906 assert "Error executing command" not in output
3907 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3908 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3909 main.log.info( self.name + ": " + output )
3910 if re.search( positiveMatch, output):
3911 return main.TRUE
3912 elif re.search( negativeMatch, output):
3913 return main.FALSE
3914 else:
3915 main.log.error( self.name + ": setTestAdd did not" +
3916 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003917 main.log.debug( self.name + " actual: " + repr( output ) )
3918 return main.ERROR
3919 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003920 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003921 return main.ERROR
3922 except TypeError:
3923 main.log.exception( self.name + ": Object not as expected" )
3924 return main.ERROR
3925 except pexpect.EOF:
3926 main.log.error( self.name + ": EOF exception found" )
3927 main.log.error( self.name + ": " + self.handle.before )
3928 main.cleanup()
3929 main.exit()
3930 except Exception:
3931 main.log.exception( self.name + ": Uncaught exception!" )
3932 main.cleanup()
3933 main.exit()
3934
3935 def setTestRemove( self, setName, values, clear=False, retain=False ):
3936 """
3937 CLI command to remove elements from a distributed set.
3938 Required arguments:
3939 setName - The name of the set to remove from.
3940 values - The value(s) to remove from the set, space seperated.
3941 Optional arguments:
3942 clear - Clear all elements from the set
3943 retain - Retain only the given values. (intersection of the
3944 original set and the given set)
3945 returns:
3946 main.TRUE on success OR
3947 main.FALSE if the set was not changed OR
3948 main.ERROR on error
3949 """
3950 try:
3951 cmdStr = "set-test-remove "
3952 if clear:
3953 cmdStr += "-c " + str( setName )
3954 elif retain:
3955 cmdStr += "-r " + str( setName ) + " " + str( values )
3956 else:
3957 cmdStr += str( setName ) + " " + str( values )
3958 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003959 try:
3960 # TODO: Maybe make this less hardcoded
3961 # ConsistentMap Exceptions
3962 assert "org.onosproject.store.service" not in output
3963 # Node not leader
3964 assert "java.lang.IllegalStateException" not in output
3965 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003966 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003967 "command: " + str( output ) )
3968 retryTime = 30 # Conservative time, given by Madan
3969 main.log.info( "Waiting " + str( retryTime ) +
3970 "seconds before retrying." )
3971 time.sleep( retryTime ) # Due to change in mastership
3972 output = self.sendline( cmdStr )
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:
4059 # TODO: Maybe make this less hardcoded
4060 # ConsistentMap Exceptions
4061 assert "org.onosproject.store.service" not in output
4062 # Node not leader
4063 assert "java.lang.IllegalStateException" not in output
4064 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004065 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004066 "command: " + str( output ) )
4067 retryTime = 30 # Conservative time, given by Madan
4068 main.log.info( "Waiting " + str( retryTime ) +
4069 "seconds before retrying." )
4070 time.sleep( retryTime ) # Due to change in mastership
4071 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004072 assert "Command not found:" not in output, output
4073 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004074 main.log.info( self.name + ": " + output )
4075
4076 if length == 0:
4077 match = re.search( pattern, output )
4078 else: # if given values
4079 if length == 1: # Contains output
4080 patternTrue = pattern + "\n" + containsTrue
4081 patternFalse = pattern + "\n" + containsFalse
4082 else: # ContainsAll output
4083 patternTrue = pattern + "\n" + containsAllTrue
4084 patternFalse = pattern + "\n" + containsAllFalse
4085 matchTrue = re.search( patternTrue, output )
4086 matchFalse = re.search( patternFalse, output )
4087 if matchTrue:
4088 containsCheck = main.TRUE
4089 match = matchTrue
4090 elif matchFalse:
4091 containsCheck = main.FALSE
4092 match = matchFalse
4093 else:
4094 main.log.error( self.name + " setTestGet did not match " +\
4095 "expected output" )
4096 main.log.debug( self.name + " expected: " + pattern )
4097 main.log.debug( self.name + " actual: " + repr( output ) )
4098 match = None
4099 if match:
4100 setMatch = match.group( 1 )
4101 if setMatch == '':
4102 setList = []
4103 else:
4104 setList = setMatch.split( ", " )
4105 if length > 0:
4106 return ( setList, containsCheck )
4107 else:
4108 return setList
4109 else: # no match
4110 main.log.error( self.name + ": setTestGet did not" +
4111 " match expected output" )
4112 main.log.debug( self.name + " expected: " + pattern )
4113 main.log.debug( self.name + " actual: " + repr( output ) )
4114 return main.ERROR
4115 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004116 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004117 return main.ERROR
4118 except TypeError:
4119 main.log.exception( self.name + ": Object not as expected" )
4120 return main.ERROR
4121 except pexpect.EOF:
4122 main.log.error( self.name + ": EOF exception found" )
4123 main.log.error( self.name + ": " + self.handle.before )
4124 main.cleanup()
4125 main.exit()
4126 except Exception:
4127 main.log.exception( self.name + ": Uncaught exception!" )
4128 main.cleanup()
4129 main.exit()
4130
4131 def setTestSize( self, setName ):
4132 """
4133 CLI command to get the elements in a distributed set.
4134 Required arguments:
4135 setName - The name of the set to remove from.
4136 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004137 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004138 None on error
4139 """
4140 try:
4141 # TODO: Should this check against the number of elements returned
4142 # and then return true/false based on that?
4143 setName = str( setName ).strip()
4144 # Patterns to match
4145 setPattern = "\[(.*)\]"
4146 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4147 setPattern
4148 cmdStr = "set-test-get -s "
4149 cmdStr += setName
4150 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004151 try:
4152 # TODO: Maybe make this less hardcoded
4153 # ConsistentMap Exceptions
4154 assert "org.onosproject.store.service" not in output
4155 # Node not leader
4156 assert "java.lang.IllegalStateException" not in output
4157 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004158 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004159 "command: " + str( output ) )
4160 retryTime = 30 # Conservative time, given by Madan
4161 main.log.info( "Waiting " + str( retryTime ) +
4162 "seconds before retrying." )
4163 time.sleep( retryTime ) # Due to change in mastership
4164 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004165 assert "Command not found:" not in output, output
4166 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004167 main.log.info( self.name + ": " + output )
4168 match = re.search( pattern, output )
4169 if match:
4170 setSize = int( match.group( 1 ) )
4171 setMatch = match.group( 2 )
4172 if len( setMatch.split() ) == setSize:
4173 main.log.info( "The size returned by " + self.name +
4174 " matches the number of elements in " +
4175 "the returned set" )
4176 else:
4177 main.log.error( "The size returned by " + self.name +
4178 " does not match the number of " +
4179 "elements in the returned set." )
4180 return setSize
4181 else: # no match
4182 main.log.error( self.name + ": setTestGet did not" +
4183 " match expected output" )
4184 main.log.debug( self.name + " expected: " + pattern )
4185 main.log.debug( self.name + " actual: " + repr( output ) )
4186 return None
4187 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004188 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004189 return None
Jon Hall390696c2015-05-05 17:13:41 -07004190 except TypeError:
4191 main.log.exception( self.name + ": Object not as expected" )
4192 return None
4193 except pexpect.EOF:
4194 main.log.error( self.name + ": EOF exception found" )
4195 main.log.error( self.name + ": " + self.handle.before )
4196 main.cleanup()
4197 main.exit()
4198 except Exception:
4199 main.log.exception( self.name + ": Uncaught exception!" )
4200 main.cleanup()
4201 main.exit()
4202
Jon Hall80daded2015-05-27 16:07:00 -07004203 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004204 """
4205 Command to list the various counters in the system.
4206 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004207 if jsonFormat, a string of the json object returned by the cli
4208 command
4209 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004210 None on error
4211 """
Jon Hall390696c2015-05-05 17:13:41 -07004212 try:
4213 counters = {}
4214 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004215 if jsonFormat:
4216 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004217 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004218 assert "Command not found:" not in output, output
4219 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004220 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004221 return output
Jon Hall390696c2015-05-05 17:13:41 -07004222 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004223 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004224 return None
Jon Hall390696c2015-05-05 17:13:41 -07004225 except TypeError:
4226 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004227 return None
Jon Hall390696c2015-05-05 17:13:41 -07004228 except pexpect.EOF:
4229 main.log.error( self.name + ": EOF exception found" )
4230 main.log.error( self.name + ": " + self.handle.before )
4231 main.cleanup()
4232 main.exit()
4233 except Exception:
4234 main.log.exception( self.name + ": Uncaught exception!" )
4235 main.cleanup()
4236 main.exit()
4237
Jon Hall935db192016-04-19 00:22:04 -07004238 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004239 """
Jon Halle1a3b752015-07-22 13:02:46 -07004240 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004241 Required arguments:
4242 counter - The name of the counter to increment.
4243 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004244 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004245 returns:
4246 integer value of the counter or
4247 None on Error
4248 """
4249 try:
4250 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004251 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004252 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004253 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004254 if delta != 1:
4255 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004256 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004257 try:
4258 # TODO: Maybe make this less hardcoded
4259 # ConsistentMap Exceptions
4260 assert "org.onosproject.store.service" not in output
4261 # Node not leader
4262 assert "java.lang.IllegalStateException" not in output
4263 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004264 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004265 "command: " + str( output ) )
4266 retryTime = 30 # Conservative time, given by Madan
4267 main.log.info( "Waiting " + str( retryTime ) +
4268 "seconds before retrying." )
4269 time.sleep( retryTime ) # Due to change in mastership
4270 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004271 assert "Command not found:" not in output, output
4272 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004273 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004274 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004275 match = re.search( pattern, output )
4276 if match:
4277 return int( match.group( 1 ) )
4278 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004279 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004280 " match expected output." )
4281 main.log.debug( self.name + " expected: " + pattern )
4282 main.log.debug( self.name + " actual: " + repr( output ) )
4283 return None
4284 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004285 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004286 return None
4287 except TypeError:
4288 main.log.exception( self.name + ": Object not as expected" )
4289 return None
4290 except pexpect.EOF:
4291 main.log.error( self.name + ": EOF exception found" )
4292 main.log.error( self.name + ": " + self.handle.before )
4293 main.cleanup()
4294 main.exit()
4295 except Exception:
4296 main.log.exception( self.name + ": Uncaught exception!" )
4297 main.cleanup()
4298 main.exit()
4299
Jon Hall935db192016-04-19 00:22:04 -07004300 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004301 """
4302 CLI command to get a distributed counter then add a delta to it.
4303 Required arguments:
4304 counter - The name of the counter to increment.
4305 Optional arguments:
4306 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004307 returns:
4308 integer value of the counter or
4309 None on Error
4310 """
4311 try:
4312 counter = str( counter )
4313 delta = int( delta )
4314 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004315 cmdStr += counter
4316 if delta != 1:
4317 cmdStr += " " + str( delta )
4318 output = self.sendline( cmdStr )
4319 try:
4320 # TODO: Maybe make this less hardcoded
4321 # ConsistentMap Exceptions
4322 assert "org.onosproject.store.service" not in output
4323 # Node not leader
4324 assert "java.lang.IllegalStateException" not in output
4325 except AssertionError:
4326 main.log.error( "Error in processing '" + cmdStr + "' " +
4327 "command: " + str( output ) )
4328 retryTime = 30 # Conservative time, given by Madan
4329 main.log.info( "Waiting " + str( retryTime ) +
4330 "seconds before retrying." )
4331 time.sleep( retryTime ) # Due to change in mastership
4332 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004333 assert "Command not found:" not in output, output
4334 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004335 main.log.info( self.name + ": " + output )
4336 pattern = counter + " was updated to (-?\d+)"
4337 match = re.search( pattern, output )
4338 if match:
4339 return int( match.group( 1 ) )
4340 else:
4341 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4342 " match expected output." )
4343 main.log.debug( self.name + " expected: " + pattern )
4344 main.log.debug( self.name + " actual: " + repr( output ) )
4345 return None
4346 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004347 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004348 return None
4349 except TypeError:
4350 main.log.exception( self.name + ": Object not as expected" )
4351 return None
4352 except pexpect.EOF:
4353 main.log.error( self.name + ": EOF exception found" )
4354 main.log.error( self.name + ": " + self.handle.before )
4355 main.cleanup()
4356 main.exit()
4357 except Exception:
4358 main.log.exception( self.name + ": Uncaught exception!" )
4359 main.cleanup()
4360 main.exit()
4361
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004362 def summary( self, jsonFormat=True ):
4363 """
4364 Description: Execute summary command in onos
4365 Returns: json object ( summary -j ), returns main.FALSE if there is
4366 no output
4367
4368 """
4369 try:
4370 cmdStr = "summary"
4371 if jsonFormat:
4372 cmdStr += " -j"
4373 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004374 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004375 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004376 if not handle:
4377 main.log.error( self.name + ": There is no output in " +
4378 "summary command" )
4379 return main.FALSE
4380 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004381 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004382 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004383 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004384 except TypeError:
4385 main.log.exception( self.name + ": Object not as expected" )
4386 return None
4387 except pexpect.EOF:
4388 main.log.error( self.name + ": EOF exception found" )
4389 main.log.error( self.name + ": " + self.handle.before )
4390 main.cleanup()
4391 main.exit()
4392 except Exception:
4393 main.log.exception( self.name + ": Uncaught exception!" )
4394 main.cleanup()
4395 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004396
Jon Hall935db192016-04-19 00:22:04 -07004397 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004398 """
4399 CLI command to get the value of a key in a consistent map using
4400 transactions. This a test function and can only get keys from the
4401 test map hard coded into the cli command
4402 Required arguments:
4403 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004404 returns:
4405 The string value of the key or
4406 None on Error
4407 """
4408 try:
4409 keyName = str( keyName )
4410 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004411 cmdStr += keyName
4412 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004413 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004414 try:
4415 # TODO: Maybe make this less hardcoded
4416 # ConsistentMap Exceptions
4417 assert "org.onosproject.store.service" not in output
4418 # Node not leader
4419 assert "java.lang.IllegalStateException" not in output
4420 except AssertionError:
4421 main.log.error( "Error in processing '" + cmdStr + "' " +
4422 "command: " + str( output ) )
4423 return None
4424 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4425 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004426 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004427 return None
4428 else:
4429 match = re.search( pattern, output )
4430 if match:
4431 return match.groupdict()[ 'value' ]
4432 else:
4433 main.log.error( self.name + ": transactionlMapGet did not" +
4434 " match expected output." )
4435 main.log.debug( self.name + " expected: " + pattern )
4436 main.log.debug( self.name + " actual: " + repr( output ) )
4437 return None
Jon Hallc6793552016-01-19 14:18:37 -08004438 except AssertionError:
4439 main.log.exception( "" )
4440 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return None
4444 except pexpect.EOF:
4445 main.log.error( self.name + ": EOF exception found" )
4446 main.log.error( self.name + ": " + self.handle.before )
4447 main.cleanup()
4448 main.exit()
4449 except Exception:
4450 main.log.exception( self.name + ": Uncaught exception!" )
4451 main.cleanup()
4452 main.exit()
4453
Jon Hall935db192016-04-19 00:22:04 -07004454 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004455 """
4456 CLI command to put a value into 'numKeys' number of keys in a
4457 consistent map using transactions. This a test function and can only
4458 put into keys named 'Key#' of the test map hard coded into the cli command
4459 Required arguments:
4460 numKeys - Number of keys to add the value to
4461 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004462 returns:
4463 A dictionary whose keys are the name of the keys put into the map
4464 and the values of the keys are dictionaries whose key-values are
4465 'value': value put into map and optionaly
4466 'oldValue': Previous value in the key or
4467 None on Error
4468
4469 Example output
4470 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4471 'Key2': {'value': 'Testing'} }
4472 """
4473 try:
4474 numKeys = str( numKeys )
4475 value = str( value )
4476 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004477 cmdStr += numKeys + " " + value
4478 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004479 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004480 try:
4481 # TODO: Maybe make this less hardcoded
4482 # ConsistentMap Exceptions
4483 assert "org.onosproject.store.service" not in output
4484 # Node not leader
4485 assert "java.lang.IllegalStateException" not in output
4486 except AssertionError:
4487 main.log.error( "Error in processing '" + cmdStr + "' " +
4488 "command: " + str( output ) )
4489 return None
4490 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4491 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4492 results = {}
4493 for line in output.splitlines():
4494 new = re.search( newPattern, line )
4495 updated = re.search( updatedPattern, line )
4496 if new:
4497 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4498 elif updated:
4499 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004500 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004501 else:
4502 main.log.error( self.name + ": transactionlMapGet did not" +
4503 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004504 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4505 newPattern,
4506 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004507 main.log.debug( self.name + " actual: " + repr( output ) )
4508 return results
Jon Hallc6793552016-01-19 14:18:37 -08004509 except AssertionError:
4510 main.log.exception( "" )
4511 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004512 except TypeError:
4513 main.log.exception( self.name + ": Object not as expected" )
4514 return None
4515 except pexpect.EOF:
4516 main.log.error( self.name + ": EOF exception found" )
4517 main.log.error( self.name + ": " + self.handle.before )
4518 main.cleanup()
4519 main.exit()
4520 except Exception:
4521 main.log.exception( self.name + ": Uncaught exception!" )
4522 main.cleanup()
4523 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004524
acsmarsdaea66c2015-09-03 11:44:06 -07004525 def maps( self, jsonFormat=True ):
4526 """
4527 Description: Returns result of onos:maps
4528 Optional:
4529 * jsonFormat: enable json formatting of output
4530 """
4531 try:
4532 cmdStr = "maps"
4533 if jsonFormat:
4534 cmdStr += " -j"
4535 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004536 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004537 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004538 except AssertionError:
4539 main.log.exception( "" )
4540 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004541 except TypeError:
4542 main.log.exception( self.name + ": Object not as expected" )
4543 return None
4544 except pexpect.EOF:
4545 main.log.error( self.name + ": EOF exception found" )
4546 main.log.error( self.name + ": " + self.handle.before )
4547 main.cleanup()
4548 main.exit()
4549 except Exception:
4550 main.log.exception( self.name + ": Uncaught exception!" )
4551 main.cleanup()
4552 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004553
4554 def getSwController( self, uri, jsonFormat=True ):
4555 """
4556 Descrition: Gets the controller information from the device
4557 """
4558 try:
4559 cmd = "device-controllers "
4560 if jsonFormat:
4561 cmd += "-j "
4562 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004563 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004564 return response
Jon Hallc6793552016-01-19 14:18:37 -08004565 except AssertionError:
4566 main.log.exception( "" )
4567 return None
GlennRC050596c2015-11-18 17:06:41 -08004568 except TypeError:
4569 main.log.exception( self.name + ": Object not as expected" )
4570 return None
4571 except pexpect.EOF:
4572 main.log.error( self.name + ": EOF exception found" )
4573 main.log.error( self.name + ": " + self.handle.before )
4574 main.cleanup()
4575 main.exit()
4576 except Exception:
4577 main.log.exception( self.name + ": Uncaught exception!" )
4578 main.cleanup()
4579 main.exit()
4580
4581 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4582 """
4583 Descrition: sets the controller(s) for the specified device
4584
4585 Parameters:
4586 Required: uri - String: The uri of the device(switch).
4587 ip - String or List: The ip address of the controller.
4588 This parameter can be formed in a couple of different ways.
4589 VALID:
4590 10.0.0.1 - just the ip address
4591 tcp:10.0.0.1 - the protocol and the ip address
4592 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4593 so that you can add controllers with different
4594 protocols and ports
4595 INVALID:
4596 10.0.0.1:6653 - this is not supported by ONOS
4597
4598 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4599 port - The port number.
4600 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4601
4602 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4603 """
4604 try:
4605 cmd = "device-setcontrollers"
4606
4607 if jsonFormat:
4608 cmd += " -j"
4609 cmd += " " + uri
4610 if isinstance( ip, str ):
4611 ip = [ip]
4612 for item in ip:
4613 if ":" in item:
4614 sitem = item.split( ":" )
4615 if len(sitem) == 3:
4616 cmd += " " + item
4617 elif "." in sitem[1]:
4618 cmd += " {}:{}".format(item, port)
4619 else:
4620 main.log.error( "Malformed entry: " + item )
4621 raise TypeError
4622 else:
4623 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004624 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004625 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004626 if "Error" in response:
4627 main.log.error( response )
4628 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004629 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004630 except AssertionError:
4631 main.log.exception( "" )
4632 return None
GlennRC050596c2015-11-18 17:06:41 -08004633 except TypeError:
4634 main.log.exception( self.name + ": Object not as expected" )
4635 return main.FALSE
4636 except pexpect.EOF:
4637 main.log.error( self.name + ": EOF exception found" )
4638 main.log.error( self.name + ": " + self.handle.before )
4639 main.cleanup()
4640 main.exit()
4641 except Exception:
4642 main.log.exception( self.name + ": Uncaught exception!" )
4643 main.cleanup()
4644 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004645
4646 def removeDevice( self, device ):
4647 '''
4648 Description:
4649 Remove a device from ONOS by passing the uri of the device(s).
4650 Parameters:
4651 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4652 Returns:
4653 Returns main.FALSE if an exception is thrown or an error is present
4654 in the response. Otherwise, returns main.TRUE.
4655 NOTE:
4656 If a host cannot be removed, then this function will return main.FALSE
4657 '''
4658 try:
4659 if type( device ) is str:
4660 device = list( device )
4661
4662 for d in device:
4663 time.sleep( 1 )
4664 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004665 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004666 if "Error" in response:
4667 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4668 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004669 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004670 except AssertionError:
4671 main.log.exception( "" )
4672 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004673 except TypeError:
4674 main.log.exception( self.name + ": Object not as expected" )
4675 return main.FALSE
4676 except pexpect.EOF:
4677 main.log.error( self.name + ": EOF exception found" )
4678 main.log.error( self.name + ": " + self.handle.before )
4679 main.cleanup()
4680 main.exit()
4681 except Exception:
4682 main.log.exception( self.name + ": Uncaught exception!" )
4683 main.cleanup()
4684 main.exit()
4685
4686 def removeHost( self, host ):
4687 '''
4688 Description:
4689 Remove a host from ONOS by passing the id of the host(s)
4690 Parameters:
4691 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4692 Returns:
4693 Returns main.FALSE if an exception is thrown or an error is present
4694 in the response. Otherwise, returns main.TRUE.
4695 NOTE:
4696 If a host cannot be removed, then this function will return main.FALSE
4697 '''
4698 try:
4699 if type( host ) is str:
4700 host = list( host )
4701
4702 for h in host:
4703 time.sleep( 1 )
4704 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004705 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004706 if "Error" in response:
4707 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4708 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004709 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004710 except AssertionError:
4711 main.log.exception( "" )
4712 return None
GlennRC20fc6522015-12-23 23:26:57 -08004713 except TypeError:
4714 main.log.exception( self.name + ": Object not as expected" )
4715 return main.FALSE
4716 except pexpect.EOF:
4717 main.log.error( self.name + ": EOF exception found" )
4718 main.log.error( self.name + ": " + self.handle.before )
4719 main.cleanup()
4720 main.exit()
4721 except Exception:
4722 main.log.exception( self.name + ": Uncaught exception!" )
4723 main.cleanup()
4724 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004725
Jon Hallc6793552016-01-19 14:18:37 -08004726 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004727 '''
4728 Description:
4729 Bring link down or up in the null-provider.
4730 params:
4731 begin - (string) One end of a device or switch.
4732 end - (string) the other end of the device or switch
4733 returns:
4734 main.TRUE if no exceptions were thrown and no Errors are
4735 present in the resoponse. Otherwise, returns main.FALSE
4736 '''
4737 try:
Jon Hallc6793552016-01-19 14:18:37 -08004738 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004739 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004740 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004741 if "Error" in response or "Failure" in response:
4742 main.log.error( response )
4743 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004744 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004745 except AssertionError:
4746 main.log.exception( "" )
4747 return None
GlennRCed771242016-01-13 17:02:47 -08004748 except TypeError:
4749 main.log.exception( self.name + ": Object not as expected" )
4750 return main.FALSE
4751 except pexpect.EOF:
4752 main.log.error( self.name + ": EOF exception found" )
4753 main.log.error( self.name + ": " + self.handle.before )
4754 main.cleanup()
4755 main.exit()
4756 except Exception:
4757 main.log.exception( self.name + ": Uncaught exception!" )
4758 main.cleanup()
4759 main.exit()
4760