blob: f4d55e1f9b4ec687d864f94814843c850a1d252b [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700154 try:
155 self.handle.expect( "\$" )
156 except pexpect.TIMEOUT:
157 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700158 return main.TRUE
159 else: # some other output
160 main.log.warn( "Unknown repsonse to logout command: '{}'",
161 repr( self.handle.before ) )
162 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700163 elif i == 1: # not in CLI
164 return main.TRUE
165 elif i == 3: # Timeout
166 return main.FALSE
167 else:
andrewonlab9627f432014-11-14 12:45:10 -0500168 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800169 except TypeError:
170 main.log.exception( self.name + ": Object not as expected" )
171 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800173 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700174 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500175 main.cleanup()
176 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700177 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700178 main.log.error( self.name +
179 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800180 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800181 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
184
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800186 """
andrewonlab95ce8322014-10-13 14:12:04 -0400187 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800188
andrewonlab95ce8322014-10-13 14:12:04 -0400189 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800190 """
andrewonlab95ce8322014-10-13 14:12:04 -0400191 try:
192 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800193 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400194 main.cleanup()
195 main.exit()
196 else:
kelvin8ec71442015-01-15 16:57:00 -0800197 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800199 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400200 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800201 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800202 handleBefore = self.handle.before
203 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800204 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800205 self.handle.sendline("")
206 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800207 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400208
kelvin-onlabd3b64892015-01-20 13:26:24 -0800209 main.log.info( "Cell call returned: " + handleBefore +
210 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400211
212 return main.TRUE
213
Jon Halld4d4b372015-01-28 16:02:41 -0800214 except TypeError:
215 main.log.exception( self.name + ": Object not as expected" )
216 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400217 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800218 main.log.error( self.name + ": eof exception found" )
219 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400220 main.cleanup()
221 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800222 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800223 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400224 main.cleanup()
225 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800226
pingping-lin57a56ce2015-05-20 16:43:48 -0700227 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800228 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800229 """
Jon Hallefbd9792015-03-05 16:11:36 -0800230 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 by user would be used to set the current karaf shell idle timeout.
232 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800233 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 Below is an example to start a session with 60 seconds idle timeout
235 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800236
Hari Krishna25d42f72015-01-05 15:08:28 -0800237 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800239
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 Note: karafTimeout is left as str so that this could be read
241 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800242 """
You Wangf69ab392016-01-26 16:34:38 -0800243 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400244 try:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline( "" )
246 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700247 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500248
249 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800250 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500251 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400252
kelvin8ec71442015-01-15 16:57:00 -0800253 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800255 i = self.handle.expect( [
256 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700257 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400258
259 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800261 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800262 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800263 "config:property-set -p org.apache.karaf.shell\
264 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800265 karafTimeout )
266 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800268 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400269 return main.TRUE
270 else:
kelvin8ec71442015-01-15 16:57:00 -0800271 # If failed, send ctrl+c to process and try again
272 main.log.info( "Starting CLI failed. Retrying..." )
273 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800275 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
276 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400277 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800279 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800280 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800281 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 "config:property-set -p org.apache.karaf.shell\
283 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800284 karafTimeout )
285 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400288 return main.TRUE
289 else:
kelvin8ec71442015-01-15 16:57:00 -0800290 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400292 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400293
Jon Halld4d4b372015-01-28 16:02:41 -0800294 except TypeError:
295 main.log.exception( self.name + ": Object not as expected" )
296 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800298 main.log.error( self.name + ": EOF exception found" )
299 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400300 main.cleanup()
301 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800303 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400304 main.cleanup()
305 main.exit()
306
suibin zhang116647a2016-05-06 16:30:09 -0700307 def startCellCli( self, karafTimeout="",
308 commandlineTimeout=10, onosStartTimeout=60 ):
309 """
310 Start CLI on onos ecll handle.
311
312 karafTimeout is an optional argument. karafTimeout value passed
313 by user would be used to set the current karaf shell idle timeout.
314 Note that when ever this property is modified the shell will exit and
315 the subsequent login would reflect new idle timeout.
316 Below is an example to start a session with 60 seconds idle timeout
317 ( input value is in milliseconds ):
318
319 tValue = "60000"
320
321 Note: karafTimeout is left as str so that this could be read
322 and passed to startOnosCli from PARAMS file as str.
323 """
324
325 try:
326 self.handle.sendline( "" )
327 x = self.handle.expect( [
328 "\$", "onos>" ], commandlineTimeout)
329
330 if x == 1:
331 main.log.info( "ONOS cli is already running" )
332 return main.TRUE
333
334 # Wait for onos start ( -w ) and enter onos cli
335 self.handle.sendline( "/opt/onos/bin/onos" )
336 i = self.handle.expect( [
337 "onos>",
338 pexpect.TIMEOUT ], onosStartTimeout )
339
340 if i == 0:
341 main.log.info( self.name + " CLI Started successfully" )
342 if karafTimeout:
343 self.handle.sendline(
344 "config:property-set -p org.apache.karaf.shell\
345 sshIdleTimeout " +
346 karafTimeout )
347 self.handle.expect( "\$" )
348 self.handle.sendline( "/opt/onos/bin/onos" )
349 self.handle.expect( "onos>" )
350 return main.TRUE
351 else:
352 # If failed, send ctrl+c to process and try again
353 main.log.info( "Starting CLI failed. Retrying..." )
354 self.handle.send( "\x03" )
355 self.handle.sendline( "/opt/onos/bin/onos" )
356 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
357 timeout=30 )
358 if i == 0:
359 main.log.info( self.name + " CLI Started " +
360 "successfully after retry attempt" )
361 if karafTimeout:
362 self.handle.sendline(
363 "config:property-set -p org.apache.karaf.shell\
364 sshIdleTimeout " +
365 karafTimeout )
366 self.handle.expect( "\$" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 self.handle.expect( "onos>" )
369 return main.TRUE
370 else:
371 main.log.error( "Connection to CLI " +
372 self.name + " timeout" )
373 return main.FALSE
374
375 except TypeError:
376 main.log.exception( self.name + ": Object not as expected" )
377 return None
378 except pexpect.EOF:
379 main.log.error( self.name + ": EOF exception found" )
380 main.log.error( self.name + ": " + self.handle.before )
381 main.cleanup()
382 main.exit()
383 except Exception:
384 main.log.exception( self.name + ": Uncaught exception!" )
385 main.cleanup()
386 main.exit()
387
YPZhangebf9eb52016-05-12 15:20:24 -0700388 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800389 """
390 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800391 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800392 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700393 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800394 Available level: DEBUG, TRACE, INFO, WARN, ERROR
395 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800396 """
397 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800398 lvlStr = ""
399 if level:
400 lvlStr = "--level=" + level
401
kelvin-onlab338f5512015-02-06 10:53:16 -0800402 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700403 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800404 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800405
kelvin-onlab9f541032015-02-04 16:19:53 -0800406 response = self.handle.before
407 if re.search( "Error", response ):
408 return main.FALSE
409 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700410 except pexpect.TIMEOUT:
411 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700412 if noExit:
413 main.cleanup()
414 return None
415 else:
416 main.cleanup()
417 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 except pexpect.EOF:
419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700421 if noExit:
422 main.cleanup()
423 return None
424 else:
425 main.cleanup()
426 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800427 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800428 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700429 if noExit:
430 main.cleanup()
431 return None
432 else:
433 main.cleanup()
434 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400435
YPZhangebf9eb52016-05-12 15:20:24 -0700436 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800437 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800438 Send a completely user specified string to
439 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400440 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800441
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit is True, TestON will not exit, but clean up
443
andrewonlaba18f6bf2014-10-13 19:31:54 -0400444 Warning: There are no sanity checking to commands
445 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800446
kelvin8ec71442015-01-15 16:57:00 -0800447 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400448 try:
Jon Halla495f562016-05-16 18:03:26 -0700449 # Try to reconnect if disconnected from cli
450 self.handle.sendline( "" )
451 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
452 if i == 1:
453 main.log.error( self.name + ": onos cli session closed. ")
454 if self.onosIp:
455 main.log.warn( "Trying to reconnect " + self.onosIp )
456 reconnectResult = self.startOnosCli( self.onosIp )
457 if reconnectResult:
458 main.log.info( self.name + ": onos cli session reconnected." )
459 else:
460 main.log.error( self.name + ": reconnection failed." )
461 main.cleanup()
462 main.exit()
463 else:
464 main.cleanup()
465 main.exit()
466 if i == 2:
467 self.handle.sendline( "" )
468 self.handle.expect( "onos>" )
469
Jon Hall14a03b52016-05-11 12:07:30 -0700470 if debug:
471 # NOTE: This adds and average of .4 seconds per call
472 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700473 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800475 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800476 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800477 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800478 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
479 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700480 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700481 main.log.debug( self.name + ": Raw output" )
482 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483
484 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800486 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700487 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700488 main.log.debug( self.name + ": ansiEscape output" )
489 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490
kelvin-onlabfb521662015-02-27 09:52:40 -0800491 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800492 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700493 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700494 main.log.debug( self.name + ": Removed extra returns " +
495 "from output" )
496 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497
498 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800499 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700501 main.log.debug( self.name + ": parsed and stripped output" )
502 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503
Jon Hall63604932015-02-26 17:09:50 -0800504 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 output = response.split( cmdStr.strip(), 1 )
506 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700507 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700509 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800510 output = output[1].strip()
511 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800512 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800513 return output
GlennRCed771242016-01-13 17:02:47 -0800514 except pexpect.TIMEOUT:
515 main.log.error( self.name + ":ONOS timeout" )
516 if debug:
517 main.log.debug( self.handle.before )
518 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700519 except IndexError:
520 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700521 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800523 except TypeError:
524 main.log.exception( self.name + ": Object not as expected" )
525 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400526 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800527 main.log.error( self.name + ": EOF exception found" )
528 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700529 if noExit:
530 main.cleanup()
531 return None
532 else:
533 main.cleanup()
534 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800536 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700537 if noExit:
538 main.cleanup()
539 return None
540 else:
541 main.cleanup()
542 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400543
kelvin8ec71442015-01-15 16:57:00 -0800544 # IMPORTANT NOTE:
545 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 # the cli command changing 'a:b' with 'aB'.
547 # Ex ) onos:topology > onosTopology
548 # onos:links > onosLinks
549 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800552 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 Adds a new cluster node by ID and address information.
554 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 * nodeId
556 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400557 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800559 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400560 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800561 cmdStr = "add-node " + str( nodeId ) + " " +\
562 str( ONOSIp ) + " " + str( tcpPort )
563 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700564 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800565 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800566 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error( "Error in adding node" )
568 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800569 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400570 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800573 except AssertionError:
574 main.log.exception( "" )
575 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800576 except TypeError:
577 main.log.exception( self.name + ": Object not as expected" )
578 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error( self.name + ": EOF exception found" )
581 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 main.cleanup()
583 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800584 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800585 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 main.cleanup()
587 main.exit()
588
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlab86dc3082014-10-13 18:18:38 -0400591 Removes a cluster by ID
592 Issues command: 'remove-node [<node-id>]'
593 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800595 """
andrewonlab86dc3082014-10-13 18:18:38 -0400596 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700599 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700600 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800601 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700602 if re.search( "Error", handle ):
603 main.log.error( "Error in removing node" )
604 main.log.error( handle )
605 return main.FALSE
606 else:
607 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800608 except AssertionError:
609 main.log.exception( "" )
610 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800611 except TypeError:
612 main.log.exception( self.name + ": Object not as expected" )
613 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800615 main.log.error( self.name + ": EOF exception found" )
616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400617 main.cleanup()
618 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400621 main.cleanup()
622 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400623
Jon Hall61282e32015-03-19 11:34:11 -0700624 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800625 """
andrewonlab7c211572014-10-15 16:45:20 -0400626 List the nodes currently visible
627 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700628 Optional argument:
629 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800630 """
andrewonlab7c211572014-10-15 16:45:20 -0400631 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700632 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700633 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 cmdStr += " -j"
635 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700636 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800637 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 return output
Jon Hallc6793552016-01-19 14:18:37 -0800639 except AssertionError:
640 main.log.exception( "" )
641 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800642 except TypeError:
643 main.log.exception( self.name + ": Object not as expected" )
644 return None
andrewonlab7c211572014-10-15 16:45:20 -0400645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": EOF exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800651 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400652 main.cleanup()
653 main.exit()
654
kelvin8ec71442015-01-15 16:57:00 -0800655 def topology( self ):
656 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700657 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700658 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700659 Return:
660 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800661 """
andrewonlab95ce8322014-10-13 14:12:04 -0400662 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700663 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800665 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700666 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400667 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800668 except AssertionError:
669 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800670 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400674 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400677 main.cleanup()
678 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800679 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800680 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400681 main.cleanup()
682 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800683
jenkins7ead5a82015-03-13 10:28:21 -0700684 def deviceRemove( self, deviceId ):
685 """
686 Removes particular device from storage
687
688 TODO: refactor this function
689 """
690 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr = "device-remove " + str( deviceId )
692 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800693 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700694 if re.search( "Error", handle ):
695 main.log.error( "Error in removing device" )
696 main.log.error( handle )
697 return main.FALSE
698 else:
699 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800700 except AssertionError:
701 main.log.exception( "" )
702 return None
jenkins7ead5a82015-03-13 10:28:21 -0700703 except TypeError:
704 main.log.exception( self.name + ": Object not as expected" )
705 return None
706 except pexpect.EOF:
707 main.log.error( self.name + ": EOF exception found" )
708 main.log.error( self.name + ": " + self.handle.before )
709 main.cleanup()
710 main.exit()
711 except Exception:
712 main.log.exception( self.name + ": Uncaught exception!" )
713 main.cleanup()
714 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700715
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800717 """
Jon Hall7b02d952014-10-17 20:14:54 -0400718 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400719 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800721 """
andrewonlab86dc3082014-10-13 18:18:38 -0400722 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700723 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr += " -j"
726 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800727 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700728 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800729 except AssertionError:
730 main.log.exception( "" )
731 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800732 except TypeError:
733 main.log.exception( self.name + ": Object not as expected" )
734 return None
andrewonlab7c211572014-10-15 16:45:20 -0400735 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800736 main.log.error( self.name + ": EOF exception found" )
737 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400738 main.cleanup()
739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800741 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400742 main.cleanup()
743 main.exit()
744
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800746 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800747 This balances the devices across all controllers
748 by issuing command: 'onos> onos:balance-masters'
749 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800750 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800751 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800754 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 if re.search( "Error", handle ):
756 main.log.error( "Error in balancing masters" )
757 main.log.error( handle )
758 return main.FALSE
759 else:
760 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800761 except AssertionError:
762 main.log.exception( "" )
763 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800764 except TypeError:
765 main.log.exception( self.name + ": Object not as expected" )
766 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800768 main.log.error( self.name + ": EOF exception found" )
769 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800770 main.cleanup()
771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800773 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800774 main.cleanup()
775 main.exit()
776
Jon Hallc6793552016-01-19 14:18:37 -0800777 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700778 """
779 Returns the output of the masters command.
780 Optional argument:
781 * jsonFormat - boolean indicating if you want output in json
782 """
783 try:
784 cmdStr = "onos:masters"
785 if jsonFormat:
786 cmdStr += " -j"
787 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700788 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800789 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700790 return output
Jon Hallc6793552016-01-19 14:18:37 -0800791 except AssertionError:
792 main.log.exception( "" )
793 return None
acsmars24950022015-07-30 18:00:43 -0700794 except TypeError:
795 main.log.exception( self.name + ": Object not as expected" )
796 return None
797 except pexpect.EOF:
798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
800 main.cleanup()
801 main.exit()
802 except Exception:
803 main.log.exception( self.name + ": Uncaught exception!" )
804 main.cleanup()
805 main.exit()
806
Jon Hallc6793552016-01-19 14:18:37 -0800807 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700808 """
809 Uses the master command to check that the devices' leadership
810 is evenly divided
811
812 Dependencies: checkMasters() and summary()
813
814 Returns main.True if the devices are balanced
815 Returns main.False if the devices are unbalanced
816 Exits on Exception
817 Returns None on TypeError
818 """
819 try:
Jon Hallc6793552016-01-19 14:18:37 -0800820 summaryOutput = self.summary()
821 totalDevices = json.loads( summaryOutput )[ "devices" ]
822 except ( TypeError, ValueError ):
823 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
824 return None
825 try:
acsmars24950022015-07-30 18:00:43 -0700826 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800827 mastersOutput = self.checkMasters()
828 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700829 first = masters[ 0 ][ "size" ]
830 for master in masters:
831 totalOwnedDevices += master[ "size" ]
832 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
833 main.log.error( "Mastership not balanced" )
834 main.log.info( "\n" + self.checkMasters( False ) )
835 return main.FALSE
836 main.log.info( "Mastership balanced between " \
837 + str( len(masters) ) + " masters" )
838 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800839 except ( TypeError, ValueError ):
840 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700841 return None
842 except pexpect.EOF:
843 main.log.error( self.name + ": EOF exception found" )
844 main.log.error( self.name + ": " + self.handle.before )
845 main.cleanup()
846 main.exit()
847 except Exception:
848 main.log.exception( self.name + ": Uncaught exception!" )
849 main.cleanup()
850 main.exit()
851
YPZhangfebf7302016-05-24 16:45:56 -0700852 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800853 """
Jon Halle8217482014-10-17 13:49:14 -0400854 Lists all core links
855 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800857 """
Jon Halle8217482014-10-17 13:49:14 -0400858 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700859 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700862 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800863 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700864 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800865 except AssertionError:
866 main.log.exception( "" )
867 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800868 except TypeError:
869 main.log.exception( self.name + ": Object not as expected" )
870 return None
Jon Halle8217482014-10-17 13:49:14 -0400871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800872 main.log.error( self.name + ": EOF exception found" )
873 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400874 main.cleanup()
875 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800876 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800877 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400878 main.cleanup()
879 main.exit()
880
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800882 """
Jon Halle8217482014-10-17 13:49:14 -0400883 Lists all ports
884 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800886 """
Jon Halle8217482014-10-17 13:49:14 -0400887 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700888 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700890 cmdStr += " -j"
891 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800892 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700893 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800894 except AssertionError:
895 main.log.exception( "" )
896 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800897 except TypeError:
898 main.log.exception( self.name + ": Object not as expected" )
899 return None
Jon Halle8217482014-10-17 13:49:14 -0400900 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400903 main.cleanup()
904 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800905 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800906 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400907 main.cleanup()
908 main.exit()
909
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800911 """
Jon Hall983a1702014-10-28 18:44:22 -0400912 Lists all devices and the controllers with roles assigned to them
913 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800915 """
andrewonlab7c211572014-10-15 16:45:20 -0400916 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700917 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700919 cmdStr += " -j"
920 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800921 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800923 except AssertionError:
924 main.log.exception( "" )
925 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800926 except TypeError:
927 main.log.exception( self.name + ": Object not as expected" )
928 return None
Jon Hall983a1702014-10-28 18:44:22 -0400929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400932 main.cleanup()
933 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800935 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400936 main.cleanup()
937 main.exit()
938
kelvin-onlabd3b64892015-01-20 13:26:24 -0800939 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800940 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800941 Given the a string containing the json representation of the "roles"
942 cli command and a partial or whole device id, returns a json object
943 containing the roles output for the first device whose id contains
944 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400945
946 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800947 A dict of the role assignments for the given device or
948 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800949 """
Jon Hall983a1702014-10-28 18:44:22 -0400950 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400952 return None
953 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 rawRoles = self.roles()
955 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800956 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800958 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400960 return device
961 return None
Jon Hallc6793552016-01-19 14:18:37 -0800962 except ( TypeError, ValueError ):
963 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800964 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400965 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400968 main.cleanup()
969 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800970 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800971 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400972 main.cleanup()
973 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800974
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800976 """
Jon Hall94fd0472014-12-08 11:52:42 -0800977 Iterates through each device and checks if there is a master assigned
978 Returns: main.TRUE if each device has a master
979 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800980 """
Jon Hall94fd0472014-12-08 11:52:42 -0800981 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 rawRoles = self.roles()
983 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800984 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800986 # print device
987 if device[ 'master' ] == "none":
988 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800989 return main.FALSE
990 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800991 except ( TypeError, ValueError ):
992 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800993 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.error( self.name + ": EOF exception found" )
996 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800997 main.cleanup()
998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001000 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 main.cleanup()
1002 main.exit()
1003
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001005 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001006 Returns string of paths, and the cost.
1007 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001008 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001009 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1011 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001012 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001013 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.error( "Error in getting paths" )
1015 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 else:
kelvin8ec71442015-01-15 16:57:00 -08001017 path = handle.split( ";" )[ 0 ]
1018 cost = handle.split( ";" )[ 1 ]
1019 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001020 except AssertionError:
1021 main.log.exception( "" )
1022 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001023 except TypeError:
1024 main.log.exception( self.name + ": Object not as expected" )
1025 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 main.cleanup()
1030 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001031 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001032 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001033 main.cleanup()
1034 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001035
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001037 """
Jon Hallffb386d2014-11-21 13:43:38 -08001038 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001039 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001040 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001041 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001042 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001043 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001045 cmdStr += " -j"
1046 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001047 if handle:
1048 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001049 # TODO: Maybe make this less hardcoded
1050 # ConsistentMap Exceptions
1051 assert "org.onosproject.store.service" not in handle
1052 # Node not leader
1053 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001055 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001057 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001058 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001059 except TypeError:
1060 main.log.exception( self.name + ": Object not as expected" )
1061 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.error( self.name + ": EOF exception found" )
1064 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001065 main.cleanup()
1066 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001074 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001075
Jon Hallefbd9792015-03-05 16:11:36 -08001076 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001077 partial mac address
1078
Jon Hall42db6dc2014-10-24 19:03:48 -04001079 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 try:
kelvin8ec71442015-01-15 16:57:00 -08001082 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001083 return None
1084 else:
1085 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 rawHosts = self.hosts()
1087 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001088 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001090 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001091 if not host:
1092 pass
1093 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001094 return host
1095 return None
Jon Hallc6793552016-01-19 14:18:37 -08001096 except ( TypeError, ValueError ):
1097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001102 main.cleanup()
1103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001105 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 main.cleanup()
1107 main.exit()
1108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001110 """
1111 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001112 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001113
andrewonlab3f0a4af2014-10-17 12:25:14 -04001114 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 IMPORTANT:
1117 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001118 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Furthermore, it assumes that value of VLAN is '-1'
1120 Description:
kelvin8ec71442015-01-15 16:57:00 -08001121 Converts mininet hosts ( h1, h2, h3... ) into
1122 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1123 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001128 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 hostHex = hex( int( host ) ).zfill( 12 )
1130 hostHex = str( hostHex ).replace( 'x', '0' )
1131 i = iter( str( hostHex ) )
1132 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1133 hostHex = hostHex + "/-1"
1134 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137
Jon Halld4d4b372015-01-28 16:02:41 -08001138 except TypeError:
1139 main.log.exception( self.name + ": Object not as expected" )
1140 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001142 main.log.error( self.name + ": EOF exception found" )
1143 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144 main.cleanup()
1145 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001146 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001147 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 main.cleanup()
1149 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001150
Jeremy Songsterff553672016-05-12 17:06:23 -07001151 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001152 """
andrewonlabe6745342014-10-17 14:29:13 -04001153 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 * hostIdOne: ONOS host id for host1
1155 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001156 Optional:
1157 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001158 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001159 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001160 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001161 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001162 Returns:
1163 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlabe6745342014-10-17 14:29:13 -04001165 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001166 cmdStr = "add-host-intent "
1167 if vlanId:
1168 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001169 if setVlan:
1170 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001171 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001173 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001174 if re.search( "Error", handle ):
1175 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001176 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001177 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001178 else:
1179 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001180 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1181 match = re.search('id=0x([\da-f]+),', handle)
1182 if match:
1183 return match.group()[3:-1]
1184 else:
1185 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001186 main.log.debug( "Response from ONOS was: " +
1187 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 return None
Jon Hallc6793552016-01-19 14:18:37 -08001189 except AssertionError:
1190 main.log.exception( "" )
1191 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001192 except TypeError:
1193 main.log.exception( self.name + ": Object not as expected" )
1194 return None
andrewonlabe6745342014-10-17 14:29:13 -04001195 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001196 main.log.error( self.name + ": EOF exception found" )
1197 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001198 main.cleanup()
1199 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001200 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001201 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001202 main.cleanup()
1203 main.exit()
1204
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001206 """
andrewonlab7b31d232014-10-24 13:31:47 -04001207 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 * ingressDevice: device id of ingress device
1209 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001210 Optional:
1211 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001212 Description:
1213 Adds an optical intent by specifying an ingress and egress device
1214 Returns:
1215 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001216 """
andrewonlab7b31d232014-10-24 13:31:47 -04001217 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1219 " " + str( egressDevice )
1220 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001221 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001223 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001224 main.log.error( "Error in adding Optical intent" )
1225 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001226 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 main.log.info( "Optical intent installed between " +
1228 str( ingressDevice ) + " and " +
1229 str( egressDevice ) )
1230 match = re.search('id=0x([\da-f]+),', handle)
1231 if match:
1232 return match.group()[3:-1]
1233 else:
1234 main.log.error( "Error, intent ID not found" )
1235 return None
Jon Hallc6793552016-01-19 14:18:37 -08001236 except AssertionError:
1237 main.log.exception( "" )
1238 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001239 except TypeError:
1240 main.log.exception( self.name + ": Object not as expected" )
1241 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001243 main.log.error( self.name + ": EOF exception found" )
1244 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001245 main.cleanup()
1246 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001247 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001248 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001249 main.cleanup()
1250 main.exit()
1251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 ingressDevice,
1255 egressDevice,
1256 portIngress="",
1257 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 ethType="",
1259 ethSrc="",
1260 ethDst="",
1261 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 ipProto="",
1264 ipSrc="",
1265 ipDst="",
1266 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001267 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001268 vlanId="",
1269 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001270 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001271 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 * ingressDevice: device id of ingress device
1273 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001274 Optional:
1275 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001276 * ethSrc: specify ethSrc ( i.e. src mac addr )
1277 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001278 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001280 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001281 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001282 * ipSrc: specify ip source address
1283 * ipDst: specify ip destination address
1284 * tcpSrc: specify tcp source port
1285 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001286 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001287 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001288 Description:
kelvin8ec71442015-01-15 16:57:00 -08001289 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001290 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 Returns:
1292 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001293
Jon Halle3f39ff2015-01-13 11:50:53 -08001294 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001295 options developers provide for point-to-point
1296 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001297 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001298 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001299 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001300
Jeremy Songsterff553672016-05-12 17:06:23 -07001301 if ethType:
1302 cmd += " --ethType " + str( ethType )
1303 if ethSrc:
1304 cmd += " --ethSrc " + str( ethSrc )
1305 if ethDst:
1306 cmd += " --ethDst " + str( ethDst )
1307 if bandwidth:
1308 cmd += " --bandwidth " + str( bandwidth )
1309 if lambdaAlloc:
1310 cmd += " --lambda "
1311 if ipProto:
1312 cmd += " --ipProto " + str( ipProto )
1313 if ipSrc:
1314 cmd += " --ipSrc " + str( ipSrc )
1315 if ipDst:
1316 cmd += " --ipDst " + str( ipDst )
1317 if tcpSrc:
1318 cmd += " --tcpSrc " + str( tcpSrc )
1319 if tcpDst:
1320 cmd += " --tcpDst " + str( tcpDst )
1321 if vlanId:
1322 cmd += " -v " + str( vlanId )
1323 if setVlan:
1324 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001325
kelvin8ec71442015-01-15 16:57:00 -08001326 # Check whether the user appended the port
1327 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 if "/" in ingressDevice:
1329 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001330 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001331 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001332 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001333 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 # Would it make sense to throw an exception and exit
1335 # the test?
1336 return None
andrewonlab36af3822014-11-18 17:48:18 -05001337
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 str( ingressDevice ) + "/" +\
1340 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001341
kelvin-onlabd3b64892015-01-20 13:26:24 -08001342 if "/" in egressDevice:
1343 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001344 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 main.log.error( "You must specify the egress port" )
1347 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001348
kelvin8ec71442015-01-15 16:57:00 -08001349 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001350 str( egressDevice ) + "/" +\
1351 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001352
kelvin-onlab898a6c62015-01-16 14:13:53 -08001353 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001354 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001355 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001356 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001357 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001359 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001360 # TODO: print out all the options in this message?
1361 main.log.info( "Point-to-point intent installed between " +
1362 str( ingressDevice ) + " and " +
1363 str( egressDevice ) )
1364 match = re.search('id=0x([\da-f]+),', handle)
1365 if match:
1366 return match.group()[3:-1]
1367 else:
1368 main.log.error( "Error, intent ID not found" )
1369 return None
Jon Hallc6793552016-01-19 14:18:37 -08001370 except AssertionError:
1371 main.log.exception( "" )
1372 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001373 except TypeError:
1374 main.log.exception( self.name + ": Object not as expected" )
1375 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001376 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001377 main.log.error( self.name + ": EOF exception found" )
1378 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001379 main.cleanup()
1380 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001381 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001382 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001383 main.cleanup()
1384 main.exit()
1385
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001387 self,
shahshreyac2f97072015-03-19 17:04:29 -07001388 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001390 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001392 ethType="",
1393 ethSrc="",
1394 ethDst="",
1395 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001397 ipProto="",
1398 ipSrc="",
1399 ipDst="",
1400 tcpSrc="",
1401 tcpDst="",
1402 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001403 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001404 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001405 setVlan="",
1406 partial=False ):
kelvin8ec71442015-01-15 16:57:00 -08001407 """
shahshreyad0c80432014-12-04 16:56:05 -08001408 Note:
shahshreya70622b12015-03-19 17:19:00 -07001409 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001410 is same. That is, all ingress devices include port numbers
1411 with a "/" or all ingress devices could specify device
1412 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001413 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001414 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001415 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001417 Optional:
1418 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001419 * ethSrc: specify ethSrc ( i.e. src mac addr )
1420 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001421 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001422 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001423 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001424 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001425 * ipSrc: specify ip source address
1426 * ipDst: specify ip destination address
1427 * tcpSrc: specify tcp source port
1428 * tcpDst: specify tcp destination port
1429 * setEthSrc: action to Rewrite Source MAC Address
1430 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001431 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001432 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001433 Description:
kelvin8ec71442015-01-15 16:57:00 -08001434 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001435 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001436 Returns:
1437 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001438
Jon Halle3f39ff2015-01-13 11:50:53 -08001439 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001440 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001441 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001442 """
shahshreyad0c80432014-12-04 16:56:05 -08001443 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001444 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001445
Jeremy Songsterff553672016-05-12 17:06:23 -07001446 if ethType:
1447 cmd += " --ethType " + str( ethType )
1448 if ethSrc:
1449 cmd += " --ethSrc " + str( ethSrc )
1450 if ethDst:
1451 cmd += " --ethDst " + str( ethDst )
1452 if bandwidth:
1453 cmd += " --bandwidth " + str( bandwidth )
1454 if lambdaAlloc:
1455 cmd += " --lambda "
1456 if ipProto:
1457 cmd += " --ipProto " + str( ipProto )
1458 if ipSrc:
1459 cmd += " --ipSrc " + str( ipSrc )
1460 if ipDst:
1461 cmd += " --ipDst " + str( ipDst )
1462 if tcpSrc:
1463 cmd += " --tcpSrc " + str( tcpSrc )
1464 if tcpDst:
1465 cmd += " --tcpDst " + str( tcpDst )
1466 if setEthSrc:
1467 cmd += " --setEthSrc " + str( setEthSrc )
1468 if setEthDst:
1469 cmd += " --setEthDst " + str( setEthDst )
1470 if vlanId:
1471 cmd += " -v " + str( vlanId )
1472 if setVlan:
1473 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001474 if partial:
1475 cmd += " --partial"
shahshreyad0c80432014-12-04 16:56:05 -08001476
kelvin8ec71442015-01-15 16:57:00 -08001477 # Check whether the user appended the port
1478 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001479
1480 if portIngressList is None:
1481 for ingressDevice in ingressDeviceList:
1482 if "/" in ingressDevice:
1483 cmd += " " + str( ingressDevice )
1484 else:
1485 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001486 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001487 # TODO: perhaps more meaningful return
1488 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001489 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001490 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001491 for ingressDevice, portIngress in zip( ingressDeviceList,
1492 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001493 cmd += " " + \
1494 str( ingressDevice ) + "/" +\
1495 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001496 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001497 main.log.error( "Device list and port list does not " +
1498 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001499 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 if "/" in egressDevice:
1501 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001502 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001504 main.log.error( "You must specify " +
1505 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001506 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001507
kelvin8ec71442015-01-15 16:57:00 -08001508 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 str( egressDevice ) + "/" +\
1510 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001511 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001512 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001513 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001514 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001515 main.log.error( "Error in adding multipoint-to-singlepoint " +
1516 "intent" )
1517 return None
shahshreyad0c80432014-12-04 16:56:05 -08001518 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001519 match = re.search('id=0x([\da-f]+),', handle)
1520 if match:
1521 return match.group()[3:-1]
1522 else:
1523 main.log.error( "Error, intent ID not found" )
1524 return None
Jon Hallc6793552016-01-19 14:18:37 -08001525 except AssertionError:
1526 main.log.exception( "" )
1527 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001528 except TypeError:
1529 main.log.exception( self.name + ": Object not as expected" )
1530 return None
1531 except pexpect.EOF:
1532 main.log.error( self.name + ": EOF exception found" )
1533 main.log.error( self.name + ": " + self.handle.before )
1534 main.cleanup()
1535 main.exit()
1536 except Exception:
1537 main.log.exception( self.name + ": Uncaught exception!" )
1538 main.cleanup()
1539 main.exit()
1540
1541 def addSinglepointToMultipointIntent(
1542 self,
1543 ingressDevice,
1544 egressDeviceList,
1545 portIngress="",
1546 portEgressList=None,
1547 ethType="",
1548 ethSrc="",
1549 ethDst="",
1550 bandwidth="",
1551 lambdaAlloc=False,
1552 ipProto="",
1553 ipSrc="",
1554 ipDst="",
1555 tcpSrc="",
1556 tcpDst="",
1557 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001558 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001559 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001560 setVlan="",
1561 partial=False ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001562 """
1563 Note:
1564 This function assumes the format of all egress devices
1565 is same. That is, all egress devices include port numbers
1566 with a "/" or all egress devices could specify device
1567 ids and port numbers seperately.
1568 Required:
1569 * EgressDeviceList: List of device ids of egress device
1570 ( Atleast 2 eress devices required in the list )
1571 * ingressDevice: device id of ingress device
1572 Optional:
1573 * ethType: specify ethType
1574 * ethSrc: specify ethSrc ( i.e. src mac addr )
1575 * ethDst: specify ethDst ( i.e. dst mac addr )
1576 * bandwidth: specify bandwidth capacity of link
1577 * lambdaAlloc: if True, intent will allocate lambda
1578 for the specified intent
1579 * ipProto: specify ip protocol
1580 * ipSrc: specify ip source address
1581 * ipDst: specify ip destination address
1582 * tcpSrc: specify tcp source port
1583 * tcpDst: specify tcp destination port
1584 * setEthSrc: action to Rewrite Source MAC Address
1585 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001586 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001587 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001588 Description:
1589 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1590 specifying device id's and optional fields
1591 Returns:
1592 A string of the intent id or None on error
1593
1594 NOTE: This function may change depending on the
1595 options developers provide for singlepoint-to-multipoint
1596 intent via cli
1597 """
1598 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001599 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001600
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 if ethType:
1602 cmd += " --ethType " + str( ethType )
1603 if ethSrc:
1604 cmd += " --ethSrc " + str( ethSrc )
1605 if ethDst:
1606 cmd += " --ethDst " + str( ethDst )
1607 if bandwidth:
1608 cmd += " --bandwidth " + str( bandwidth )
1609 if lambdaAlloc:
1610 cmd += " --lambda "
1611 if ipProto:
1612 cmd += " --ipProto " + str( ipProto )
1613 if ipSrc:
1614 cmd += " --ipSrc " + str( ipSrc )
1615 if ipDst:
1616 cmd += " --ipDst " + str( ipDst )
1617 if tcpSrc:
1618 cmd += " --tcpSrc " + str( tcpSrc )
1619 if tcpDst:
1620 cmd += " --tcpDst " + str( tcpDst )
1621 if setEthSrc:
1622 cmd += " --setEthSrc " + str( setEthSrc )
1623 if setEthDst:
1624 cmd += " --setEthDst " + str( setEthDst )
1625 if vlanId:
1626 cmd += " -v " + str( vlanId )
1627 if setVlan:
1628 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001629 if partial:
1630 cmd += " --partial"
kelvin-onlabb9408212015-04-01 13:34:04 -07001631
1632 # Check whether the user appended the port
1633 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001634
kelvin-onlabb9408212015-04-01 13:34:04 -07001635 if "/" in ingressDevice:
1636 cmd += " " + str( ingressDevice )
1637 else:
1638 if not portIngress:
1639 main.log.error( "You must specify " +
1640 "the Ingress port" )
1641 return main.FALSE
1642
1643 cmd += " " +\
1644 str( ingressDevice ) + "/" +\
1645 str( portIngress )
1646
1647 if portEgressList is None:
1648 for egressDevice in egressDeviceList:
1649 if "/" in egressDevice:
1650 cmd += " " + str( egressDevice )
1651 else:
1652 main.log.error( "You must specify " +
1653 "the egress port" )
1654 # TODO: perhaps more meaningful return
1655 return main.FALSE
1656 else:
1657 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001658 for egressDevice, portEgress in zip( egressDeviceList,
1659 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001660 cmd += " " + \
1661 str( egressDevice ) + "/" +\
1662 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001663 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001664 main.log.error( "Device list and port list does not " +
1665 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001666 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001667 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001668 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001669 # If error, return error message
1670 if re.search( "Error", handle ):
1671 main.log.error( "Error in adding singlepoint-to-multipoint " +
1672 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001673 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001674 else:
1675 match = re.search('id=0x([\da-f]+),', handle)
1676 if match:
1677 return match.group()[3:-1]
1678 else:
1679 main.log.error( "Error, intent ID not found" )
1680 return None
Jon Hallc6793552016-01-19 14:18:37 -08001681 except AssertionError:
1682 main.log.exception( "" )
1683 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001684 except TypeError:
1685 main.log.exception( self.name + ": Object not as expected" )
1686 return None
shahshreyad0c80432014-12-04 16:56:05 -08001687 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001688 main.log.error( self.name + ": EOF exception found" )
1689 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001690 main.cleanup()
1691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001692 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001693 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001694 main.cleanup()
1695 main.exit()
1696
Hari Krishna9e232602015-04-13 17:29:08 -07001697 def addMplsIntent(
1698 self,
1699 ingressDevice,
1700 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001701 ingressPort="",
1702 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001703 ethType="",
1704 ethSrc="",
1705 ethDst="",
1706 bandwidth="",
1707 lambdaAlloc=False,
1708 ipProto="",
1709 ipSrc="",
1710 ipDst="",
1711 tcpSrc="",
1712 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001713 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001714 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001715 priority=""):
1716 """
1717 Required:
1718 * ingressDevice: device id of ingress device
1719 * egressDevice: device id of egress device
1720 Optional:
1721 * ethType: specify ethType
1722 * ethSrc: specify ethSrc ( i.e. src mac addr )
1723 * ethDst: specify ethDst ( i.e. dst mac addr )
1724 * bandwidth: specify bandwidth capacity of link
1725 * lambdaAlloc: if True, intent will allocate lambda
1726 for the specified intent
1727 * ipProto: specify ip protocol
1728 * ipSrc: specify ip source address
1729 * ipDst: specify ip destination address
1730 * tcpSrc: specify tcp source port
1731 * tcpDst: specify tcp destination port
1732 * ingressLabel: Ingress MPLS label
1733 * egressLabel: Egress MPLS label
1734 Description:
1735 Adds MPLS intent by
1736 specifying device id's and optional fields
1737 Returns:
1738 A string of the intent id or None on error
1739
1740 NOTE: This function may change depending on the
1741 options developers provide for MPLS
1742 intent via cli
1743 """
1744 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001745 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001746
Jeremy Songsterff553672016-05-12 17:06:23 -07001747 if ethType:
1748 cmd += " --ethType " + str( ethType )
1749 if ethSrc:
1750 cmd += " --ethSrc " + str( ethSrc )
1751 if ethDst:
1752 cmd += " --ethDst " + str( ethDst )
1753 if bandwidth:
1754 cmd += " --bandwidth " + str( bandwidth )
1755 if lambdaAlloc:
1756 cmd += " --lambda "
1757 if ipProto:
1758 cmd += " --ipProto " + str( ipProto )
1759 if ipSrc:
1760 cmd += " --ipSrc " + str( ipSrc )
1761 if ipDst:
1762 cmd += " --ipDst " + str( ipDst )
1763 if tcpSrc:
1764 cmd += " --tcpSrc " + str( tcpSrc )
1765 if tcpDst:
1766 cmd += " --tcpDst " + str( tcpDst )
1767 if ingressLabel:
1768 cmd += " --ingressLabel " + str( ingressLabel )
1769 if egressLabel:
1770 cmd += " --egressLabel " + str( egressLabel )
1771 if priority:
1772 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001773
1774 # Check whether the user appended the port
1775 # or provided it as an input
1776 if "/" in ingressDevice:
1777 cmd += " " + str( ingressDevice )
1778 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001779 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001780 main.log.error( "You must specify the ingress port" )
1781 return None
1782
1783 cmd += " " + \
1784 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001785 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001786
1787 if "/" in egressDevice:
1788 cmd += " " + str( egressDevice )
1789 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001790 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001791 main.log.error( "You must specify the egress port" )
1792 return None
1793
1794 cmd += " " +\
1795 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001796 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001797
1798 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001799 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001800 # If error, return error message
1801 if re.search( "Error", handle ):
1802 main.log.error( "Error in adding mpls intent" )
1803 return None
1804 else:
1805 # TODO: print out all the options in this message?
1806 main.log.info( "MPLS intent installed between " +
1807 str( ingressDevice ) + " and " +
1808 str( egressDevice ) )
1809 match = re.search('id=0x([\da-f]+),', handle)
1810 if match:
1811 return match.group()[3:-1]
1812 else:
1813 main.log.error( "Error, intent ID not found" )
1814 return None
Jon Hallc6793552016-01-19 14:18:37 -08001815 except AssertionError:
1816 main.log.exception( "" )
1817 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001818 except TypeError:
1819 main.log.exception( self.name + ": Object not as expected" )
1820 return None
1821 except pexpect.EOF:
1822 main.log.error( self.name + ": EOF exception found" )
1823 main.log.error( self.name + ": " + self.handle.before )
1824 main.cleanup()
1825 main.exit()
1826 except Exception:
1827 main.log.exception( self.name + ": Uncaught exception!" )
1828 main.cleanup()
1829 main.exit()
1830
Jon Hallefbd9792015-03-05 16:11:36 -08001831 def removeIntent( self, intentId, app='org.onosproject.cli',
1832 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001833 """
shahshreya1c818fc2015-02-26 13:44:08 -08001834 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001835 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001836 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001837 -p or --purge: Purge the intent from the store after removal
1838
Jon Halle3f39ff2015-01-13 11:50:53 -08001839 Returns:
1840 main.False on error and
1841 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001842 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001843 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001844 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001845 if purge:
1846 cmdStr += " -p"
1847 if sync:
1848 cmdStr += " -s"
1849
1850 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001852 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001853 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001854 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001856 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 # TODO: Should this be main.TRUE
1858 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001859 except AssertionError:
1860 main.log.exception( "" )
1861 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001862 except TypeError:
1863 main.log.exception( self.name + ": Object not as expected" )
1864 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001866 main.log.error( self.name + ": EOF exception found" )
1867 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001868 main.cleanup()
1869 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001870 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001871 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 main.cleanup()
1873 main.exit()
1874
YPZhangfebf7302016-05-24 16:45:56 -07001875 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001876 """
1877 Description:
1878 Remove all the intents
1879 Optional args:-
1880 -s or --sync: Waits for the removal before returning
1881 -p or --purge: Purge the intent from the store after removal
1882 Returns:
1883 Returns main.TRUE if all intents are removed, otherwise returns
1884 main.FALSE; Returns None for exception
1885 """
1886 try:
1887 cmdStr = "remove-intent"
1888 if purge:
1889 cmdStr += " -p"
1890 if sync:
1891 cmdStr += " -s"
1892
1893 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001894 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001895 assert "Command not found:" not in handle, handle
1896 if re.search( "Error", handle ):
1897 main.log.error( "Error in removing intent" )
1898 return main.FALSE
1899 else:
1900 return main.TRUE
1901 except AssertionError:
1902 main.log.exception( "" )
1903 return None
1904 except TypeError:
1905 main.log.exception( self.name + ": Object not as expected" )
1906 return None
1907 except pexpect.EOF:
1908 main.log.error( self.name + ": EOF exception found" )
1909 main.log.error( self.name + ": " + self.handle.before )
1910 main.cleanup()
1911 main.exit()
1912 except Exception:
1913 main.log.exception( self.name + ": Uncaught exception!" )
1914 main.cleanup()
1915 main.exit()
1916
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001917 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001918 """
1919 Purges all WITHDRAWN Intents
1920 """
1921 try:
1922 cmdStr = "purge-intents"
1923 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001924 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001925 if re.search( "Error", handle ):
1926 main.log.error( "Error in purging intents" )
1927 return main.FALSE
1928 else:
1929 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001930 except AssertionError:
1931 main.log.exception( "" )
1932 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001933 except TypeError:
1934 main.log.exception( self.name + ": Object not as expected" )
1935 return None
1936 except pexpect.EOF:
1937 main.log.error( self.name + ": EOF exception found" )
1938 main.log.error( self.name + ": " + self.handle.before )
1939 main.cleanup()
1940 main.exit()
1941 except Exception:
1942 main.log.exception( self.name + ": Uncaught exception!" )
1943 main.cleanup()
1944 main.exit()
1945
kelvin-onlabd3b64892015-01-20 13:26:24 -08001946 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001947 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001948 NOTE: This method should be used after installing application:
1949 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001950 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001951 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001952 Description:
1953 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001954 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001955 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001956 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001957 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001958 cmdStr += " -j"
1959 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001960 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001961 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001962 except AssertionError:
1963 main.log.exception( "" )
1964 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001965 except TypeError:
1966 main.log.exception( self.name + ": Object not as expected" )
1967 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001969 main.log.error( self.name + ": EOF exception found" )
1970 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001971 main.cleanup()
1972 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001973 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001974 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 main.cleanup()
1976 main.exit()
1977
pingping-lin54b03372015-08-13 14:43:10 -07001978 def ipv4RouteNumber( self ):
1979 """
1980 NOTE: This method should be used after installing application:
1981 onos-app-sdnip
1982 Description:
1983 Obtain the total IPv4 routes number in the system
1984 """
1985 try:
1986 cmdStr = "routes -s -j"
1987 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001988 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001989 jsonResult = json.loads( handle )
1990 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001991 except AssertionError:
1992 main.log.exception( "" )
1993 return None
1994 except ( TypeError, ValueError ):
1995 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001996 return None
1997 except pexpect.EOF:
1998 main.log.error( self.name + ": EOF exception found" )
1999 main.log.error( self.name + ": " + self.handle.before )
2000 main.cleanup()
2001 main.exit()
2002 except Exception:
2003 main.log.exception( self.name + ": Uncaught exception!" )
2004 main.cleanup()
2005 main.exit()
2006
pingping-lin8244a3b2015-09-16 13:36:56 -07002007 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002008 """
andrewonlabe6745342014-10-17 14:29:13 -04002009 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002010 Obtain intents from the ONOS cli.
2011 Optional:
2012 * jsonFormat: Enable output formatting in json, default to True
2013 * summary: Whether only output the intent summary, defaults to False
2014 * type: Only output a certain type of intent. This options is valid
2015 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002016 """
andrewonlabe6745342014-10-17 14:29:13 -04002017 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002018 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002019 if summary:
2020 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002021 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002022 cmdStr += " -j"
2023 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002024 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002025 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002026 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002027 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002028 else:
Jon Hallff566d52016-01-15 14:45:36 -08002029 intentType = ""
2030 # IF we want the summary of a specific intent type
2031 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002032 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002033 if intentType in jsonResult.keys():
2034 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002035 else:
Jon Hallff566d52016-01-15 14:45:36 -08002036 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002037 return handle
2038 else:
2039 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002040 except AssertionError:
2041 main.log.exception( "" )
2042 return None
2043 except ( TypeError, ValueError ):
2044 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002045 return None
2046 except pexpect.EOF:
2047 main.log.error( self.name + ": EOF exception found" )
2048 main.log.error( self.name + ": " + self.handle.before )
2049 main.cleanup()
2050 main.exit()
2051 except Exception:
2052 main.log.exception( self.name + ": Uncaught exception!" )
2053 main.cleanup()
2054 main.exit()
2055
kelvin-onlab54400a92015-02-26 18:05:51 -08002056 def getIntentState(self, intentsId, intentsJson=None):
2057 """
You Wangfdcbfc42016-05-16 12:16:53 -07002058 Description:
2059 Gets intent state. Accepts a single intent ID (string type) or a
2060 list of intent IDs.
2061 Parameters:
2062 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002063 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002064 Returns:
2065 Returns the state (string type) of the ID if a single intent ID is
2066 accepted.
2067 Returns a list of dictionaries if a list of intent IDs is accepted,
2068 and each dictionary maps 'id' to the Intent ID and 'state' to
2069 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002071 try:
2072 state = "State is Undefined"
2073 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002074 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002075 else:
Jon Hallc6793552016-01-19 14:18:37 -08002076 rawJson = intentsJson
2077 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002078 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002079 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002080 if intentsId == intent[ 'id' ]:
2081 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002082 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002083 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2084 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002085 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002086 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002087 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002088 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002089 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002090 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002091 if intentsId[ i ] == intents[ 'id' ]:
2092 stateDict[ 'state' ] = intents[ 'state' ]
2093 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002094 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002095 break
Jon Hallefbd9792015-03-05 16:11:36 -08002096 if len( intentsId ) != len( dictList ):
2097 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002098 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002099 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002100 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002101 return None
Jon Hallc6793552016-01-19 14:18:37 -08002102 except ( TypeError, ValueError ):
2103 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002104 return None
2105 except pexpect.EOF:
2106 main.log.error( self.name + ": EOF exception found" )
2107 main.log.error( self.name + ": " + self.handle.before )
2108 main.cleanup()
2109 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002110 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002111 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002112 main.cleanup()
2113 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002114
kelvin-onlabf512e942015-06-08 19:42:59 -07002115 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002116 """
2117 Description:
2118 Check intents state
2119 Required:
2120 intentsId - List of intents ID to be checked
2121 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002122 expectedState - Check the expected state(s) of each intents
2123 state in the list.
2124 *NOTE: You can pass in a list of expected state,
2125 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002126 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002127 Returns main.TRUE only if all intent are the same as expected states
2128 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002129 """
2130 try:
2131 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002132 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002133 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002134 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002135 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002136 "getting intents state" )
2137 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002138
2139 if isinstance( expectedState, types.StringType ):
2140 for intents in intentsDict:
2141 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002142 main.log.debug( self.name + " : Intent ID - " +
2143 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002144 " actual state = " +
2145 intents.get( 'state' )
2146 + " does not equal expected state = "
2147 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002148 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002149
2150 elif isinstance( expectedState, types.ListType ):
2151 for intents in intentsDict:
2152 if not any( state == intents.get( 'state' ) for state in
2153 expectedState ):
2154 main.log.debug( self.name + " : Intent ID - " +
2155 intents.get( 'id' ) +
2156 " actual state = " +
2157 intents.get( 'state' ) +
2158 " does not equal expected states = "
2159 + str( expectedState ) )
2160 returnValue = main.FALSE
2161
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002162 if returnValue == main.TRUE:
2163 main.log.info( self.name + ": All " +
2164 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002165 " intents are in " + str( expectedState ) +
2166 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002167 return returnValue
2168 except TypeError:
2169 main.log.exception( self.name + ": Object not as expected" )
2170 return None
2171 except pexpect.EOF:
2172 main.log.error( self.name + ": EOF exception found" )
2173 main.log.error( self.name + ": " + self.handle.before )
2174 main.cleanup()
2175 main.exit()
2176 except Exception:
2177 main.log.exception( self.name + ": Uncaught exception!" )
2178 main.cleanup()
2179 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002180
You Wang66518af2016-05-16 15:32:59 -07002181 def compareIntent( self, intentDict ):
2182 """
2183 Description:
2184 Compare the intent ids and states provided in the argument with all intents in ONOS
2185 Return:
2186 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2187 Arguments:
2188 intentDict: a dictionary which maps intent ids to intent states
2189 """
2190 try:
2191 intentsRaw = self.intents()
2192 intentsJson = json.loads( intentsRaw )
2193 intentDictONOS = {}
2194 for intent in intentsJson:
2195 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2196 if len( intentDict ) != len( intentDictONOS ):
2197 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2198 str( len( intentDict ) ) + " expected and " +
2199 str( len( intentDictONOS ) ) + " actual" )
2200 return main.FALSE
2201 returnValue = main.TRUE
2202 for intentID in intentDict.keys():
2203 if not intentID in intentDictONOS.keys():
2204 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2205 returnValue = main.FALSE
2206 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2207 main.log.debug( self.name + ": intent ID - " + intentID +
2208 " expected state is " + intentDict[ intentID ] +
2209 " but actual state is " + intentDictONOS[ intentID ] )
2210 returnValue = main.FALSE
2211 if returnValue == main.TRUE:
2212 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2213 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002214 except KeyError:
2215 main.log.exception( self.name + ": KeyError exception found" )
2216 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002217 except ( TypeError, ValueError ):
2218 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002219 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002220 except pexpect.EOF:
2221 main.log.error( self.name + ": EOF exception found" )
2222 main.log.error( self.name + ": " + self.handle.before )
2223 main.cleanup()
2224 main.exit()
2225 except Exception:
2226 main.log.exception( self.name + ": Uncaught exception!" )
2227 main.cleanup()
2228 main.exit()
2229
GlennRCed771242016-01-13 17:02:47 -08002230 def checkIntentSummary( self, timeout=60 ):
2231 """
2232 Description:
2233 Check the number of installed intents.
2234 Optional:
2235 timeout - the timeout for pexcept
2236 Return:
2237 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2238 , otherwise, returns main.FALSE.
2239 """
2240
2241 try:
2242 cmd = "intents -s -j"
2243
2244 # Check response if something wrong
2245 response = self.sendline( cmd, timeout=timeout )
2246 if response == None:
2247 return main.False
2248 response = json.loads( response )
2249
2250 # get total and installed number, see if they are match
2251 allState = response.get( 'all' )
2252 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002253 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002254 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002255 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002256 return main.FALSE
2257
Jon Hallc6793552016-01-19 14:18:37 -08002258 except ( TypeError, ValueError ):
2259 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002260 return None
2261 except pexpect.EOF:
2262 main.log.error( self.name + ": EOF exception found" )
2263 main.log.error( self.name + ": " + self.handle.before )
2264 main.cleanup()
2265 main.exit()
2266 except Exception:
2267 main.log.exception( self.name + ": Uncaught exception!" )
2268 main.cleanup()
2269 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002270 except pexpect.TIMEOUT:
2271 main.log.error( self.name + ": ONOS timeout" )
2272 return None
GlennRCed771242016-01-13 17:02:47 -08002273
YPZhangebf9eb52016-05-12 15:20:24 -07002274 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002275 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002276 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002277 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002278 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002279 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002280 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002281 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002282 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002284 cmdStr += " -j "
2285 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002286 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002287 assert "Command not found:" not in handle, handle
2288 if re.search( "Error:", handle ):
2289 main.log.error( self.name + ": flows() response: " +
2290 str( handle ) )
2291 return handle
2292 except AssertionError:
2293 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002294 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002295 except TypeError:
2296 main.log.exception( self.name + ": Object not as expected" )
2297 return None
Jon Hallc6793552016-01-19 14:18:37 -08002298 except pexpect.TIMEOUT:
2299 main.log.error( self.name + ": ONOS timeout" )
2300 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002301 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002302 main.log.error( self.name + ": EOF exception found" )
2303 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002304 main.cleanup()
2305 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002306 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002307 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002308 main.cleanup()
2309 main.exit()
2310
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002311 def checkFlowCount(self, min=0, timeout=60 ):
2312 count = int(self.getTotalFlowsNum( timeout=timeout ))
2313 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002314
YPZhangebf9eb52016-05-12 15:20:24 -07002315 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002316 """
2317 Description:
GlennRCed771242016-01-13 17:02:47 -08002318 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002319 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2320 if the count of those states is 0, which means all current flows
2321 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002322 Optional:
GlennRCed771242016-01-13 17:02:47 -08002323 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002324 Return:
2325 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002326 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002327 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002328 """
2329 try:
GlennRCed771242016-01-13 17:02:47 -08002330 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2331 checkedStates = []
2332 statesCount = [0, 0, 0, 0]
2333 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002334 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002335 if rawFlows:
2336 # if we didn't get flows or flows function return None, we should return
2337 # main.Flase
2338 checkedStates.append( json.loads( rawFlows ) )
2339 else:
2340 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002341 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002342 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002343 try:
2344 statesCount[i] += int( c.get( "flowCount" ) )
2345 except TypeError:
2346 main.log.exception( "Json object not as expected" )
2347 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002348
GlennRCed771242016-01-13 17:02:47 -08002349 # We want to count PENDING_ADD if isPENDING is true
2350 if isPENDING:
2351 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2352 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002353 else:
GlennRCed771242016-01-13 17:02:47 -08002354 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2355 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002356 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002357 except ( TypeError, ValueError ):
2358 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002359 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002360
YPZhang240842b2016-05-17 12:00:50 -07002361 except AssertionError:
2362 main.log.exception( "" )
2363 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002364 except pexpect.EOF:
2365 main.log.error( self.name + ": EOF exception found" )
2366 main.log.error( self.name + ": " + self.handle.before )
2367 main.cleanup()
2368 main.exit()
2369 except Exception:
2370 main.log.exception( self.name + ": Uncaught exception!" )
2371 main.cleanup()
2372 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002373 except pexpect.TIMEOUT:
2374 main.log.error( self.name + ": ONOS timeout" )
2375 return None
2376
kelvin-onlab4df89f22015-04-13 18:10:23 -07002377
GlennRCed771242016-01-13 17:02:47 -08002378 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002379 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002380 """
andrewonlab87852b02014-11-19 18:44:19 -05002381 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002382 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002383 a specific point-to-point intent definition
2384 Required:
GlennRCed771242016-01-13 17:02:47 -08002385 * ingress: specify source dpid
2386 * egress: specify destination dpid
2387 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002388 Optional:
GlennRCed771242016-01-13 17:02:47 -08002389 * offset: the keyOffset is where the next batch of intents
2390 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002391 * noExit: If set to True, TestON will not exit if any error when issus command
2392 * getResponse: If set to True, function will return ONOS response.
2393
GlennRCed771242016-01-13 17:02:47 -08002394 Returns: If failed to push test intents, it will returen None,
2395 if successful, return true.
2396 Timeout expection will return None,
2397 TypeError will return false
2398 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002399 """
andrewonlab87852b02014-11-19 18:44:19 -05002400 try:
GlennRCed771242016-01-13 17:02:47 -08002401 if background:
2402 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002403 else:
GlennRCed771242016-01-13 17:02:47 -08002404 back = ""
2405 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002406 ingress,
2407 egress,
2408 batchSize,
2409 offset,
2410 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002411 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002412 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002413 main.log.info( response )
2414 if response == None:
2415 return None
2416
YPZhangb34b7e12016-06-14 14:28:19 -07002417 if getResponse:
2418 return response
2419
GlennRCed771242016-01-13 17:02:47 -08002420 # TODO: We should handle if there is failure in installation
2421 return main.TRUE
2422
Jon Hallc6793552016-01-19 14:18:37 -08002423 except AssertionError:
2424 main.log.exception( "" )
2425 return None
GlennRCed771242016-01-13 17:02:47 -08002426 except pexpect.TIMEOUT:
2427 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002428 return None
andrewonlab87852b02014-11-19 18:44:19 -05002429 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002430 main.log.error( self.name + ": EOF exception found" )
2431 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002432 main.cleanup()
2433 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002434 except TypeError:
2435 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002436 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002437 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002438 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002439 main.cleanup()
2440 main.exit()
2441
YPZhangebf9eb52016-05-12 15:20:24 -07002442 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002443 """
2444 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002445 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002446 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002447 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002448 """
YPZhange3109a72016-02-02 11:25:37 -08002449
YPZhangb5d3f832016-01-23 22:54:26 -08002450 try:
YPZhange3109a72016-02-02 11:25:37 -08002451 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002452 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002453 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002454
2455 if totalFlows == None:
2456 # if timeout, we will get total number of all flows, and subtract other states
2457 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2458 checkedStates = []
2459 totalFlows = 0
2460 statesCount = [0, 0, 0, 0]
2461
2462 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002463 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002464 totalFlows = int( response.get("flows") )
2465
2466 for s in states:
2467 rawFlows = self.flows( state=s, timeout = timeout )
2468 if rawFlows == None:
2469 # if timeout, return the total flows number from summary command
2470 return totalFlows
2471 checkedStates.append( json.loads( rawFlows ) )
2472
2473 # Calculate ADDED flows number, equal total subtracts others
2474 for i in range( len( states ) ):
2475 for c in checkedStates[i]:
2476 try:
2477 statesCount[i] += int( c.get( "flowCount" ) )
2478 except TypeError:
2479 main.log.exception( "Json object not as expected" )
2480 totalFlows = totalFlows - int( statesCount[i] )
2481 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2482
2483 return totalFlows
2484
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002485 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002486
You Wangd3cb2ce2016-05-16 14:01:24 -07002487 except ( TypeError, ValueError ):
2488 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002489 return None
2490 except pexpect.EOF:
2491 main.log.error( self.name + ": EOF exception found" )
2492 main.log.error( self.name + ": " + self.handle.before )
2493 main.cleanup()
2494 main.exit()
2495 except Exception:
2496 main.log.exception( self.name + ": Uncaught exception!" )
2497 main.cleanup()
2498 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002499 except pexpect.TIMEOUT:
2500 main.log.error( self.name + ": ONOS timeout" )
2501 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002502
YPZhangebf9eb52016-05-12 15:20:24 -07002503 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002504 """
2505 Description:
2506 Get the total number of intents, include every states.
2507 Return:
2508 The number of intents
2509 """
2510 try:
2511 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002512 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002513 if response == None:
2514 return -1
2515 response = json.loads( response )
2516 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002517 except ( TypeError, ValueError ):
2518 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002519 return None
2520 except pexpect.EOF:
2521 main.log.error( self.name + ": EOF exception found" )
2522 main.log.error( self.name + ": " + self.handle.before )
2523 main.cleanup()
2524 main.exit()
2525 except Exception:
2526 main.log.exception( self.name + ": Uncaught exception!" )
2527 main.cleanup()
2528 main.exit()
2529
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002531 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002532 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002533 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002534 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002535 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002536 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002537 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002538 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002539 cmdStr += " -j"
2540 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002541 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002542 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002543 except AssertionError:
2544 main.log.exception( "" )
2545 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002546 except TypeError:
2547 main.log.exception( self.name + ": Object not as expected" )
2548 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002549 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002550 main.log.error( self.name + ": EOF exception found" )
2551 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002552 main.cleanup()
2553 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002554 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002555 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002556 main.cleanup()
2557 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002558
kelvin-onlabd3b64892015-01-20 13:26:24 -08002559 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002560 """
2561 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002562 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002563 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002564 """
andrewonlab867212a2014-10-22 20:13:38 -04002565 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002566 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002567 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002568 cmdStr += " -j"
2569 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002570 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002571 if handle:
2572 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002573 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002574 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002575 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002576 else:
2577 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002578 except AssertionError:
2579 main.log.exception( "" )
2580 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002581 except TypeError:
2582 main.log.exception( self.name + ": Object not as expected" )
2583 return None
andrewonlab867212a2014-10-22 20:13:38 -04002584 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002585 main.log.error( self.name + ": EOF exception found" )
2586 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002587 main.cleanup()
2588 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002589 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002590 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002591 main.cleanup()
2592 main.exit()
2593
kelvin8ec71442015-01-15 16:57:00 -08002594 # Wrapper functions ****************
2595 # Wrapper functions use existing driver
2596 # functions and extends their use case.
2597 # For example, we may use the output of
2598 # a normal driver function, and parse it
2599 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002600
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002602 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002603 Description:
2604 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002605 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002606 try:
kelvin8ec71442015-01-15 16:57:00 -08002607 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002608 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002609 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002610
kelvin8ec71442015-01-15 16:57:00 -08002611 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002612 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2613 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002614 match = re.search('id=0x([\da-f]+),', intents)
2615 if match:
2616 tmpId = match.group()[3:-1]
2617 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002618 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002619
Jon Halld4d4b372015-01-28 16:02:41 -08002620 except TypeError:
2621 main.log.exception( self.name + ": Object not as expected" )
2622 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002623 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002624 main.log.error( self.name + ": EOF exception found" )
2625 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002626 main.cleanup()
2627 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002628 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002629 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002630 main.cleanup()
2631 main.exit()
2632
Jon Hall30b82fa2015-03-04 17:15:43 -08002633 def FlowAddedCount( self, deviceId ):
2634 """
2635 Determine the number of flow rules for the given device id that are
2636 in the added state
2637 """
2638 try:
2639 cmdStr = "flows any " + str( deviceId ) + " | " +\
2640 "grep 'state=ADDED' | wc -l"
2641 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002642 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002643 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002644 except AssertionError:
2645 main.log.exception( "" )
2646 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002647 except pexpect.EOF:
2648 main.log.error( self.name + ": EOF exception found" )
2649 main.log.error( self.name + ": " + self.handle.before )
2650 main.cleanup()
2651 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002652 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002653 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002654 main.cleanup()
2655 main.exit()
2656
kelvin-onlabd3b64892015-01-20 13:26:24 -08002657 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002658 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002659 Use 'devices' function to obtain list of all devices
2660 and parse the result to obtain a list of all device
2661 id's. Returns this list. Returns empty list if no
2662 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002663 List is ordered sequentially
2664
andrewonlab3e15ead2014-10-15 14:21:34 -04002665 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002666 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002667 the ids. By obtaining the list of device ids on the fly,
2668 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002669 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002670 try:
kelvin8ec71442015-01-15 16:57:00 -08002671 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002672 devicesStr = self.devices( jsonFormat=False )
2673 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002674
kelvin-onlabd3b64892015-01-20 13:26:24 -08002675 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002676 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002677 return idList
kelvin8ec71442015-01-15 16:57:00 -08002678
2679 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002680 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002681 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002683 # Split list further into arguments before and after string
2684 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002685 # append to idList
2686 for arg in tempList:
2687 idList.append( arg.split( "id=" )[ 1 ] )
2688 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002689
Jon Halld4d4b372015-01-28 16:02:41 -08002690 except TypeError:
2691 main.log.exception( self.name + ": Object not as expected" )
2692 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002693 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002694 main.log.error( self.name + ": EOF exception found" )
2695 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002696 main.cleanup()
2697 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002698 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002699 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002700 main.cleanup()
2701 main.exit()
2702
kelvin-onlabd3b64892015-01-20 13:26:24 -08002703 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002704 """
andrewonlab7c211572014-10-15 16:45:20 -04002705 Uses 'nodes' function to obtain list of all nodes
2706 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002707 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002708 Returns:
2709 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002710 """
andrewonlab7c211572014-10-15 16:45:20 -04002711 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002712 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002713 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002714 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002715 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002717 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002719 nodesJson = json.loads( nodesStr )
2720 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002722 except ( TypeError, ValueError ):
2723 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002724 return None
andrewonlab7c211572014-10-15 16:45:20 -04002725 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002726 main.log.error( self.name + ": EOF exception found" )
2727 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002728 main.cleanup()
2729 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002730 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002731 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002732 main.cleanup()
2733 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002734
kelvin-onlabd3b64892015-01-20 13:26:24 -08002735 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002736 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002737 Return the first device from the devices api whose 'id' contains 'dpid'
2738 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002739 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002740 try:
kelvin8ec71442015-01-15 16:57:00 -08002741 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002742 return None
2743 else:
kelvin8ec71442015-01-15 16:57:00 -08002744 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002745 rawDevices = self.devices()
2746 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002747 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002748 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002749 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2750 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002751 return device
2752 return None
Jon Hallc6793552016-01-19 14:18:37 -08002753 except ( TypeError, ValueError ):
2754 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002755 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002757 main.log.error( self.name + ": EOF exception found" )
2758 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002759 main.cleanup()
2760 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002761 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002762 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002763 main.cleanup()
2764 main.exit()
2765
You Wang24139872016-05-03 11:48:47 -07002766 def getTopology( self, topologyOutput ):
2767 """
2768 Definition:
2769 Loads a json topology output
2770 Return:
2771 topology = current ONOS topology
2772 """
2773 import json
2774 try:
2775 # either onos:topology or 'topology' will work in CLI
2776 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002777 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002778 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002779 except ( TypeError, ValueError ):
2780 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2781 return None
You Wang24139872016-05-03 11:48:47 -07002782 except pexpect.EOF:
2783 main.log.error( self.name + ": EOF exception found" )
2784 main.log.error( self.name + ": " + self.handle.before )
2785 main.cleanup()
2786 main.exit()
2787 except Exception:
2788 main.log.exception( self.name + ": Uncaught exception!" )
2789 main.cleanup()
2790 main.exit()
2791
Flavio Castro82ee2f62016-06-07 15:04:12 -07002792 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002793 """
Jon Hallefbd9792015-03-05 16:11:36 -08002794 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002795 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002796 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002797
Flavio Castro82ee2f62016-06-07 15:04:12 -07002798 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002799 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002800 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002801 logLevel = level to log to.
2802 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002803
Jon Hallefbd9792015-03-05 16:11:36 -08002804 Returns: main.TRUE if the number of switches and links are correct,
2805 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002806 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002807 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002808 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002809 try:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002810 topology = self.getTopology( self.topology() )
2811 summary = json.loads( self.summary() )
2812
2813 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002814 return main.ERROR
2815 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002816 # Is the number of switches is what we expected
2817 devices = topology.get( 'devices', False )
2818 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002819 nodes = summary.get( 'nodes', False )
2820 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002821 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002822 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002823 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002824 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002825 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2826 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002827 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002828 output = output + "The number of links and switches match "\
2829 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002830 result = main.TRUE
2831 else:
You Wang24139872016-05-03 11:48:47 -07002832 output = output + \
2833 "The number of links and switches does not match " + \
2834 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002835 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002836 output = output + "\n ONOS sees %i devices" % int( devices )
2837 output = output + " (%i expected) " % int( numoswitch )
2838 output = output + "and %i links " % int( links )
2839 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002840 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002841 output = output + "and %i controllers " % int( nodes )
2842 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002843 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002844 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002845 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002846 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002847 else:
You Wang24139872016-05-03 11:48:47 -07002848 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002849 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002850 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002851 main.log.error( self.name + ": EOF exception found" )
2852 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002853 main.cleanup()
2854 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002855 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002856 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002857 main.cleanup()
2858 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002859
kelvin-onlabd3b64892015-01-20 13:26:24 -08002860 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002861 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002862 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002863 deviceId must be the id of a device as seen in the onos devices command
2864 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002865 role must be either master, standby, or none
2866
Jon Halle3f39ff2015-01-13 11:50:53 -08002867 Returns:
2868 main.TRUE or main.FALSE based on argument verification and
2869 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002870 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002871 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002872 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002873 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002874 cmdStr = "device-role " +\
2875 str( deviceId ) + " " +\
2876 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002877 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002878 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002879 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002880 if re.search( "Error", handle ):
2881 # end color output to escape any colours
2882 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002883 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002884 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002885 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002886 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002887 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002888 main.log.error( "Invalid 'role' given to device_role(). " +
2889 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002890 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002891 except AssertionError:
2892 main.log.exception( "" )
2893 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002894 except TypeError:
2895 main.log.exception( self.name + ": Object not as expected" )
2896 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002898 main.log.error( self.name + ": EOF exception found" )
2899 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002900 main.cleanup()
2901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002903 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002904 main.cleanup()
2905 main.exit()
2906
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002908 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002909 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002910 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002911 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002912 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002913 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002914 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002915 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002916 cmdStr += " -j"
2917 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002918 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002919 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002920 except AssertionError:
2921 main.log.exception( "" )
2922 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002923 except TypeError:
2924 main.log.exception( self.name + ": Object not as expected" )
2925 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002926 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002927 main.log.error( self.name + ": EOF exception found" )
2928 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002929 main.cleanup()
2930 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002931 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002932 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002933 main.cleanup()
2934 main.exit()
2935
kelvin-onlabd3b64892015-01-20 13:26:24 -08002936 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002937 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002938 CLI command to get the current leader for the Election test application
2939 NOTE: Requires installation of the onos-app-election feature
2940 Returns: Node IP of the leader if one exists
2941 None if none exists
2942 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002943 """
Jon Hall94fd0472014-12-08 11:52:42 -08002944 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002945 cmdStr = "election-test-leader"
2946 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002947 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 # Leader
2949 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002950 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002951 nodeSearch = re.search( leaderPattern, response )
2952 if nodeSearch:
2953 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002954 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002955 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002956 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002957 # no leader
2958 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002959 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002960 nullSearch = re.search( nullPattern, response )
2961 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002962 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002963 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002964 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002965 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002966 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002967 if re.search( errorPattern, response ):
2968 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002969 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002970 return main.FALSE
2971 else:
Jon Hall390696c2015-05-05 17:13:41 -07002972 main.log.error( "Error in electionTestLeader on " + self.name +
2973 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002974 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002975 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002976 except AssertionError:
2977 main.log.exception( "" )
2978 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002979 except TypeError:
2980 main.log.exception( self.name + ": Object not as expected" )
2981 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002983 main.log.error( self.name + ": EOF exception found" )
2984 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002985 main.cleanup()
2986 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002987 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002988 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002989 main.cleanup()
2990 main.exit()
2991
kelvin-onlabd3b64892015-01-20 13:26:24 -08002992 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002993 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002994 CLI command to run for leadership of the Election test application.
2995 NOTE: Requires installation of the onos-app-election feature
2996 Returns: Main.TRUE on success
2997 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002998 """
Jon Hall94fd0472014-12-08 11:52:42 -08002999 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003000 cmdStr = "election-test-run"
3001 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003002 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003004 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003005 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003006 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003007 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003008 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003009 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003010 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003011 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003012 errorPattern = "Command\snot\sfound"
3013 if re.search( errorPattern, response ):
3014 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003015 return main.FALSE
3016 else:
Jon Hall390696c2015-05-05 17:13:41 -07003017 main.log.error( "Error in electionTestRun on " + self.name +
3018 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003019 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003020 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003021 except AssertionError:
3022 main.log.exception( "" )
3023 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003024 except TypeError:
3025 main.log.exception( self.name + ": Object not as expected" )
3026 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003027 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003028 main.log.error( self.name + ": EOF exception found" )
3029 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003030 main.cleanup()
3031 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003032 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003033 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003034 main.cleanup()
3035 main.exit()
3036
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003038 """
Jon Hall94fd0472014-12-08 11:52:42 -08003039 * CLI command to withdraw the local node from leadership election for
3040 * the Election test application.
3041 #NOTE: Requires installation of the onos-app-election feature
3042 Returns: Main.TRUE on success
3043 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003044 """
Jon Hall94fd0472014-12-08 11:52:42 -08003045 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003046 cmdStr = "election-test-withdraw"
3047 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003048 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003049 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003050 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003051 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003052 if re.search( successPattern, response ):
3053 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003054 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003055 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003056 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003057 errorPattern = "Command\snot\sfound"
3058 if re.search( errorPattern, response ):
3059 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003060 return main.FALSE
3061 else:
Jon Hall390696c2015-05-05 17:13:41 -07003062 main.log.error( "Error in electionTestWithdraw on " +
3063 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003064 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003065 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003066 except AssertionError:
3067 main.log.exception( "" )
3068 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003069 except TypeError:
3070 main.log.exception( self.name + ": Object not as expected" )
3071 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003072 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003073 main.log.error( self.name + ": EOF exception found" )
3074 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003075 main.cleanup()
3076 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003077 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003078 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003079 main.cleanup()
3080 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003081
kelvin8ec71442015-01-15 16:57:00 -08003082 def getDevicePortsEnabledCount( self, dpid ):
3083 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003084 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003085 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003086 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003087 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003088 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3089 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003090 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003091 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003092 if re.search( "No such device", output ):
3093 main.log.error( "Error in getting ports" )
3094 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003095 return output
Jon Hallc6793552016-01-19 14:18:37 -08003096 except AssertionError:
3097 main.log.exception( "" )
3098 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003099 except TypeError:
3100 main.log.exception( self.name + ": Object not as expected" )
3101 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003102 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003103 main.log.error( self.name + ": EOF exception found" )
3104 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003105 main.cleanup()
3106 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003107 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003108 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003109 main.cleanup()
3110 main.exit()
3111
kelvin8ec71442015-01-15 16:57:00 -08003112 def getDeviceLinksActiveCount( self, dpid ):
3113 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003114 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003115 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003116 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003117 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003118 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3119 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003120 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003121 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003122 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003123 main.log.error( "Error in getting ports " )
3124 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003125 return output
Jon Hallc6793552016-01-19 14:18:37 -08003126 except AssertionError:
3127 main.log.exception( "" )
3128 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003129 except TypeError:
3130 main.log.exception( self.name + ": Object not as expected" )
3131 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003132 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003133 main.log.error( self.name + ": EOF exception found" )
3134 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003135 main.cleanup()
3136 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003137 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003138 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003139 main.cleanup()
3140 main.exit()
3141
kelvin8ec71442015-01-15 16:57:00 -08003142 def getAllIntentIds( self ):
3143 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003144 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003145 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003146 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003147 cmdStr = "onos:intents | grep id="
3148 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003149 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003150 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003151 if re.search( "Error", output ):
3152 main.log.error( "Error in getting ports" )
3153 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003154 return output
Jon Hallc6793552016-01-19 14:18:37 -08003155 except AssertionError:
3156 main.log.exception( "" )
3157 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003158 except TypeError:
3159 main.log.exception( self.name + ": Object not as expected" )
3160 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003161 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003162 main.log.error( self.name + ": EOF exception found" )
3163 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003164 main.cleanup()
3165 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003167 main.log.exception( self.name + ": Uncaught exception!" )
3168 main.cleanup()
3169 main.exit()
3170
Jon Hall73509952015-02-24 16:42:56 -08003171 def intentSummary( self ):
3172 """
Jon Hallefbd9792015-03-05 16:11:36 -08003173 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003174 """
3175 try:
3176 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003177 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003178 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003179 states.append( intent.get( 'state', None ) )
3180 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003181 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003182 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003183 except ( TypeError, ValueError ):
3184 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003185 return None
3186 except pexpect.EOF:
3187 main.log.error( self.name + ": EOF exception found" )
3188 main.log.error( self.name + ": " + self.handle.before )
3189 main.cleanup()
3190 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003191 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003192 main.log.exception( self.name + ": Uncaught exception!" )
3193 main.cleanup()
3194 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003195
Jon Hall61282e32015-03-19 11:34:11 -07003196 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003197 """
3198 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003199 Optional argument:
3200 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003201 """
Jon Hall63604932015-02-26 17:09:50 -08003202 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003203 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003204 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003205 cmdStr += " -j"
3206 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003207 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003208 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003209 return output
Jon Hallc6793552016-01-19 14:18:37 -08003210 except AssertionError:
3211 main.log.exception( "" )
3212 return None
Jon Hall63604932015-02-26 17:09:50 -08003213 except TypeError:
3214 main.log.exception( self.name + ": Object not as expected" )
3215 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003216 except pexpect.EOF:
3217 main.log.error( self.name + ": EOF exception found" )
3218 main.log.error( self.name + ": " + self.handle.before )
3219 main.cleanup()
3220 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003221 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003222 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003223 main.cleanup()
3224 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003225
acsmarsa4a4d1e2015-07-10 16:01:24 -07003226 def leaderCandidates( self, jsonFormat=True ):
3227 """
3228 Returns the output of the leaders -c command.
3229 Optional argument:
3230 * jsonFormat - boolean indicating if you want output in json
3231 """
3232 try:
3233 cmdStr = "onos:leaders -c"
3234 if jsonFormat:
3235 cmdStr += " -j"
3236 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003237 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003238 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003239 return output
Jon Hallc6793552016-01-19 14:18:37 -08003240 except AssertionError:
3241 main.log.exception( "" )
3242 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003243 except TypeError:
3244 main.log.exception( self.name + ": Object not as expected" )
3245 return None
3246 except pexpect.EOF:
3247 main.log.error( self.name + ": EOF exception found" )
3248 main.log.error( self.name + ": " + self.handle.before )
3249 main.cleanup()
3250 main.exit()
3251 except Exception:
3252 main.log.exception( self.name + ": Uncaught exception!" )
3253 main.cleanup()
3254 main.exit()
3255
Jon Hallc6793552016-01-19 14:18:37 -08003256 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003257 """
3258 Returns a list in format [leader,candidate1,candidate2,...] for a given
3259 topic parameter and an empty list if the topic doesn't exist
3260 If no leader is elected leader in the returned list will be "none"
3261 Returns None if there is a type error processing the json object
3262 """
3263 try:
Jon Hall6e709752016-02-01 13:38:46 -08003264 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003265 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003266 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003267 assert "Command not found:" not in rawOutput, rawOutput
3268 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003269 results = []
3270 for dict in output:
3271 if dict["topic"] == topic:
3272 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003273 candidates = re.split( ", ", dict["candidates"][1:-1] )
3274 results.append( leader )
3275 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003276 return results
Jon Hallc6793552016-01-19 14:18:37 -08003277 except AssertionError:
3278 main.log.exception( "" )
3279 return None
3280 except ( TypeError, ValueError ):
3281 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003282 return None
3283 except pexpect.EOF:
3284 main.log.error( self.name + ": EOF exception found" )
3285 main.log.error( self.name + ": " + self.handle.before )
3286 main.cleanup()
3287 main.exit()
3288 except Exception:
3289 main.log.exception( self.name + ": Uncaught exception!" )
3290 main.cleanup()
3291 main.exit()
3292
Jon Hall61282e32015-03-19 11:34:11 -07003293 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003294 """
3295 Returns the output of the intent Pending map.
3296 """
Jon Hall63604932015-02-26 17:09:50 -08003297 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003298 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003299 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003300 cmdStr += " -j"
3301 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003302 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003303 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003304 return output
Jon Hallc6793552016-01-19 14:18:37 -08003305 except AssertionError:
3306 main.log.exception( "" )
3307 return None
Jon Hall63604932015-02-26 17:09:50 -08003308 except TypeError:
3309 main.log.exception( self.name + ": Object not as expected" )
3310 return None
3311 except pexpect.EOF:
3312 main.log.error( self.name + ": EOF exception found" )
3313 main.log.error( self.name + ": " + self.handle.before )
3314 main.cleanup()
3315 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003316 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003317 main.log.exception( self.name + ": Uncaught exception!" )
3318 main.cleanup()
3319 main.exit()
3320
Jon Hall61282e32015-03-19 11:34:11 -07003321 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003322 """
3323 Returns the output of the raft partitions command for ONOS.
3324 """
Jon Hall61282e32015-03-19 11:34:11 -07003325 # Sample JSON
3326 # {
3327 # "leader": "tcp://10.128.30.11:7238",
3328 # "members": [
3329 # "tcp://10.128.30.11:7238",
3330 # "tcp://10.128.30.17:7238",
3331 # "tcp://10.128.30.13:7238",
3332 # ],
3333 # "name": "p1",
3334 # "term": 3
3335 # },
Jon Hall63604932015-02-26 17:09:50 -08003336 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003337 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003338 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003339 cmdStr += " -j"
3340 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003341 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003342 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003343 return output
Jon Hallc6793552016-01-19 14:18:37 -08003344 except AssertionError:
3345 main.log.exception( "" )
3346 return None
Jon Hall63604932015-02-26 17:09:50 -08003347 except TypeError:
3348 main.log.exception( self.name + ": Object not as expected" )
3349 return None
3350 except pexpect.EOF:
3351 main.log.error( self.name + ": EOF exception found" )
3352 main.log.error( self.name + ": " + self.handle.before )
3353 main.cleanup()
3354 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003355 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003356 main.log.exception( self.name + ": Uncaught exception!" )
3357 main.cleanup()
3358 main.exit()
3359
Jon Hallbe379602015-03-24 13:39:32 -07003360 def apps( self, jsonFormat=True ):
3361 """
3362 Returns the output of the apps command for ONOS. This command lists
3363 information about installed ONOS applications
3364 """
3365 # Sample JSON object
3366 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3367 # "description":"ONOS OpenFlow protocol southbound providers",
3368 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3369 # "features":"[onos-openflow]","state":"ACTIVE"}]
3370 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003371 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003372 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003373 cmdStr += " -j"
3374 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003375 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003376 assert "Command not found:" not in output, output
3377 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003378 return output
Jon Hallbe379602015-03-24 13:39:32 -07003379 # FIXME: look at specific exceptions/Errors
3380 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003381 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003382 return None
3383 except TypeError:
3384 main.log.exception( self.name + ": Object not as expected" )
3385 return None
3386 except pexpect.EOF:
3387 main.log.error( self.name + ": EOF exception found" )
3388 main.log.error( self.name + ": " + self.handle.before )
3389 main.cleanup()
3390 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003391 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003392 main.log.exception( self.name + ": Uncaught exception!" )
3393 main.cleanup()
3394 main.exit()
3395
Jon Hall146f1522015-03-24 15:33:24 -07003396 def appStatus( self, appName ):
3397 """
3398 Uses the onos:apps cli command to return the status of an application.
3399 Returns:
3400 "ACTIVE" - If app is installed and activated
3401 "INSTALLED" - If app is installed and deactivated
3402 "UNINSTALLED" - If app is not installed
3403 None - on error
3404 """
Jon Hall146f1522015-03-24 15:33:24 -07003405 try:
3406 if not isinstance( appName, types.StringType ):
3407 main.log.error( self.name + ".appStatus(): appName must be" +
3408 " a string" )
3409 return None
3410 output = self.apps( jsonFormat=True )
3411 appsJson = json.loads( output )
3412 state = None
3413 for app in appsJson:
3414 if appName == app.get('name'):
3415 state = app.get('state')
3416 break
3417 if state == "ACTIVE" or state == "INSTALLED":
3418 return state
3419 elif state is None:
3420 return "UNINSTALLED"
3421 elif state:
3422 main.log.error( "Unexpected state from 'onos:apps': " +
3423 str( state ) )
3424 return state
Jon Hallc6793552016-01-19 14:18:37 -08003425 except ( TypeError, ValueError ):
3426 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003427 return None
3428 except pexpect.EOF:
3429 main.log.error( self.name + ": EOF exception found" )
3430 main.log.error( self.name + ": " + self.handle.before )
3431 main.cleanup()
3432 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003433 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003434 main.log.exception( self.name + ": Uncaught exception!" )
3435 main.cleanup()
3436 main.exit()
3437
Jon Hallbe379602015-03-24 13:39:32 -07003438 def app( self, appName, option ):
3439 """
3440 Interacts with the app command for ONOS. This command manages
3441 application inventory.
3442 """
Jon Hallbe379602015-03-24 13:39:32 -07003443 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003444 # Validate argument types
3445 valid = True
3446 if not isinstance( appName, types.StringType ):
3447 main.log.error( self.name + ".app(): appName must be a " +
3448 "string" )
3449 valid = False
3450 if not isinstance( option, types.StringType ):
3451 main.log.error( self.name + ".app(): option must be a string" )
3452 valid = False
3453 if not valid:
3454 return main.FALSE
3455 # Validate Option
3456 option = option.lower()
3457 # NOTE: Install may become a valid option
3458 if option == "activate":
3459 pass
3460 elif option == "deactivate":
3461 pass
3462 elif option == "uninstall":
3463 pass
3464 else:
3465 # Invalid option
3466 main.log.error( "The ONOS app command argument only takes " +
3467 "the values: (activate|deactivate|uninstall)" +
3468 "; was given '" + option + "'")
3469 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003470 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003471 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003472 if "Error executing command" in output:
3473 main.log.error( "Error in processing onos:app command: " +
3474 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003475 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003476 elif "No such application" in output:
3477 main.log.error( "The application '" + appName +
3478 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003479 return main.FALSE
3480 elif "Command not found:" in output:
3481 main.log.error( "Error in processing onos:app command: " +
3482 str( output ) )
3483 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003484 elif "Unsupported command:" in output:
3485 main.log.error( "Incorrect command given to 'app': " +
3486 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003487 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003488 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003489 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003490 return main.TRUE
3491 except TypeError:
3492 main.log.exception( self.name + ": Object not as expected" )
3493 return main.ERROR
3494 except pexpect.EOF:
3495 main.log.error( self.name + ": EOF exception found" )
3496 main.log.error( self.name + ": " + self.handle.before )
3497 main.cleanup()
3498 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003499 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003500 main.log.exception( self.name + ": Uncaught exception!" )
3501 main.cleanup()
3502 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003503
Jon Hallbd16b922015-03-26 17:53:15 -07003504 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003505 """
3506 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003507 appName is the hierarchical app name, not the feature name
3508 If check is True, method will check the status of the app after the
3509 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003510 Returns main.TRUE if the command was successfully sent
3511 main.FALSE if the cli responded with an error or given
3512 incorrect input
3513 """
3514 try:
3515 if not isinstance( appName, types.StringType ):
3516 main.log.error( self.name + ".activateApp(): appName must be" +
3517 " a string" )
3518 return main.FALSE
3519 status = self.appStatus( appName )
3520 if status == "INSTALLED":
3521 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003522 if check and response == main.TRUE:
3523 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003524 status = self.appStatus( appName )
3525 if status == "ACTIVE":
3526 return main.TRUE
3527 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003528 main.log.debug( "The state of application " +
3529 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003530 time.sleep( 1 )
3531 return main.FALSE
3532 else: # not 'check' or command didn't succeed
3533 return response
Jon Hall146f1522015-03-24 15:33:24 -07003534 elif status == "ACTIVE":
3535 return main.TRUE
3536 elif status == "UNINSTALLED":
3537 main.log.error( self.name + ": Tried to activate the " +
3538 "application '" + appName + "' which is not " +
3539 "installed." )
3540 else:
3541 main.log.error( "Unexpected return value from appStatus: " +
3542 str( status ) )
3543 return main.ERROR
3544 except TypeError:
3545 main.log.exception( self.name + ": Object not as expected" )
3546 return main.ERROR
3547 except pexpect.EOF:
3548 main.log.error( self.name + ": EOF exception found" )
3549 main.log.error( self.name + ": " + self.handle.before )
3550 main.cleanup()
3551 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003552 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003553 main.log.exception( self.name + ": Uncaught exception!" )
3554 main.cleanup()
3555 main.exit()
3556
Jon Hallbd16b922015-03-26 17:53:15 -07003557 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003558 """
3559 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003560 appName is the hierarchical app name, not the feature name
3561 If check is True, method will check the status of the app after the
3562 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003563 Returns main.TRUE if the command was successfully sent
3564 main.FALSE if the cli responded with an error or given
3565 incorrect input
3566 """
3567 try:
3568 if not isinstance( appName, types.StringType ):
3569 main.log.error( self.name + ".deactivateApp(): appName must " +
3570 "be a string" )
3571 return main.FALSE
3572 status = self.appStatus( appName )
3573 if status == "INSTALLED":
3574 return main.TRUE
3575 elif status == "ACTIVE":
3576 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003577 if check and response == main.TRUE:
3578 for i in range(10): # try 10 times then give up
3579 status = self.appStatus( appName )
3580 if status == "INSTALLED":
3581 return main.TRUE
3582 else:
3583 time.sleep( 1 )
3584 return main.FALSE
3585 else: # not check or command didn't succeed
3586 return response
Jon Hall146f1522015-03-24 15:33:24 -07003587 elif status == "UNINSTALLED":
3588 main.log.warn( self.name + ": Tried to deactivate the " +
3589 "application '" + appName + "' which is not " +
3590 "installed." )
3591 return main.TRUE
3592 else:
3593 main.log.error( "Unexpected return value from appStatus: " +
3594 str( status ) )
3595 return main.ERROR
3596 except TypeError:
3597 main.log.exception( self.name + ": Object not as expected" )
3598 return main.ERROR
3599 except pexpect.EOF:
3600 main.log.error( self.name + ": EOF exception found" )
3601 main.log.error( self.name + ": " + self.handle.before )
3602 main.cleanup()
3603 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003604 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003605 main.log.exception( self.name + ": Uncaught exception!" )
3606 main.cleanup()
3607 main.exit()
3608
Jon Hallbd16b922015-03-26 17:53:15 -07003609 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003610 """
3611 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003612 appName is the hierarchical app name, not the feature name
3613 If check is True, method will check the status of the app after the
3614 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003615 Returns main.TRUE if the command was successfully sent
3616 main.FALSE if the cli responded with an error or given
3617 incorrect input
3618 """
3619 # TODO: check with Thomas about the state machine for apps
3620 try:
3621 if not isinstance( appName, types.StringType ):
3622 main.log.error( self.name + ".uninstallApp(): appName must " +
3623 "be a string" )
3624 return main.FALSE
3625 status = self.appStatus( appName )
3626 if status == "INSTALLED":
3627 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003628 if check and response == main.TRUE:
3629 for i in range(10): # try 10 times then give up
3630 status = self.appStatus( appName )
3631 if status == "UNINSTALLED":
3632 return main.TRUE
3633 else:
3634 time.sleep( 1 )
3635 return main.FALSE
3636 else: # not check or command didn't succeed
3637 return response
Jon Hall146f1522015-03-24 15:33:24 -07003638 elif status == "ACTIVE":
3639 main.log.warn( self.name + ": Tried to uninstall the " +
3640 "application '" + appName + "' which is " +
3641 "currently active." )
3642 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003643 if check and response == main.TRUE:
3644 for i in range(10): # try 10 times then give up
3645 status = self.appStatus( appName )
3646 if status == "UNINSTALLED":
3647 return main.TRUE
3648 else:
3649 time.sleep( 1 )
3650 return main.FALSE
3651 else: # not check or command didn't succeed
3652 return response
Jon Hall146f1522015-03-24 15:33:24 -07003653 elif status == "UNINSTALLED":
3654 return main.TRUE
3655 else:
3656 main.log.error( "Unexpected return value from appStatus: " +
3657 str( status ) )
3658 return main.ERROR
3659 except TypeError:
3660 main.log.exception( self.name + ": Object not as expected" )
3661 return main.ERROR
3662 except pexpect.EOF:
3663 main.log.error( self.name + ": EOF exception found" )
3664 main.log.error( self.name + ": " + self.handle.before )
3665 main.cleanup()
3666 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003667 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003668 main.log.exception( self.name + ": Uncaught exception!" )
3669 main.cleanup()
3670 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003671
3672 def appIDs( self, jsonFormat=True ):
3673 """
3674 Show the mappings between app id and app names given by the 'app-ids'
3675 cli command
3676 """
3677 try:
3678 cmdStr = "app-ids"
3679 if jsonFormat:
3680 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003681 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003682 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003683 assert "Command not found:" not in output, output
3684 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003685 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003686 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003687 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003688 return None
3689 except TypeError:
3690 main.log.exception( self.name + ": Object not as expected" )
3691 return None
3692 except pexpect.EOF:
3693 main.log.error( self.name + ": EOF exception found" )
3694 main.log.error( self.name + ": " + self.handle.before )
3695 main.cleanup()
3696 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003697 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003698 main.log.exception( self.name + ": Uncaught exception!" )
3699 main.cleanup()
3700 main.exit()
3701
3702 def appToIDCheck( self ):
3703 """
3704 This method will check that each application's ID listed in 'apps' is
3705 the same as the ID listed in 'app-ids'. The check will also check that
3706 there are no duplicate IDs issued. Note that an app ID should be
3707 a globaly unique numerical identifier for app/app-like features. Once
3708 an ID is registered, the ID is never freed up so that if an app is
3709 reinstalled it will have the same ID.
3710
3711 Returns: main.TRUE if the check passes and
3712 main.FALSE if the check fails or
3713 main.ERROR if there is some error in processing the test
3714 """
3715 try:
Jon Hall390696c2015-05-05 17:13:41 -07003716 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003717 rawJson = self.appIDs( jsonFormat=True )
3718 if rawJson:
3719 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003720 else:
Jon Hallc6793552016-01-19 14:18:37 -08003721 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003722 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003723 rawJson = self.apps( jsonFormat=True )
3724 if rawJson:
3725 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003726 else:
Jon Hallc6793552016-01-19 14:18:37 -08003727 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003728 bail = True
3729 if bail:
3730 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003731 result = main.TRUE
3732 for app in apps:
3733 appID = app.get( 'id' )
3734 if appID is None:
3735 main.log.error( "Error parsing app: " + str( app ) )
3736 result = main.FALSE
3737 appName = app.get( 'name' )
3738 if appName is None:
3739 main.log.error( "Error parsing app: " + str( app ) )
3740 result = main.FALSE
3741 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003742 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003743 # main.log.debug( "Comparing " + str( app ) + " to " +
3744 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003745 if not current: # if ids doesn't have this id
3746 result = main.FALSE
3747 main.log.error( "'app-ids' does not have the ID for " +
3748 str( appName ) + " that apps does." )
3749 elif len( current ) > 1:
3750 # there is more than one app with this ID
3751 result = main.FALSE
3752 # We will log this later in the method
3753 elif not current[0][ 'name' ] == appName:
3754 currentName = current[0][ 'name' ]
3755 result = main.FALSE
3756 main.log.error( "'app-ids' has " + str( currentName ) +
3757 " registered under id:" + str( appID ) +
3758 " but 'apps' has " + str( appName ) )
3759 else:
3760 pass # id and name match!
3761 # now make sure that app-ids has no duplicates
3762 idsList = []
3763 namesList = []
3764 for item in ids:
3765 idsList.append( item[ 'id' ] )
3766 namesList.append( item[ 'name' ] )
3767 if len( idsList ) != len( set( idsList ) ) or\
3768 len( namesList ) != len( set( namesList ) ):
3769 main.log.error( "'app-ids' has some duplicate entries: \n"
3770 + json.dumps( ids,
3771 sort_keys=True,
3772 indent=4,
3773 separators=( ',', ': ' ) ) )
3774 result = main.FALSE
3775 return result
Jon Hallc6793552016-01-19 14:18:37 -08003776 except ( TypeError, ValueError ):
3777 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003778 return main.ERROR
3779 except pexpect.EOF:
3780 main.log.error( self.name + ": EOF exception found" )
3781 main.log.error( self.name + ": " + self.handle.before )
3782 main.cleanup()
3783 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003784 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003785 main.log.exception( self.name + ": Uncaught exception!" )
3786 main.cleanup()
3787 main.exit()
3788
Jon Hallfb760a02015-04-13 15:35:03 -07003789 def getCfg( self, component=None, propName=None, short=False,
3790 jsonFormat=True ):
3791 """
3792 Get configuration settings from onos cli
3793 Optional arguments:
3794 component - Optionally only list configurations for a specific
3795 component. If None, all components with configurations
3796 are displayed. Case Sensitive string.
3797 propName - If component is specified, propName option will show
3798 only this specific configuration from that component.
3799 Case Sensitive string.
3800 jsonFormat - Returns output as json. Note that this will override
3801 the short option
3802 short - Short, less verbose, version of configurations.
3803 This is overridden by the json option
3804 returns:
3805 Output from cli as a string or None on error
3806 """
3807 try:
3808 baseStr = "cfg"
3809 cmdStr = " get"
3810 componentStr = ""
3811 if component:
3812 componentStr += " " + component
3813 if propName:
3814 componentStr += " " + propName
3815 if jsonFormat:
3816 baseStr += " -j"
3817 elif short:
3818 baseStr += " -s"
3819 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003820 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003821 assert "Command not found:" not in output, output
3822 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003823 return output
3824 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003825 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003826 return None
3827 except TypeError:
3828 main.log.exception( self.name + ": Object not as expected" )
3829 return None
3830 except pexpect.EOF:
3831 main.log.error( self.name + ": EOF exception found" )
3832 main.log.error( self.name + ": " + self.handle.before )
3833 main.cleanup()
3834 main.exit()
3835 except Exception:
3836 main.log.exception( self.name + ": Uncaught exception!" )
3837 main.cleanup()
3838 main.exit()
3839
3840 def setCfg( self, component, propName, value=None, check=True ):
3841 """
3842 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003843 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003844 component - The case sensitive name of the component whose
3845 property is to be set
3846 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003847 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003848 value - The value to set the property to. If None, will unset the
3849 property and revert it to it's default value(if applicable)
3850 check - Boolean, Check whether the option was successfully set this
3851 only applies when a value is given.
3852 returns:
3853 main.TRUE on success or main.FALSE on failure. If check is False,
3854 will return main.TRUE unless there is an error
3855 """
3856 try:
3857 baseStr = "cfg"
3858 cmdStr = " set " + str( component ) + " " + str( propName )
3859 if value is not None:
3860 cmdStr += " " + str( value )
3861 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003862 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003863 assert "Command not found:" not in output, output
3864 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003865 if value and check:
3866 results = self.getCfg( component=str( component ),
3867 propName=str( propName ),
3868 jsonFormat=True )
3869 # Check if current value is what we just set
3870 try:
3871 jsonOutput = json.loads( results )
3872 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003873 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003874 main.log.exception( "Error parsing cfg output" )
3875 main.log.error( "output:" + repr( results ) )
3876 return main.FALSE
3877 if current == str( value ):
3878 return main.TRUE
3879 return main.FALSE
3880 return main.TRUE
3881 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003882 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003883 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003884 except ( TypeError, ValueError ):
3885 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003886 return main.FALSE
3887 except pexpect.EOF:
3888 main.log.error( self.name + ": EOF exception found" )
3889 main.log.error( self.name + ": " + self.handle.before )
3890 main.cleanup()
3891 main.exit()
3892 except Exception:
3893 main.log.exception( self.name + ": Uncaught exception!" )
3894 main.cleanup()
3895 main.exit()
3896
Jon Hall390696c2015-05-05 17:13:41 -07003897 def setTestAdd( self, setName, values ):
3898 """
3899 CLI command to add elements to a distributed set.
3900 Arguments:
3901 setName - The name of the set to add to.
3902 values - The value(s) to add to the set, space seperated.
3903 Example usages:
3904 setTestAdd( "set1", "a b c" )
3905 setTestAdd( "set2", "1" )
3906 returns:
3907 main.TRUE on success OR
3908 main.FALSE if elements were already in the set OR
3909 main.ERROR on error
3910 """
3911 try:
3912 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3913 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003914 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003915 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003916 try:
3917 # TODO: Maybe make this less hardcoded
3918 # ConsistentMap Exceptions
3919 assert "org.onosproject.store.service" not in output
3920 # Node not leader
3921 assert "java.lang.IllegalStateException" not in output
3922 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003923 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003924 "command: " + str( output ) )
3925 retryTime = 30 # Conservative time, given by Madan
3926 main.log.info( "Waiting " + str( retryTime ) +
3927 "seconds before retrying." )
3928 time.sleep( retryTime ) # Due to change in mastership
3929 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003930 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003931 assert "Error executing command" not in output
3932 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3933 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3934 main.log.info( self.name + ": " + output )
3935 if re.search( positiveMatch, output):
3936 return main.TRUE
3937 elif re.search( negativeMatch, output):
3938 return main.FALSE
3939 else:
3940 main.log.error( self.name + ": setTestAdd did not" +
3941 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003942 main.log.debug( self.name + " actual: " + repr( output ) )
3943 return main.ERROR
3944 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003945 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003946 return main.ERROR
3947 except TypeError:
3948 main.log.exception( self.name + ": Object not as expected" )
3949 return main.ERROR
3950 except pexpect.EOF:
3951 main.log.error( self.name + ": EOF exception found" )
3952 main.log.error( self.name + ": " + self.handle.before )
3953 main.cleanup()
3954 main.exit()
3955 except Exception:
3956 main.log.exception( self.name + ": Uncaught exception!" )
3957 main.cleanup()
3958 main.exit()
3959
3960 def setTestRemove( self, setName, values, clear=False, retain=False ):
3961 """
3962 CLI command to remove elements from a distributed set.
3963 Required arguments:
3964 setName - The name of the set to remove from.
3965 values - The value(s) to remove from the set, space seperated.
3966 Optional arguments:
3967 clear - Clear all elements from the set
3968 retain - Retain only the given values. (intersection of the
3969 original set and the given set)
3970 returns:
3971 main.TRUE on success OR
3972 main.FALSE if the set was not changed OR
3973 main.ERROR on error
3974 """
3975 try:
3976 cmdStr = "set-test-remove "
3977 if clear:
3978 cmdStr += "-c " + str( setName )
3979 elif retain:
3980 cmdStr += "-r " + str( setName ) + " " + str( values )
3981 else:
3982 cmdStr += str( setName ) + " " + str( values )
3983 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003984 try:
Jon Halla495f562016-05-16 18:03:26 -07003985 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003986 # TODO: Maybe make this less hardcoded
3987 # ConsistentMap Exceptions
3988 assert "org.onosproject.store.service" not in output
3989 # Node not leader
3990 assert "java.lang.IllegalStateException" not in output
3991 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003992 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003993 "command: " + str( output ) )
3994 retryTime = 30 # Conservative time, given by Madan
3995 main.log.info( "Waiting " + str( retryTime ) +
3996 "seconds before retrying." )
3997 time.sleep( retryTime ) # Due to change in mastership
3998 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003999 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004000 assert "Command not found:" not in output, output
4001 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004002 main.log.info( self.name + ": " + output )
4003 if clear:
4004 pattern = "Set " + str( setName ) + " cleared"
4005 if re.search( pattern, output ):
4006 return main.TRUE
4007 elif retain:
4008 positivePattern = str( setName ) + " was pruned to contain " +\
4009 "only elements of set \[(.*)\]"
4010 negativePattern = str( setName ) + " was not changed by " +\
4011 "retaining only elements of the set " +\
4012 "\[(.*)\]"
4013 if re.search( positivePattern, output ):
4014 return main.TRUE
4015 elif re.search( negativePattern, output ):
4016 return main.FALSE
4017 else:
4018 positivePattern = "\[(.*)\] was removed from the set " +\
4019 str( setName )
4020 if ( len( values.split() ) == 1 ):
4021 negativePattern = "\[(.*)\] was not in set " +\
4022 str( setName )
4023 else:
4024 negativePattern = "No element of \[(.*)\] was in set " +\
4025 str( setName )
4026 if re.search( positivePattern, output ):
4027 return main.TRUE
4028 elif re.search( negativePattern, output ):
4029 return main.FALSE
4030 main.log.error( self.name + ": setTestRemove did not" +
4031 " match expected output" )
4032 main.log.debug( self.name + " expected: " + pattern )
4033 main.log.debug( self.name + " actual: " + repr( output ) )
4034 return main.ERROR
4035 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004036 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004037 return main.ERROR
4038 except TypeError:
4039 main.log.exception( self.name + ": Object not as expected" )
4040 return main.ERROR
4041 except pexpect.EOF:
4042 main.log.error( self.name + ": EOF exception found" )
4043 main.log.error( self.name + ": " + self.handle.before )
4044 main.cleanup()
4045 main.exit()
4046 except Exception:
4047 main.log.exception( self.name + ": Uncaught exception!" )
4048 main.cleanup()
4049 main.exit()
4050
4051 def setTestGet( self, setName, values="" ):
4052 """
4053 CLI command to get the elements in a distributed set.
4054 Required arguments:
4055 setName - The name of the set to remove from.
4056 Optional arguments:
4057 values - The value(s) to check if in the set, space seperated.
4058 returns:
4059 main.ERROR on error OR
4060 A list of elements in the set if no optional arguments are
4061 supplied OR
4062 A tuple containing the list then:
4063 main.FALSE if the given values are not in the set OR
4064 main.TRUE if the given values are in the set OR
4065 """
4066 try:
4067 values = str( values ).strip()
4068 setName = str( setName ).strip()
4069 length = len( values.split() )
4070 containsCheck = None
4071 # Patterns to match
4072 setPattern = "\[(.*)\]"
4073 pattern = "Items in set " + setName + ":\n" + setPattern
4074 containsTrue = "Set " + setName + " contains the value " + values
4075 containsFalse = "Set " + setName + " did not contain the value " +\
4076 values
4077 containsAllTrue = "Set " + setName + " contains the the subset " +\
4078 setPattern
4079 containsAllFalse = "Set " + setName + " did not contain the the" +\
4080 " subset " + setPattern
4081
4082 cmdStr = "set-test-get "
4083 cmdStr += setName + " " + values
4084 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004085 try:
Jon Halla495f562016-05-16 18:03:26 -07004086 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004087 # TODO: Maybe make this less hardcoded
4088 # ConsistentMap Exceptions
4089 assert "org.onosproject.store.service" not in output
4090 # Node not leader
4091 assert "java.lang.IllegalStateException" not in output
4092 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004093 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004094 "command: " + str( output ) )
4095 retryTime = 30 # Conservative time, given by Madan
4096 main.log.info( "Waiting " + str( retryTime ) +
4097 "seconds before retrying." )
4098 time.sleep( retryTime ) # Due to change in mastership
4099 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004100 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004101 assert "Command not found:" not in output, output
4102 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004103 main.log.info( self.name + ": " + output )
4104
4105 if length == 0:
4106 match = re.search( pattern, output )
4107 else: # if given values
4108 if length == 1: # Contains output
4109 patternTrue = pattern + "\n" + containsTrue
4110 patternFalse = pattern + "\n" + containsFalse
4111 else: # ContainsAll output
4112 patternTrue = pattern + "\n" + containsAllTrue
4113 patternFalse = pattern + "\n" + containsAllFalse
4114 matchTrue = re.search( patternTrue, output )
4115 matchFalse = re.search( patternFalse, output )
4116 if matchTrue:
4117 containsCheck = main.TRUE
4118 match = matchTrue
4119 elif matchFalse:
4120 containsCheck = main.FALSE
4121 match = matchFalse
4122 else:
4123 main.log.error( self.name + " setTestGet did not match " +\
4124 "expected output" )
4125 main.log.debug( self.name + " expected: " + pattern )
4126 main.log.debug( self.name + " actual: " + repr( output ) )
4127 match = None
4128 if match:
4129 setMatch = match.group( 1 )
4130 if setMatch == '':
4131 setList = []
4132 else:
4133 setList = setMatch.split( ", " )
4134 if length > 0:
4135 return ( setList, containsCheck )
4136 else:
4137 return setList
4138 else: # no match
4139 main.log.error( self.name + ": setTestGet did not" +
4140 " match expected output" )
4141 main.log.debug( self.name + " expected: " + pattern )
4142 main.log.debug( self.name + " actual: " + repr( output ) )
4143 return main.ERROR
4144 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004145 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004146 return main.ERROR
4147 except TypeError:
4148 main.log.exception( self.name + ": Object not as expected" )
4149 return main.ERROR
4150 except pexpect.EOF:
4151 main.log.error( self.name + ": EOF exception found" )
4152 main.log.error( self.name + ": " + self.handle.before )
4153 main.cleanup()
4154 main.exit()
4155 except Exception:
4156 main.log.exception( self.name + ": Uncaught exception!" )
4157 main.cleanup()
4158 main.exit()
4159
4160 def setTestSize( self, setName ):
4161 """
4162 CLI command to get the elements in a distributed set.
4163 Required arguments:
4164 setName - The name of the set to remove from.
4165 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004166 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004167 None on error
4168 """
4169 try:
4170 # TODO: Should this check against the number of elements returned
4171 # and then return true/false based on that?
4172 setName = str( setName ).strip()
4173 # Patterns to match
4174 setPattern = "\[(.*)\]"
4175 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4176 setPattern
4177 cmdStr = "set-test-get -s "
4178 cmdStr += setName
4179 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004180 try:
Jon Halla495f562016-05-16 18:03:26 -07004181 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004182 # TODO: Maybe make this less hardcoded
4183 # ConsistentMap Exceptions
4184 assert "org.onosproject.store.service" not in output
4185 # Node not leader
4186 assert "java.lang.IllegalStateException" not in output
4187 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004188 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004189 "command: " + str( output ) )
4190 retryTime = 30 # Conservative time, given by Madan
4191 main.log.info( "Waiting " + str( retryTime ) +
4192 "seconds before retrying." )
4193 time.sleep( retryTime ) # Due to change in mastership
4194 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004195 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004196 assert "Command not found:" not in output, output
4197 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004198 main.log.info( self.name + ": " + output )
4199 match = re.search( pattern, output )
4200 if match:
4201 setSize = int( match.group( 1 ) )
4202 setMatch = match.group( 2 )
4203 if len( setMatch.split() ) == setSize:
4204 main.log.info( "The size returned by " + self.name +
4205 " matches the number of elements in " +
4206 "the returned set" )
4207 else:
4208 main.log.error( "The size returned by " + self.name +
4209 " does not match the number of " +
4210 "elements in the returned set." )
4211 return setSize
4212 else: # no match
4213 main.log.error( self.name + ": setTestGet did not" +
4214 " match expected output" )
4215 main.log.debug( self.name + " expected: " + pattern )
4216 main.log.debug( self.name + " actual: " + repr( output ) )
4217 return None
4218 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004219 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004220 return None
Jon Hall390696c2015-05-05 17:13:41 -07004221 except TypeError:
4222 main.log.exception( self.name + ": Object not as expected" )
4223 return None
4224 except pexpect.EOF:
4225 main.log.error( self.name + ": EOF exception found" )
4226 main.log.error( self.name + ": " + self.handle.before )
4227 main.cleanup()
4228 main.exit()
4229 except Exception:
4230 main.log.exception( self.name + ": Uncaught exception!" )
4231 main.cleanup()
4232 main.exit()
4233
Jon Hall80daded2015-05-27 16:07:00 -07004234 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004235 """
4236 Command to list the various counters in the system.
4237 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004238 if jsonFormat, a string of the json object returned by the cli
4239 command
4240 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004241 None on error
4242 """
Jon Hall390696c2015-05-05 17:13:41 -07004243 try:
4244 counters = {}
4245 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004246 if jsonFormat:
4247 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004248 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004249 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004250 assert "Command not found:" not in output, output
4251 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004252 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004253 return output
Jon Hall390696c2015-05-05 17:13:41 -07004254 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004255 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004256 return None
Jon Hall390696c2015-05-05 17:13:41 -07004257 except TypeError:
4258 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004259 return None
Jon Hall390696c2015-05-05 17:13:41 -07004260 except pexpect.EOF:
4261 main.log.error( self.name + ": EOF exception found" )
4262 main.log.error( self.name + ": " + self.handle.before )
4263 main.cleanup()
4264 main.exit()
4265 except Exception:
4266 main.log.exception( self.name + ": Uncaught exception!" )
4267 main.cleanup()
4268 main.exit()
4269
Jon Hall935db192016-04-19 00:22:04 -07004270 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004271 """
Jon Halle1a3b752015-07-22 13:02:46 -07004272 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004273 Required arguments:
4274 counter - The name of the counter to increment.
4275 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004276 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004277 returns:
4278 integer value of the counter or
4279 None on Error
4280 """
4281 try:
4282 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004283 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004284 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004285 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004286 if delta != 1:
4287 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004288 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004289 try:
Jon Halla495f562016-05-16 18:03:26 -07004290 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004291 # TODO: Maybe make this less hardcoded
4292 # ConsistentMap Exceptions
4293 assert "org.onosproject.store.service" not in output
4294 # Node not leader
4295 assert "java.lang.IllegalStateException" not in output
4296 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004297 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004298 "command: " + str( output ) )
4299 retryTime = 30 # Conservative time, given by Madan
4300 main.log.info( "Waiting " + str( retryTime ) +
4301 "seconds before retrying." )
4302 time.sleep( retryTime ) # Due to change in mastership
4303 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004304 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004305 assert "Command not found:" not in output, output
4306 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004307 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004308 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004309 match = re.search( pattern, output )
4310 if match:
4311 return int( match.group( 1 ) )
4312 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004313 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004314 " match expected output." )
4315 main.log.debug( self.name + " expected: " + pattern )
4316 main.log.debug( self.name + " actual: " + repr( output ) )
4317 return None
4318 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004319 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004320 return None
4321 except TypeError:
4322 main.log.exception( self.name + ": Object not as expected" )
4323 return None
4324 except pexpect.EOF:
4325 main.log.error( self.name + ": EOF exception found" )
4326 main.log.error( self.name + ": " + self.handle.before )
4327 main.cleanup()
4328 main.exit()
4329 except Exception:
4330 main.log.exception( self.name + ": Uncaught exception!" )
4331 main.cleanup()
4332 main.exit()
4333
Jon Hall935db192016-04-19 00:22:04 -07004334 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004335 """
4336 CLI command to get a distributed counter then add a delta to it.
4337 Required arguments:
4338 counter - The name of the counter to increment.
4339 Optional arguments:
4340 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004341 returns:
4342 integer value of the counter or
4343 None on Error
4344 """
4345 try:
4346 counter = str( counter )
4347 delta = int( delta )
4348 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004349 cmdStr += counter
4350 if delta != 1:
4351 cmdStr += " " + str( delta )
4352 output = self.sendline( cmdStr )
4353 try:
Jon Halla495f562016-05-16 18:03:26 -07004354 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004355 # TODO: Maybe make this less hardcoded
4356 # ConsistentMap Exceptions
4357 assert "org.onosproject.store.service" not in output
4358 # Node not leader
4359 assert "java.lang.IllegalStateException" not in output
4360 except AssertionError:
4361 main.log.error( "Error in processing '" + cmdStr + "' " +
4362 "command: " + str( output ) )
4363 retryTime = 30 # Conservative time, given by Madan
4364 main.log.info( "Waiting " + str( retryTime ) +
4365 "seconds before retrying." )
4366 time.sleep( retryTime ) # Due to change in mastership
4367 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004368 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004369 assert "Command not found:" not in output, output
4370 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004371 main.log.info( self.name + ": " + output )
4372 pattern = counter + " was updated to (-?\d+)"
4373 match = re.search( pattern, output )
4374 if match:
4375 return int( match.group( 1 ) )
4376 else:
4377 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4378 " match expected output." )
4379 main.log.debug( self.name + " expected: " + pattern )
4380 main.log.debug( self.name + " actual: " + repr( output ) )
4381 return None
4382 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004383 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004384 return None
4385 except TypeError:
4386 main.log.exception( self.name + ": Object not as expected" )
4387 return None
4388 except pexpect.EOF:
4389 main.log.error( self.name + ": EOF exception found" )
4390 main.log.error( self.name + ": " + self.handle.before )
4391 main.cleanup()
4392 main.exit()
4393 except Exception:
4394 main.log.exception( self.name + ": Uncaught exception!" )
4395 main.cleanup()
4396 main.exit()
4397
YPZhangfebf7302016-05-24 16:45:56 -07004398 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004399 """
4400 Description: Execute summary command in onos
4401 Returns: json object ( summary -j ), returns main.FALSE if there is
4402 no output
4403
4404 """
4405 try:
4406 cmdStr = "summary"
4407 if jsonFormat:
4408 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004409 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004410 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004411 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004412 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004413 if not handle:
4414 main.log.error( self.name + ": There is no output in " +
4415 "summary command" )
4416 return main.FALSE
4417 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004418 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004419 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004420 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004421 except TypeError:
4422 main.log.exception( self.name + ": Object not as expected" )
4423 return None
4424 except pexpect.EOF:
4425 main.log.error( self.name + ": EOF exception found" )
4426 main.log.error( self.name + ": " + self.handle.before )
4427 main.cleanup()
4428 main.exit()
4429 except Exception:
4430 main.log.exception( self.name + ": Uncaught exception!" )
4431 main.cleanup()
4432 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004433
Jon Hall935db192016-04-19 00:22:04 -07004434 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004435 """
4436 CLI command to get the value of a key in a consistent map using
4437 transactions. This a test function and can only get keys from the
4438 test map hard coded into the cli command
4439 Required arguments:
4440 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004441 returns:
4442 The string value of the key or
4443 None on Error
4444 """
4445 try:
4446 keyName = str( keyName )
4447 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004448 cmdStr += keyName
4449 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004450 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004451 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004452 try:
4453 # TODO: Maybe make this less hardcoded
4454 # ConsistentMap Exceptions
4455 assert "org.onosproject.store.service" not in output
4456 # Node not leader
4457 assert "java.lang.IllegalStateException" not in output
4458 except AssertionError:
4459 main.log.error( "Error in processing '" + cmdStr + "' " +
4460 "command: " + str( output ) )
4461 return None
4462 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4463 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004464 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004465 return None
4466 else:
4467 match = re.search( pattern, output )
4468 if match:
4469 return match.groupdict()[ 'value' ]
4470 else:
4471 main.log.error( self.name + ": transactionlMapGet did not" +
4472 " match expected output." )
4473 main.log.debug( self.name + " expected: " + pattern )
4474 main.log.debug( self.name + " actual: " + repr( output ) )
4475 return None
Jon Hallc6793552016-01-19 14:18:37 -08004476 except AssertionError:
4477 main.log.exception( "" )
4478 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004479 except TypeError:
4480 main.log.exception( self.name + ": Object not as expected" )
4481 return None
4482 except pexpect.EOF:
4483 main.log.error( self.name + ": EOF exception found" )
4484 main.log.error( self.name + ": " + self.handle.before )
4485 main.cleanup()
4486 main.exit()
4487 except Exception:
4488 main.log.exception( self.name + ": Uncaught exception!" )
4489 main.cleanup()
4490 main.exit()
4491
Jon Hall935db192016-04-19 00:22:04 -07004492 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004493 """
4494 CLI command to put a value into 'numKeys' number of keys in a
4495 consistent map using transactions. This a test function and can only
4496 put into keys named 'Key#' of the test map hard coded into the cli command
4497 Required arguments:
4498 numKeys - Number of keys to add the value to
4499 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004500 returns:
4501 A dictionary whose keys are the name of the keys put into the map
4502 and the values of the keys are dictionaries whose key-values are
4503 'value': value put into map and optionaly
4504 'oldValue': Previous value in the key or
4505 None on Error
4506
4507 Example output
4508 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4509 'Key2': {'value': 'Testing'} }
4510 """
4511 try:
4512 numKeys = str( numKeys )
4513 value = str( value )
4514 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004515 cmdStr += numKeys + " " + value
4516 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004517 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004518 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004519 try:
4520 # TODO: Maybe make this less hardcoded
4521 # ConsistentMap Exceptions
4522 assert "org.onosproject.store.service" not in output
4523 # Node not leader
4524 assert "java.lang.IllegalStateException" not in output
4525 except AssertionError:
4526 main.log.error( "Error in processing '" + cmdStr + "' " +
4527 "command: " + str( output ) )
4528 return None
4529 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4530 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4531 results = {}
4532 for line in output.splitlines():
4533 new = re.search( newPattern, line )
4534 updated = re.search( updatedPattern, line )
4535 if new:
4536 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4537 elif updated:
4538 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004539 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004540 else:
4541 main.log.error( self.name + ": transactionlMapGet did not" +
4542 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004543 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4544 newPattern,
4545 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004546 main.log.debug( self.name + " actual: " + repr( output ) )
4547 return results
Jon Hallc6793552016-01-19 14:18:37 -08004548 except AssertionError:
4549 main.log.exception( "" )
4550 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004551 except TypeError:
4552 main.log.exception( self.name + ": Object not as expected" )
4553 return None
4554 except pexpect.EOF:
4555 main.log.error( self.name + ": EOF exception found" )
4556 main.log.error( self.name + ": " + self.handle.before )
4557 main.cleanup()
4558 main.exit()
4559 except Exception:
4560 main.log.exception( self.name + ": Uncaught exception!" )
4561 main.cleanup()
4562 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004563
acsmarsdaea66c2015-09-03 11:44:06 -07004564 def maps( self, jsonFormat=True ):
4565 """
4566 Description: Returns result of onos:maps
4567 Optional:
4568 * jsonFormat: enable json formatting of output
4569 """
4570 try:
4571 cmdStr = "maps"
4572 if jsonFormat:
4573 cmdStr += " -j"
4574 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004575 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004576 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004577 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004578 except AssertionError:
4579 main.log.exception( "" )
4580 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004581 except TypeError:
4582 main.log.exception( self.name + ": Object not as expected" )
4583 return None
4584 except pexpect.EOF:
4585 main.log.error( self.name + ": EOF exception found" )
4586 main.log.error( self.name + ": " + self.handle.before )
4587 main.cleanup()
4588 main.exit()
4589 except Exception:
4590 main.log.exception( self.name + ": Uncaught exception!" )
4591 main.cleanup()
4592 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004593
4594 def getSwController( self, uri, jsonFormat=True ):
4595 """
4596 Descrition: Gets the controller information from the device
4597 """
4598 try:
4599 cmd = "device-controllers "
4600 if jsonFormat:
4601 cmd += "-j "
4602 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004603 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004604 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004605 return response
Jon Hallc6793552016-01-19 14:18:37 -08004606 except AssertionError:
4607 main.log.exception( "" )
4608 return None
GlennRC050596c2015-11-18 17:06:41 -08004609 except TypeError:
4610 main.log.exception( self.name + ": Object not as expected" )
4611 return None
4612 except pexpect.EOF:
4613 main.log.error( self.name + ": EOF exception found" )
4614 main.log.error( self.name + ": " + self.handle.before )
4615 main.cleanup()
4616 main.exit()
4617 except Exception:
4618 main.log.exception( self.name + ": Uncaught exception!" )
4619 main.cleanup()
4620 main.exit()
4621
4622 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4623 """
4624 Descrition: sets the controller(s) for the specified device
4625
4626 Parameters:
4627 Required: uri - String: The uri of the device(switch).
4628 ip - String or List: The ip address of the controller.
4629 This parameter can be formed in a couple of different ways.
4630 VALID:
4631 10.0.0.1 - just the ip address
4632 tcp:10.0.0.1 - the protocol and the ip address
4633 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4634 so that you can add controllers with different
4635 protocols and ports
4636 INVALID:
4637 10.0.0.1:6653 - this is not supported by ONOS
4638
4639 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4640 port - The port number.
4641 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4642
4643 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4644 """
4645 try:
4646 cmd = "device-setcontrollers"
4647
4648 if jsonFormat:
4649 cmd += " -j"
4650 cmd += " " + uri
4651 if isinstance( ip, str ):
4652 ip = [ip]
4653 for item in ip:
4654 if ":" in item:
4655 sitem = item.split( ":" )
4656 if len(sitem) == 3:
4657 cmd += " " + item
4658 elif "." in sitem[1]:
4659 cmd += " {}:{}".format(item, port)
4660 else:
4661 main.log.error( "Malformed entry: " + item )
4662 raise TypeError
4663 else:
4664 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004665 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004666 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004667 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004668 if "Error" in response:
4669 main.log.error( response )
4670 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004671 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004672 except AssertionError:
4673 main.log.exception( "" )
4674 return None
GlennRC050596c2015-11-18 17:06:41 -08004675 except TypeError:
4676 main.log.exception( self.name + ": Object not as expected" )
4677 return main.FALSE
4678 except pexpect.EOF:
4679 main.log.error( self.name + ": EOF exception found" )
4680 main.log.error( self.name + ": " + self.handle.before )
4681 main.cleanup()
4682 main.exit()
4683 except Exception:
4684 main.log.exception( self.name + ": Uncaught exception!" )
4685 main.cleanup()
4686 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004687
4688 def removeDevice( self, device ):
4689 '''
4690 Description:
4691 Remove a device from ONOS by passing the uri of the device(s).
4692 Parameters:
4693 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4694 Returns:
4695 Returns main.FALSE if an exception is thrown or an error is present
4696 in the response. Otherwise, returns main.TRUE.
4697 NOTE:
4698 If a host cannot be removed, then this function will return main.FALSE
4699 '''
4700 try:
4701 if type( device ) is str:
4702 device = list( device )
4703
4704 for d in device:
4705 time.sleep( 1 )
4706 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004707 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004708 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004709 if "Error" in response:
4710 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4711 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004712 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004713 except AssertionError:
4714 main.log.exception( "" )
4715 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004716 except TypeError:
4717 main.log.exception( self.name + ": Object not as expected" )
4718 return main.FALSE
4719 except pexpect.EOF:
4720 main.log.error( self.name + ": EOF exception found" )
4721 main.log.error( self.name + ": " + self.handle.before )
4722 main.cleanup()
4723 main.exit()
4724 except Exception:
4725 main.log.exception( self.name + ": Uncaught exception!" )
4726 main.cleanup()
4727 main.exit()
4728
4729 def removeHost( self, host ):
4730 '''
4731 Description:
4732 Remove a host from ONOS by passing the id of the host(s)
4733 Parameters:
4734 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4735 Returns:
4736 Returns main.FALSE if an exception is thrown or an error is present
4737 in the response. Otherwise, returns main.TRUE.
4738 NOTE:
4739 If a host cannot be removed, then this function will return main.FALSE
4740 '''
4741 try:
4742 if type( host ) is str:
4743 host = list( host )
4744
4745 for h in host:
4746 time.sleep( 1 )
4747 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004748 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004749 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004750 if "Error" in response:
4751 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4752 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004753 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004754 except AssertionError:
4755 main.log.exception( "" )
4756 return None
GlennRC20fc6522015-12-23 23:26:57 -08004757 except TypeError:
4758 main.log.exception( self.name + ": Object not as expected" )
4759 return main.FALSE
4760 except pexpect.EOF:
4761 main.log.error( self.name + ": EOF exception found" )
4762 main.log.error( self.name + ": " + self.handle.before )
4763 main.cleanup()
4764 main.exit()
4765 except Exception:
4766 main.log.exception( self.name + ": Uncaught exception!" )
4767 main.cleanup()
4768 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004769
YPZhangfebf7302016-05-24 16:45:56 -07004770 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004771 '''
4772 Description:
4773 Bring link down or up in the null-provider.
4774 params:
4775 begin - (string) One end of a device or switch.
4776 end - (string) the other end of the device or switch
4777 returns:
4778 main.TRUE if no exceptions were thrown and no Errors are
4779 present in the resoponse. Otherwise, returns main.FALSE
4780 '''
4781 try:
Jon Hallc6793552016-01-19 14:18:37 -08004782 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004783 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004784 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004785 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004786 if "Error" in response or "Failure" in response:
4787 main.log.error( response )
4788 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004789 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004790 except AssertionError:
4791 main.log.exception( "" )
4792 return None
GlennRCed771242016-01-13 17:02:47 -08004793 except TypeError:
4794 main.log.exception( self.name + ": Object not as expected" )
4795 return main.FALSE
4796 except pexpect.EOF:
4797 main.log.error( self.name + ": EOF exception found" )
4798 main.log.error( self.name + ": " + self.handle.before )
4799 main.cleanup()
4800 main.exit()
4801 except Exception:
4802 main.log.exception( self.name + ": Uncaught exception!" )
4803 main.cleanup()
4804 main.exit()
4805
Flavio Castro82ee2f62016-06-07 15:04:12 -07004806 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4807 '''
4808 Description:
4809 Changes the state of port in an OF switch by means of the
4810 PORTSTATUS OF messages.
4811 params:
4812 dpid - (string) Datapath ID of the device
4813 port - (string) target port in the device
4814 state - (string) target state (enable or disabled)
4815 returns:
4816 main.TRUE if no exceptions were thrown and no Errors are
4817 present in the resoponse. Otherwise, returns main.FALSE
4818 '''
4819 try:
4820 cmd = "portstate {} {} {}".format( dpid, port, state )
4821 response = self.sendline( cmd, showResponse=True )
4822 assert response is not None, "Error in sendline"
4823 assert "Command not found:" not in response, response
4824 if "Error" in response or "Failure" in response:
4825 main.log.error( response )
4826 return main.FALSE
4827 return main.TRUE
4828 except AssertionError:
4829 main.log.exception( "" )
4830 return None
4831 except TypeError:
4832 main.log.exception( self.name + ": Object not as expected" )
4833 return main.FALSE
4834 except pexpect.EOF:
4835 main.log.error( self.name + ": EOF exception found" )
4836 main.log.error( self.name + ": " + self.handle.before )
4837 main.cleanup()
4838 main.exit()
4839 except Exception:
4840 main.log.exception( self.name + ": Uncaught exception!" )
4841 main.cleanup()
4842 main.exit()
4843
4844 def logSet( self, level="INFO", app="org.onosproject" ):
4845 """
4846 Set the logging level to lvl for a specific app
4847 returns main.TRUE on success
4848 returns main.FALSE if Error occurred
4849 if noExit is True, TestON will not exit, but clean up
4850 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4851 Level defaults to INFO
4852 """
4853 try:
4854 self.handle.sendline( "log:set %s %s" %( level, app ) )
4855 self.handle.expect( "onos>" )
4856
4857 response = self.handle.before
4858 if re.search( "Error", response ):
4859 return main.FALSE
4860 return main.TRUE
4861 except pexpect.TIMEOUT:
4862 main.log.exception( self.name + ": TIMEOUT exception found" )
4863 main.cleanup()
4864 main.exit()
4865 except pexpect.EOF:
4866 main.log.error( self.name + ": EOF exception found" )
4867 main.log.error( self.name + ": " + self.handle.before )
4868 main.cleanup()
4869 main.exit()
4870 except Exception:
4871 main.log.exception( self.name + ": Uncaught exception!" )
4872 main.cleanup()
4873 main.exit()