blob: ce493ed3640e0ef7b5a2927fd2e23e1d1b12fec9 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700154 try:
155 self.handle.expect( "\$" )
156 except pexpect.TIMEOUT:
157 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700158 return main.TRUE
159 else: # some other output
160 main.log.warn( "Unknown repsonse to logout command: '{}'",
161 repr( self.handle.before ) )
162 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700163 elif i == 1: # not in CLI
164 return main.TRUE
165 elif i == 3: # Timeout
166 return main.FALSE
167 else:
andrewonlab9627f432014-11-14 12:45:10 -0500168 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800169 except TypeError:
170 main.log.exception( self.name + ": Object not as expected" )
171 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800173 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700174 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500175 main.cleanup()
176 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700177 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700178 main.log.error( self.name +
179 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800180 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800181 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
184
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800186 """
andrewonlab95ce8322014-10-13 14:12:04 -0400187 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800188
andrewonlab95ce8322014-10-13 14:12:04 -0400189 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800190 """
andrewonlab95ce8322014-10-13 14:12:04 -0400191 try:
192 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800193 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400194 main.cleanup()
195 main.exit()
196 else:
kelvin8ec71442015-01-15 16:57:00 -0800197 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800199 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400200 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800201 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800202 handleBefore = self.handle.before
203 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800204 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800205 self.handle.sendline("")
206 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800207 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400208
kelvin-onlabd3b64892015-01-20 13:26:24 -0800209 main.log.info( "Cell call returned: " + handleBefore +
210 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400211
212 return main.TRUE
213
Jon Halld4d4b372015-01-28 16:02:41 -0800214 except TypeError:
215 main.log.exception( self.name + ": Object not as expected" )
216 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400217 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800218 main.log.error( self.name + ": eof exception found" )
219 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400220 main.cleanup()
221 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800222 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800223 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400224 main.cleanup()
225 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800226
pingping-lin57a56ce2015-05-20 16:43:48 -0700227 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800228 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800229 """
Jon Hallefbd9792015-03-05 16:11:36 -0800230 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 by user would be used to set the current karaf shell idle timeout.
232 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800233 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 Below is an example to start a session with 60 seconds idle timeout
235 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800236
Hari Krishna25d42f72015-01-05 15:08:28 -0800237 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800239
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 Note: karafTimeout is left as str so that this could be read
241 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800242 """
You Wangf69ab392016-01-26 16:34:38 -0800243 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400244 try:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline( "" )
246 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700247 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500248
249 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800250 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500251 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400252
kelvin8ec71442015-01-15 16:57:00 -0800253 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800255 i = self.handle.expect( [
256 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700257 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400258
259 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800261 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800262 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800263 "config:property-set -p org.apache.karaf.shell\
264 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800265 karafTimeout )
266 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800268 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400269 return main.TRUE
270 else:
kelvin8ec71442015-01-15 16:57:00 -0800271 # If failed, send ctrl+c to process and try again
272 main.log.info( "Starting CLI failed. Retrying..." )
273 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800275 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
276 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400277 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800279 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800280 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800281 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 "config:property-set -p org.apache.karaf.shell\
283 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800284 karafTimeout )
285 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400288 return main.TRUE
289 else:
kelvin8ec71442015-01-15 16:57:00 -0800290 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400292 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400293
Jon Halld4d4b372015-01-28 16:02:41 -0800294 except TypeError:
295 main.log.exception( self.name + ": Object not as expected" )
296 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800298 main.log.error( self.name + ": EOF exception found" )
299 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400300 main.cleanup()
301 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800303 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400304 main.cleanup()
305 main.exit()
306
suibin zhang116647a2016-05-06 16:30:09 -0700307 def startCellCli( self, karafTimeout="",
308 commandlineTimeout=10, onosStartTimeout=60 ):
309 """
310 Start CLI on onos ecll handle.
311
312 karafTimeout is an optional argument. karafTimeout value passed
313 by user would be used to set the current karaf shell idle timeout.
314 Note that when ever this property is modified the shell will exit and
315 the subsequent login would reflect new idle timeout.
316 Below is an example to start a session with 60 seconds idle timeout
317 ( input value is in milliseconds ):
318
319 tValue = "60000"
320
321 Note: karafTimeout is left as str so that this could be read
322 and passed to startOnosCli from PARAMS file as str.
323 """
324
325 try:
326 self.handle.sendline( "" )
327 x = self.handle.expect( [
328 "\$", "onos>" ], commandlineTimeout)
329
330 if x == 1:
331 main.log.info( "ONOS cli is already running" )
332 return main.TRUE
333
334 # Wait for onos start ( -w ) and enter onos cli
335 self.handle.sendline( "/opt/onos/bin/onos" )
336 i = self.handle.expect( [
337 "onos>",
338 pexpect.TIMEOUT ], onosStartTimeout )
339
340 if i == 0:
341 main.log.info( self.name + " CLI Started successfully" )
342 if karafTimeout:
343 self.handle.sendline(
344 "config:property-set -p org.apache.karaf.shell\
345 sshIdleTimeout " +
346 karafTimeout )
347 self.handle.expect( "\$" )
348 self.handle.sendline( "/opt/onos/bin/onos" )
349 self.handle.expect( "onos>" )
350 return main.TRUE
351 else:
352 # If failed, send ctrl+c to process and try again
353 main.log.info( "Starting CLI failed. Retrying..." )
354 self.handle.send( "\x03" )
355 self.handle.sendline( "/opt/onos/bin/onos" )
356 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
357 timeout=30 )
358 if i == 0:
359 main.log.info( self.name + " CLI Started " +
360 "successfully after retry attempt" )
361 if karafTimeout:
362 self.handle.sendline(
363 "config:property-set -p org.apache.karaf.shell\
364 sshIdleTimeout " +
365 karafTimeout )
366 self.handle.expect( "\$" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 self.handle.expect( "onos>" )
369 return main.TRUE
370 else:
371 main.log.error( "Connection to CLI " +
372 self.name + " timeout" )
373 return main.FALSE
374
375 except TypeError:
376 main.log.exception( self.name + ": Object not as expected" )
377 return None
378 except pexpect.EOF:
379 main.log.error( self.name + ": EOF exception found" )
380 main.log.error( self.name + ": " + self.handle.before )
381 main.cleanup()
382 main.exit()
383 except Exception:
384 main.log.exception( self.name + ": Uncaught exception!" )
385 main.cleanup()
386 main.exit()
387
YPZhangebf9eb52016-05-12 15:20:24 -0700388 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800389 """
390 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800391 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800392 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700393 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800394 Available level: DEBUG, TRACE, INFO, WARN, ERROR
395 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800396 """
397 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800398 lvlStr = ""
399 if level:
400 lvlStr = "--level=" + level
401
kelvin-onlab9f541032015-02-04 16:19:53 -0800402 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800403 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700404 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800405 main.log.error( self.name + ": onos cli session closed. ")
406 if self.onosIp:
407 main.log.warn( "Trying to reconnect " + self.onosIp )
408 reconnectResult = self.startOnosCli( self.onosIp )
409 if reconnectResult:
410 main.log.info( self.name + ": onos cli session reconnected." )
411 else:
412 main.log.error( self.name + ": reconnection failed." )
413 main.cleanup()
414 main.exit()
415 else:
416 main.cleanup()
417 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700418 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700419 self.handle.sendline( "" )
420 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800421 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700422 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800423 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800424
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 response = self.handle.before
426 if re.search( "Error", response ):
427 return main.FALSE
428 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700429 except pexpect.TIMEOUT:
430 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700431 if noExit:
432 main.cleanup()
433 return None
434 else:
435 main.cleanup()
436 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800437 except pexpect.EOF:
438 main.log.error( self.name + ": EOF exception found" )
439 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700440 if noExit:
441 main.cleanup()
442 return None
443 else:
444 main.cleanup()
445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800446 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800447 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700448 if noExit:
449 main.cleanup()
450 return None
451 else:
452 main.cleanup()
453 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400454
YPZhangebf9eb52016-05-12 15:20:24 -0700455 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800456 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800457 Send a completely user specified string to
458 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400459 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800460
YPZhangebf9eb52016-05-12 15:20:24 -0700461 if noExit is True, TestON will not exit, but clean up
462
andrewonlaba18f6bf2014-10-13 19:31:54 -0400463 Warning: There are no sanity checking to commands
464 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800465
kelvin8ec71442015-01-15 16:57:00 -0800466 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 try:
Jon Hall14a03b52016-05-11 12:07:30 -0700468 if debug:
469 # NOTE: This adds and average of .4 seconds per call
470 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700471 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800473 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800474 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800475 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800476 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
477 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700478 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700479 main.log.debug( self.name + ": Raw output" )
480 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700481
482 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800483 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800484 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700485 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700486 main.log.debug( self.name + ": ansiEscape output" )
487 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700488
kelvin-onlabfb521662015-02-27 09:52:40 -0800489 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800490 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700491 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700492 main.log.debug( self.name + ": Removed extra returns " +
493 "from output" )
494 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700495
496 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800497 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700498 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700499 main.log.debug( self.name + ": parsed and stripped output" )
500 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700501
Jon Hall63604932015-02-26 17:09:50 -0800502 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 output = response.split( cmdStr.strip(), 1 )
504 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700505 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700506 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700507 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800508 output = output[1].strip()
509 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800510 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800511 return output
GlennRCed771242016-01-13 17:02:47 -0800512 except pexpect.TIMEOUT:
513 main.log.error( self.name + ":ONOS timeout" )
514 if debug:
515 main.log.debug( self.handle.before )
516 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700517 except IndexError:
518 main.log.exception( self.name + ": Object not as expected" )
519 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800520 except TypeError:
521 main.log.exception( self.name + ": Object not as expected" )
522 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400523 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800524 main.log.error( self.name + ": EOF exception found" )
525 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700526 if noExit:
527 main.cleanup()
528 return None
529 else:
530 main.cleanup()
531 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800532 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800533 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700534 if noExit:
535 main.cleanup()
536 return None
537 else:
538 main.cleanup()
539 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400540
kelvin8ec71442015-01-15 16:57:00 -0800541 # IMPORTANT NOTE:
542 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800543 # the cli command changing 'a:b' with 'aB'.
544 # Ex ) onos:topology > onosTopology
545 # onos:links > onosLinks
546 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800547
kelvin-onlabd3b64892015-01-20 13:26:24 -0800548 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800549 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400550 Adds a new cluster node by ID and address information.
551 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 * nodeId
553 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400554 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800556 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400557 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 cmdStr = "add-node " + str( nodeId ) + " " +\
559 str( ONOSIp ) + " " + str( tcpPort )
560 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800561 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800562 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800563 main.log.error( "Error in adding node" )
564 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800565 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400568 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800569 except AssertionError:
570 main.log.exception( "" )
571 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800572 except TypeError:
573 main.log.exception( self.name + ": Object not as expected" )
574 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400575 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800576 main.log.error( self.name + ": EOF exception found" )
577 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400578 main.cleanup()
579 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800580 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800581 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 main.cleanup()
583 main.exit()
584
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800586 """
andrewonlab86dc3082014-10-13 18:18:38 -0400587 Removes a cluster by ID
588 Issues command: 'remove-node [<node-id>]'
589 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800590 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800591 """
andrewonlab86dc3082014-10-13 18:18:38 -0400592 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400593
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700595 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700597 if re.search( "Error", handle ):
598 main.log.error( "Error in removing node" )
599 main.log.error( handle )
600 return main.FALSE
601 else:
602 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800603 except AssertionError:
604 main.log.exception( "" )
605 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800606 except TypeError:
607 main.log.exception( self.name + ": Object not as expected" )
608 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800610 main.log.error( self.name + ": EOF exception found" )
611 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400612 main.cleanup()
613 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400616 main.cleanup()
617 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400618
Jon Hall61282e32015-03-19 11:34:11 -0700619 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800620 """
andrewonlab7c211572014-10-15 16:45:20 -0400621 List the nodes currently visible
622 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700623 Optional argument:
624 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800625 """
andrewonlab7c211572014-10-15 16:45:20 -0400626 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700627 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700628 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 cmdStr += " -j"
630 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800631 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700632 return output
Jon Hallc6793552016-01-19 14:18:37 -0800633 except AssertionError:
634 main.log.exception( "" )
635 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
andrewonlab7c211572014-10-15 16:45:20 -0400639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400646 main.cleanup()
647 main.exit()
648
kelvin8ec71442015-01-15 16:57:00 -0800649 def topology( self ):
650 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700651 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700652 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700653 Return:
654 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800655 """
andrewonlab95ce8322014-10-13 14:12:04 -0400656 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700657 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800659 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400661 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800662 except AssertionError:
663 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800664 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800665 except TypeError:
666 main.log.exception( self.name + ": Object not as expected" )
667 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400668 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800669 main.log.error( self.name + ": EOF exception found" )
670 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400671 main.cleanup()
672 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800673 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800674 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400675 main.cleanup()
676 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800677
jenkins7ead5a82015-03-13 10:28:21 -0700678 def deviceRemove( self, deviceId ):
679 """
680 Removes particular device from storage
681
682 TODO: refactor this function
683 """
684 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700685 cmdStr = "device-remove " + str( deviceId )
686 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800687 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700688 if re.search( "Error", handle ):
689 main.log.error( "Error in removing device" )
690 main.log.error( handle )
691 return main.FALSE
692 else:
693 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
696 return None
jenkins7ead5a82015-03-13 10:28:21 -0700697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
700 except pexpect.EOF:
701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
703 main.cleanup()
704 main.exit()
705 except Exception:
706 main.log.exception( self.name + ": Uncaught exception!" )
707 main.cleanup()
708 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800711 """
Jon Hall7b02d952014-10-17 20:14:54 -0400712 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400713 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800715 """
andrewonlab86dc3082014-10-13 18:18:38 -0400716 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700717 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 cmdStr += " -j"
720 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800721 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700722 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800723 except AssertionError:
724 main.log.exception( "" )
725 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800726 except TypeError:
727 main.log.exception( self.name + ": Object not as expected" )
728 return None
andrewonlab7c211572014-10-15 16:45:20 -0400729 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400732 main.cleanup()
733 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800735 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400736 main.cleanup()
737 main.exit()
738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800741 This balances the devices across all controllers
742 by issuing command: 'onos> onos:balance-masters'
743 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800744 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800745 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800748 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700749 if re.search( "Error", handle ):
750 main.log.error( "Error in balancing masters" )
751 main.log.error( handle )
752 return main.FALSE
753 else:
754 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800755 except AssertionError:
756 main.log.exception( "" )
757 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800758 except TypeError:
759 main.log.exception( self.name + ": Object not as expected" )
760 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800764 main.cleanup()
765 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800766 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800767 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800768 main.cleanup()
769 main.exit()
770
Jon Hallc6793552016-01-19 14:18:37 -0800771 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700772 """
773 Returns the output of the masters command.
774 Optional argument:
775 * jsonFormat - boolean indicating if you want output in json
776 """
777 try:
778 cmdStr = "onos:masters"
779 if jsonFormat:
780 cmdStr += " -j"
781 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800782 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700783 return output
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
acsmars24950022015-07-30 18:00:43 -0700787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
790 except pexpect.EOF:
791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
793 main.cleanup()
794 main.exit()
795 except Exception:
796 main.log.exception( self.name + ": Uncaught exception!" )
797 main.cleanup()
798 main.exit()
799
Jon Hallc6793552016-01-19 14:18:37 -0800800 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700801 """
802 Uses the master command to check that the devices' leadership
803 is evenly divided
804
805 Dependencies: checkMasters() and summary()
806
807 Returns main.True if the devices are balanced
808 Returns main.False if the devices are unbalanced
809 Exits on Exception
810 Returns None on TypeError
811 """
812 try:
Jon Hallc6793552016-01-19 14:18:37 -0800813 summaryOutput = self.summary()
814 totalDevices = json.loads( summaryOutput )[ "devices" ]
815 except ( TypeError, ValueError ):
816 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
817 return None
818 try:
acsmars24950022015-07-30 18:00:43 -0700819 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800820 mastersOutput = self.checkMasters()
821 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700822 first = masters[ 0 ][ "size" ]
823 for master in masters:
824 totalOwnedDevices += master[ "size" ]
825 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
826 main.log.error( "Mastership not balanced" )
827 main.log.info( "\n" + self.checkMasters( False ) )
828 return main.FALSE
829 main.log.info( "Mastership balanced between " \
830 + str( len(masters) ) + " masters" )
831 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800832 except ( TypeError, ValueError ):
833 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700834 return None
835 except pexpect.EOF:
836 main.log.error( self.name + ": EOF exception found" )
837 main.log.error( self.name + ": " + self.handle.before )
838 main.cleanup()
839 main.exit()
840 except Exception:
841 main.log.exception( self.name + ": Uncaught exception!" )
842 main.cleanup()
843 main.exit()
844
kelvin-onlabd3b64892015-01-20 13:26:24 -0800845 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800846 """
Jon Halle8217482014-10-17 13:49:14 -0400847 Lists all core links
848 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800850 """
Jon Halle8217482014-10-17 13:49:14 -0400851 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700852 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700854 cmdStr += " -j"
855 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800856 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700857 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800858 except AssertionError:
859 main.log.exception( "" )
860 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800861 except TypeError:
862 main.log.exception( self.name + ": Object not as expected" )
863 return None
Jon Halle8217482014-10-17 13:49:14 -0400864 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800865 main.log.error( self.name + ": EOF exception found" )
866 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400867 main.cleanup()
868 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800869 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800870 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400871 main.cleanup()
872 main.exit()
873
kelvin-onlabd3b64892015-01-20 13:26:24 -0800874 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800875 """
Jon Halle8217482014-10-17 13:49:14 -0400876 Lists all ports
877 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800878 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800879 """
Jon Halle8217482014-10-17 13:49:14 -0400880 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700883 cmdStr += " -j"
884 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800885 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700886 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800887 except AssertionError:
888 main.log.exception( "" )
889 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800890 except TypeError:
891 main.log.exception( self.name + ": Object not as expected" )
892 return None
Jon Halle8217482014-10-17 13:49:14 -0400893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.error( self.name + ": EOF exception found" )
895 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400896 main.cleanup()
897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800898 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800899 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400900 main.cleanup()
901 main.exit()
902
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800904 """
Jon Hall983a1702014-10-28 18:44:22 -0400905 Lists all devices and the controllers with roles assigned to them
906 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800908 """
andrewonlab7c211572014-10-15 16:45:20 -0400909 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700912 cmdStr += " -j"
913 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800914 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700915 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800916 except AssertionError:
917 main.log.exception( "" )
918 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800919 except TypeError:
920 main.log.exception( self.name + ": Object not as expected" )
921 return None
Jon Hall983a1702014-10-28 18:44:22 -0400922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400925 main.cleanup()
926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800927 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800928 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400929 main.cleanup()
930 main.exit()
931
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800933 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800934 Given the a string containing the json representation of the "roles"
935 cli command and a partial or whole device id, returns a json object
936 containing the roles output for the first device whose id contains
937 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400938
939 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800940 A dict of the role assignments for the given device or
941 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800942 """
Jon Hall983a1702014-10-28 18:44:22 -0400943 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400945 return None
946 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 rawRoles = self.roles()
948 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800949 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800951 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400953 return device
954 return None
Jon Hallc6793552016-01-19 14:18:37 -0800955 except ( TypeError, ValueError ):
956 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800957 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400961 main.cleanup()
962 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800963 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800964 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400965 main.cleanup()
966 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800967
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800969 """
Jon Hall94fd0472014-12-08 11:52:42 -0800970 Iterates through each device and checks if there is a master assigned
971 Returns: main.TRUE if each device has a master
972 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800973 """
Jon Hall94fd0472014-12-08 11:52:42 -0800974 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 rawRoles = self.roles()
976 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800977 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800979 # print device
980 if device[ 'master' ] == "none":
981 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800982 return main.FALSE
983 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800984 except ( TypeError, ValueError ):
985 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800986 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800988 main.log.error( self.name + ": EOF exception found" )
989 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800990 main.cleanup()
991 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800992 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800993 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800994 main.cleanup()
995 main.exit()
996
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800998 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400999 Returns string of paths, and the cost.
1000 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001001 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001002 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1004 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001005 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001006 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( "Error in getting paths" )
1008 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001009 else:
kelvin8ec71442015-01-15 16:57:00 -08001010 path = handle.split( ";" )[ 0 ]
1011 cost = handle.split( ";" )[ 1 ]
1012 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001013 except AssertionError:
1014 main.log.exception( "" )
1015 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001016 except TypeError:
1017 main.log.exception( self.name + ": Object not as expected" )
1018 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001022 main.cleanup()
1023 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001025 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 main.cleanup()
1027 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001028
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001030 """
Jon Hallffb386d2014-11-21 13:43:38 -08001031 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001032 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001034 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001035 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001036 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001038 cmdStr += " -j"
1039 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001040 if handle:
1041 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001042 # TODO: Maybe make this less hardcoded
1043 # ConsistentMap Exceptions
1044 assert "org.onosproject.store.service" not in handle
1045 # Node not leader
1046 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001047 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001048 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001049 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001050 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001051 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001052 except TypeError:
1053 main.log.exception( self.name + ": Object not as expected" )
1054 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001055 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001056 main.log.error( self.name + ": EOF exception found" )
1057 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001058 main.cleanup()
1059 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001060 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001061 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001062 main.cleanup()
1063 main.exit()
1064
kelvin-onlabd3b64892015-01-20 13:26:24 -08001065 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001066 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001067 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001068
Jon Hallefbd9792015-03-05 16:11:36 -08001069 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001070 partial mac address
1071
Jon Hall42db6dc2014-10-24 19:03:48 -04001072 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001073 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001074 try:
kelvin8ec71442015-01-15 16:57:00 -08001075 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001076 return None
1077 else:
1078 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 rawHosts = self.hosts()
1080 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001081 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001083 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001084 if not host:
1085 pass
1086 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 return host
1088 return None
Jon Hallc6793552016-01-19 14:18:37 -08001089 except ( TypeError, ValueError ):
1090 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001091 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001093 main.log.error( self.name + ": EOF exception found" )
1094 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001095 main.cleanup()
1096 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001098 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 main.cleanup()
1100 main.exit()
1101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001103 """
1104 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001105 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001106
andrewonlab3f0a4af2014-10-17 12:25:14 -04001107 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001109 IMPORTANT:
1110 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001111 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001112 Furthermore, it assumes that value of VLAN is '-1'
1113 Description:
kelvin8ec71442015-01-15 16:57:00 -08001114 Converts mininet hosts ( h1, h2, h3... ) into
1115 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1116 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001121 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 hostHex = hex( int( host ) ).zfill( 12 )
1123 hostHex = str( hostHex ).replace( 'x', '0' )
1124 i = iter( str( hostHex ) )
1125 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1126 hostHex = hostHex + "/-1"
1127 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001130
Jon Halld4d4b372015-01-28 16:02:41 -08001131 except TypeError:
1132 main.log.exception( self.name + ": Object not as expected" )
1133 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001135 main.log.error( self.name + ": EOF exception found" )
1136 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137 main.cleanup()
1138 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001139 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001140 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141 main.cleanup()
1142 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001143
Jeremy Songster832f9e92016-05-05 14:30:49 -07001144 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001145 """
andrewonlabe6745342014-10-17 14:29:13 -04001146 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001147 * hostIdOne: ONOS host id for host1
1148 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001149 Optional:
1150 * vlanId: specify a VLAN id for the intent
andrewonlabe6745342014-10-17 14:29:13 -04001151 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001152 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001153 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001154 Returns:
1155 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001156 """
andrewonlabe6745342014-10-17 14:29:13 -04001157 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001158 cmdStr = "add-host-intent "
1159 if vlanId:
1160 cmdStr += "-v " + str( vlanId ) + " "
1161 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001163 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001164 if re.search( "Error", handle ):
1165 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001166 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001167 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001168 else:
1169 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001170 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1171 match = re.search('id=0x([\da-f]+),', handle)
1172 if match:
1173 return match.group()[3:-1]
1174 else:
1175 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001176 main.log.debug( "Response from ONOS was: " +
1177 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001178 return None
Jon Hallc6793552016-01-19 14:18:37 -08001179 except AssertionError:
1180 main.log.exception( "" )
1181 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001182 except TypeError:
1183 main.log.exception( self.name + ": Object not as expected" )
1184 return None
andrewonlabe6745342014-10-17 14:29:13 -04001185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001188 main.cleanup()
1189 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001190 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001191 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001192 main.cleanup()
1193 main.exit()
1194
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001196 """
andrewonlab7b31d232014-10-24 13:31:47 -04001197 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 * ingressDevice: device id of ingress device
1199 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001200 Optional:
1201 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001202 Description:
1203 Adds an optical intent by specifying an ingress and egress device
1204 Returns:
1205 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001206 """
andrewonlab7b31d232014-10-24 13:31:47 -04001207 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1209 " " + str( egressDevice )
1210 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001211 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001212 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001213 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 main.log.error( "Error in adding Optical intent" )
1215 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001216 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001217 main.log.info( "Optical intent installed between " +
1218 str( ingressDevice ) + " and " +
1219 str( egressDevice ) )
1220 match = re.search('id=0x([\da-f]+),', handle)
1221 if match:
1222 return match.group()[3:-1]
1223 else:
1224 main.log.error( "Error, intent ID not found" )
1225 return None
Jon Hallc6793552016-01-19 14:18:37 -08001226 except AssertionError:
1227 main.log.exception( "" )
1228 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001229 except TypeError:
1230 main.log.exception( self.name + ": Object not as expected" )
1231 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001232 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.error( self.name + ": EOF exception found" )
1234 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001235 main.cleanup()
1236 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001237 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001238 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001239 main.cleanup()
1240 main.exit()
1241
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001243 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 ingressDevice,
1245 egressDevice,
1246 portIngress="",
1247 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001248 ethType="",
1249 ethSrc="",
1250 ethDst="",
1251 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 ipProto="",
1254 ipSrc="",
1255 ipDst="",
1256 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001257 tcpDst="",
1258 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001259 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001260 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 * ingressDevice: device id of ingress device
1262 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001263 Optional:
1264 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001265 * ethSrc: specify ethSrc ( i.e. src mac addr )
1266 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001267 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001269 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001270 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001271 * ipSrc: specify ip source address
1272 * ipDst: specify ip destination address
1273 * tcpSrc: specify tcp source port
1274 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001275 * vlanId: specify vlan ID
andrewonlab4dbb4d82014-10-17 18:22:31 -04001276 Description:
kelvin8ec71442015-01-15 16:57:00 -08001277 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001278 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001279 Returns:
1280 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001281
Jon Halle3f39ff2015-01-13 11:50:53 -08001282 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001283 options developers provide for point-to-point
1284 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001285 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001286 try:
kelvin8ec71442015-01-15 16:57:00 -08001287 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001288 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001290 and not ipProto and not ipSrc and not ipDst \
1291 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001292 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001293
andrewonlab289e4b72014-10-21 21:24:18 -04001294 else:
andrewonlab36af3822014-11-18 17:48:18 -05001295 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001296
andrewonlab0c0a6772014-10-22 12:31:18 -04001297 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001298 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001299 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001300 cmd += " --ethSrc " + str( ethSrc )
1301 if ethDst:
1302 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001303 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001304 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001306 cmd += " --lambda "
1307 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001308 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001309 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001310 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001311 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001312 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001313 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001314 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001315 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001316 cmd += " --tcpDst " + str( tcpDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001317 if vlanId:
1318 cmd += " -v " + str( vlanId )
andrewonlab289e4b72014-10-21 21:24:18 -04001319
kelvin8ec71442015-01-15 16:57:00 -08001320 # Check whether the user appended the port
1321 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 if "/" in ingressDevice:
1323 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001324 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001326 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001327 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001328 # Would it make sense to throw an exception and exit
1329 # the test?
1330 return None
andrewonlab36af3822014-11-18 17:48:18 -05001331
kelvin8ec71442015-01-15 16:57:00 -08001332 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 str( ingressDevice ) + "/" +\
1334 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001335
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 if "/" in egressDevice:
1337 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001338 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001340 main.log.error( "You must specify the egress port" )
1341 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001342
kelvin8ec71442015-01-15 16:57:00 -08001343 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 str( egressDevice ) + "/" +\
1345 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001346
kelvin-onlab898a6c62015-01-16 14:13:53 -08001347 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001348 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001349 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001350 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001351 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001352 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001353 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001354 # TODO: print out all the options in this message?
1355 main.log.info( "Point-to-point intent installed between " +
1356 str( ingressDevice ) + " and " +
1357 str( egressDevice ) )
1358 match = re.search('id=0x([\da-f]+),', handle)
1359 if match:
1360 return match.group()[3:-1]
1361 else:
1362 main.log.error( "Error, intent ID not found" )
1363 return None
Jon Hallc6793552016-01-19 14:18:37 -08001364 except AssertionError:
1365 main.log.exception( "" )
1366 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001367 except TypeError:
1368 main.log.exception( self.name + ": Object not as expected" )
1369 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001370 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001371 main.log.error( self.name + ": EOF exception found" )
1372 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001373 main.cleanup()
1374 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001375 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001376 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001377 main.cleanup()
1378 main.exit()
1379
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001381 self,
shahshreyac2f97072015-03-19 17:04:29 -07001382 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001384 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001385 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001386 ethType="",
1387 ethSrc="",
1388 ethDst="",
1389 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001391 ipProto="",
1392 ipSrc="",
1393 ipDst="",
1394 tcpSrc="",
1395 tcpDst="",
1396 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001397 setEthDst="",
1398 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001399 """
shahshreyad0c80432014-12-04 16:56:05 -08001400 Note:
shahshreya70622b12015-03-19 17:19:00 -07001401 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001402 is same. That is, all ingress devices include port numbers
1403 with a "/" or all ingress devices could specify device
1404 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001405 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001406 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001407 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001409 Optional:
1410 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001411 * ethSrc: specify ethSrc ( i.e. src mac addr )
1412 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001413 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001414 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001415 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001416 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001417 * ipSrc: specify ip source address
1418 * ipDst: specify ip destination address
1419 * tcpSrc: specify tcp source port
1420 * tcpDst: specify tcp destination port
1421 * setEthSrc: action to Rewrite Source MAC Address
1422 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001423 * vlanId: specify vlan Id
shahshreyad0c80432014-12-04 16:56:05 -08001424 Description:
kelvin8ec71442015-01-15 16:57:00 -08001425 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001426 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001427 Returns:
1428 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001429
Jon Halle3f39ff2015-01-13 11:50:53 -08001430 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001431 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001432 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001433 """
shahshreyad0c80432014-12-04 16:56:05 -08001434 try:
kelvin8ec71442015-01-15 16:57:00 -08001435 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001436 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001438 and not ipProto and not ipSrc and not ipDst\
1439 and not tcpSrc and not tcpDst and not setEthSrc\
1440 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001441 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001442
1443 else:
1444 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001445
shahshreyad0c80432014-12-04 16:56:05 -08001446 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001447 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001448 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001449 cmd += " --ethSrc " + str( ethSrc )
1450 if ethDst:
1451 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001452 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001453 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001455 cmd += " --lambda "
1456 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001457 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001458 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001459 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001460 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001461 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001462 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001463 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001464 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001465 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001466 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001467 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001468 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001469 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001470 if vlanId:
1471 cmd += " -v " + str( vlanId )
shahshreyad0c80432014-12-04 16:56:05 -08001472
kelvin8ec71442015-01-15 16:57:00 -08001473 # Check whether the user appended the port
1474 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001475
1476 if portIngressList is None:
1477 for ingressDevice in ingressDeviceList:
1478 if "/" in ingressDevice:
1479 cmd += " " + str( ingressDevice )
1480 else:
1481 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001482 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001483 # TODO: perhaps more meaningful return
1484 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001485 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001486 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001487 for ingressDevice, portIngress in zip( ingressDeviceList,
1488 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001489 cmd += " " + \
1490 str( ingressDevice ) + "/" +\
1491 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001492 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001493 main.log.error( "Device list and port list does not " +
1494 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001495 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 if "/" in egressDevice:
1497 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001498 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001499 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001500 main.log.error( "You must specify " +
1501 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001502 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001503
kelvin8ec71442015-01-15 16:57:00 -08001504 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 str( egressDevice ) + "/" +\
1506 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001507 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001508 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001509 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001510 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001511 main.log.error( "Error in adding multipoint-to-singlepoint " +
1512 "intent" )
1513 return None
shahshreyad0c80432014-12-04 16:56:05 -08001514 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001515 match = re.search('id=0x([\da-f]+),', handle)
1516 if match:
1517 return match.group()[3:-1]
1518 else:
1519 main.log.error( "Error, intent ID not found" )
1520 return None
Jon Hallc6793552016-01-19 14:18:37 -08001521 except AssertionError:
1522 main.log.exception( "" )
1523 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001524 except TypeError:
1525 main.log.exception( self.name + ": Object not as expected" )
1526 return None
1527 except pexpect.EOF:
1528 main.log.error( self.name + ": EOF exception found" )
1529 main.log.error( self.name + ": " + self.handle.before )
1530 main.cleanup()
1531 main.exit()
1532 except Exception:
1533 main.log.exception( self.name + ": Uncaught exception!" )
1534 main.cleanup()
1535 main.exit()
1536
1537 def addSinglepointToMultipointIntent(
1538 self,
1539 ingressDevice,
1540 egressDeviceList,
1541 portIngress="",
1542 portEgressList=None,
1543 ethType="",
1544 ethSrc="",
1545 ethDst="",
1546 bandwidth="",
1547 lambdaAlloc=False,
1548 ipProto="",
1549 ipSrc="",
1550 ipDst="",
1551 tcpSrc="",
1552 tcpDst="",
1553 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001554 setEthDst="",
1555 vlanId="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001556 """
1557 Note:
1558 This function assumes the format of all egress devices
1559 is same. That is, all egress devices include port numbers
1560 with a "/" or all egress devices could specify device
1561 ids and port numbers seperately.
1562 Required:
1563 * EgressDeviceList: List of device ids of egress device
1564 ( Atleast 2 eress devices required in the list )
1565 * ingressDevice: device id of ingress device
1566 Optional:
1567 * ethType: specify ethType
1568 * ethSrc: specify ethSrc ( i.e. src mac addr )
1569 * ethDst: specify ethDst ( i.e. dst mac addr )
1570 * bandwidth: specify bandwidth capacity of link
1571 * lambdaAlloc: if True, intent will allocate lambda
1572 for the specified intent
1573 * ipProto: specify ip protocol
1574 * ipSrc: specify ip source address
1575 * ipDst: specify ip destination address
1576 * tcpSrc: specify tcp source port
1577 * tcpDst: specify tcp destination port
1578 * setEthSrc: action to Rewrite Source MAC Address
1579 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001580 * vlanId: specify vlan Id
kelvin-onlabb9408212015-04-01 13:34:04 -07001581 Description:
1582 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1583 specifying device id's and optional fields
1584 Returns:
1585 A string of the intent id or None on error
1586
1587 NOTE: This function may change depending on the
1588 options developers provide for singlepoint-to-multipoint
1589 intent via cli
1590 """
1591 try:
1592 # If there are no optional arguments
1593 if not ethType and not ethSrc and not ethDst\
1594 and not bandwidth and not lambdaAlloc\
1595 and not ipProto and not ipSrc and not ipDst\
1596 and not tcpSrc and not tcpDst and not setEthSrc\
1597 and not setEthDst:
1598 cmd = "add-single-to-multi-intent"
1599
1600 else:
1601 cmd = "add-single-to-multi-intent"
1602
1603 if ethType:
1604 cmd += " --ethType " + str( ethType )
1605 if ethSrc:
1606 cmd += " --ethSrc " + str( ethSrc )
1607 if ethDst:
1608 cmd += " --ethDst " + str( ethDst )
1609 if bandwidth:
1610 cmd += " --bandwidth " + str( bandwidth )
1611 if lambdaAlloc:
1612 cmd += " --lambda "
1613 if ipProto:
1614 cmd += " --ipProto " + str( ipProto )
1615 if ipSrc:
1616 cmd += " --ipSrc " + str( ipSrc )
1617 if ipDst:
1618 cmd += " --ipDst " + str( ipDst )
1619 if tcpSrc:
1620 cmd += " --tcpSrc " + str( tcpSrc )
1621 if tcpDst:
1622 cmd += " --tcpDst " + str( tcpDst )
1623 if setEthSrc:
1624 cmd += " --setEthSrc " + str( setEthSrc )
1625 if setEthDst:
1626 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001627 if vlanId:
1628 cmd += " -v " + str( vlanId )
kelvin-onlabb9408212015-04-01 13:34:04 -07001629
1630 # Check whether the user appended the port
1631 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001632
kelvin-onlabb9408212015-04-01 13:34:04 -07001633 if "/" in ingressDevice:
1634 cmd += " " + str( ingressDevice )
1635 else:
1636 if not portIngress:
1637 main.log.error( "You must specify " +
1638 "the Ingress port" )
1639 return main.FALSE
1640
1641 cmd += " " +\
1642 str( ingressDevice ) + "/" +\
1643 str( portIngress )
1644
1645 if portEgressList is None:
1646 for egressDevice in egressDeviceList:
1647 if "/" in egressDevice:
1648 cmd += " " + str( egressDevice )
1649 else:
1650 main.log.error( "You must specify " +
1651 "the egress port" )
1652 # TODO: perhaps more meaningful return
1653 return main.FALSE
1654 else:
1655 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001656 for egressDevice, portEgress in zip( egressDeviceList,
1657 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001658 cmd += " " + \
1659 str( egressDevice ) + "/" +\
1660 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001661 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001662 main.log.error( "Device list and port list does not " +
1663 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001664 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001665 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001666 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001667 # If error, return error message
1668 if re.search( "Error", handle ):
1669 main.log.error( "Error in adding singlepoint-to-multipoint " +
1670 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001671 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001672 else:
1673 match = re.search('id=0x([\da-f]+),', handle)
1674 if match:
1675 return match.group()[3:-1]
1676 else:
1677 main.log.error( "Error, intent ID not found" )
1678 return None
Jon Hallc6793552016-01-19 14:18:37 -08001679 except AssertionError:
1680 main.log.exception( "" )
1681 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001682 except TypeError:
1683 main.log.exception( self.name + ": Object not as expected" )
1684 return None
shahshreyad0c80432014-12-04 16:56:05 -08001685 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( self.name + ": EOF exception found" )
1687 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001688 main.cleanup()
1689 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001690 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001691 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001692 main.cleanup()
1693 main.exit()
1694
Hari Krishna9e232602015-04-13 17:29:08 -07001695 def addMplsIntent(
1696 self,
1697 ingressDevice,
1698 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001699 ingressPort="",
1700 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001701 ethType="",
1702 ethSrc="",
1703 ethDst="",
1704 bandwidth="",
1705 lambdaAlloc=False,
1706 ipProto="",
1707 ipSrc="",
1708 ipDst="",
1709 tcpSrc="",
1710 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001711 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001712 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001713 priority=""):
1714 """
1715 Required:
1716 * ingressDevice: device id of ingress device
1717 * egressDevice: device id of egress device
1718 Optional:
1719 * ethType: specify ethType
1720 * ethSrc: specify ethSrc ( i.e. src mac addr )
1721 * ethDst: specify ethDst ( i.e. dst mac addr )
1722 * bandwidth: specify bandwidth capacity of link
1723 * lambdaAlloc: if True, intent will allocate lambda
1724 for the specified intent
1725 * ipProto: specify ip protocol
1726 * ipSrc: specify ip source address
1727 * ipDst: specify ip destination address
1728 * tcpSrc: specify tcp source port
1729 * tcpDst: specify tcp destination port
1730 * ingressLabel: Ingress MPLS label
1731 * egressLabel: Egress MPLS label
1732 Description:
1733 Adds MPLS intent by
1734 specifying device id's and optional fields
1735 Returns:
1736 A string of the intent id or None on error
1737
1738 NOTE: This function may change depending on the
1739 options developers provide for MPLS
1740 intent via cli
1741 """
1742 try:
1743 # If there are no optional arguments
1744 if not ethType and not ethSrc and not ethDst\
1745 and not bandwidth and not lambdaAlloc \
1746 and not ipProto and not ipSrc and not ipDst \
1747 and not tcpSrc and not tcpDst and not ingressLabel \
1748 and not egressLabel:
1749 cmd = "add-mpls-intent"
1750
1751 else:
1752 cmd = "add-mpls-intent"
1753
1754 if ethType:
1755 cmd += " --ethType " + str( ethType )
1756 if ethSrc:
1757 cmd += " --ethSrc " + str( ethSrc )
1758 if ethDst:
1759 cmd += " --ethDst " + str( ethDst )
1760 if bandwidth:
1761 cmd += " --bandwidth " + str( bandwidth )
1762 if lambdaAlloc:
1763 cmd += " --lambda "
1764 if ipProto:
1765 cmd += " --ipProto " + str( ipProto )
1766 if ipSrc:
1767 cmd += " --ipSrc " + str( ipSrc )
1768 if ipDst:
1769 cmd += " --ipDst " + str( ipDst )
1770 if tcpSrc:
1771 cmd += " --tcpSrc " + str( tcpSrc )
1772 if tcpDst:
1773 cmd += " --tcpDst " + str( tcpDst )
1774 if ingressLabel:
1775 cmd += " --ingressLabel " + str( ingressLabel )
1776 if egressLabel:
1777 cmd += " --egressLabel " + str( egressLabel )
1778 if priority:
1779 cmd += " --priority " + str( priority )
1780
1781 # Check whether the user appended the port
1782 # or provided it as an input
1783 if "/" in ingressDevice:
1784 cmd += " " + str( ingressDevice )
1785 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001786 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001787 main.log.error( "You must specify the ingress port" )
1788 return None
1789
1790 cmd += " " + \
1791 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001792 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001793
1794 if "/" in egressDevice:
1795 cmd += " " + str( egressDevice )
1796 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001797 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001798 main.log.error( "You must specify the egress port" )
1799 return None
1800
1801 cmd += " " +\
1802 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001803 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001806 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001807 # If error, return error message
1808 if re.search( "Error", handle ):
1809 main.log.error( "Error in adding mpls intent" )
1810 return None
1811 else:
1812 # TODO: print out all the options in this message?
1813 main.log.info( "MPLS intent installed between " +
1814 str( ingressDevice ) + " and " +
1815 str( egressDevice ) )
1816 match = re.search('id=0x([\da-f]+),', handle)
1817 if match:
1818 return match.group()[3:-1]
1819 else:
1820 main.log.error( "Error, intent ID not found" )
1821 return None
Jon Hallc6793552016-01-19 14:18:37 -08001822 except AssertionError:
1823 main.log.exception( "" )
1824 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001825 except TypeError:
1826 main.log.exception( self.name + ": Object not as expected" )
1827 return None
1828 except pexpect.EOF:
1829 main.log.error( self.name + ": EOF exception found" )
1830 main.log.error( self.name + ": " + self.handle.before )
1831 main.cleanup()
1832 main.exit()
1833 except Exception:
1834 main.log.exception( self.name + ": Uncaught exception!" )
1835 main.cleanup()
1836 main.exit()
1837
Jon Hallefbd9792015-03-05 16:11:36 -08001838 def removeIntent( self, intentId, app='org.onosproject.cli',
1839 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001840 """
shahshreya1c818fc2015-02-26 13:44:08 -08001841 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001842 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001843 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001844 -p or --purge: Purge the intent from the store after removal
1845
Jon Halle3f39ff2015-01-13 11:50:53 -08001846 Returns:
1847 main.False on error and
1848 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001850 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001851 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001852 if purge:
1853 cmdStr += " -p"
1854 if sync:
1855 cmdStr += " -s"
1856
1857 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001859 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001860 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001862 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001863 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 # TODO: Should this be main.TRUE
1865 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001866 except AssertionError:
1867 main.log.exception( "" )
1868 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001875 main.cleanup()
1876 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001879 main.cleanup()
1880 main.exit()
1881
Jeremy42df2e72016-02-23 16:37:46 -08001882 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1883 """
1884 Description:
1885 Remove all the intents
1886 Optional args:-
1887 -s or --sync: Waits for the removal before returning
1888 -p or --purge: Purge the intent from the store after removal
1889 Returns:
1890 Returns main.TRUE if all intents are removed, otherwise returns
1891 main.FALSE; Returns None for exception
1892 """
1893 try:
1894 cmdStr = "remove-intent"
1895 if purge:
1896 cmdStr += " -p"
1897 if sync:
1898 cmdStr += " -s"
1899
1900 cmdStr += " " + app
1901 handle = self.sendline( cmdStr )
1902 assert "Command not found:" not in handle, handle
1903 if re.search( "Error", handle ):
1904 main.log.error( "Error in removing intent" )
1905 return main.FALSE
1906 else:
1907 return main.TRUE
1908 except AssertionError:
1909 main.log.exception( "" )
1910 return None
1911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
1914 except pexpect.EOF:
1915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
1917 main.cleanup()
1918 main.exit()
1919 except Exception:
1920 main.log.exception( self.name + ": Uncaught exception!" )
1921 main.cleanup()
1922 main.exit()
1923
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001924 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001925 """
1926 Purges all WITHDRAWN Intents
1927 """
1928 try:
1929 cmdStr = "purge-intents"
1930 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001931 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 if re.search( "Error", handle ):
1933 main.log.error( "Error in purging intents" )
1934 return main.FALSE
1935 else:
1936 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001937 except AssertionError:
1938 main.log.exception( "" )
1939 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 except TypeError:
1941 main.log.exception( self.name + ": Object not as expected" )
1942 return None
1943 except pexpect.EOF:
1944 main.log.error( self.name + ": EOF exception found" )
1945 main.log.error( self.name + ": " + self.handle.before )
1946 main.cleanup()
1947 main.exit()
1948 except Exception:
1949 main.log.exception( self.name + ": Uncaught exception!" )
1950 main.cleanup()
1951 main.exit()
1952
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001954 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001955 NOTE: This method should be used after installing application:
1956 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001957 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001959 Description:
1960 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001961 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001963 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001965 cmdStr += " -j"
1966 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001967 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001969 except AssertionError:
1970 main.log.exception( "" )
1971 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001972 except TypeError:
1973 main.log.exception( self.name + ": Object not as expected" )
1974 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001976 main.log.error( self.name + ": EOF exception found" )
1977 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001978 main.cleanup()
1979 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001981 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 main.cleanup()
1983 main.exit()
1984
pingping-lin54b03372015-08-13 14:43:10 -07001985 def ipv4RouteNumber( self ):
1986 """
1987 NOTE: This method should be used after installing application:
1988 onos-app-sdnip
1989 Description:
1990 Obtain the total IPv4 routes number in the system
1991 """
1992 try:
1993 cmdStr = "routes -s -j"
1994 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001995 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001996 jsonResult = json.loads( handle )
1997 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001998 except AssertionError:
1999 main.log.exception( "" )
2000 return None
2001 except ( TypeError, ValueError ):
2002 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002003 return None
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
2007 main.cleanup()
2008 main.exit()
2009 except Exception:
2010 main.log.exception( self.name + ": Uncaught exception!" )
2011 main.cleanup()
2012 main.exit()
2013
pingping-lin8244a3b2015-09-16 13:36:56 -07002014 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002015 """
andrewonlabe6745342014-10-17 14:29:13 -04002016 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002017 Obtain intents from the ONOS cli.
2018 Optional:
2019 * jsonFormat: Enable output formatting in json, default to True
2020 * summary: Whether only output the intent summary, defaults to False
2021 * type: Only output a certain type of intent. This options is valid
2022 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002023 """
andrewonlabe6745342014-10-17 14:29:13 -04002024 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002025 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002026 if summary:
2027 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002028 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002029 cmdStr += " -j"
2030 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002031 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002032 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002033 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002034 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002035 else:
Jon Hallff566d52016-01-15 14:45:36 -08002036 intentType = ""
2037 # IF we want the summary of a specific intent type
2038 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002040 if intentType in jsonResult.keys():
2041 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002042 else:
Jon Hallff566d52016-01-15 14:45:36 -08002043 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002044 return handle
2045 else:
2046 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002047 except AssertionError:
2048 main.log.exception( "" )
2049 return None
2050 except ( TypeError, ValueError ):
2051 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002052 return None
2053 except pexpect.EOF:
2054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
2056 main.cleanup()
2057 main.exit()
2058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
2060 main.cleanup()
2061 main.exit()
2062
kelvin-onlab54400a92015-02-26 18:05:51 -08002063 def getIntentState(self, intentsId, intentsJson=None):
2064 """
You Wangfdcbfc42016-05-16 12:16:53 -07002065 Description:
2066 Gets intent state. Accepts a single intent ID (string type) or a
2067 list of intent IDs.
2068 Parameters:
2069 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002071 Returns:
2072 Returns the state (string type) of the ID if a single intent ID is
2073 accepted.
2074 Returns a list of dictionaries if a list of intent IDs is accepted,
2075 and each dictionary maps 'id' to the Intent ID and 'state' to
2076 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002078 try:
2079 state = "State is Undefined"
2080 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002081 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002082 else:
Jon Hallc6793552016-01-19 14:18:37 -08002083 rawJson = intentsJson
2084 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002085 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002086 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002087 if intentsId == intent[ 'id' ]:
2088 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002090 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2091 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002092 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002093 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002094 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002095 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002096 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002097 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002098 if intentsId[ i ] == intents[ 'id' ]:
2099 stateDict[ 'state' ] = intents[ 'state' ]
2100 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002101 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 break
Jon Hallefbd9792015-03-05 16:11:36 -08002103 if len( intentsId ) != len( dictList ):
2104 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002105 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002107 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 return None
Jon Hallc6793552016-01-19 14:18:37 -08002109 except ( TypeError, ValueError ):
2110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002111 return None
2112 except pexpect.EOF:
2113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
2115 main.cleanup()
2116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002117 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002118 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002119 main.cleanup()
2120 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002121
kelvin-onlabf512e942015-06-08 19:42:59 -07002122 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 """
2124 Description:
2125 Check intents state
2126 Required:
2127 intentsId - List of intents ID to be checked
2128 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 expectedState - Check the expected state(s) of each intents
2130 state in the list.
2131 *NOTE: You can pass in a list of expected state,
2132 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002133 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002134 Returns main.TRUE only if all intent are the same as expected states
2135 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002136 """
2137 try:
2138 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002139 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002140 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002141 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002142 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 "getting intents state" )
2144 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002145
2146 if isinstance( expectedState, types.StringType ):
2147 for intents in intentsDict:
2148 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002149 main.log.debug( self.name + " : Intent ID - " +
2150 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002151 " actual state = " +
2152 intents.get( 'state' )
2153 + " does not equal expected state = "
2154 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002155 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002156
2157 elif isinstance( expectedState, types.ListType ):
2158 for intents in intentsDict:
2159 if not any( state == intents.get( 'state' ) for state in
2160 expectedState ):
2161 main.log.debug( self.name + " : Intent ID - " +
2162 intents.get( 'id' ) +
2163 " actual state = " +
2164 intents.get( 'state' ) +
2165 " does not equal expected states = "
2166 + str( expectedState ) )
2167 returnValue = main.FALSE
2168
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002169 if returnValue == main.TRUE:
2170 main.log.info( self.name + ": All " +
2171 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002172 " intents are in " + str( expectedState ) +
2173 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002174 return returnValue
2175 except TypeError:
2176 main.log.exception( self.name + ": Object not as expected" )
2177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
2181 main.cleanup()
2182 main.exit()
2183 except Exception:
2184 main.log.exception( self.name + ": Uncaught exception!" )
2185 main.cleanup()
2186 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002187
GlennRCed771242016-01-13 17:02:47 -08002188 def checkIntentSummary( self, timeout=60 ):
2189 """
2190 Description:
2191 Check the number of installed intents.
2192 Optional:
2193 timeout - the timeout for pexcept
2194 Return:
2195 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2196 , otherwise, returns main.FALSE.
2197 """
2198
2199 try:
2200 cmd = "intents -s -j"
2201
2202 # Check response if something wrong
2203 response = self.sendline( cmd, timeout=timeout )
2204 if response == None:
2205 return main.False
2206 response = json.loads( response )
2207
2208 # get total and installed number, see if they are match
2209 allState = response.get( 'all' )
2210 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002211 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002212 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002213 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002214 return main.FALSE
2215
Jon Hallc6793552016-01-19 14:18:37 -08002216 except ( TypeError, ValueError ):
2217 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002218 return None
2219 except pexpect.EOF:
2220 main.log.error( self.name + ": EOF exception found" )
2221 main.log.error( self.name + ": " + self.handle.before )
2222 main.cleanup()
2223 main.exit()
2224 except Exception:
2225 main.log.exception( self.name + ": Uncaught exception!" )
2226 main.cleanup()
2227 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002228 except pexpect.TIMEOUT:
2229 main.log.error( self.name + ": ONOS timeout" )
2230 return None
GlennRCed771242016-01-13 17:02:47 -08002231
YPZhangebf9eb52016-05-12 15:20:24 -07002232 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002233 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002234 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002235 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002236 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002237 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002238 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002239 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002240 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002241 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002242 cmdStr += " -j "
2243 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002244 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002245 assert "Command not found:" not in handle, handle
2246 if re.search( "Error:", handle ):
2247 main.log.error( self.name + ": flows() response: " +
2248 str( handle ) )
2249 return handle
2250 except AssertionError:
2251 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002252 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002253 except TypeError:
2254 main.log.exception( self.name + ": Object not as expected" )
2255 return None
Jon Hallc6793552016-01-19 14:18:37 -08002256 except pexpect.TIMEOUT:
2257 main.log.error( self.name + ": ONOS timeout" )
2258 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002260 main.log.error( self.name + ": EOF exception found" )
2261 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002262 main.cleanup()
2263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002265 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002266 main.cleanup()
2267 main.exit()
2268
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002269 def checkFlowCount(self, min=0, timeout=60 ):
2270 count = int(self.getTotalFlowsNum( timeout=timeout ))
2271 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002272
YPZhangebf9eb52016-05-12 15:20:24 -07002273 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002274 """
2275 Description:
GlennRCed771242016-01-13 17:02:47 -08002276 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002277 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2278 if the count of those states is 0, which means all current flows
2279 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002280 Optional:
GlennRCed771242016-01-13 17:02:47 -08002281 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002282 Return:
2283 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002284 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002285 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002286 """
2287 try:
GlennRCed771242016-01-13 17:02:47 -08002288 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2289 checkedStates = []
2290 statesCount = [0, 0, 0, 0]
2291 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002292 rawFlows = self.flows( state=s, timeout = timeout )
2293 checkedStates.append( json.loads( rawFlows ) )
2294 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002295 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002296 try:
2297 statesCount[i] += int( c.get( "flowCount" ) )
2298 except TypeError:
2299 main.log.exception( "Json object not as expected" )
2300 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002301
GlennRCed771242016-01-13 17:02:47 -08002302 # We want to count PENDING_ADD if isPENDING is true
2303 if isPENDING:
2304 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2305 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002306 else:
GlennRCed771242016-01-13 17:02:47 -08002307 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2308 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002309 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002310 except ( TypeError, ValueError ):
2311 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002312 return None
2313 except pexpect.EOF:
2314 main.log.error( self.name + ": EOF exception found" )
2315 main.log.error( self.name + ": " + self.handle.before )
2316 main.cleanup()
2317 main.exit()
2318 except Exception:
2319 main.log.exception( self.name + ": Uncaught exception!" )
2320 main.cleanup()
2321 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002322 except pexpect.TIMEOUT:
2323 main.log.error( self.name + ": ONOS timeout" )
2324 return None
2325
kelvin-onlab4df89f22015-04-13 18:10:23 -07002326
GlennRCed771242016-01-13 17:02:47 -08002327 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002328 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002329 """
andrewonlab87852b02014-11-19 18:44:19 -05002330 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002331 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002332 a specific point-to-point intent definition
2333 Required:
GlennRCed771242016-01-13 17:02:47 -08002334 * ingress: specify source dpid
2335 * egress: specify destination dpid
2336 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002337 Optional:
GlennRCed771242016-01-13 17:02:47 -08002338 * offset: the keyOffset is where the next batch of intents
2339 will be installed
2340 Returns: If failed to push test intents, it will returen None,
2341 if successful, return true.
2342 Timeout expection will return None,
2343 TypeError will return false
2344 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002345 """
andrewonlab87852b02014-11-19 18:44:19 -05002346 try:
GlennRCed771242016-01-13 17:02:47 -08002347 if background:
2348 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002349 else:
GlennRCed771242016-01-13 17:02:47 -08002350 back = ""
2351 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002352 ingress,
2353 egress,
2354 batchSize,
2355 offset,
2356 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002357 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002358 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002359 main.log.info( response )
2360 if response == None:
2361 return None
2362
2363 # TODO: We should handle if there is failure in installation
2364 return main.TRUE
2365
Jon Hallc6793552016-01-19 14:18:37 -08002366 except AssertionError:
2367 main.log.exception( "" )
2368 return None
GlennRCed771242016-01-13 17:02:47 -08002369 except pexpect.TIMEOUT:
2370 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002371 return None
andrewonlab87852b02014-11-19 18:44:19 -05002372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002373 main.log.error( self.name + ": EOF exception found" )
2374 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002375 main.cleanup()
2376 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002377 except TypeError:
2378 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002379 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002380 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002381 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002382 main.cleanup()
2383 main.exit()
2384
YPZhangebf9eb52016-05-12 15:20:24 -07002385 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002386 """
2387 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002388 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002389 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002390 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002391 """
YPZhange3109a72016-02-02 11:25:37 -08002392
YPZhangb5d3f832016-01-23 22:54:26 -08002393 try:
YPZhange3109a72016-02-02 11:25:37 -08002394 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002395 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002396 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002397
2398 if totalFlows == None:
2399 # if timeout, we will get total number of all flows, and subtract other states
2400 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2401 checkedStates = []
2402 totalFlows = 0
2403 statesCount = [0, 0, 0, 0]
2404
2405 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002406 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002407 totalFlows = int( response.get("flows") )
2408
2409 for s in states:
2410 rawFlows = self.flows( state=s, timeout = timeout )
2411 if rawFlows == None:
2412 # if timeout, return the total flows number from summary command
2413 return totalFlows
2414 checkedStates.append( json.loads( rawFlows ) )
2415
2416 # Calculate ADDED flows number, equal total subtracts others
2417 for i in range( len( states ) ):
2418 for c in checkedStates[i]:
2419 try:
2420 statesCount[i] += int( c.get( "flowCount" ) )
2421 except TypeError:
2422 main.log.exception( "Json object not as expected" )
2423 totalFlows = totalFlows - int( statesCount[i] )
2424 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2425
2426 return totalFlows
2427
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002428 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002429
You Wangd3cb2ce2016-05-16 14:01:24 -07002430 except ( TypeError, ValueError ):
2431 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002432 return None
2433 except pexpect.EOF:
2434 main.log.error( self.name + ": EOF exception found" )
2435 main.log.error( self.name + ": " + self.handle.before )
2436 main.cleanup()
2437 main.exit()
2438 except Exception:
2439 main.log.exception( self.name + ": Uncaught exception!" )
2440 main.cleanup()
2441 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002442 except pexpect.TIMEOUT:
2443 main.log.error( self.name + ": ONOS timeout" )
2444 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002445
YPZhangebf9eb52016-05-12 15:20:24 -07002446 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002447 """
2448 Description:
2449 Get the total number of intents, include every states.
2450 Return:
2451 The number of intents
2452 """
2453 try:
2454 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002455 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002456 if response == None:
2457 return -1
2458 response = json.loads( response )
2459 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002460 except ( TypeError, ValueError ):
2461 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002462 return None
2463 except pexpect.EOF:
2464 main.log.error( self.name + ": EOF exception found" )
2465 main.log.error( self.name + ": " + self.handle.before )
2466 main.cleanup()
2467 main.exit()
2468 except Exception:
2469 main.log.exception( self.name + ": Uncaught exception!" )
2470 main.cleanup()
2471 main.exit()
2472
kelvin-onlabd3b64892015-01-20 13:26:24 -08002473 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002474 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002475 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002476 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002477 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002478 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002479 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002480 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002481 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002482 cmdStr += " -j"
2483 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002484 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002485 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002486 except AssertionError:
2487 main.log.exception( "" )
2488 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002489 except TypeError:
2490 main.log.exception( self.name + ": Object not as expected" )
2491 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002493 main.log.error( self.name + ": EOF exception found" )
2494 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002495 main.cleanup()
2496 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002497 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002498 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002499 main.cleanup()
2500 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002501
kelvin-onlabd3b64892015-01-20 13:26:24 -08002502 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002503 """
2504 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002505 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002506 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002507 """
andrewonlab867212a2014-10-22 20:13:38 -04002508 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002509 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002511 cmdStr += " -j"
2512 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002513 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002514 if handle:
2515 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002516 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002517 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002518 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002519 else:
2520 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002521 except AssertionError:
2522 main.log.exception( "" )
2523 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002524 except TypeError:
2525 main.log.exception( self.name + ": Object not as expected" )
2526 return None
andrewonlab867212a2014-10-22 20:13:38 -04002527 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002528 main.log.error( self.name + ": EOF exception found" )
2529 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002530 main.cleanup()
2531 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002532 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002533 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002534 main.cleanup()
2535 main.exit()
2536
kelvin8ec71442015-01-15 16:57:00 -08002537 # Wrapper functions ****************
2538 # Wrapper functions use existing driver
2539 # functions and extends their use case.
2540 # For example, we may use the output of
2541 # a normal driver function, and parse it
2542 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002543
kelvin-onlabd3b64892015-01-20 13:26:24 -08002544 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002545 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002546 Description:
2547 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002548 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002549 try:
kelvin8ec71442015-01-15 16:57:00 -08002550 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002551 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002552 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002553
kelvin8ec71442015-01-15 16:57:00 -08002554 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002555 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2556 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002557 match = re.search('id=0x([\da-f]+),', intents)
2558 if match:
2559 tmpId = match.group()[3:-1]
2560 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002561 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002562
Jon Halld4d4b372015-01-28 16:02:41 -08002563 except TypeError:
2564 main.log.exception( self.name + ": Object not as expected" )
2565 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002566 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002567 main.log.error( self.name + ": EOF exception found" )
2568 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002569 main.cleanup()
2570 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002571 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002572 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002573 main.cleanup()
2574 main.exit()
2575
Jon Hall30b82fa2015-03-04 17:15:43 -08002576 def FlowAddedCount( self, deviceId ):
2577 """
2578 Determine the number of flow rules for the given device id that are
2579 in the added state
2580 """
2581 try:
2582 cmdStr = "flows any " + str( deviceId ) + " | " +\
2583 "grep 'state=ADDED' | wc -l"
2584 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002585 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002586 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002587 except AssertionError:
2588 main.log.exception( "" )
2589 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002590 except pexpect.EOF:
2591 main.log.error( self.name + ": EOF exception found" )
2592 main.log.error( self.name + ": " + self.handle.before )
2593 main.cleanup()
2594 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002595 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002596 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002597 main.cleanup()
2598 main.exit()
2599
kelvin-onlabd3b64892015-01-20 13:26:24 -08002600 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002601 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002602 Use 'devices' function to obtain list of all devices
2603 and parse the result to obtain a list of all device
2604 id's. Returns this list. Returns empty list if no
2605 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002606 List is ordered sequentially
2607
andrewonlab3e15ead2014-10-15 14:21:34 -04002608 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002609 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002610 the ids. By obtaining the list of device ids on the fly,
2611 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002612 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002613 try:
kelvin8ec71442015-01-15 16:57:00 -08002614 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002615 devicesStr = self.devices( jsonFormat=False )
2616 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002617
kelvin-onlabd3b64892015-01-20 13:26:24 -08002618 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002619 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002620 return idList
kelvin8ec71442015-01-15 16:57:00 -08002621
2622 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002623 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002624 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002625 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002626 # Split list further into arguments before and after string
2627 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002628 # append to idList
2629 for arg in tempList:
2630 idList.append( arg.split( "id=" )[ 1 ] )
2631 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002632
Jon Halld4d4b372015-01-28 16:02:41 -08002633 except TypeError:
2634 main.log.exception( self.name + ": Object not as expected" )
2635 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002637 main.log.error( self.name + ": EOF exception found" )
2638 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002639 main.cleanup()
2640 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002641 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002642 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002643 main.cleanup()
2644 main.exit()
2645
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002647 """
andrewonlab7c211572014-10-15 16:45:20 -04002648 Uses 'nodes' function to obtain list of all nodes
2649 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002650 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002651 Returns:
2652 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002653 """
andrewonlab7c211572014-10-15 16:45:20 -04002654 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002655 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002656 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002657 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002658 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002659 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002660 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002661 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002662 nodesJson = json.loads( nodesStr )
2663 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002665 except ( TypeError, ValueError ):
2666 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002667 return None
andrewonlab7c211572014-10-15 16:45:20 -04002668 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002669 main.log.error( self.name + ": EOF exception found" )
2670 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002671 main.cleanup()
2672 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002673 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002674 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002675 main.cleanup()
2676 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002677
kelvin-onlabd3b64892015-01-20 13:26:24 -08002678 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002679 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002680 Return the first device from the devices api whose 'id' contains 'dpid'
2681 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002682 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002683 try:
kelvin8ec71442015-01-15 16:57:00 -08002684 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002685 return None
2686 else:
kelvin8ec71442015-01-15 16:57:00 -08002687 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002688 rawDevices = self.devices()
2689 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002690 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002691 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002692 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2693 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002694 return device
2695 return None
Jon Hallc6793552016-01-19 14:18:37 -08002696 except ( TypeError, ValueError ):
2697 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002698 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002699 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002700 main.log.error( self.name + ": EOF exception found" )
2701 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002702 main.cleanup()
2703 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002705 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002706 main.cleanup()
2707 main.exit()
2708
You Wang24139872016-05-03 11:48:47 -07002709 def getTopology( self, topologyOutput ):
2710 """
2711 Definition:
2712 Loads a json topology output
2713 Return:
2714 topology = current ONOS topology
2715 """
2716 import json
2717 try:
2718 # either onos:topology or 'topology' will work in CLI
2719 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002720 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002721 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002722 except ( TypeError, ValueError ):
2723 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2724 return None
You Wang24139872016-05-03 11:48:47 -07002725 except pexpect.EOF:
2726 main.log.error( self.name + ": EOF exception found" )
2727 main.log.error( self.name + ": " + self.handle.before )
2728 main.cleanup()
2729 main.exit()
2730 except Exception:
2731 main.log.exception( self.name + ": Uncaught exception!" )
2732 main.cleanup()
2733 main.exit()
2734
2735 def checkStatus(
2736 self,
2737 topologyResult,
2738 numoswitch,
2739 numolink,
2740 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002741 """
Jon Hallefbd9792015-03-05 16:11:36 -08002742 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002743 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002744 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002745
You Wang24139872016-05-03 11:48:47 -07002746 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002747 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002748 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002749 logLevel = level to log to.
2750 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002751
Jon Hallefbd9792015-03-05 16:11:36 -08002752 Returns: main.TRUE if the number of switches and links are correct,
2753 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002754 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002755 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002756 try:
You Wang24139872016-05-03 11:48:47 -07002757 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002758 if topology == {}:
2759 return main.ERROR
2760 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002761 # Is the number of switches is what we expected
2762 devices = topology.get( 'devices', False )
2763 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002764 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002765 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002766 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002767 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002768 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002769 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002770 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002771 output = output + "The number of links and switches match "\
2772 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002773 result = main.TRUE
2774 else:
You Wang24139872016-05-03 11:48:47 -07002775 output = output + \
2776 "The number of links and switches does not match " + \
2777 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002778 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002779 output = output + "\n ONOS sees %i devices" % int( devices )
2780 output = output + " (%i expected) " % int( numoswitch )
2781 output = output + "and %i links " % int( links )
2782 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002783 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002784 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002785 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002786 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002787 else:
You Wang24139872016-05-03 11:48:47 -07002788 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002789 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002791 main.log.error( self.name + ": EOF exception found" )
2792 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002793 main.cleanup()
2794 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002795 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002796 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002797 main.cleanup()
2798 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002799
kelvin-onlabd3b64892015-01-20 13:26:24 -08002800 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002801 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002802 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002803 deviceId must be the id of a device as seen in the onos devices command
2804 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002805 role must be either master, standby, or none
2806
Jon Halle3f39ff2015-01-13 11:50:53 -08002807 Returns:
2808 main.TRUE or main.FALSE based on argument verification and
2809 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002810 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002811 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002812 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002813 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 cmdStr = "device-role " +\
2815 str( deviceId ) + " " +\
2816 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002817 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002818 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002819 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002820 if re.search( "Error", handle ):
2821 # end color output to escape any colours
2822 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002823 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002824 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002825 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002826 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002827 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002828 main.log.error( "Invalid 'role' given to device_role(). " +
2829 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002830 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002831 except AssertionError:
2832 main.log.exception( "" )
2833 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002834 except TypeError:
2835 main.log.exception( self.name + ": Object not as expected" )
2836 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002837 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002838 main.log.error( self.name + ": EOF exception found" )
2839 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002840 main.cleanup()
2841 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002842 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002843 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002844 main.cleanup()
2845 main.exit()
2846
kelvin-onlabd3b64892015-01-20 13:26:24 -08002847 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002848 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002849 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002850 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002852 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002853 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002854 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002855 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002856 cmdStr += " -j"
2857 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002858 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002859 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002860 except AssertionError:
2861 main.log.exception( "" )
2862 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002863 except TypeError:
2864 main.log.exception( self.name + ": Object not as expected" )
2865 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002867 main.log.error( self.name + ": EOF exception found" )
2868 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002869 main.cleanup()
2870 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002871 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002872 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002873 main.cleanup()
2874 main.exit()
2875
kelvin-onlabd3b64892015-01-20 13:26:24 -08002876 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002877 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002878 CLI command to get the current leader for the Election test application
2879 NOTE: Requires installation of the onos-app-election feature
2880 Returns: Node IP of the leader if one exists
2881 None if none exists
2882 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002883 """
Jon Hall94fd0472014-12-08 11:52:42 -08002884 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 cmdStr = "election-test-leader"
2886 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002887 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002888 # Leader
2889 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002890 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002891 nodeSearch = re.search( leaderPattern, response )
2892 if nodeSearch:
2893 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002894 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002895 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002896 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002897 # no leader
2898 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002899 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002900 nullSearch = re.search( nullPattern, response )
2901 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002902 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002903 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002904 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002905 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002906 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002907 if re.search( errorPattern, response ):
2908 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002909 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002910 return main.FALSE
2911 else:
Jon Hall390696c2015-05-05 17:13:41 -07002912 main.log.error( "Error in electionTestLeader on " + self.name +
2913 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002914 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002915 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002916 except AssertionError:
2917 main.log.exception( "" )
2918 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002919 except TypeError:
2920 main.log.exception( self.name + ": Object not as expected" )
2921 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002923 main.log.error( self.name + ": EOF exception found" )
2924 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002925 main.cleanup()
2926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002927 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002928 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002929 main.cleanup()
2930 main.exit()
2931
kelvin-onlabd3b64892015-01-20 13:26:24 -08002932 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002933 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002934 CLI command to run for leadership of the Election test application.
2935 NOTE: Requires installation of the onos-app-election feature
2936 Returns: Main.TRUE on success
2937 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002938 """
Jon Hall94fd0472014-12-08 11:52:42 -08002939 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002940 cmdStr = "election-test-run"
2941 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002942 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002943 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002944 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002945 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002946 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002947 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002949 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002950 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002951 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002952 errorPattern = "Command\snot\sfound"
2953 if re.search( errorPattern, response ):
2954 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002955 return main.FALSE
2956 else:
Jon Hall390696c2015-05-05 17:13:41 -07002957 main.log.error( "Error in electionTestRun on " + self.name +
2958 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002959 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002960 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002961 except AssertionError:
2962 main.log.exception( "" )
2963 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002964 except TypeError:
2965 main.log.exception( self.name + ": Object not as expected" )
2966 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002967 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002968 main.log.error( self.name + ": EOF exception found" )
2969 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002970 main.cleanup()
2971 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002972 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002973 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002974 main.cleanup()
2975 main.exit()
2976
kelvin-onlabd3b64892015-01-20 13:26:24 -08002977 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002978 """
Jon Hall94fd0472014-12-08 11:52:42 -08002979 * CLI command to withdraw the local node from leadership election for
2980 * the Election test application.
2981 #NOTE: Requires installation of the onos-app-election feature
2982 Returns: Main.TRUE on success
2983 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002984 """
Jon Hall94fd0472014-12-08 11:52:42 -08002985 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002986 cmdStr = "election-test-withdraw"
2987 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002988 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002989 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002990 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002991 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002992 if re.search( successPattern, response ):
2993 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002994 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002995 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002996 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002997 errorPattern = "Command\snot\sfound"
2998 if re.search( errorPattern, response ):
2999 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003000 return main.FALSE
3001 else:
Jon Hall390696c2015-05-05 17:13:41 -07003002 main.log.error( "Error in electionTestWithdraw on " +
3003 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003004 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003005 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003006 except AssertionError:
3007 main.log.exception( "" )
3008 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003009 except TypeError:
3010 main.log.exception( self.name + ": Object not as expected" )
3011 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003012 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003013 main.log.error( self.name + ": EOF exception found" )
3014 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003015 main.cleanup()
3016 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003017 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003018 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003019 main.cleanup()
3020 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003021
kelvin8ec71442015-01-15 16:57:00 -08003022 def getDevicePortsEnabledCount( self, dpid ):
3023 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003024 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003025 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003026 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003027 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003028 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3029 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003030 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003031 if re.search( "No such device", output ):
3032 main.log.error( "Error in getting ports" )
3033 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003034 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003035 return output
Jon Hallc6793552016-01-19 14:18:37 -08003036 except AssertionError:
3037 main.log.exception( "" )
3038 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003039 except TypeError:
3040 main.log.exception( self.name + ": Object not as expected" )
3041 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003042 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003043 main.log.error( self.name + ": EOF exception found" )
3044 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003045 main.cleanup()
3046 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003047 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003048 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003049 main.cleanup()
3050 main.exit()
3051
kelvin8ec71442015-01-15 16:57:00 -08003052 def getDeviceLinksActiveCount( self, dpid ):
3053 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003054 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003055 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003056 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003057 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003058 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3059 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003060 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003061 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003062 main.log.error( "Error in getting ports " )
3063 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003064 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003065 return output
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 ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -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 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -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!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003079 main.cleanup()
3080 main.exit()
3081
kelvin8ec71442015-01-15 16:57:00 -08003082 def getAllIntentIds( self ):
3083 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003084 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003085 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003086 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003087 cmdStr = "onos:intents | grep id="
3088 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003089 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003090 if re.search( "Error", output ):
3091 main.log.error( "Error in getting ports" )
3092 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003093 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003094 return output
Jon Hallc6793552016-01-19 14:18:37 -08003095 except AssertionError:
3096 main.log.exception( "" )
3097 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003098 except TypeError:
3099 main.log.exception( self.name + ": Object not as expected" )
3100 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003104 main.cleanup()
3105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003106 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003107 main.log.exception( self.name + ": Uncaught exception!" )
3108 main.cleanup()
3109 main.exit()
3110
Jon Hall73509952015-02-24 16:42:56 -08003111 def intentSummary( self ):
3112 """
Jon Hallefbd9792015-03-05 16:11:36 -08003113 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003114 """
3115 try:
3116 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003117 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003118 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003119 states.append( intent.get( 'state', None ) )
3120 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003121 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003122 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003123 except ( TypeError, ValueError ):
3124 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003125 return None
3126 except pexpect.EOF:
3127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
3129 main.cleanup()
3130 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003131 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003132 main.log.exception( self.name + ": Uncaught exception!" )
3133 main.cleanup()
3134 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003135
Jon Hall61282e32015-03-19 11:34:11 -07003136 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003137 """
3138 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003139 Optional argument:
3140 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003141 """
Jon Hall63604932015-02-26 17:09:50 -08003142 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003143 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003144 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003145 cmdStr += " -j"
3146 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003147 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003148 return output
Jon Hallc6793552016-01-19 14:18:37 -08003149 except AssertionError:
3150 main.log.exception( "" )
3151 return None
Jon Hall63604932015-02-26 17:09:50 -08003152 except TypeError:
3153 main.log.exception( self.name + ": Object not as expected" )
3154 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003155 except pexpect.EOF:
3156 main.log.error( self.name + ": EOF exception found" )
3157 main.log.error( self.name + ": " + self.handle.before )
3158 main.cleanup()
3159 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003160 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003161 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003162 main.cleanup()
3163 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003164
acsmarsa4a4d1e2015-07-10 16:01:24 -07003165 def leaderCandidates( self, jsonFormat=True ):
3166 """
3167 Returns the output of the leaders -c command.
3168 Optional argument:
3169 * jsonFormat - boolean indicating if you want output in json
3170 """
3171 try:
3172 cmdStr = "onos:leaders -c"
3173 if jsonFormat:
3174 cmdStr += " -j"
3175 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003176 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003177 return output
Jon Hallc6793552016-01-19 14:18:37 -08003178 except AssertionError:
3179 main.log.exception( "" )
3180 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003181 except TypeError:
3182 main.log.exception( self.name + ": Object not as expected" )
3183 return None
3184 except pexpect.EOF:
3185 main.log.error( self.name + ": EOF exception found" )
3186 main.log.error( self.name + ": " + self.handle.before )
3187 main.cleanup()
3188 main.exit()
3189 except Exception:
3190 main.log.exception( self.name + ": Uncaught exception!" )
3191 main.cleanup()
3192 main.exit()
3193
Jon Hallc6793552016-01-19 14:18:37 -08003194 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003195 """
3196 Returns a list in format [leader,candidate1,candidate2,...] for a given
3197 topic parameter and an empty list if the topic doesn't exist
3198 If no leader is elected leader in the returned list will be "none"
3199 Returns None if there is a type error processing the json object
3200 """
3201 try:
Jon Hall6e709752016-02-01 13:38:46 -08003202 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003203 rawOutput = self.sendline( cmdStr )
3204 assert "Command not found:" not in rawOutput, rawOutput
3205 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003206 results = []
3207 for dict in output:
3208 if dict["topic"] == topic:
3209 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003210 candidates = re.split( ", ", dict["candidates"][1:-1] )
3211 results.append( leader )
3212 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003213 return results
Jon Hallc6793552016-01-19 14:18:37 -08003214 except AssertionError:
3215 main.log.exception( "" )
3216 return None
3217 except ( TypeError, ValueError ):
3218 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003219 return None
3220 except pexpect.EOF:
3221 main.log.error( self.name + ": EOF exception found" )
3222 main.log.error( self.name + ": " + self.handle.before )
3223 main.cleanup()
3224 main.exit()
3225 except Exception:
3226 main.log.exception( self.name + ": Uncaught exception!" )
3227 main.cleanup()
3228 main.exit()
3229
Jon Hall61282e32015-03-19 11:34:11 -07003230 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003231 """
3232 Returns the output of the intent Pending map.
3233 """
Jon Hall63604932015-02-26 17:09:50 -08003234 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003235 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003236 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003237 cmdStr += " -j"
3238 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003239 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003240 return output
Jon Hallc6793552016-01-19 14:18:37 -08003241 except AssertionError:
3242 main.log.exception( "" )
3243 return None
Jon Hall63604932015-02-26 17:09:50 -08003244 except TypeError:
3245 main.log.exception( self.name + ": Object not as expected" )
3246 return None
3247 except pexpect.EOF:
3248 main.log.error( self.name + ": EOF exception found" )
3249 main.log.error( self.name + ": " + self.handle.before )
3250 main.cleanup()
3251 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003252 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003253 main.log.exception( self.name + ": Uncaught exception!" )
3254 main.cleanup()
3255 main.exit()
3256
Jon Hall61282e32015-03-19 11:34:11 -07003257 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003258 """
3259 Returns the output of the raft partitions command for ONOS.
3260 """
Jon Hall61282e32015-03-19 11:34:11 -07003261 # Sample JSON
3262 # {
3263 # "leader": "tcp://10.128.30.11:7238",
3264 # "members": [
3265 # "tcp://10.128.30.11:7238",
3266 # "tcp://10.128.30.17:7238",
3267 # "tcp://10.128.30.13:7238",
3268 # ],
3269 # "name": "p1",
3270 # "term": 3
3271 # },
Jon Hall63604932015-02-26 17:09:50 -08003272 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003273 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003274 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003275 cmdStr += " -j"
3276 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003277 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003278 return output
Jon Hallc6793552016-01-19 14:18:37 -08003279 except AssertionError:
3280 main.log.exception( "" )
3281 return None
Jon Hall63604932015-02-26 17:09:50 -08003282 except TypeError:
3283 main.log.exception( self.name + ": Object not as expected" )
3284 return None
3285 except pexpect.EOF:
3286 main.log.error( self.name + ": EOF exception found" )
3287 main.log.error( self.name + ": " + self.handle.before )
3288 main.cleanup()
3289 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003290 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003291 main.log.exception( self.name + ": Uncaught exception!" )
3292 main.cleanup()
3293 main.exit()
3294
Jon Hallbe379602015-03-24 13:39:32 -07003295 def apps( self, jsonFormat=True ):
3296 """
3297 Returns the output of the apps command for ONOS. This command lists
3298 information about installed ONOS applications
3299 """
3300 # Sample JSON object
3301 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3302 # "description":"ONOS OpenFlow protocol southbound providers",
3303 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3304 # "features":"[onos-openflow]","state":"ACTIVE"}]
3305 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003306 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003307 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003308 cmdStr += " -j"
3309 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003310 assert "Command not found:" not in output, output
3311 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003312 return output
Jon Hallbe379602015-03-24 13:39:32 -07003313 # FIXME: look at specific exceptions/Errors
3314 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003315 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003316 return None
3317 except TypeError:
3318 main.log.exception( self.name + ": Object not as expected" )
3319 return None
3320 except pexpect.EOF:
3321 main.log.error( self.name + ": EOF exception found" )
3322 main.log.error( self.name + ": " + self.handle.before )
3323 main.cleanup()
3324 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003325 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003326 main.log.exception( self.name + ": Uncaught exception!" )
3327 main.cleanup()
3328 main.exit()
3329
Jon Hall146f1522015-03-24 15:33:24 -07003330 def appStatus( self, appName ):
3331 """
3332 Uses the onos:apps cli command to return the status of an application.
3333 Returns:
3334 "ACTIVE" - If app is installed and activated
3335 "INSTALLED" - If app is installed and deactivated
3336 "UNINSTALLED" - If app is not installed
3337 None - on error
3338 """
Jon Hall146f1522015-03-24 15:33:24 -07003339 try:
3340 if not isinstance( appName, types.StringType ):
3341 main.log.error( self.name + ".appStatus(): appName must be" +
3342 " a string" )
3343 return None
3344 output = self.apps( jsonFormat=True )
3345 appsJson = json.loads( output )
3346 state = None
3347 for app in appsJson:
3348 if appName == app.get('name'):
3349 state = app.get('state')
3350 break
3351 if state == "ACTIVE" or state == "INSTALLED":
3352 return state
3353 elif state is None:
3354 return "UNINSTALLED"
3355 elif state:
3356 main.log.error( "Unexpected state from 'onos:apps': " +
3357 str( state ) )
3358 return state
Jon Hallc6793552016-01-19 14:18:37 -08003359 except ( TypeError, ValueError ):
3360 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003361 return None
3362 except pexpect.EOF:
3363 main.log.error( self.name + ": EOF exception found" )
3364 main.log.error( self.name + ": " + self.handle.before )
3365 main.cleanup()
3366 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003367 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003368 main.log.exception( self.name + ": Uncaught exception!" )
3369 main.cleanup()
3370 main.exit()
3371
Jon Hallbe379602015-03-24 13:39:32 -07003372 def app( self, appName, option ):
3373 """
3374 Interacts with the app command for ONOS. This command manages
3375 application inventory.
3376 """
Jon Hallbe379602015-03-24 13:39:32 -07003377 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003378 # Validate argument types
3379 valid = True
3380 if not isinstance( appName, types.StringType ):
3381 main.log.error( self.name + ".app(): appName must be a " +
3382 "string" )
3383 valid = False
3384 if not isinstance( option, types.StringType ):
3385 main.log.error( self.name + ".app(): option must be a string" )
3386 valid = False
3387 if not valid:
3388 return main.FALSE
3389 # Validate Option
3390 option = option.lower()
3391 # NOTE: Install may become a valid option
3392 if option == "activate":
3393 pass
3394 elif option == "deactivate":
3395 pass
3396 elif option == "uninstall":
3397 pass
3398 else:
3399 # Invalid option
3400 main.log.error( "The ONOS app command argument only takes " +
3401 "the values: (activate|deactivate|uninstall)" +
3402 "; was given '" + option + "'")
3403 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003404 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003405 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003406 if "Error executing command" in output:
3407 main.log.error( "Error in processing onos:app command: " +
3408 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003409 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003410 elif "No such application" in output:
3411 main.log.error( "The application '" + appName +
3412 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003413 return main.FALSE
3414 elif "Command not found:" in output:
3415 main.log.error( "Error in processing onos:app command: " +
3416 str( output ) )
3417 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003418 elif "Unsupported command:" in output:
3419 main.log.error( "Incorrect command given to 'app': " +
3420 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003421 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003422 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003423 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003424 return main.TRUE
3425 except TypeError:
3426 main.log.exception( self.name + ": Object not as expected" )
3427 return main.ERROR
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 Hallbe379602015-03-24 13:39:32 -07003434 main.log.exception( self.name + ": Uncaught exception!" )
3435 main.cleanup()
3436 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003437
Jon Hallbd16b922015-03-26 17:53:15 -07003438 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003439 """
3440 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003441 appName is the hierarchical app name, not the feature name
3442 If check is True, method will check the status of the app after the
3443 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003444 Returns main.TRUE if the command was successfully sent
3445 main.FALSE if the cli responded with an error or given
3446 incorrect input
3447 """
3448 try:
3449 if not isinstance( appName, types.StringType ):
3450 main.log.error( self.name + ".activateApp(): appName must be" +
3451 " a string" )
3452 return main.FALSE
3453 status = self.appStatus( appName )
3454 if status == "INSTALLED":
3455 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003456 if check and response == main.TRUE:
3457 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003458 status = self.appStatus( appName )
3459 if status == "ACTIVE":
3460 return main.TRUE
3461 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003462 main.log.debug( "The state of application " +
3463 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003464 time.sleep( 1 )
3465 return main.FALSE
3466 else: # not 'check' or command didn't succeed
3467 return response
Jon Hall146f1522015-03-24 15:33:24 -07003468 elif status == "ACTIVE":
3469 return main.TRUE
3470 elif status == "UNINSTALLED":
3471 main.log.error( self.name + ": Tried to activate the " +
3472 "application '" + appName + "' which is not " +
3473 "installed." )
3474 else:
3475 main.log.error( "Unexpected return value from appStatus: " +
3476 str( status ) )
3477 return main.ERROR
3478 except TypeError:
3479 main.log.exception( self.name + ": Object not as expected" )
3480 return main.ERROR
3481 except pexpect.EOF:
3482 main.log.error( self.name + ": EOF exception found" )
3483 main.log.error( self.name + ": " + self.handle.before )
3484 main.cleanup()
3485 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003486 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003487 main.log.exception( self.name + ": Uncaught exception!" )
3488 main.cleanup()
3489 main.exit()
3490
Jon Hallbd16b922015-03-26 17:53:15 -07003491 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003492 """
3493 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003494 appName is the hierarchical app name, not the feature name
3495 If check is True, method will check the status of the app after the
3496 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003497 Returns main.TRUE if the command was successfully sent
3498 main.FALSE if the cli responded with an error or given
3499 incorrect input
3500 """
3501 try:
3502 if not isinstance( appName, types.StringType ):
3503 main.log.error( self.name + ".deactivateApp(): appName must " +
3504 "be a string" )
3505 return main.FALSE
3506 status = self.appStatus( appName )
3507 if status == "INSTALLED":
3508 return main.TRUE
3509 elif status == "ACTIVE":
3510 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003511 if check and response == main.TRUE:
3512 for i in range(10): # try 10 times then give up
3513 status = self.appStatus( appName )
3514 if status == "INSTALLED":
3515 return main.TRUE
3516 else:
3517 time.sleep( 1 )
3518 return main.FALSE
3519 else: # not check or command didn't succeed
3520 return response
Jon Hall146f1522015-03-24 15:33:24 -07003521 elif status == "UNINSTALLED":
3522 main.log.warn( self.name + ": Tried to deactivate the " +
3523 "application '" + appName + "' which is not " +
3524 "installed." )
3525 return main.TRUE
3526 else:
3527 main.log.error( "Unexpected return value from appStatus: " +
3528 str( status ) )
3529 return main.ERROR
3530 except TypeError:
3531 main.log.exception( self.name + ": Object not as expected" )
3532 return main.ERROR
3533 except pexpect.EOF:
3534 main.log.error( self.name + ": EOF exception found" )
3535 main.log.error( self.name + ": " + self.handle.before )
3536 main.cleanup()
3537 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003538 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003539 main.log.exception( self.name + ": Uncaught exception!" )
3540 main.cleanup()
3541 main.exit()
3542
Jon Hallbd16b922015-03-26 17:53:15 -07003543 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003544 """
3545 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003546 appName is the hierarchical app name, not the feature name
3547 If check is True, method will check the status of the app after the
3548 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003549 Returns main.TRUE if the command was successfully sent
3550 main.FALSE if the cli responded with an error or given
3551 incorrect input
3552 """
3553 # TODO: check with Thomas about the state machine for apps
3554 try:
3555 if not isinstance( appName, types.StringType ):
3556 main.log.error( self.name + ".uninstallApp(): appName must " +
3557 "be a string" )
3558 return main.FALSE
3559 status = self.appStatus( appName )
3560 if status == "INSTALLED":
3561 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003562 if check and response == main.TRUE:
3563 for i in range(10): # try 10 times then give up
3564 status = self.appStatus( appName )
3565 if status == "UNINSTALLED":
3566 return main.TRUE
3567 else:
3568 time.sleep( 1 )
3569 return main.FALSE
3570 else: # not check or command didn't succeed
3571 return response
Jon Hall146f1522015-03-24 15:33:24 -07003572 elif status == "ACTIVE":
3573 main.log.warn( self.name + ": Tried to uninstall the " +
3574 "application '" + appName + "' which is " +
3575 "currently active." )
3576 response = self.app( appName, "uninstall" )
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 == "UNINSTALLED":
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 return main.TRUE
3589 else:
3590 main.log.error( "Unexpected return value from appStatus: " +
3591 str( status ) )
3592 return main.ERROR
3593 except TypeError:
3594 main.log.exception( self.name + ": Object not as expected" )
3595 return main.ERROR
3596 except pexpect.EOF:
3597 main.log.error( self.name + ": EOF exception found" )
3598 main.log.error( self.name + ": " + self.handle.before )
3599 main.cleanup()
3600 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003601 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003602 main.log.exception( self.name + ": Uncaught exception!" )
3603 main.cleanup()
3604 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003605
3606 def appIDs( self, jsonFormat=True ):
3607 """
3608 Show the mappings between app id and app names given by the 'app-ids'
3609 cli command
3610 """
3611 try:
3612 cmdStr = "app-ids"
3613 if jsonFormat:
3614 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003615 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003616 assert "Command not found:" not in output, output
3617 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003618 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003619 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003620 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003621 return None
3622 except TypeError:
3623 main.log.exception( self.name + ": Object not as expected" )
3624 return None
3625 except pexpect.EOF:
3626 main.log.error( self.name + ": EOF exception found" )
3627 main.log.error( self.name + ": " + self.handle.before )
3628 main.cleanup()
3629 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003630 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003631 main.log.exception( self.name + ": Uncaught exception!" )
3632 main.cleanup()
3633 main.exit()
3634
3635 def appToIDCheck( self ):
3636 """
3637 This method will check that each application's ID listed in 'apps' is
3638 the same as the ID listed in 'app-ids'. The check will also check that
3639 there are no duplicate IDs issued. Note that an app ID should be
3640 a globaly unique numerical identifier for app/app-like features. Once
3641 an ID is registered, the ID is never freed up so that if an app is
3642 reinstalled it will have the same ID.
3643
3644 Returns: main.TRUE if the check passes and
3645 main.FALSE if the check fails or
3646 main.ERROR if there is some error in processing the test
3647 """
3648 try:
Jon Hall390696c2015-05-05 17:13:41 -07003649 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003650 rawJson = self.appIDs( jsonFormat=True )
3651 if rawJson:
3652 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003653 else:
Jon Hallc6793552016-01-19 14:18:37 -08003654 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003655 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003656 rawJson = self.apps( jsonFormat=True )
3657 if rawJson:
3658 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003659 else:
Jon Hallc6793552016-01-19 14:18:37 -08003660 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003661 bail = True
3662 if bail:
3663 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003664 result = main.TRUE
3665 for app in apps:
3666 appID = app.get( 'id' )
3667 if appID is None:
3668 main.log.error( "Error parsing app: " + str( app ) )
3669 result = main.FALSE
3670 appName = app.get( 'name' )
3671 if appName is None:
3672 main.log.error( "Error parsing app: " + str( app ) )
3673 result = main.FALSE
3674 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003675 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003676 # main.log.debug( "Comparing " + str( app ) + " to " +
3677 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003678 if not current: # if ids doesn't have this id
3679 result = main.FALSE
3680 main.log.error( "'app-ids' does not have the ID for " +
3681 str( appName ) + " that apps does." )
3682 elif len( current ) > 1:
3683 # there is more than one app with this ID
3684 result = main.FALSE
3685 # We will log this later in the method
3686 elif not current[0][ 'name' ] == appName:
3687 currentName = current[0][ 'name' ]
3688 result = main.FALSE
3689 main.log.error( "'app-ids' has " + str( currentName ) +
3690 " registered under id:" + str( appID ) +
3691 " but 'apps' has " + str( appName ) )
3692 else:
3693 pass # id and name match!
3694 # now make sure that app-ids has no duplicates
3695 idsList = []
3696 namesList = []
3697 for item in ids:
3698 idsList.append( item[ 'id' ] )
3699 namesList.append( item[ 'name' ] )
3700 if len( idsList ) != len( set( idsList ) ) or\
3701 len( namesList ) != len( set( namesList ) ):
3702 main.log.error( "'app-ids' has some duplicate entries: \n"
3703 + json.dumps( ids,
3704 sort_keys=True,
3705 indent=4,
3706 separators=( ',', ': ' ) ) )
3707 result = main.FALSE
3708 return result
Jon Hallc6793552016-01-19 14:18:37 -08003709 except ( TypeError, ValueError ):
3710 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003711 return main.ERROR
3712 except pexpect.EOF:
3713 main.log.error( self.name + ": EOF exception found" )
3714 main.log.error( self.name + ": " + self.handle.before )
3715 main.cleanup()
3716 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003717 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003718 main.log.exception( self.name + ": Uncaught exception!" )
3719 main.cleanup()
3720 main.exit()
3721
Jon Hallfb760a02015-04-13 15:35:03 -07003722 def getCfg( self, component=None, propName=None, short=False,
3723 jsonFormat=True ):
3724 """
3725 Get configuration settings from onos cli
3726 Optional arguments:
3727 component - Optionally only list configurations for a specific
3728 component. If None, all components with configurations
3729 are displayed. Case Sensitive string.
3730 propName - If component is specified, propName option will show
3731 only this specific configuration from that component.
3732 Case Sensitive string.
3733 jsonFormat - Returns output as json. Note that this will override
3734 the short option
3735 short - Short, less verbose, version of configurations.
3736 This is overridden by the json option
3737 returns:
3738 Output from cli as a string or None on error
3739 """
3740 try:
3741 baseStr = "cfg"
3742 cmdStr = " get"
3743 componentStr = ""
3744 if component:
3745 componentStr += " " + component
3746 if propName:
3747 componentStr += " " + propName
3748 if jsonFormat:
3749 baseStr += " -j"
3750 elif short:
3751 baseStr += " -s"
3752 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003753 assert "Command not found:" not in output, output
3754 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003755 return output
3756 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003757 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003758 return None
3759 except TypeError:
3760 main.log.exception( self.name + ": Object not as expected" )
3761 return None
3762 except pexpect.EOF:
3763 main.log.error( self.name + ": EOF exception found" )
3764 main.log.error( self.name + ": " + self.handle.before )
3765 main.cleanup()
3766 main.exit()
3767 except Exception:
3768 main.log.exception( self.name + ": Uncaught exception!" )
3769 main.cleanup()
3770 main.exit()
3771
3772 def setCfg( self, component, propName, value=None, check=True ):
3773 """
3774 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003775 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003776 component - The case sensitive name of the component whose
3777 property is to be set
3778 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003779 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003780 value - The value to set the property to. If None, will unset the
3781 property and revert it to it's default value(if applicable)
3782 check - Boolean, Check whether the option was successfully set this
3783 only applies when a value is given.
3784 returns:
3785 main.TRUE on success or main.FALSE on failure. If check is False,
3786 will return main.TRUE unless there is an error
3787 """
3788 try:
3789 baseStr = "cfg"
3790 cmdStr = " set " + str( component ) + " " + str( propName )
3791 if value is not None:
3792 cmdStr += " " + str( value )
3793 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003794 assert "Command not found:" not in output, output
3795 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003796 if value and check:
3797 results = self.getCfg( component=str( component ),
3798 propName=str( propName ),
3799 jsonFormat=True )
3800 # Check if current value is what we just set
3801 try:
3802 jsonOutput = json.loads( results )
3803 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003804 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003805 main.log.exception( "Error parsing cfg output" )
3806 main.log.error( "output:" + repr( results ) )
3807 return main.FALSE
3808 if current == str( value ):
3809 return main.TRUE
3810 return main.FALSE
3811 return main.TRUE
3812 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003813 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003814 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003815 except ( TypeError, ValueError ):
3816 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003817 return main.FALSE
3818 except pexpect.EOF:
3819 main.log.error( self.name + ": EOF exception found" )
3820 main.log.error( self.name + ": " + self.handle.before )
3821 main.cleanup()
3822 main.exit()
3823 except Exception:
3824 main.log.exception( self.name + ": Uncaught exception!" )
3825 main.cleanup()
3826 main.exit()
3827
Jon Hall390696c2015-05-05 17:13:41 -07003828 def setTestAdd( self, setName, values ):
3829 """
3830 CLI command to add elements to a distributed set.
3831 Arguments:
3832 setName - The name of the set to add to.
3833 values - The value(s) to add to the set, space seperated.
3834 Example usages:
3835 setTestAdd( "set1", "a b c" )
3836 setTestAdd( "set2", "1" )
3837 returns:
3838 main.TRUE on success OR
3839 main.FALSE if elements were already in the set OR
3840 main.ERROR on error
3841 """
3842 try:
3843 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3844 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003845 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003846 try:
3847 # TODO: Maybe make this less hardcoded
3848 # ConsistentMap Exceptions
3849 assert "org.onosproject.store.service" not in output
3850 # Node not leader
3851 assert "java.lang.IllegalStateException" not in output
3852 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003853 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003854 "command: " + str( output ) )
3855 retryTime = 30 # Conservative time, given by Madan
3856 main.log.info( "Waiting " + str( retryTime ) +
3857 "seconds before retrying." )
3858 time.sleep( retryTime ) # Due to change in mastership
3859 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003860 assert "Error executing command" not in output
3861 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3862 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3863 main.log.info( self.name + ": " + output )
3864 if re.search( positiveMatch, output):
3865 return main.TRUE
3866 elif re.search( negativeMatch, output):
3867 return main.FALSE
3868 else:
3869 main.log.error( self.name + ": setTestAdd did not" +
3870 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003871 main.log.debug( self.name + " actual: " + repr( output ) )
3872 return main.ERROR
3873 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003874 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003875 return main.ERROR
3876 except TypeError:
3877 main.log.exception( self.name + ": Object not as expected" )
3878 return main.ERROR
3879 except pexpect.EOF:
3880 main.log.error( self.name + ": EOF exception found" )
3881 main.log.error( self.name + ": " + self.handle.before )
3882 main.cleanup()
3883 main.exit()
3884 except Exception:
3885 main.log.exception( self.name + ": Uncaught exception!" )
3886 main.cleanup()
3887 main.exit()
3888
3889 def setTestRemove( self, setName, values, clear=False, retain=False ):
3890 """
3891 CLI command to remove elements from a distributed set.
3892 Required arguments:
3893 setName - The name of the set to remove from.
3894 values - The value(s) to remove from the set, space seperated.
3895 Optional arguments:
3896 clear - Clear all elements from the set
3897 retain - Retain only the given values. (intersection of the
3898 original set and the given set)
3899 returns:
3900 main.TRUE on success OR
3901 main.FALSE if the set was not changed OR
3902 main.ERROR on error
3903 """
3904 try:
3905 cmdStr = "set-test-remove "
3906 if clear:
3907 cmdStr += "-c " + str( setName )
3908 elif retain:
3909 cmdStr += "-r " + str( setName ) + " " + str( values )
3910 else:
3911 cmdStr += str( setName ) + " " + str( values )
3912 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003913 try:
3914 # TODO: Maybe make this less hardcoded
3915 # ConsistentMap Exceptions
3916 assert "org.onosproject.store.service" not in output
3917 # Node not leader
3918 assert "java.lang.IllegalStateException" not in output
3919 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003920 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003921 "command: " + str( output ) )
3922 retryTime = 30 # Conservative time, given by Madan
3923 main.log.info( "Waiting " + str( retryTime ) +
3924 "seconds before retrying." )
3925 time.sleep( retryTime ) # Due to change in mastership
3926 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003927 assert "Command not found:" not in output, output
3928 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003929 main.log.info( self.name + ": " + output )
3930 if clear:
3931 pattern = "Set " + str( setName ) + " cleared"
3932 if re.search( pattern, output ):
3933 return main.TRUE
3934 elif retain:
3935 positivePattern = str( setName ) + " was pruned to contain " +\
3936 "only elements of set \[(.*)\]"
3937 negativePattern = str( setName ) + " was not changed by " +\
3938 "retaining only elements of the set " +\
3939 "\[(.*)\]"
3940 if re.search( positivePattern, output ):
3941 return main.TRUE
3942 elif re.search( negativePattern, output ):
3943 return main.FALSE
3944 else:
3945 positivePattern = "\[(.*)\] was removed from the set " +\
3946 str( setName )
3947 if ( len( values.split() ) == 1 ):
3948 negativePattern = "\[(.*)\] was not in set " +\
3949 str( setName )
3950 else:
3951 negativePattern = "No element of \[(.*)\] was in set " +\
3952 str( setName )
3953 if re.search( positivePattern, output ):
3954 return main.TRUE
3955 elif re.search( negativePattern, output ):
3956 return main.FALSE
3957 main.log.error( self.name + ": setTestRemove did not" +
3958 " match expected output" )
3959 main.log.debug( self.name + " expected: " + pattern )
3960 main.log.debug( self.name + " actual: " + repr( output ) )
3961 return main.ERROR
3962 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003963 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003964 return main.ERROR
3965 except TypeError:
3966 main.log.exception( self.name + ": Object not as expected" )
3967 return main.ERROR
3968 except pexpect.EOF:
3969 main.log.error( self.name + ": EOF exception found" )
3970 main.log.error( self.name + ": " + self.handle.before )
3971 main.cleanup()
3972 main.exit()
3973 except Exception:
3974 main.log.exception( self.name + ": Uncaught exception!" )
3975 main.cleanup()
3976 main.exit()
3977
3978 def setTestGet( self, setName, values="" ):
3979 """
3980 CLI command to get the elements in a distributed set.
3981 Required arguments:
3982 setName - The name of the set to remove from.
3983 Optional arguments:
3984 values - The value(s) to check if in the set, space seperated.
3985 returns:
3986 main.ERROR on error OR
3987 A list of elements in the set if no optional arguments are
3988 supplied OR
3989 A tuple containing the list then:
3990 main.FALSE if the given values are not in the set OR
3991 main.TRUE if the given values are in the set OR
3992 """
3993 try:
3994 values = str( values ).strip()
3995 setName = str( setName ).strip()
3996 length = len( values.split() )
3997 containsCheck = None
3998 # Patterns to match
3999 setPattern = "\[(.*)\]"
4000 pattern = "Items in set " + setName + ":\n" + setPattern
4001 containsTrue = "Set " + setName + " contains the value " + values
4002 containsFalse = "Set " + setName + " did not contain the value " +\
4003 values
4004 containsAllTrue = "Set " + setName + " contains the the subset " +\
4005 setPattern
4006 containsAllFalse = "Set " + setName + " did not contain the the" +\
4007 " subset " + setPattern
4008
4009 cmdStr = "set-test-get "
4010 cmdStr += setName + " " + values
4011 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004012 try:
4013 # TODO: Maybe make this less hardcoded
4014 # ConsistentMap Exceptions
4015 assert "org.onosproject.store.service" not in output
4016 # Node not leader
4017 assert "java.lang.IllegalStateException" not in output
4018 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004019 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004020 "command: " + str( output ) )
4021 retryTime = 30 # Conservative time, given by Madan
4022 main.log.info( "Waiting " + str( retryTime ) +
4023 "seconds before retrying." )
4024 time.sleep( retryTime ) # Due to change in mastership
4025 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004026 assert "Command not found:" not in output, output
4027 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004028 main.log.info( self.name + ": " + output )
4029
4030 if length == 0:
4031 match = re.search( pattern, output )
4032 else: # if given values
4033 if length == 1: # Contains output
4034 patternTrue = pattern + "\n" + containsTrue
4035 patternFalse = pattern + "\n" + containsFalse
4036 else: # ContainsAll output
4037 patternTrue = pattern + "\n" + containsAllTrue
4038 patternFalse = pattern + "\n" + containsAllFalse
4039 matchTrue = re.search( patternTrue, output )
4040 matchFalse = re.search( patternFalse, output )
4041 if matchTrue:
4042 containsCheck = main.TRUE
4043 match = matchTrue
4044 elif matchFalse:
4045 containsCheck = main.FALSE
4046 match = matchFalse
4047 else:
4048 main.log.error( self.name + " setTestGet did not match " +\
4049 "expected output" )
4050 main.log.debug( self.name + " expected: " + pattern )
4051 main.log.debug( self.name + " actual: " + repr( output ) )
4052 match = None
4053 if match:
4054 setMatch = match.group( 1 )
4055 if setMatch == '':
4056 setList = []
4057 else:
4058 setList = setMatch.split( ", " )
4059 if length > 0:
4060 return ( setList, containsCheck )
4061 else:
4062 return setList
4063 else: # no match
4064 main.log.error( self.name + ": setTestGet did not" +
4065 " match expected output" )
4066 main.log.debug( self.name + " expected: " + pattern )
4067 main.log.debug( self.name + " actual: " + repr( output ) )
4068 return main.ERROR
4069 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004070 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004071 return main.ERROR
4072 except TypeError:
4073 main.log.exception( self.name + ": Object not as expected" )
4074 return main.ERROR
4075 except pexpect.EOF:
4076 main.log.error( self.name + ": EOF exception found" )
4077 main.log.error( self.name + ": " + self.handle.before )
4078 main.cleanup()
4079 main.exit()
4080 except Exception:
4081 main.log.exception( self.name + ": Uncaught exception!" )
4082 main.cleanup()
4083 main.exit()
4084
4085 def setTestSize( self, setName ):
4086 """
4087 CLI command to get the elements in a distributed set.
4088 Required arguments:
4089 setName - The name of the set to remove from.
4090 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004091 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004092 None on error
4093 """
4094 try:
4095 # TODO: Should this check against the number of elements returned
4096 # and then return true/false based on that?
4097 setName = str( setName ).strip()
4098 # Patterns to match
4099 setPattern = "\[(.*)\]"
4100 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4101 setPattern
4102 cmdStr = "set-test-get -s "
4103 cmdStr += setName
4104 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004105 try:
4106 # TODO: Maybe make this less hardcoded
4107 # ConsistentMap Exceptions
4108 assert "org.onosproject.store.service" not in output
4109 # Node not leader
4110 assert "java.lang.IllegalStateException" not in output
4111 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004112 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004113 "command: " + str( output ) )
4114 retryTime = 30 # Conservative time, given by Madan
4115 main.log.info( "Waiting " + str( retryTime ) +
4116 "seconds before retrying." )
4117 time.sleep( retryTime ) # Due to change in mastership
4118 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004119 assert "Command not found:" not in output, output
4120 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004121 main.log.info( self.name + ": " + output )
4122 match = re.search( pattern, output )
4123 if match:
4124 setSize = int( match.group( 1 ) )
4125 setMatch = match.group( 2 )
4126 if len( setMatch.split() ) == setSize:
4127 main.log.info( "The size returned by " + self.name +
4128 " matches the number of elements in " +
4129 "the returned set" )
4130 else:
4131 main.log.error( "The size returned by " + self.name +
4132 " does not match the number of " +
4133 "elements in the returned set." )
4134 return setSize
4135 else: # no match
4136 main.log.error( self.name + ": setTestGet did not" +
4137 " match expected output" )
4138 main.log.debug( self.name + " expected: " + pattern )
4139 main.log.debug( self.name + " actual: " + repr( output ) )
4140 return None
4141 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004142 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004143 return None
Jon Hall390696c2015-05-05 17:13:41 -07004144 except TypeError:
4145 main.log.exception( self.name + ": Object not as expected" )
4146 return None
4147 except pexpect.EOF:
4148 main.log.error( self.name + ": EOF exception found" )
4149 main.log.error( self.name + ": " + self.handle.before )
4150 main.cleanup()
4151 main.exit()
4152 except Exception:
4153 main.log.exception( self.name + ": Uncaught exception!" )
4154 main.cleanup()
4155 main.exit()
4156
Jon Hall80daded2015-05-27 16:07:00 -07004157 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004158 """
4159 Command to list the various counters in the system.
4160 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004161 if jsonFormat, a string of the json object returned by the cli
4162 command
4163 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004164 None on error
4165 """
Jon Hall390696c2015-05-05 17:13:41 -07004166 try:
4167 counters = {}
4168 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004169 if jsonFormat:
4170 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004171 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004172 assert "Command not found:" not in output, output
4173 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004174 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004175 return output
Jon Hall390696c2015-05-05 17:13:41 -07004176 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004177 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004178 return None
Jon Hall390696c2015-05-05 17:13:41 -07004179 except TypeError:
4180 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004181 return None
Jon Hall390696c2015-05-05 17:13:41 -07004182 except pexpect.EOF:
4183 main.log.error( self.name + ": EOF exception found" )
4184 main.log.error( self.name + ": " + self.handle.before )
4185 main.cleanup()
4186 main.exit()
4187 except Exception:
4188 main.log.exception( self.name + ": Uncaught exception!" )
4189 main.cleanup()
4190 main.exit()
4191
Jon Hall935db192016-04-19 00:22:04 -07004192 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004193 """
Jon Halle1a3b752015-07-22 13:02:46 -07004194 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004195 Required arguments:
4196 counter - The name of the counter to increment.
4197 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004198 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004199 returns:
4200 integer value of the counter or
4201 None on Error
4202 """
4203 try:
4204 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004205 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004206 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004207 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004208 if delta != 1:
4209 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004210 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004211 try:
4212 # TODO: Maybe make this less hardcoded
4213 # ConsistentMap Exceptions
4214 assert "org.onosproject.store.service" not in output
4215 # Node not leader
4216 assert "java.lang.IllegalStateException" not in output
4217 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004218 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004219 "command: " + str( output ) )
4220 retryTime = 30 # Conservative time, given by Madan
4221 main.log.info( "Waiting " + str( retryTime ) +
4222 "seconds before retrying." )
4223 time.sleep( retryTime ) # Due to change in mastership
4224 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004225 assert "Command not found:" not in output, output
4226 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004227 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004228 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004229 match = re.search( pattern, output )
4230 if match:
4231 return int( match.group( 1 ) )
4232 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004233 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004234 " match expected output." )
4235 main.log.debug( self.name + " expected: " + pattern )
4236 main.log.debug( self.name + " actual: " + repr( output ) )
4237 return None
4238 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004239 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004240 return None
4241 except TypeError:
4242 main.log.exception( self.name + ": Object not as expected" )
4243 return None
4244 except pexpect.EOF:
4245 main.log.error( self.name + ": EOF exception found" )
4246 main.log.error( self.name + ": " + self.handle.before )
4247 main.cleanup()
4248 main.exit()
4249 except Exception:
4250 main.log.exception( self.name + ": Uncaught exception!" )
4251 main.cleanup()
4252 main.exit()
4253
Jon Hall935db192016-04-19 00:22:04 -07004254 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004255 """
4256 CLI command to get a distributed counter then add a delta to it.
4257 Required arguments:
4258 counter - The name of the counter to increment.
4259 Optional arguments:
4260 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004261 returns:
4262 integer value of the counter or
4263 None on Error
4264 """
4265 try:
4266 counter = str( counter )
4267 delta = int( delta )
4268 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004269 cmdStr += counter
4270 if delta != 1:
4271 cmdStr += " " + str( delta )
4272 output = self.sendline( cmdStr )
4273 try:
4274 # TODO: Maybe make this less hardcoded
4275 # ConsistentMap Exceptions
4276 assert "org.onosproject.store.service" not in output
4277 # Node not leader
4278 assert "java.lang.IllegalStateException" not in output
4279 except AssertionError:
4280 main.log.error( "Error in processing '" + cmdStr + "' " +
4281 "command: " + str( output ) )
4282 retryTime = 30 # Conservative time, given by Madan
4283 main.log.info( "Waiting " + str( retryTime ) +
4284 "seconds before retrying." )
4285 time.sleep( retryTime ) # Due to change in mastership
4286 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004287 assert "Command not found:" not in output, output
4288 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004289 main.log.info( self.name + ": " + output )
4290 pattern = counter + " was updated to (-?\d+)"
4291 match = re.search( pattern, output )
4292 if match:
4293 return int( match.group( 1 ) )
4294 else:
4295 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4296 " match expected output." )
4297 main.log.debug( self.name + " expected: " + pattern )
4298 main.log.debug( self.name + " actual: " + repr( output ) )
4299 return None
4300 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004301 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004302 return None
4303 except TypeError:
4304 main.log.exception( self.name + ": Object not as expected" )
4305 return None
4306 except pexpect.EOF:
4307 main.log.error( self.name + ": EOF exception found" )
4308 main.log.error( self.name + ": " + self.handle.before )
4309 main.cleanup()
4310 main.exit()
4311 except Exception:
4312 main.log.exception( self.name + ": Uncaught exception!" )
4313 main.cleanup()
4314 main.exit()
4315
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004316 def summary( self, jsonFormat=True ):
4317 """
4318 Description: Execute summary command in onos
4319 Returns: json object ( summary -j ), returns main.FALSE if there is
4320 no output
4321
4322 """
4323 try:
4324 cmdStr = "summary"
4325 if jsonFormat:
4326 cmdStr += " -j"
4327 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004328 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004329 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004330 if not handle:
4331 main.log.error( self.name + ": There is no output in " +
4332 "summary command" )
4333 return main.FALSE
4334 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004335 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004336 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004337 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004338 except TypeError:
4339 main.log.exception( self.name + ": Object not as expected" )
4340 return None
4341 except pexpect.EOF:
4342 main.log.error( self.name + ": EOF exception found" )
4343 main.log.error( self.name + ": " + self.handle.before )
4344 main.cleanup()
4345 main.exit()
4346 except Exception:
4347 main.log.exception( self.name + ": Uncaught exception!" )
4348 main.cleanup()
4349 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004350
Jon Hall935db192016-04-19 00:22:04 -07004351 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004352 """
4353 CLI command to get the value of a key in a consistent map using
4354 transactions. This a test function and can only get keys from the
4355 test map hard coded into the cli command
4356 Required arguments:
4357 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004358 returns:
4359 The string value of the key or
4360 None on Error
4361 """
4362 try:
4363 keyName = str( keyName )
4364 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004365 cmdStr += keyName
4366 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004367 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004368 try:
4369 # TODO: Maybe make this less hardcoded
4370 # ConsistentMap Exceptions
4371 assert "org.onosproject.store.service" not in output
4372 # Node not leader
4373 assert "java.lang.IllegalStateException" not in output
4374 except AssertionError:
4375 main.log.error( "Error in processing '" + cmdStr + "' " +
4376 "command: " + str( output ) )
4377 return None
4378 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4379 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004380 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004381 return None
4382 else:
4383 match = re.search( pattern, output )
4384 if match:
4385 return match.groupdict()[ 'value' ]
4386 else:
4387 main.log.error( self.name + ": transactionlMapGet did not" +
4388 " match expected output." )
4389 main.log.debug( self.name + " expected: " + pattern )
4390 main.log.debug( self.name + " actual: " + repr( output ) )
4391 return None
Jon Hallc6793552016-01-19 14:18:37 -08004392 except AssertionError:
4393 main.log.exception( "" )
4394 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004395 except TypeError:
4396 main.log.exception( self.name + ": Object not as expected" )
4397 return None
4398 except pexpect.EOF:
4399 main.log.error( self.name + ": EOF exception found" )
4400 main.log.error( self.name + ": " + self.handle.before )
4401 main.cleanup()
4402 main.exit()
4403 except Exception:
4404 main.log.exception( self.name + ": Uncaught exception!" )
4405 main.cleanup()
4406 main.exit()
4407
Jon Hall935db192016-04-19 00:22:04 -07004408 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004409 """
4410 CLI command to put a value into 'numKeys' number of keys in a
4411 consistent map using transactions. This a test function and can only
4412 put into keys named 'Key#' of the test map hard coded into the cli command
4413 Required arguments:
4414 numKeys - Number of keys to add the value to
4415 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004416 returns:
4417 A dictionary whose keys are the name of the keys put into the map
4418 and the values of the keys are dictionaries whose key-values are
4419 'value': value put into map and optionaly
4420 'oldValue': Previous value in the key or
4421 None on Error
4422
4423 Example output
4424 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4425 'Key2': {'value': 'Testing'} }
4426 """
4427 try:
4428 numKeys = str( numKeys )
4429 value = str( value )
4430 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004431 cmdStr += numKeys + " " + value
4432 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004433 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004434 try:
4435 # TODO: Maybe make this less hardcoded
4436 # ConsistentMap Exceptions
4437 assert "org.onosproject.store.service" not in output
4438 # Node not leader
4439 assert "java.lang.IllegalStateException" not in output
4440 except AssertionError:
4441 main.log.error( "Error in processing '" + cmdStr + "' " +
4442 "command: " + str( output ) )
4443 return None
4444 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4445 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4446 results = {}
4447 for line in output.splitlines():
4448 new = re.search( newPattern, line )
4449 updated = re.search( updatedPattern, line )
4450 if new:
4451 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4452 elif updated:
4453 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004454 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004455 else:
4456 main.log.error( self.name + ": transactionlMapGet did not" +
4457 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004458 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4459 newPattern,
4460 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004461 main.log.debug( self.name + " actual: " + repr( output ) )
4462 return results
Jon Hallc6793552016-01-19 14:18:37 -08004463 except AssertionError:
4464 main.log.exception( "" )
4465 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004466 except TypeError:
4467 main.log.exception( self.name + ": Object not as expected" )
4468 return None
4469 except pexpect.EOF:
4470 main.log.error( self.name + ": EOF exception found" )
4471 main.log.error( self.name + ": " + self.handle.before )
4472 main.cleanup()
4473 main.exit()
4474 except Exception:
4475 main.log.exception( self.name + ": Uncaught exception!" )
4476 main.cleanup()
4477 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004478
acsmarsdaea66c2015-09-03 11:44:06 -07004479 def maps( self, jsonFormat=True ):
4480 """
4481 Description: Returns result of onos:maps
4482 Optional:
4483 * jsonFormat: enable json formatting of output
4484 """
4485 try:
4486 cmdStr = "maps"
4487 if jsonFormat:
4488 cmdStr += " -j"
4489 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004490 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004491 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004492 except AssertionError:
4493 main.log.exception( "" )
4494 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004495 except TypeError:
4496 main.log.exception( self.name + ": Object not as expected" )
4497 return None
4498 except pexpect.EOF:
4499 main.log.error( self.name + ": EOF exception found" )
4500 main.log.error( self.name + ": " + self.handle.before )
4501 main.cleanup()
4502 main.exit()
4503 except Exception:
4504 main.log.exception( self.name + ": Uncaught exception!" )
4505 main.cleanup()
4506 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004507
4508 def getSwController( self, uri, jsonFormat=True ):
4509 """
4510 Descrition: Gets the controller information from the device
4511 """
4512 try:
4513 cmd = "device-controllers "
4514 if jsonFormat:
4515 cmd += "-j "
4516 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004517 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004518 return response
Jon Hallc6793552016-01-19 14:18:37 -08004519 except AssertionError:
4520 main.log.exception( "" )
4521 return None
GlennRC050596c2015-11-18 17:06:41 -08004522 except TypeError:
4523 main.log.exception( self.name + ": Object not as expected" )
4524 return None
4525 except pexpect.EOF:
4526 main.log.error( self.name + ": EOF exception found" )
4527 main.log.error( self.name + ": " + self.handle.before )
4528 main.cleanup()
4529 main.exit()
4530 except Exception:
4531 main.log.exception( self.name + ": Uncaught exception!" )
4532 main.cleanup()
4533 main.exit()
4534
4535 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4536 """
4537 Descrition: sets the controller(s) for the specified device
4538
4539 Parameters:
4540 Required: uri - String: The uri of the device(switch).
4541 ip - String or List: The ip address of the controller.
4542 This parameter can be formed in a couple of different ways.
4543 VALID:
4544 10.0.0.1 - just the ip address
4545 tcp:10.0.0.1 - the protocol and the ip address
4546 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4547 so that you can add controllers with different
4548 protocols and ports
4549 INVALID:
4550 10.0.0.1:6653 - this is not supported by ONOS
4551
4552 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4553 port - The port number.
4554 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4555
4556 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4557 """
4558 try:
4559 cmd = "device-setcontrollers"
4560
4561 if jsonFormat:
4562 cmd += " -j"
4563 cmd += " " + uri
4564 if isinstance( ip, str ):
4565 ip = [ip]
4566 for item in ip:
4567 if ":" in item:
4568 sitem = item.split( ":" )
4569 if len(sitem) == 3:
4570 cmd += " " + item
4571 elif "." in sitem[1]:
4572 cmd += " {}:{}".format(item, port)
4573 else:
4574 main.log.error( "Malformed entry: " + item )
4575 raise TypeError
4576 else:
4577 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004578 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004579 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004580 if "Error" in response:
4581 main.log.error( response )
4582 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004583 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004584 except AssertionError:
4585 main.log.exception( "" )
4586 return None
GlennRC050596c2015-11-18 17:06:41 -08004587 except TypeError:
4588 main.log.exception( self.name + ": Object not as expected" )
4589 return main.FALSE
4590 except pexpect.EOF:
4591 main.log.error( self.name + ": EOF exception found" )
4592 main.log.error( self.name + ": " + self.handle.before )
4593 main.cleanup()
4594 main.exit()
4595 except Exception:
4596 main.log.exception( self.name + ": Uncaught exception!" )
4597 main.cleanup()
4598 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004599
4600 def removeDevice( self, device ):
4601 '''
4602 Description:
4603 Remove a device from ONOS by passing the uri of the device(s).
4604 Parameters:
4605 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4606 Returns:
4607 Returns main.FALSE if an exception is thrown or an error is present
4608 in the response. Otherwise, returns main.TRUE.
4609 NOTE:
4610 If a host cannot be removed, then this function will return main.FALSE
4611 '''
4612 try:
4613 if type( device ) is str:
4614 device = list( device )
4615
4616 for d in device:
4617 time.sleep( 1 )
4618 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004619 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004620 if "Error" in response:
4621 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4622 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004623 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004624 except AssertionError:
4625 main.log.exception( "" )
4626 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004627 except TypeError:
4628 main.log.exception( self.name + ": Object not as expected" )
4629 return main.FALSE
4630 except pexpect.EOF:
4631 main.log.error( self.name + ": EOF exception found" )
4632 main.log.error( self.name + ": " + self.handle.before )
4633 main.cleanup()
4634 main.exit()
4635 except Exception:
4636 main.log.exception( self.name + ": Uncaught exception!" )
4637 main.cleanup()
4638 main.exit()
4639
4640 def removeHost( self, host ):
4641 '''
4642 Description:
4643 Remove a host from ONOS by passing the id of the host(s)
4644 Parameters:
4645 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4646 Returns:
4647 Returns main.FALSE if an exception is thrown or an error is present
4648 in the response. Otherwise, returns main.TRUE.
4649 NOTE:
4650 If a host cannot be removed, then this function will return main.FALSE
4651 '''
4652 try:
4653 if type( host ) is str:
4654 host = list( host )
4655
4656 for h in host:
4657 time.sleep( 1 )
4658 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004659 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004660 if "Error" in response:
4661 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4662 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004663 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004664 except AssertionError:
4665 main.log.exception( "" )
4666 return None
GlennRC20fc6522015-12-23 23:26:57 -08004667 except TypeError:
4668 main.log.exception( self.name + ": Object not as expected" )
4669 return main.FALSE
4670 except pexpect.EOF:
4671 main.log.error( self.name + ": EOF exception found" )
4672 main.log.error( self.name + ": " + self.handle.before )
4673 main.cleanup()
4674 main.exit()
4675 except Exception:
4676 main.log.exception( self.name + ": Uncaught exception!" )
4677 main.cleanup()
4678 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004679
Jon Hallc6793552016-01-19 14:18:37 -08004680 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004681 '''
4682 Description:
4683 Bring link down or up in the null-provider.
4684 params:
4685 begin - (string) One end of a device or switch.
4686 end - (string) the other end of the device or switch
4687 returns:
4688 main.TRUE if no exceptions were thrown and no Errors are
4689 present in the resoponse. Otherwise, returns main.FALSE
4690 '''
4691 try:
Jon Hallc6793552016-01-19 14:18:37 -08004692 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004693 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004694 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004695 if "Error" in response or "Failure" in response:
4696 main.log.error( response )
4697 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004698 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004699 except AssertionError:
4700 main.log.exception( "" )
4701 return None
GlennRCed771242016-01-13 17:02:47 -08004702 except TypeError:
4703 main.log.exception( self.name + ": Object not as expected" )
4704 return main.FALSE
4705 except pexpect.EOF:
4706 main.log.error( self.name + ": EOF exception found" )
4707 main.log.error( self.name + ": " + self.handle.before )
4708 main.cleanup()
4709 main.exit()
4710 except Exception:
4711 main.log.exception( self.name + ": Uncaught exception!" )
4712 main.cleanup()
4713 main.exit()
4714