blob: 61c38b779f11bbf360be61ffe4a24c0cfec7e738 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700154 try:
155 self.handle.expect( "\$" )
156 except pexpect.TIMEOUT:
157 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700158 return main.TRUE
159 else: # some other output
160 main.log.warn( "Unknown repsonse to logout command: '{}'",
161 repr( self.handle.before ) )
162 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700163 elif i == 1: # not in CLI
164 return main.TRUE
165 elif i == 3: # Timeout
166 return main.FALSE
167 else:
andrewonlab9627f432014-11-14 12:45:10 -0500168 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800169 except TypeError:
170 main.log.exception( self.name + ": Object not as expected" )
171 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800173 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700174 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500175 main.cleanup()
176 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700177 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700178 main.log.error( self.name +
179 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800180 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800181 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
184
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800186 """
andrewonlab95ce8322014-10-13 14:12:04 -0400187 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800188
andrewonlab95ce8322014-10-13 14:12:04 -0400189 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800190 """
andrewonlab95ce8322014-10-13 14:12:04 -0400191 try:
192 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800193 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400194 main.cleanup()
195 main.exit()
196 else:
kelvin8ec71442015-01-15 16:57:00 -0800197 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800199 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400200 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800201 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800202 handleBefore = self.handle.before
203 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800204 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800205 self.handle.sendline("")
206 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800207 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400208
kelvin-onlabd3b64892015-01-20 13:26:24 -0800209 main.log.info( "Cell call returned: " + handleBefore +
210 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400211
212 return main.TRUE
213
Jon Halld4d4b372015-01-28 16:02:41 -0800214 except TypeError:
215 main.log.exception( self.name + ": Object not as expected" )
216 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400217 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800218 main.log.error( self.name + ": eof exception found" )
219 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400220 main.cleanup()
221 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800222 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800223 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400224 main.cleanup()
225 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800226
pingping-lin57a56ce2015-05-20 16:43:48 -0700227 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800228 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800229 """
Jon Hallefbd9792015-03-05 16:11:36 -0800230 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 by user would be used to set the current karaf shell idle timeout.
232 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800233 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 Below is an example to start a session with 60 seconds idle timeout
235 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800236
Hari Krishna25d42f72015-01-05 15:08:28 -0800237 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800239
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 Note: karafTimeout is left as str so that this could be read
241 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800242 """
You Wangf69ab392016-01-26 16:34:38 -0800243 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400244 try:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline( "" )
246 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700247 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500248
249 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800250 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500251 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400252
kelvin8ec71442015-01-15 16:57:00 -0800253 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800255 i = self.handle.expect( [
256 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700257 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400258
259 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800261 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800262 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800263 "config:property-set -p org.apache.karaf.shell\
264 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800265 karafTimeout )
266 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800268 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400269 return main.TRUE
270 else:
kelvin8ec71442015-01-15 16:57:00 -0800271 # If failed, send ctrl+c to process and try again
272 main.log.info( "Starting CLI failed. Retrying..." )
273 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800275 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
276 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400277 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800279 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800280 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800281 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 "config:property-set -p org.apache.karaf.shell\
283 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800284 karafTimeout )
285 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400288 return main.TRUE
289 else:
kelvin8ec71442015-01-15 16:57:00 -0800290 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400292 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400293
Jon Halld4d4b372015-01-28 16:02:41 -0800294 except TypeError:
295 main.log.exception( self.name + ": Object not as expected" )
296 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800298 main.log.error( self.name + ": EOF exception found" )
299 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400300 main.cleanup()
301 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800303 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400304 main.cleanup()
305 main.exit()
306
suibin zhang116647a2016-05-06 16:30:09 -0700307 def startCellCli( self, karafTimeout="",
308 commandlineTimeout=10, onosStartTimeout=60 ):
309 """
310 Start CLI on onos ecll handle.
311
312 karafTimeout is an optional argument. karafTimeout value passed
313 by user would be used to set the current karaf shell idle timeout.
314 Note that when ever this property is modified the shell will exit and
315 the subsequent login would reflect new idle timeout.
316 Below is an example to start a session with 60 seconds idle timeout
317 ( input value is in milliseconds ):
318
319 tValue = "60000"
320
321 Note: karafTimeout is left as str so that this could be read
322 and passed to startOnosCli from PARAMS file as str.
323 """
324
325 try:
326 self.handle.sendline( "" )
327 x = self.handle.expect( [
328 "\$", "onos>" ], commandlineTimeout)
329
330 if x == 1:
331 main.log.info( "ONOS cli is already running" )
332 return main.TRUE
333
334 # Wait for onos start ( -w ) and enter onos cli
335 self.handle.sendline( "/opt/onos/bin/onos" )
336 i = self.handle.expect( [
337 "onos>",
338 pexpect.TIMEOUT ], onosStartTimeout )
339
340 if i == 0:
341 main.log.info( self.name + " CLI Started successfully" )
342 if karafTimeout:
343 self.handle.sendline(
344 "config:property-set -p org.apache.karaf.shell\
345 sshIdleTimeout " +
346 karafTimeout )
347 self.handle.expect( "\$" )
348 self.handle.sendline( "/opt/onos/bin/onos" )
349 self.handle.expect( "onos>" )
350 return main.TRUE
351 else:
352 # If failed, send ctrl+c to process and try again
353 main.log.info( "Starting CLI failed. Retrying..." )
354 self.handle.send( "\x03" )
355 self.handle.sendline( "/opt/onos/bin/onos" )
356 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
357 timeout=30 )
358 if i == 0:
359 main.log.info( self.name + " CLI Started " +
360 "successfully after retry attempt" )
361 if karafTimeout:
362 self.handle.sendline(
363 "config:property-set -p org.apache.karaf.shell\
364 sshIdleTimeout " +
365 karafTimeout )
366 self.handle.expect( "\$" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 self.handle.expect( "onos>" )
369 return main.TRUE
370 else:
371 main.log.error( "Connection to CLI " +
372 self.name + " timeout" )
373 return main.FALSE
374
375 except TypeError:
376 main.log.exception( self.name + ": Object not as expected" )
377 return None
378 except pexpect.EOF:
379 main.log.error( self.name + ": EOF exception found" )
380 main.log.error( self.name + ": " + self.handle.before )
381 main.cleanup()
382 main.exit()
383 except Exception:
384 main.log.exception( self.name + ": Uncaught exception!" )
385 main.cleanup()
386 main.exit()
387
YPZhangebf9eb52016-05-12 15:20:24 -0700388 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800389 """
390 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800391 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800392 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700393 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800394 Available level: DEBUG, TRACE, INFO, WARN, ERROR
395 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800396 """
397 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800398 lvlStr = ""
399 if level:
400 lvlStr = "--level=" + level
401
kelvin-onlab338f5512015-02-06 10:53:16 -0800402 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700403 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800404 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800405
kelvin-onlab9f541032015-02-04 16:19:53 -0800406 response = self.handle.before
407 if re.search( "Error", response ):
408 return main.FALSE
409 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700410 except pexpect.TIMEOUT:
411 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700412 if noExit:
413 main.cleanup()
414 return None
415 else:
416 main.cleanup()
417 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 except pexpect.EOF:
419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700421 if noExit:
422 main.cleanup()
423 return None
424 else:
425 main.cleanup()
426 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800427 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800428 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700429 if noExit:
430 main.cleanup()
431 return None
432 else:
433 main.cleanup()
434 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400435
YPZhangebf9eb52016-05-12 15:20:24 -0700436 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800437 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800438 Send a completely user specified string to
439 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400440 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800441
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit is True, TestON will not exit, but clean up
443
andrewonlaba18f6bf2014-10-13 19:31:54 -0400444 Warning: There are no sanity checking to commands
445 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800446
kelvin8ec71442015-01-15 16:57:00 -0800447 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400448 try:
Jon Halla495f562016-05-16 18:03:26 -0700449 # Try to reconnect if disconnected from cli
450 self.handle.sendline( "" )
451 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
452 if i == 1:
453 main.log.error( self.name + ": onos cli session closed. ")
454 if self.onosIp:
455 main.log.warn( "Trying to reconnect " + self.onosIp )
456 reconnectResult = self.startOnosCli( self.onosIp )
457 if reconnectResult:
458 main.log.info( self.name + ": onos cli session reconnected." )
459 else:
460 main.log.error( self.name + ": reconnection failed." )
461 main.cleanup()
462 main.exit()
463 else:
464 main.cleanup()
465 main.exit()
466 if i == 2:
467 self.handle.sendline( "" )
468 self.handle.expect( "onos>" )
469
Jon Hall14a03b52016-05-11 12:07:30 -0700470 if debug:
471 # NOTE: This adds and average of .4 seconds per call
472 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700473 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800475 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800476 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800477 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800478 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
479 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700480 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700481 main.log.debug( self.name + ": Raw output" )
482 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483
484 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800486 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700487 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700488 main.log.debug( self.name + ": ansiEscape output" )
489 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490
kelvin-onlabfb521662015-02-27 09:52:40 -0800491 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800492 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700493 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700494 main.log.debug( self.name + ": Removed extra returns " +
495 "from output" )
496 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497
498 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800499 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700501 main.log.debug( self.name + ": parsed and stripped output" )
502 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503
Jon Hall63604932015-02-26 17:09:50 -0800504 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 output = response.split( cmdStr.strip(), 1 )
506 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700507 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700509 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800510 output = output[1].strip()
511 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800512 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800513 return output
GlennRCed771242016-01-13 17:02:47 -0800514 except pexpect.TIMEOUT:
515 main.log.error( self.name + ":ONOS timeout" )
516 if debug:
517 main.log.debug( self.handle.before )
518 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700519 except IndexError:
520 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700521 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800523 except TypeError:
524 main.log.exception( self.name + ": Object not as expected" )
525 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400526 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800527 main.log.error( self.name + ": EOF exception found" )
528 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700529 if noExit:
530 main.cleanup()
531 return None
532 else:
533 main.cleanup()
534 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800536 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700537 if noExit:
538 main.cleanup()
539 return None
540 else:
541 main.cleanup()
542 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400543
kelvin8ec71442015-01-15 16:57:00 -0800544 # IMPORTANT NOTE:
545 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 # the cli command changing 'a:b' with 'aB'.
547 # Ex ) onos:topology > onosTopology
548 # onos:links > onosLinks
549 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800552 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 Adds a new cluster node by ID and address information.
554 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 * nodeId
556 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400557 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800559 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400560 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800561 cmdStr = "add-node " + str( nodeId ) + " " +\
562 str( ONOSIp ) + " " + str( tcpPort )
563 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700564 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800565 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800566 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error( "Error in adding node" )
568 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800569 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400570 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800573 except AssertionError:
574 main.log.exception( "" )
575 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800576 except TypeError:
577 main.log.exception( self.name + ": Object not as expected" )
578 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error( self.name + ": EOF exception found" )
581 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 main.cleanup()
583 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800584 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800585 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 main.cleanup()
587 main.exit()
588
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlab86dc3082014-10-13 18:18:38 -0400591 Removes a cluster by ID
592 Issues command: 'remove-node [<node-id>]'
593 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800595 """
andrewonlab86dc3082014-10-13 18:18:38 -0400596 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700599 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700600 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800601 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700602 if re.search( "Error", handle ):
603 main.log.error( "Error in removing node" )
604 main.log.error( handle )
605 return main.FALSE
606 else:
607 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800608 except AssertionError:
609 main.log.exception( "" )
610 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800611 except TypeError:
612 main.log.exception( self.name + ": Object not as expected" )
613 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800615 main.log.error( self.name + ": EOF exception found" )
616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400617 main.cleanup()
618 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400621 main.cleanup()
622 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400623
Jon Hall61282e32015-03-19 11:34:11 -0700624 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800625 """
andrewonlab7c211572014-10-15 16:45:20 -0400626 List the nodes currently visible
627 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700628 Optional argument:
629 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800630 """
andrewonlab7c211572014-10-15 16:45:20 -0400631 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700632 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700633 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 cmdStr += " -j"
635 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700636 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800637 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 return output
Jon Hallc6793552016-01-19 14:18:37 -0800639 except AssertionError:
640 main.log.exception( "" )
641 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800642 except TypeError:
643 main.log.exception( self.name + ": Object not as expected" )
644 return None
andrewonlab7c211572014-10-15 16:45:20 -0400645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": EOF exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800651 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400652 main.cleanup()
653 main.exit()
654
kelvin8ec71442015-01-15 16:57:00 -0800655 def topology( self ):
656 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700657 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700658 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700659 Return:
660 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800661 """
andrewonlab95ce8322014-10-13 14:12:04 -0400662 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700663 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800665 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700666 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400667 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800668 except AssertionError:
669 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800670 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400674 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400677 main.cleanup()
678 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800679 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800680 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400681 main.cleanup()
682 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800683
jenkins7ead5a82015-03-13 10:28:21 -0700684 def deviceRemove( self, deviceId ):
685 """
686 Removes particular device from storage
687
688 TODO: refactor this function
689 """
690 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr = "device-remove " + str( deviceId )
692 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800693 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700694 if re.search( "Error", handle ):
695 main.log.error( "Error in removing device" )
696 main.log.error( handle )
697 return main.FALSE
698 else:
699 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800700 except AssertionError:
701 main.log.exception( "" )
702 return None
jenkins7ead5a82015-03-13 10:28:21 -0700703 except TypeError:
704 main.log.exception( self.name + ": Object not as expected" )
705 return None
706 except pexpect.EOF:
707 main.log.error( self.name + ": EOF exception found" )
708 main.log.error( self.name + ": " + self.handle.before )
709 main.cleanup()
710 main.exit()
711 except Exception:
712 main.log.exception( self.name + ": Uncaught exception!" )
713 main.cleanup()
714 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700715
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800717 """
Jon Hall7b02d952014-10-17 20:14:54 -0400718 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400719 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800721 """
andrewonlab86dc3082014-10-13 18:18:38 -0400722 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700723 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr += " -j"
726 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800727 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700728 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800729 except AssertionError:
730 main.log.exception( "" )
731 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800732 except TypeError:
733 main.log.exception( self.name + ": Object not as expected" )
734 return None
andrewonlab7c211572014-10-15 16:45:20 -0400735 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800736 main.log.error( self.name + ": EOF exception found" )
737 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400738 main.cleanup()
739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800741 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400742 main.cleanup()
743 main.exit()
744
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800746 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800747 This balances the devices across all controllers
748 by issuing command: 'onos> onos:balance-masters'
749 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800750 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800751 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800754 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 if re.search( "Error", handle ):
756 main.log.error( "Error in balancing masters" )
757 main.log.error( handle )
758 return main.FALSE
759 else:
760 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800761 except AssertionError:
762 main.log.exception( "" )
763 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800764 except TypeError:
765 main.log.exception( self.name + ": Object not as expected" )
766 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800768 main.log.error( self.name + ": EOF exception found" )
769 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800770 main.cleanup()
771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800773 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800774 main.cleanup()
775 main.exit()
776
Jon Hallc6793552016-01-19 14:18:37 -0800777 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700778 """
779 Returns the output of the masters command.
780 Optional argument:
781 * jsonFormat - boolean indicating if you want output in json
782 """
783 try:
784 cmdStr = "onos:masters"
785 if jsonFormat:
786 cmdStr += " -j"
787 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700788 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800789 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700790 return output
Jon Hallc6793552016-01-19 14:18:37 -0800791 except AssertionError:
792 main.log.exception( "" )
793 return None
acsmars24950022015-07-30 18:00:43 -0700794 except TypeError:
795 main.log.exception( self.name + ": Object not as expected" )
796 return None
797 except pexpect.EOF:
798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
800 main.cleanup()
801 main.exit()
802 except Exception:
803 main.log.exception( self.name + ": Uncaught exception!" )
804 main.cleanup()
805 main.exit()
806
Jon Hallc6793552016-01-19 14:18:37 -0800807 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700808 """
809 Uses the master command to check that the devices' leadership
810 is evenly divided
811
812 Dependencies: checkMasters() and summary()
813
814 Returns main.True if the devices are balanced
815 Returns main.False if the devices are unbalanced
816 Exits on Exception
817 Returns None on TypeError
818 """
819 try:
Jon Hallc6793552016-01-19 14:18:37 -0800820 summaryOutput = self.summary()
821 totalDevices = json.loads( summaryOutput )[ "devices" ]
822 except ( TypeError, ValueError ):
823 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
824 return None
825 try:
acsmars24950022015-07-30 18:00:43 -0700826 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800827 mastersOutput = self.checkMasters()
828 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700829 first = masters[ 0 ][ "size" ]
830 for master in masters:
831 totalOwnedDevices += master[ "size" ]
832 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
833 main.log.error( "Mastership not balanced" )
834 main.log.info( "\n" + self.checkMasters( False ) )
835 return main.FALSE
836 main.log.info( "Mastership balanced between " \
837 + str( len(masters) ) + " masters" )
838 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800839 except ( TypeError, ValueError ):
840 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700841 return None
842 except pexpect.EOF:
843 main.log.error( self.name + ": EOF exception found" )
844 main.log.error( self.name + ": " + self.handle.before )
845 main.cleanup()
846 main.exit()
847 except Exception:
848 main.log.exception( self.name + ": Uncaught exception!" )
849 main.cleanup()
850 main.exit()
851
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800853 """
Jon Halle8217482014-10-17 13:49:14 -0400854 Lists all core links
855 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800857 """
Jon Halle8217482014-10-17 13:49:14 -0400858 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700859 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 cmdStr += " -j"
862 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800863 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700864 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800865 except AssertionError:
866 main.log.exception( "" )
867 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800868 except TypeError:
869 main.log.exception( self.name + ": Object not as expected" )
870 return None
Jon Halle8217482014-10-17 13:49:14 -0400871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800872 main.log.error( self.name + ": EOF exception found" )
873 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400874 main.cleanup()
875 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800876 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800877 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400878 main.cleanup()
879 main.exit()
880
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800882 """
Jon Halle8217482014-10-17 13:49:14 -0400883 Lists all ports
884 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800886 """
Jon Halle8217482014-10-17 13:49:14 -0400887 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700888 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700890 cmdStr += " -j"
891 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800892 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700893 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800894 except AssertionError:
895 main.log.exception( "" )
896 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800897 except TypeError:
898 main.log.exception( self.name + ": Object not as expected" )
899 return None
Jon Halle8217482014-10-17 13:49:14 -0400900 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400903 main.cleanup()
904 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800905 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800906 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400907 main.cleanup()
908 main.exit()
909
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800911 """
Jon Hall983a1702014-10-28 18:44:22 -0400912 Lists all devices and the controllers with roles assigned to them
913 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800915 """
andrewonlab7c211572014-10-15 16:45:20 -0400916 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700917 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700919 cmdStr += " -j"
920 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800921 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800923 except AssertionError:
924 main.log.exception( "" )
925 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800926 except TypeError:
927 main.log.exception( self.name + ": Object not as expected" )
928 return None
Jon Hall983a1702014-10-28 18:44:22 -0400929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400932 main.cleanup()
933 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800935 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400936 main.cleanup()
937 main.exit()
938
kelvin-onlabd3b64892015-01-20 13:26:24 -0800939 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800940 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800941 Given the a string containing the json representation of the "roles"
942 cli command and a partial or whole device id, returns a json object
943 containing the roles output for the first device whose id contains
944 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400945
946 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800947 A dict of the role assignments for the given device or
948 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800949 """
Jon Hall983a1702014-10-28 18:44:22 -0400950 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400952 return None
953 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 rawRoles = self.roles()
955 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800956 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800958 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400960 return device
961 return None
Jon Hallc6793552016-01-19 14:18:37 -0800962 except ( TypeError, ValueError ):
963 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800964 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400965 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400968 main.cleanup()
969 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800970 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800971 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400972 main.cleanup()
973 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800974
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800976 """
Jon Hall94fd0472014-12-08 11:52:42 -0800977 Iterates through each device and checks if there is a master assigned
978 Returns: main.TRUE if each device has a master
979 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800980 """
Jon Hall94fd0472014-12-08 11:52:42 -0800981 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 rawRoles = self.roles()
983 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800984 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800986 # print device
987 if device[ 'master' ] == "none":
988 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800989 return main.FALSE
990 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800991 except ( TypeError, ValueError ):
992 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800993 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.error( self.name + ": EOF exception found" )
996 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800997 main.cleanup()
998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001000 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 main.cleanup()
1002 main.exit()
1003
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001005 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001006 Returns string of paths, and the cost.
1007 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001008 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001009 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1011 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001012 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001013 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.error( "Error in getting paths" )
1015 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 else:
kelvin8ec71442015-01-15 16:57:00 -08001017 path = handle.split( ";" )[ 0 ]
1018 cost = handle.split( ";" )[ 1 ]
1019 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001020 except AssertionError:
1021 main.log.exception( "" )
1022 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001023 except TypeError:
1024 main.log.exception( self.name + ": Object not as expected" )
1025 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 main.cleanup()
1030 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001031 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001032 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001033 main.cleanup()
1034 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001035
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001037 """
Jon Hallffb386d2014-11-21 13:43:38 -08001038 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001039 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001040 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001041 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001042 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001043 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001045 cmdStr += " -j"
1046 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001047 if handle:
1048 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001049 # TODO: Maybe make this less hardcoded
1050 # ConsistentMap Exceptions
1051 assert "org.onosproject.store.service" not in handle
1052 # Node not leader
1053 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001055 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001057 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001058 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001059 except TypeError:
1060 main.log.exception( self.name + ": Object not as expected" )
1061 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.error( self.name + ": EOF exception found" )
1064 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001065 main.cleanup()
1066 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001074 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001075
Jon Hallefbd9792015-03-05 16:11:36 -08001076 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001077 partial mac address
1078
Jon Hall42db6dc2014-10-24 19:03:48 -04001079 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 try:
kelvin8ec71442015-01-15 16:57:00 -08001082 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001083 return None
1084 else:
1085 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 rawHosts = self.hosts()
1087 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001088 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001090 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001091 if not host:
1092 pass
1093 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001094 return host
1095 return None
Jon Hallc6793552016-01-19 14:18:37 -08001096 except ( TypeError, ValueError ):
1097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001102 main.cleanup()
1103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001105 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 main.cleanup()
1107 main.exit()
1108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001110 """
1111 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001112 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001113
andrewonlab3f0a4af2014-10-17 12:25:14 -04001114 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 IMPORTANT:
1117 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001118 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Furthermore, it assumes that value of VLAN is '-1'
1120 Description:
kelvin8ec71442015-01-15 16:57:00 -08001121 Converts mininet hosts ( h1, h2, h3... ) into
1122 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1123 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001128 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 hostHex = hex( int( host ) ).zfill( 12 )
1130 hostHex = str( hostHex ).replace( 'x', '0' )
1131 i = iter( str( hostHex ) )
1132 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1133 hostHex = hostHex + "/-1"
1134 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137
Jon Halld4d4b372015-01-28 16:02:41 -08001138 except TypeError:
1139 main.log.exception( self.name + ": Object not as expected" )
1140 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001142 main.log.error( self.name + ": EOF exception found" )
1143 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144 main.cleanup()
1145 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001146 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001147 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 main.cleanup()
1149 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001150
Jeremy Songsterff553672016-05-12 17:06:23 -07001151 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001152 """
andrewonlabe6745342014-10-17 14:29:13 -04001153 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 * hostIdOne: ONOS host id for host1
1155 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001156 Optional:
1157 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001158 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001159 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001160 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001161 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001162 Returns:
1163 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlabe6745342014-10-17 14:29:13 -04001165 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001166 cmdStr = "add-host-intent "
1167 if vlanId:
1168 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001169 if setVlan:
1170 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001171 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001173 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001174 if re.search( "Error", handle ):
1175 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001176 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001177 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001178 else:
1179 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001180 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1181 match = re.search('id=0x([\da-f]+),', handle)
1182 if match:
1183 return match.group()[3:-1]
1184 else:
1185 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001186 main.log.debug( "Response from ONOS was: " +
1187 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 return None
Jon Hallc6793552016-01-19 14:18:37 -08001189 except AssertionError:
1190 main.log.exception( "" )
1191 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001192 except TypeError:
1193 main.log.exception( self.name + ": Object not as expected" )
1194 return None
andrewonlabe6745342014-10-17 14:29:13 -04001195 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001196 main.log.error( self.name + ": EOF exception found" )
1197 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001198 main.cleanup()
1199 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001200 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001201 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001202 main.cleanup()
1203 main.exit()
1204
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001206 """
andrewonlab7b31d232014-10-24 13:31:47 -04001207 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 * ingressDevice: device id of ingress device
1209 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001210 Optional:
1211 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001212 Description:
1213 Adds an optical intent by specifying an ingress and egress device
1214 Returns:
1215 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001216 """
andrewonlab7b31d232014-10-24 13:31:47 -04001217 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1219 " " + str( egressDevice )
1220 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001221 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001223 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001224 main.log.error( "Error in adding Optical intent" )
1225 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001226 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 main.log.info( "Optical intent installed between " +
1228 str( ingressDevice ) + " and " +
1229 str( egressDevice ) )
1230 match = re.search('id=0x([\da-f]+),', handle)
1231 if match:
1232 return match.group()[3:-1]
1233 else:
1234 main.log.error( "Error, intent ID not found" )
1235 return None
Jon Hallc6793552016-01-19 14:18:37 -08001236 except AssertionError:
1237 main.log.exception( "" )
1238 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001239 except TypeError:
1240 main.log.exception( self.name + ": Object not as expected" )
1241 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001243 main.log.error( self.name + ": EOF exception found" )
1244 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001245 main.cleanup()
1246 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001247 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001248 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001249 main.cleanup()
1250 main.exit()
1251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 ingressDevice,
1255 egressDevice,
1256 portIngress="",
1257 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 ethType="",
1259 ethSrc="",
1260 ethDst="",
1261 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 ipProto="",
1264 ipSrc="",
1265 ipDst="",
1266 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001267 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001268 vlanId="",
1269 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001270 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001271 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 * ingressDevice: device id of ingress device
1273 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001274 Optional:
1275 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001276 * ethSrc: specify ethSrc ( i.e. src mac addr )
1277 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001278 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001280 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001281 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001282 * ipSrc: specify ip source address
1283 * ipDst: specify ip destination address
1284 * tcpSrc: specify tcp source port
1285 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001286 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001287 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001288 Description:
kelvin8ec71442015-01-15 16:57:00 -08001289 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001290 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 Returns:
1292 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001293
Jon Halle3f39ff2015-01-13 11:50:53 -08001294 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001295 options developers provide for point-to-point
1296 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001297 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001298 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001299 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001300
Jeremy Songsterff553672016-05-12 17:06:23 -07001301 if ethType:
1302 cmd += " --ethType " + str( ethType )
1303 if ethSrc:
1304 cmd += " --ethSrc " + str( ethSrc )
1305 if ethDst:
1306 cmd += " --ethDst " + str( ethDst )
1307 if bandwidth:
1308 cmd += " --bandwidth " + str( bandwidth )
1309 if lambdaAlloc:
1310 cmd += " --lambda "
1311 if ipProto:
1312 cmd += " --ipProto " + str( ipProto )
1313 if ipSrc:
1314 cmd += " --ipSrc " + str( ipSrc )
1315 if ipDst:
1316 cmd += " --ipDst " + str( ipDst )
1317 if tcpSrc:
1318 cmd += " --tcpSrc " + str( tcpSrc )
1319 if tcpDst:
1320 cmd += " --tcpDst " + str( tcpDst )
1321 if vlanId:
1322 cmd += " -v " + str( vlanId )
1323 if setVlan:
1324 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001325
kelvin8ec71442015-01-15 16:57:00 -08001326 # Check whether the user appended the port
1327 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 if "/" in ingressDevice:
1329 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001330 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001331 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001332 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001333 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 # Would it make sense to throw an exception and exit
1335 # the test?
1336 return None
andrewonlab36af3822014-11-18 17:48:18 -05001337
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 str( ingressDevice ) + "/" +\
1340 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001341
kelvin-onlabd3b64892015-01-20 13:26:24 -08001342 if "/" in egressDevice:
1343 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001344 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 main.log.error( "You must specify the egress port" )
1347 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001348
kelvin8ec71442015-01-15 16:57:00 -08001349 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001350 str( egressDevice ) + "/" +\
1351 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001352
kelvin-onlab898a6c62015-01-16 14:13:53 -08001353 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001354 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001355 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001356 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001357 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001359 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001360 # TODO: print out all the options in this message?
1361 main.log.info( "Point-to-point intent installed between " +
1362 str( ingressDevice ) + " and " +
1363 str( egressDevice ) )
1364 match = re.search('id=0x([\da-f]+),', handle)
1365 if match:
1366 return match.group()[3:-1]
1367 else:
1368 main.log.error( "Error, intent ID not found" )
1369 return None
Jon Hallc6793552016-01-19 14:18:37 -08001370 except AssertionError:
1371 main.log.exception( "" )
1372 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001373 except TypeError:
1374 main.log.exception( self.name + ": Object not as expected" )
1375 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001376 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001377 main.log.error( self.name + ": EOF exception found" )
1378 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001379 main.cleanup()
1380 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001381 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001382 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001383 main.cleanup()
1384 main.exit()
1385
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001387 self,
shahshreyac2f97072015-03-19 17:04:29 -07001388 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001390 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001392 ethType="",
1393 ethSrc="",
1394 ethDst="",
1395 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001397 ipProto="",
1398 ipSrc="",
1399 ipDst="",
1400 tcpSrc="",
1401 tcpDst="",
1402 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001403 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001404 vlanId="",
1405 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001406 """
shahshreyad0c80432014-12-04 16:56:05 -08001407 Note:
shahshreya70622b12015-03-19 17:19:00 -07001408 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001409 is same. That is, all ingress devices include port numbers
1410 with a "/" or all ingress devices could specify device
1411 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001412 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001413 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001414 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001416 Optional:
1417 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001418 * ethSrc: specify ethSrc ( i.e. src mac addr )
1419 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001420 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001422 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001423 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001424 * ipSrc: specify ip source address
1425 * ipDst: specify ip destination address
1426 * tcpSrc: specify tcp source port
1427 * tcpDst: specify tcp destination port
1428 * setEthSrc: action to Rewrite Source MAC Address
1429 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001430 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001431 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001432 Description:
kelvin8ec71442015-01-15 16:57:00 -08001433 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001434 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001435 Returns:
1436 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001437
Jon Halle3f39ff2015-01-13 11:50:53 -08001438 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001439 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001440 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001441 """
shahshreyad0c80432014-12-04 16:56:05 -08001442 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001443 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001444
Jeremy Songsterff553672016-05-12 17:06:23 -07001445 if ethType:
1446 cmd += " --ethType " + str( ethType )
1447 if ethSrc:
1448 cmd += " --ethSrc " + str( ethSrc )
1449 if ethDst:
1450 cmd += " --ethDst " + str( ethDst )
1451 if bandwidth:
1452 cmd += " --bandwidth " + str( bandwidth )
1453 if lambdaAlloc:
1454 cmd += " --lambda "
1455 if ipProto:
1456 cmd += " --ipProto " + str( ipProto )
1457 if ipSrc:
1458 cmd += " --ipSrc " + str( ipSrc )
1459 if ipDst:
1460 cmd += " --ipDst " + str( ipDst )
1461 if tcpSrc:
1462 cmd += " --tcpSrc " + str( tcpSrc )
1463 if tcpDst:
1464 cmd += " --tcpDst " + str( tcpDst )
1465 if setEthSrc:
1466 cmd += " --setEthSrc " + str( setEthSrc )
1467 if setEthDst:
1468 cmd += " --setEthDst " + str( setEthDst )
1469 if vlanId:
1470 cmd += " -v " + str( vlanId )
1471 if setVlan:
1472 cmd += " --setVlan " + str( setVlan )
shahshreyad0c80432014-12-04 16:56:05 -08001473
kelvin8ec71442015-01-15 16:57:00 -08001474 # Check whether the user appended the port
1475 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001476
1477 if portIngressList is None:
1478 for ingressDevice in ingressDeviceList:
1479 if "/" in ingressDevice:
1480 cmd += " " + str( ingressDevice )
1481 else:
1482 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001483 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001484 # TODO: perhaps more meaningful return
1485 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001486 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001487 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001488 for ingressDevice, portIngress in zip( ingressDeviceList,
1489 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001490 cmd += " " + \
1491 str( ingressDevice ) + "/" +\
1492 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001493 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001494 main.log.error( "Device list and port list does not " +
1495 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001496 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 if "/" in egressDevice:
1498 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001499 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001501 main.log.error( "You must specify " +
1502 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001503 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001504
kelvin8ec71442015-01-15 16:57:00 -08001505 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 str( egressDevice ) + "/" +\
1507 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001508 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001509 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001510 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001511 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001512 main.log.error( "Error in adding multipoint-to-singlepoint " +
1513 "intent" )
1514 return None
shahshreyad0c80432014-12-04 16:56:05 -08001515 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001516 match = re.search('id=0x([\da-f]+),', handle)
1517 if match:
1518 return match.group()[3:-1]
1519 else:
1520 main.log.error( "Error, intent ID not found" )
1521 return None
Jon Hallc6793552016-01-19 14:18:37 -08001522 except AssertionError:
1523 main.log.exception( "" )
1524 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001525 except TypeError:
1526 main.log.exception( self.name + ": Object not as expected" )
1527 return None
1528 except pexpect.EOF:
1529 main.log.error( self.name + ": EOF exception found" )
1530 main.log.error( self.name + ": " + self.handle.before )
1531 main.cleanup()
1532 main.exit()
1533 except Exception:
1534 main.log.exception( self.name + ": Uncaught exception!" )
1535 main.cleanup()
1536 main.exit()
1537
1538 def addSinglepointToMultipointIntent(
1539 self,
1540 ingressDevice,
1541 egressDeviceList,
1542 portIngress="",
1543 portEgressList=None,
1544 ethType="",
1545 ethSrc="",
1546 ethDst="",
1547 bandwidth="",
1548 lambdaAlloc=False,
1549 ipProto="",
1550 ipSrc="",
1551 ipDst="",
1552 tcpSrc="",
1553 tcpDst="",
1554 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001555 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001556 vlanId="",
1557 setVlan="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001558 """
1559 Note:
1560 This function assumes the format of all egress devices
1561 is same. That is, all egress devices include port numbers
1562 with a "/" or all egress devices could specify device
1563 ids and port numbers seperately.
1564 Required:
1565 * EgressDeviceList: List of device ids of egress device
1566 ( Atleast 2 eress devices required in the list )
1567 * ingressDevice: device id of ingress device
1568 Optional:
1569 * ethType: specify ethType
1570 * ethSrc: specify ethSrc ( i.e. src mac addr )
1571 * ethDst: specify ethDst ( i.e. dst mac addr )
1572 * bandwidth: specify bandwidth capacity of link
1573 * lambdaAlloc: if True, intent will allocate lambda
1574 for the specified intent
1575 * ipProto: specify ip protocol
1576 * ipSrc: specify ip source address
1577 * ipDst: specify ip destination address
1578 * tcpSrc: specify tcp source port
1579 * tcpDst: specify tcp destination port
1580 * setEthSrc: action to Rewrite Source MAC Address
1581 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001582 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001583 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001584 Description:
1585 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1586 specifying device id's and optional fields
1587 Returns:
1588 A string of the intent id or None on error
1589
1590 NOTE: This function may change depending on the
1591 options developers provide for singlepoint-to-multipoint
1592 intent via cli
1593 """
1594 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001595 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001596
Jeremy Songsterff553672016-05-12 17:06:23 -07001597 if ethType:
1598 cmd += " --ethType " + str( ethType )
1599 if ethSrc:
1600 cmd += " --ethSrc " + str( ethSrc )
1601 if ethDst:
1602 cmd += " --ethDst " + str( ethDst )
1603 if bandwidth:
1604 cmd += " --bandwidth " + str( bandwidth )
1605 if lambdaAlloc:
1606 cmd += " --lambda "
1607 if ipProto:
1608 cmd += " --ipProto " + str( ipProto )
1609 if ipSrc:
1610 cmd += " --ipSrc " + str( ipSrc )
1611 if ipDst:
1612 cmd += " --ipDst " + str( ipDst )
1613 if tcpSrc:
1614 cmd += " --tcpSrc " + str( tcpSrc )
1615 if tcpDst:
1616 cmd += " --tcpDst " + str( tcpDst )
1617 if setEthSrc:
1618 cmd += " --setEthSrc " + str( setEthSrc )
1619 if setEthDst:
1620 cmd += " --setEthDst " + str( setEthDst )
1621 if vlanId:
1622 cmd += " -v " + str( vlanId )
1623 if setVlan:
1624 cmd += " --setVlan " + str( setVlan )
kelvin-onlabb9408212015-04-01 13:34:04 -07001625
1626 # Check whether the user appended the port
1627 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001628
kelvin-onlabb9408212015-04-01 13:34:04 -07001629 if "/" in ingressDevice:
1630 cmd += " " + str( ingressDevice )
1631 else:
1632 if not portIngress:
1633 main.log.error( "You must specify " +
1634 "the Ingress port" )
1635 return main.FALSE
1636
1637 cmd += " " +\
1638 str( ingressDevice ) + "/" +\
1639 str( portIngress )
1640
1641 if portEgressList is None:
1642 for egressDevice in egressDeviceList:
1643 if "/" in egressDevice:
1644 cmd += " " + str( egressDevice )
1645 else:
1646 main.log.error( "You must specify " +
1647 "the egress port" )
1648 # TODO: perhaps more meaningful return
1649 return main.FALSE
1650 else:
1651 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001652 for egressDevice, portEgress in zip( egressDeviceList,
1653 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 cmd += " " + \
1655 str( egressDevice ) + "/" +\
1656 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001657 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001658 main.log.error( "Device list and port list does not " +
1659 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001660 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001661 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001662 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001663 # If error, return error message
1664 if re.search( "Error", handle ):
1665 main.log.error( "Error in adding singlepoint-to-multipoint " +
1666 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001667 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001668 else:
1669 match = re.search('id=0x([\da-f]+),', handle)
1670 if match:
1671 return match.group()[3:-1]
1672 else:
1673 main.log.error( "Error, intent ID not found" )
1674 return None
Jon Hallc6793552016-01-19 14:18:37 -08001675 except AssertionError:
1676 main.log.exception( "" )
1677 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001678 except TypeError:
1679 main.log.exception( self.name + ": Object not as expected" )
1680 return None
shahshreyad0c80432014-12-04 16:56:05 -08001681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001682 main.log.error( self.name + ": EOF exception found" )
1683 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001684 main.cleanup()
1685 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001686 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001687 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001688 main.cleanup()
1689 main.exit()
1690
Hari Krishna9e232602015-04-13 17:29:08 -07001691 def addMplsIntent(
1692 self,
1693 ingressDevice,
1694 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001695 ingressPort="",
1696 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001697 ethType="",
1698 ethSrc="",
1699 ethDst="",
1700 bandwidth="",
1701 lambdaAlloc=False,
1702 ipProto="",
1703 ipSrc="",
1704 ipDst="",
1705 tcpSrc="",
1706 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001707 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001708 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001709 priority=""):
1710 """
1711 Required:
1712 * ingressDevice: device id of ingress device
1713 * egressDevice: device id of egress device
1714 Optional:
1715 * ethType: specify ethType
1716 * ethSrc: specify ethSrc ( i.e. src mac addr )
1717 * ethDst: specify ethDst ( i.e. dst mac addr )
1718 * bandwidth: specify bandwidth capacity of link
1719 * lambdaAlloc: if True, intent will allocate lambda
1720 for the specified intent
1721 * ipProto: specify ip protocol
1722 * ipSrc: specify ip source address
1723 * ipDst: specify ip destination address
1724 * tcpSrc: specify tcp source port
1725 * tcpDst: specify tcp destination port
1726 * ingressLabel: Ingress MPLS label
1727 * egressLabel: Egress MPLS label
1728 Description:
1729 Adds MPLS intent by
1730 specifying device id's and optional fields
1731 Returns:
1732 A string of the intent id or None on error
1733
1734 NOTE: This function may change depending on the
1735 options developers provide for MPLS
1736 intent via cli
1737 """
1738 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001739 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001740
Jeremy Songsterff553672016-05-12 17:06:23 -07001741 if ethType:
1742 cmd += " --ethType " + str( ethType )
1743 if ethSrc:
1744 cmd += " --ethSrc " + str( ethSrc )
1745 if ethDst:
1746 cmd += " --ethDst " + str( ethDst )
1747 if bandwidth:
1748 cmd += " --bandwidth " + str( bandwidth )
1749 if lambdaAlloc:
1750 cmd += " --lambda "
1751 if ipProto:
1752 cmd += " --ipProto " + str( ipProto )
1753 if ipSrc:
1754 cmd += " --ipSrc " + str( ipSrc )
1755 if ipDst:
1756 cmd += " --ipDst " + str( ipDst )
1757 if tcpSrc:
1758 cmd += " --tcpSrc " + str( tcpSrc )
1759 if tcpDst:
1760 cmd += " --tcpDst " + str( tcpDst )
1761 if ingressLabel:
1762 cmd += " --ingressLabel " + str( ingressLabel )
1763 if egressLabel:
1764 cmd += " --egressLabel " + str( egressLabel )
1765 if priority:
1766 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001767
1768 # Check whether the user appended the port
1769 # or provided it as an input
1770 if "/" in ingressDevice:
1771 cmd += " " + str( ingressDevice )
1772 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001773 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001774 main.log.error( "You must specify the ingress port" )
1775 return None
1776
1777 cmd += " " + \
1778 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001779 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001780
1781 if "/" in egressDevice:
1782 cmd += " " + str( egressDevice )
1783 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001784 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001785 main.log.error( "You must specify the egress port" )
1786 return None
1787
1788 cmd += " " +\
1789 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001790 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001791
1792 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001793 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001794 # If error, return error message
1795 if re.search( "Error", handle ):
1796 main.log.error( "Error in adding mpls intent" )
1797 return None
1798 else:
1799 # TODO: print out all the options in this message?
1800 main.log.info( "MPLS intent installed between " +
1801 str( ingressDevice ) + " and " +
1802 str( egressDevice ) )
1803 match = re.search('id=0x([\da-f]+),', handle)
1804 if match:
1805 return match.group()[3:-1]
1806 else:
1807 main.log.error( "Error, intent ID not found" )
1808 return None
Jon Hallc6793552016-01-19 14:18:37 -08001809 except AssertionError:
1810 main.log.exception( "" )
1811 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001812 except TypeError:
1813 main.log.exception( self.name + ": Object not as expected" )
1814 return None
1815 except pexpect.EOF:
1816 main.log.error( self.name + ": EOF exception found" )
1817 main.log.error( self.name + ": " + self.handle.before )
1818 main.cleanup()
1819 main.exit()
1820 except Exception:
1821 main.log.exception( self.name + ": Uncaught exception!" )
1822 main.cleanup()
1823 main.exit()
1824
Jon Hallefbd9792015-03-05 16:11:36 -08001825 def removeIntent( self, intentId, app='org.onosproject.cli',
1826 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001827 """
shahshreya1c818fc2015-02-26 13:44:08 -08001828 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001829 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001830 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001831 -p or --purge: Purge the intent from the store after removal
1832
Jon Halle3f39ff2015-01-13 11:50:53 -08001833 Returns:
1834 main.False on error and
1835 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001836 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001837 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001838 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001839 if purge:
1840 cmdStr += " -p"
1841 if sync:
1842 cmdStr += " -s"
1843
1844 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001846 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001847 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001848 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001849 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001850 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001851 # TODO: Should this be main.TRUE
1852 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001853 except AssertionError:
1854 main.log.exception( "" )
1855 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001856 except TypeError:
1857 main.log.exception( self.name + ": Object not as expected" )
1858 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001859 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001860 main.log.error( self.name + ": EOF exception found" )
1861 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001862 main.cleanup()
1863 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001864 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001865 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001866 main.cleanup()
1867 main.exit()
1868
Jeremy42df2e72016-02-23 16:37:46 -08001869 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1870 """
1871 Description:
1872 Remove all the intents
1873 Optional args:-
1874 -s or --sync: Waits for the removal before returning
1875 -p or --purge: Purge the intent from the store after removal
1876 Returns:
1877 Returns main.TRUE if all intents are removed, otherwise returns
1878 main.FALSE; Returns None for exception
1879 """
1880 try:
1881 cmdStr = "remove-intent"
1882 if purge:
1883 cmdStr += " -p"
1884 if sync:
1885 cmdStr += " -s"
1886
1887 cmdStr += " " + app
1888 handle = self.sendline( cmdStr )
1889 assert "Command not found:" not in handle, handle
1890 if re.search( "Error", handle ):
1891 main.log.error( "Error in removing intent" )
1892 return main.FALSE
1893 else:
1894 return main.TRUE
1895 except AssertionError:
1896 main.log.exception( "" )
1897 return None
1898 except TypeError:
1899 main.log.exception( self.name + ": Object not as expected" )
1900 return None
1901 except pexpect.EOF:
1902 main.log.error( self.name + ": EOF exception found" )
1903 main.log.error( self.name + ": " + self.handle.before )
1904 main.cleanup()
1905 main.exit()
1906 except Exception:
1907 main.log.exception( self.name + ": Uncaught exception!" )
1908 main.cleanup()
1909 main.exit()
1910
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001911 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001912 """
1913 Purges all WITHDRAWN Intents
1914 """
1915 try:
1916 cmdStr = "purge-intents"
1917 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001918 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001919 if re.search( "Error", handle ):
1920 main.log.error( "Error in purging intents" )
1921 return main.FALSE
1922 else:
1923 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001924 except AssertionError:
1925 main.log.exception( "" )
1926 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001927 except TypeError:
1928 main.log.exception( self.name + ": Object not as expected" )
1929 return None
1930 except pexpect.EOF:
1931 main.log.error( self.name + ": EOF exception found" )
1932 main.log.error( self.name + ": " + self.handle.before )
1933 main.cleanup()
1934 main.exit()
1935 except Exception:
1936 main.log.exception( self.name + ": Uncaught exception!" )
1937 main.cleanup()
1938 main.exit()
1939
kelvin-onlabd3b64892015-01-20 13:26:24 -08001940 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001941 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001942 NOTE: This method should be used after installing application:
1943 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001944 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001945 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001946 Description:
1947 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001948 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001949 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001950 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001951 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001952 cmdStr += " -j"
1953 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001954 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001955 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001956 except AssertionError:
1957 main.log.exception( "" )
1958 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001959 except TypeError:
1960 main.log.exception( self.name + ": Object not as expected" )
1961 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001963 main.log.error( self.name + ": EOF exception found" )
1964 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001965 main.cleanup()
1966 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001968 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001969 main.cleanup()
1970 main.exit()
1971
pingping-lin54b03372015-08-13 14:43:10 -07001972 def ipv4RouteNumber( self ):
1973 """
1974 NOTE: This method should be used after installing application:
1975 onos-app-sdnip
1976 Description:
1977 Obtain the total IPv4 routes number in the system
1978 """
1979 try:
1980 cmdStr = "routes -s -j"
1981 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001982 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001983 jsonResult = json.loads( handle )
1984 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001985 except AssertionError:
1986 main.log.exception( "" )
1987 return None
1988 except ( TypeError, ValueError ):
1989 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001990 return None
1991 except pexpect.EOF:
1992 main.log.error( self.name + ": EOF exception found" )
1993 main.log.error( self.name + ": " + self.handle.before )
1994 main.cleanup()
1995 main.exit()
1996 except Exception:
1997 main.log.exception( self.name + ": Uncaught exception!" )
1998 main.cleanup()
1999 main.exit()
2000
pingping-lin8244a3b2015-09-16 13:36:56 -07002001 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002002 """
andrewonlabe6745342014-10-17 14:29:13 -04002003 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002004 Obtain intents from the ONOS cli.
2005 Optional:
2006 * jsonFormat: Enable output formatting in json, default to True
2007 * summary: Whether only output the intent summary, defaults to False
2008 * type: Only output a certain type of intent. This options is valid
2009 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002010 """
andrewonlabe6745342014-10-17 14:29:13 -04002011 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002012 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002013 if summary:
2014 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002015 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002016 cmdStr += " -j"
2017 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002018 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002019 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002020 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002021 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002022 else:
Jon Hallff566d52016-01-15 14:45:36 -08002023 intentType = ""
2024 # IF we want the summary of a specific intent type
2025 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002026 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002027 if intentType in jsonResult.keys():
2028 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002029 else:
Jon Hallff566d52016-01-15 14:45:36 -08002030 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002031 return handle
2032 else:
2033 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002034 except AssertionError:
2035 main.log.exception( "" )
2036 return None
2037 except ( TypeError, ValueError ):
2038 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002039 return None
2040 except pexpect.EOF:
2041 main.log.error( self.name + ": EOF exception found" )
2042 main.log.error( self.name + ": " + self.handle.before )
2043 main.cleanup()
2044 main.exit()
2045 except Exception:
2046 main.log.exception( self.name + ": Uncaught exception!" )
2047 main.cleanup()
2048 main.exit()
2049
kelvin-onlab54400a92015-02-26 18:05:51 -08002050 def getIntentState(self, intentsId, intentsJson=None):
2051 """
You Wangfdcbfc42016-05-16 12:16:53 -07002052 Description:
2053 Gets intent state. Accepts a single intent ID (string type) or a
2054 list of intent IDs.
2055 Parameters:
2056 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002057 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002058 Returns:
2059 Returns the state (string type) of the ID if a single intent ID is
2060 accepted.
2061 Returns a list of dictionaries if a list of intent IDs is accepted,
2062 and each dictionary maps 'id' to the Intent ID and 'state' to
2063 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002064 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002065 try:
2066 state = "State is Undefined"
2067 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002068 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002069 else:
Jon Hallc6793552016-01-19 14:18:37 -08002070 rawJson = intentsJson
2071 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002072 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002073 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002074 if intentsId == intent[ 'id' ]:
2075 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002076 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002077 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2078 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002079 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002080 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002081 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002082 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002083 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002084 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002085 if intentsId[ i ] == intents[ 'id' ]:
2086 stateDict[ 'state' ] = intents[ 'state' ]
2087 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002088 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 break
Jon Hallefbd9792015-03-05 16:11:36 -08002090 if len( intentsId ) != len( dictList ):
2091 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002092 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002093 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002094 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002095 return None
Jon Hallc6793552016-01-19 14:18:37 -08002096 except ( TypeError, ValueError ):
2097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002098 return None
2099 except pexpect.EOF:
2100 main.log.error( self.name + ": EOF exception found" )
2101 main.log.error( self.name + ": " + self.handle.before )
2102 main.cleanup()
2103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002104 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002105 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002106 main.cleanup()
2107 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002108
kelvin-onlabf512e942015-06-08 19:42:59 -07002109 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002110 """
2111 Description:
2112 Check intents state
2113 Required:
2114 intentsId - List of intents ID to be checked
2115 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002116 expectedState - Check the expected state(s) of each intents
2117 state in the list.
2118 *NOTE: You can pass in a list of expected state,
2119 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002120 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002121 Returns main.TRUE only if all intent are the same as expected states
2122 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 """
2124 try:
2125 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002126 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002127 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002128 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002129 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002130 "getting intents state" )
2131 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002132
2133 if isinstance( expectedState, types.StringType ):
2134 for intents in intentsDict:
2135 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002136 main.log.debug( self.name + " : Intent ID - " +
2137 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002138 " actual state = " +
2139 intents.get( 'state' )
2140 + " does not equal expected state = "
2141 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002142 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002143
2144 elif isinstance( expectedState, types.ListType ):
2145 for intents in intentsDict:
2146 if not any( state == intents.get( 'state' ) for state in
2147 expectedState ):
2148 main.log.debug( self.name + " : Intent ID - " +
2149 intents.get( 'id' ) +
2150 " actual state = " +
2151 intents.get( 'state' ) +
2152 " does not equal expected states = "
2153 + str( expectedState ) )
2154 returnValue = main.FALSE
2155
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002156 if returnValue == main.TRUE:
2157 main.log.info( self.name + ": All " +
2158 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002159 " intents are in " + str( expectedState ) +
2160 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002161 return returnValue
2162 except TypeError:
2163 main.log.exception( self.name + ": Object not as expected" )
2164 return None
2165 except pexpect.EOF:
2166 main.log.error( self.name + ": EOF exception found" )
2167 main.log.error( self.name + ": " + self.handle.before )
2168 main.cleanup()
2169 main.exit()
2170 except Exception:
2171 main.log.exception( self.name + ": Uncaught exception!" )
2172 main.cleanup()
2173 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002174
You Wang66518af2016-05-16 15:32:59 -07002175 def compareIntent( self, intentDict ):
2176 """
2177 Description:
2178 Compare the intent ids and states provided in the argument with all intents in ONOS
2179 Return:
2180 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2181 Arguments:
2182 intentDict: a dictionary which maps intent ids to intent states
2183 """
2184 try:
2185 intentsRaw = self.intents()
2186 intentsJson = json.loads( intentsRaw )
2187 intentDictONOS = {}
2188 for intent in intentsJson:
2189 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2190 if len( intentDict ) != len( intentDictONOS ):
2191 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2192 str( len( intentDict ) ) + " expected and " +
2193 str( len( intentDictONOS ) ) + " actual" )
2194 return main.FALSE
2195 returnValue = main.TRUE
2196 for intentID in intentDict.keys():
2197 if not intentID in intentDictONOS.keys():
2198 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2199 returnValue = main.FALSE
2200 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2201 main.log.debug( self.name + ": intent ID - " + intentID +
2202 " expected state is " + intentDict[ intentID ] +
2203 " but actual state is " + intentDictONOS[ intentID ] )
2204 returnValue = main.FALSE
2205 if returnValue == main.TRUE:
2206 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2207 return returnValue
2208 except ( TypeError, ValueError ):
2209 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002210 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002211 except pexpect.EOF:
2212 main.log.error( self.name + ": EOF exception found" )
2213 main.log.error( self.name + ": " + self.handle.before )
2214 main.cleanup()
2215 main.exit()
2216 except Exception:
2217 main.log.exception( self.name + ": Uncaught exception!" )
2218 main.cleanup()
2219 main.exit()
2220
GlennRCed771242016-01-13 17:02:47 -08002221 def checkIntentSummary( self, timeout=60 ):
2222 """
2223 Description:
2224 Check the number of installed intents.
2225 Optional:
2226 timeout - the timeout for pexcept
2227 Return:
2228 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2229 , otherwise, returns main.FALSE.
2230 """
2231
2232 try:
2233 cmd = "intents -s -j"
2234
2235 # Check response if something wrong
2236 response = self.sendline( cmd, timeout=timeout )
2237 if response == None:
2238 return main.False
2239 response = json.loads( response )
2240
2241 # get total and installed number, see if they are match
2242 allState = response.get( 'all' )
2243 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002244 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002245 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002246 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002247 return main.FALSE
2248
Jon Hallc6793552016-01-19 14:18:37 -08002249 except ( TypeError, ValueError ):
2250 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002251 return None
2252 except pexpect.EOF:
2253 main.log.error( self.name + ": EOF exception found" )
2254 main.log.error( self.name + ": " + self.handle.before )
2255 main.cleanup()
2256 main.exit()
2257 except Exception:
2258 main.log.exception( self.name + ": Uncaught exception!" )
2259 main.cleanup()
2260 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002261 except pexpect.TIMEOUT:
2262 main.log.error( self.name + ": ONOS timeout" )
2263 return None
GlennRCed771242016-01-13 17:02:47 -08002264
YPZhangebf9eb52016-05-12 15:20:24 -07002265 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002266 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002267 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002268 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002269 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002270 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002271 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002272 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002273 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002274 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002275 cmdStr += " -j "
2276 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002277 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002278 assert "Command not found:" not in handle, handle
2279 if re.search( "Error:", handle ):
2280 main.log.error( self.name + ": flows() response: " +
2281 str( handle ) )
2282 return handle
2283 except AssertionError:
2284 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002285 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002286 except TypeError:
2287 main.log.exception( self.name + ": Object not as expected" )
2288 return None
Jon Hallc6793552016-01-19 14:18:37 -08002289 except pexpect.TIMEOUT:
2290 main.log.error( self.name + ": ONOS timeout" )
2291 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002292 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002293 main.log.error( self.name + ": EOF exception found" )
2294 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002295 main.cleanup()
2296 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002297 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002298 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002299 main.cleanup()
2300 main.exit()
2301
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002302 def checkFlowCount(self, min=0, timeout=60 ):
2303 count = int(self.getTotalFlowsNum( timeout=timeout ))
2304 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002305
YPZhangebf9eb52016-05-12 15:20:24 -07002306 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002307 """
2308 Description:
GlennRCed771242016-01-13 17:02:47 -08002309 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002310 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2311 if the count of those states is 0, which means all current flows
2312 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002313 Optional:
GlennRCed771242016-01-13 17:02:47 -08002314 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002315 Return:
2316 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002317 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002318 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002319 """
2320 try:
GlennRCed771242016-01-13 17:02:47 -08002321 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2322 checkedStates = []
2323 statesCount = [0, 0, 0, 0]
2324 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002325 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002326 if rawFlows:
2327 # if we didn't get flows or flows function return None, we should return
2328 # main.Flase
2329 checkedStates.append( json.loads( rawFlows ) )
2330 else:
2331 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002332 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002333 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002334 try:
2335 statesCount[i] += int( c.get( "flowCount" ) )
2336 except TypeError:
2337 main.log.exception( "Json object not as expected" )
2338 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002339
GlennRCed771242016-01-13 17:02:47 -08002340 # We want to count PENDING_ADD if isPENDING is true
2341 if isPENDING:
2342 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2343 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002344 else:
GlennRCed771242016-01-13 17:02:47 -08002345 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2346 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002347 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002348 except ( TypeError, ValueError ):
2349 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002350 return None
YPZhang240842b2016-05-17 12:00:50 -07002351
2352 except AssertionError:
2353 main.log.exception( "" )
2354 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002355 except pexpect.EOF:
2356 main.log.error( self.name + ": EOF exception found" )
2357 main.log.error( self.name + ": " + self.handle.before )
2358 main.cleanup()
2359 main.exit()
2360 except Exception:
2361 main.log.exception( self.name + ": Uncaught exception!" )
2362 main.cleanup()
2363 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002364 except pexpect.TIMEOUT:
2365 main.log.error( self.name + ": ONOS timeout" )
2366 return None
2367
kelvin-onlab4df89f22015-04-13 18:10:23 -07002368
GlennRCed771242016-01-13 17:02:47 -08002369 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002370 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002371 """
andrewonlab87852b02014-11-19 18:44:19 -05002372 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002373 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002374 a specific point-to-point intent definition
2375 Required:
GlennRCed771242016-01-13 17:02:47 -08002376 * ingress: specify source dpid
2377 * egress: specify destination dpid
2378 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002379 Optional:
GlennRCed771242016-01-13 17:02:47 -08002380 * offset: the keyOffset is where the next batch of intents
2381 will be installed
2382 Returns: If failed to push test intents, it will returen None,
2383 if successful, return true.
2384 Timeout expection will return None,
2385 TypeError will return false
2386 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002387 """
andrewonlab87852b02014-11-19 18:44:19 -05002388 try:
GlennRCed771242016-01-13 17:02:47 -08002389 if background:
2390 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002391 else:
GlennRCed771242016-01-13 17:02:47 -08002392 back = ""
2393 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002394 ingress,
2395 egress,
2396 batchSize,
2397 offset,
2398 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002399 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002400 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002401 main.log.info( response )
2402 if response == None:
2403 return None
2404
2405 # TODO: We should handle if there is failure in installation
2406 return main.TRUE
2407
Jon Hallc6793552016-01-19 14:18:37 -08002408 except AssertionError:
2409 main.log.exception( "" )
2410 return None
GlennRCed771242016-01-13 17:02:47 -08002411 except pexpect.TIMEOUT:
2412 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002413 return None
andrewonlab87852b02014-11-19 18:44:19 -05002414 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002415 main.log.error( self.name + ": EOF exception found" )
2416 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002417 main.cleanup()
2418 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002419 except TypeError:
2420 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002421 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002422 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002423 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002424 main.cleanup()
2425 main.exit()
2426
YPZhangebf9eb52016-05-12 15:20:24 -07002427 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002428 """
2429 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002430 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002431 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002432 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002433 """
YPZhange3109a72016-02-02 11:25:37 -08002434
YPZhangb5d3f832016-01-23 22:54:26 -08002435 try:
YPZhange3109a72016-02-02 11:25:37 -08002436 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002437 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002438 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002439
2440 if totalFlows == None:
2441 # if timeout, we will get total number of all flows, and subtract other states
2442 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2443 checkedStates = []
2444 totalFlows = 0
2445 statesCount = [0, 0, 0, 0]
2446
2447 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002448 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002449 totalFlows = int( response.get("flows") )
2450
2451 for s in states:
2452 rawFlows = self.flows( state=s, timeout = timeout )
2453 if rawFlows == None:
2454 # if timeout, return the total flows number from summary command
2455 return totalFlows
2456 checkedStates.append( json.loads( rawFlows ) )
2457
2458 # Calculate ADDED flows number, equal total subtracts others
2459 for i in range( len( states ) ):
2460 for c in checkedStates[i]:
2461 try:
2462 statesCount[i] += int( c.get( "flowCount" ) )
2463 except TypeError:
2464 main.log.exception( "Json object not as expected" )
2465 totalFlows = totalFlows - int( statesCount[i] )
2466 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2467
2468 return totalFlows
2469
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002470 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002471
You Wangd3cb2ce2016-05-16 14:01:24 -07002472 except ( TypeError, ValueError ):
2473 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002474 return None
2475 except pexpect.EOF:
2476 main.log.error( self.name + ": EOF exception found" )
2477 main.log.error( self.name + ": " + self.handle.before )
2478 main.cleanup()
2479 main.exit()
2480 except Exception:
2481 main.log.exception( self.name + ": Uncaught exception!" )
2482 main.cleanup()
2483 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002484 except pexpect.TIMEOUT:
2485 main.log.error( self.name + ": ONOS timeout" )
2486 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002487
YPZhangebf9eb52016-05-12 15:20:24 -07002488 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002489 """
2490 Description:
2491 Get the total number of intents, include every states.
2492 Return:
2493 The number of intents
2494 """
2495 try:
2496 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002497 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002498 if response == None:
2499 return -1
2500 response = json.loads( response )
2501 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002502 except ( TypeError, ValueError ):
2503 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002504 return None
2505 except pexpect.EOF:
2506 main.log.error( self.name + ": EOF exception found" )
2507 main.log.error( self.name + ": " + self.handle.before )
2508 main.cleanup()
2509 main.exit()
2510 except Exception:
2511 main.log.exception( self.name + ": Uncaught exception!" )
2512 main.cleanup()
2513 main.exit()
2514
kelvin-onlabd3b64892015-01-20 13:26:24 -08002515 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002516 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002517 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002518 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002519 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002520 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002521 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002522 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002523 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002524 cmdStr += " -j"
2525 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002526 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002527 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002528 except AssertionError:
2529 main.log.exception( "" )
2530 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002531 except TypeError:
2532 main.log.exception( self.name + ": Object not as expected" )
2533 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002534 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002535 main.log.error( self.name + ": EOF exception found" )
2536 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002537 main.cleanup()
2538 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002539 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002540 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002541 main.cleanup()
2542 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002543
kelvin-onlabd3b64892015-01-20 13:26:24 -08002544 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002545 """
2546 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002547 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002548 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002549 """
andrewonlab867212a2014-10-22 20:13:38 -04002550 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002551 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002552 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002553 cmdStr += " -j"
2554 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002555 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002556 if handle:
2557 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002558 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002559 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002560 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002561 else:
2562 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002563 except AssertionError:
2564 main.log.exception( "" )
2565 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002566 except TypeError:
2567 main.log.exception( self.name + ": Object not as expected" )
2568 return None
andrewonlab867212a2014-10-22 20:13:38 -04002569 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002570 main.log.error( self.name + ": EOF exception found" )
2571 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002572 main.cleanup()
2573 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002574 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002575 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002576 main.cleanup()
2577 main.exit()
2578
kelvin8ec71442015-01-15 16:57:00 -08002579 # Wrapper functions ****************
2580 # Wrapper functions use existing driver
2581 # functions and extends their use case.
2582 # For example, we may use the output of
2583 # a normal driver function, and parse it
2584 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002585
kelvin-onlabd3b64892015-01-20 13:26:24 -08002586 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002587 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002588 Description:
2589 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002590 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002591 try:
kelvin8ec71442015-01-15 16:57:00 -08002592 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002593 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002594 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002595
kelvin8ec71442015-01-15 16:57:00 -08002596 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002597 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2598 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002599 match = re.search('id=0x([\da-f]+),', intents)
2600 if match:
2601 tmpId = match.group()[3:-1]
2602 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002604
Jon Halld4d4b372015-01-28 16:02:41 -08002605 except TypeError:
2606 main.log.exception( self.name + ": Object not as expected" )
2607 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002611 main.cleanup()
2612 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002613 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002614 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002615 main.cleanup()
2616 main.exit()
2617
Jon Hall30b82fa2015-03-04 17:15:43 -08002618 def FlowAddedCount( self, deviceId ):
2619 """
2620 Determine the number of flow rules for the given device id that are
2621 in the added state
2622 """
2623 try:
2624 cmdStr = "flows any " + str( deviceId ) + " | " +\
2625 "grep 'state=ADDED' | wc -l"
2626 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002627 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002628 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002629 except AssertionError:
2630 main.log.exception( "" )
2631 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002632 except pexpect.EOF:
2633 main.log.error( self.name + ": EOF exception found" )
2634 main.log.error( self.name + ": " + self.handle.before )
2635 main.cleanup()
2636 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002637 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002638 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002639 main.cleanup()
2640 main.exit()
2641
kelvin-onlabd3b64892015-01-20 13:26:24 -08002642 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002643 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002644 Use 'devices' function to obtain list of all devices
2645 and parse the result to obtain a list of all device
2646 id's. Returns this list. Returns empty list if no
2647 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002648 List is ordered sequentially
2649
andrewonlab3e15ead2014-10-15 14:21:34 -04002650 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002651 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002652 the ids. By obtaining the list of device ids on the fly,
2653 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002654 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002655 try:
kelvin8ec71442015-01-15 16:57:00 -08002656 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002657 devicesStr = self.devices( jsonFormat=False )
2658 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002659
kelvin-onlabd3b64892015-01-20 13:26:24 -08002660 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002661 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002662 return idList
kelvin8ec71442015-01-15 16:57:00 -08002663
2664 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002665 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002666 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002667 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002668 # Split list further into arguments before and after string
2669 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002670 # append to idList
2671 for arg in tempList:
2672 idList.append( arg.split( "id=" )[ 1 ] )
2673 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002674
Jon Halld4d4b372015-01-28 16:02:41 -08002675 except TypeError:
2676 main.log.exception( self.name + ": Object not as expected" )
2677 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002678 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002679 main.log.error( self.name + ": EOF exception found" )
2680 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002681 main.cleanup()
2682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002683 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002684 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002685 main.cleanup()
2686 main.exit()
2687
kelvin-onlabd3b64892015-01-20 13:26:24 -08002688 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002689 """
andrewonlab7c211572014-10-15 16:45:20 -04002690 Uses 'nodes' function to obtain list of all nodes
2691 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002692 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002693 Returns:
2694 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002695 """
andrewonlab7c211572014-10-15 16:45:20 -04002696 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002697 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002699 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002700 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002702 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002703 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002704 nodesJson = json.loads( nodesStr )
2705 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002706 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002707 except ( TypeError, ValueError ):
2708 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002709 return None
andrewonlab7c211572014-10-15 16:45:20 -04002710 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002711 main.log.error( self.name + ": EOF exception found" )
2712 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002713 main.cleanup()
2714 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002715 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002716 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002717 main.cleanup()
2718 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002719
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002721 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002722 Return the first device from the devices api whose 'id' contains 'dpid'
2723 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002724 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002725 try:
kelvin8ec71442015-01-15 16:57:00 -08002726 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002727 return None
2728 else:
kelvin8ec71442015-01-15 16:57:00 -08002729 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002730 rawDevices = self.devices()
2731 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002732 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002733 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002734 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2735 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002736 return device
2737 return None
Jon Hallc6793552016-01-19 14:18:37 -08002738 except ( TypeError, ValueError ):
2739 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002740 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002741 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002742 main.log.error( self.name + ": EOF exception found" )
2743 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002744 main.cleanup()
2745 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002746 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002747 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002748 main.cleanup()
2749 main.exit()
2750
You Wang24139872016-05-03 11:48:47 -07002751 def getTopology( self, topologyOutput ):
2752 """
2753 Definition:
2754 Loads a json topology output
2755 Return:
2756 topology = current ONOS topology
2757 """
2758 import json
2759 try:
2760 # either onos:topology or 'topology' will work in CLI
2761 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002762 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002763 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002764 except ( TypeError, ValueError ):
2765 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2766 return None
You Wang24139872016-05-03 11:48:47 -07002767 except pexpect.EOF:
2768 main.log.error( self.name + ": EOF exception found" )
2769 main.log.error( self.name + ": " + self.handle.before )
2770 main.cleanup()
2771 main.exit()
2772 except Exception:
2773 main.log.exception( self.name + ": Uncaught exception!" )
2774 main.cleanup()
2775 main.exit()
2776
2777 def checkStatus(
2778 self,
2779 topologyResult,
2780 numoswitch,
2781 numolink,
2782 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002783 """
Jon Hallefbd9792015-03-05 16:11:36 -08002784 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002785 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002786 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002787
You Wang24139872016-05-03 11:48:47 -07002788 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002789 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002790 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002791 logLevel = level to log to.
2792 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002793
Jon Hallefbd9792015-03-05 16:11:36 -08002794 Returns: main.TRUE if the number of switches and links are correct,
2795 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002796 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002797 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002798 try:
You Wang24139872016-05-03 11:48:47 -07002799 topology = self.getTopology( topologyResult )
You Wang85560372016-05-18 10:44:33 -07002800 if topology == {} or topology == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002801 return main.ERROR
2802 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002803 # Is the number of switches is what we expected
2804 devices = topology.get( 'devices', False )
2805 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002806 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002807 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002808 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002809 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002810 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002811 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002812 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002813 output = output + "The number of links and switches match "\
2814 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002815 result = main.TRUE
2816 else:
You Wang24139872016-05-03 11:48:47 -07002817 output = output + \
2818 "The number of links and switches does not match " + \
2819 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002820 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002821 output = output + "\n ONOS sees %i devices" % int( devices )
2822 output = output + " (%i expected) " % int( numoswitch )
2823 output = output + "and %i links " % int( links )
2824 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002825 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002826 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002827 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002828 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002829 else:
You Wang24139872016-05-03 11:48:47 -07002830 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002831 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002832 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002833 main.log.error( self.name + ": EOF exception found" )
2834 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002835 main.cleanup()
2836 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002838 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002839 main.cleanup()
2840 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002841
kelvin-onlabd3b64892015-01-20 13:26:24 -08002842 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002843 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002844 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002845 deviceId must be the id of a device as seen in the onos devices command
2846 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002847 role must be either master, standby, or none
2848
Jon Halle3f39ff2015-01-13 11:50:53 -08002849 Returns:
2850 main.TRUE or main.FALSE based on argument verification and
2851 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002852 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002853 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002854 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002855 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002856 cmdStr = "device-role " +\
2857 str( deviceId ) + " " +\
2858 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002859 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002860 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002861 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002862 if re.search( "Error", handle ):
2863 # end color output to escape any colours
2864 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002865 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002866 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002867 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002868 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002869 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002870 main.log.error( "Invalid 'role' given to device_role(). " +
2871 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002872 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002873 except AssertionError:
2874 main.log.exception( "" )
2875 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002876 except TypeError:
2877 main.log.exception( self.name + ": Object not as expected" )
2878 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002879 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002880 main.log.error( self.name + ": EOF exception found" )
2881 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002882 main.cleanup()
2883 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002884 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002885 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002886 main.cleanup()
2887 main.exit()
2888
kelvin-onlabd3b64892015-01-20 13:26:24 -08002889 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002890 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002891 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002892 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002893 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002894 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002895 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002896 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002897 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002898 cmdStr += " -j"
2899 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002900 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002901 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002902 except AssertionError:
2903 main.log.exception( "" )
2904 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002905 except TypeError:
2906 main.log.exception( self.name + ": Object not as expected" )
2907 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002908 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002909 main.log.error( self.name + ": EOF exception found" )
2910 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002911 main.cleanup()
2912 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002913 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002914 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002915 main.cleanup()
2916 main.exit()
2917
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002919 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002920 CLI command to get the current leader for the Election test application
2921 NOTE: Requires installation of the onos-app-election feature
2922 Returns: Node IP of the leader if one exists
2923 None if none exists
2924 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002925 """
Jon Hall94fd0472014-12-08 11:52:42 -08002926 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002927 cmdStr = "election-test-leader"
2928 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002929 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002930 # Leader
2931 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002932 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002933 nodeSearch = re.search( leaderPattern, response )
2934 if nodeSearch:
2935 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002936 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002937 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002938 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002939 # no leader
2940 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002941 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002942 nullSearch = re.search( nullPattern, response )
2943 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002944 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002945 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002946 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002947 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002949 if re.search( errorPattern, response ):
2950 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002951 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002952 return main.FALSE
2953 else:
Jon Hall390696c2015-05-05 17:13:41 -07002954 main.log.error( "Error in electionTestLeader on " + self.name +
2955 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002956 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002957 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002958 except AssertionError:
2959 main.log.exception( "" )
2960 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002961 except TypeError:
2962 main.log.exception( self.name + ": Object not as expected" )
2963 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002964 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002965 main.log.error( self.name + ": EOF exception found" )
2966 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002967 main.cleanup()
2968 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002969 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002970 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002971 main.cleanup()
2972 main.exit()
2973
kelvin-onlabd3b64892015-01-20 13:26:24 -08002974 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002975 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002976 CLI command to run for leadership of the Election test application.
2977 NOTE: Requires installation of the onos-app-election feature
2978 Returns: Main.TRUE on success
2979 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002980 """
Jon Hall94fd0472014-12-08 11:52:42 -08002981 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 cmdStr = "election-test-run"
2983 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002984 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002985 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002986 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002987 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002988 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002989 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002990 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002991 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002992 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002993 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002994 errorPattern = "Command\snot\sfound"
2995 if re.search( errorPattern, response ):
2996 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002997 return main.FALSE
2998 else:
Jon Hall390696c2015-05-05 17:13:41 -07002999 main.log.error( "Error in electionTestRun on " + self.name +
3000 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003001 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003002 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003003 except AssertionError:
3004 main.log.exception( "" )
3005 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003006 except TypeError:
3007 main.log.exception( self.name + ": Object not as expected" )
3008 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003010 main.log.error( self.name + ": EOF exception found" )
3011 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003012 main.cleanup()
3013 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003014 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003015 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003016 main.cleanup()
3017 main.exit()
3018
kelvin-onlabd3b64892015-01-20 13:26:24 -08003019 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003020 """
Jon Hall94fd0472014-12-08 11:52:42 -08003021 * CLI command to withdraw the local node from leadership election for
3022 * the Election test application.
3023 #NOTE: Requires installation of the onos-app-election feature
3024 Returns: Main.TRUE on success
3025 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003026 """
Jon Hall94fd0472014-12-08 11:52:42 -08003027 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003028 cmdStr = "election-test-withdraw"
3029 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003030 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003031 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003032 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003033 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003034 if re.search( successPattern, response ):
3035 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003036 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003037 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003038 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08003039 errorPattern = "Command\snot\sfound"
3040 if re.search( errorPattern, response ):
3041 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08003042 return main.FALSE
3043 else:
Jon Hall390696c2015-05-05 17:13:41 -07003044 main.log.error( "Error in electionTestWithdraw on " +
3045 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003046 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003047 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003048 except AssertionError:
3049 main.log.exception( "" )
3050 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003051 except TypeError:
3052 main.log.exception( self.name + ": Object not as expected" )
3053 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003054 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003055 main.log.error( self.name + ": EOF exception found" )
3056 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003057 main.cleanup()
3058 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003059 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003060 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003061 main.cleanup()
3062 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003063
kelvin8ec71442015-01-15 16:57:00 -08003064 def getDevicePortsEnabledCount( self, dpid ):
3065 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003066 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003067 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003068 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003069 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003070 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3071 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003072 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003073 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003074 if re.search( "No such device", output ):
3075 main.log.error( "Error in getting ports" )
3076 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003077 return output
Jon Hallc6793552016-01-19 14:18:37 -08003078 except AssertionError:
3079 main.log.exception( "" )
3080 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003081 except TypeError:
3082 main.log.exception( self.name + ": Object not as expected" )
3083 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003084 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003085 main.log.error( self.name + ": EOF exception found" )
3086 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003087 main.cleanup()
3088 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003089 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003090 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003091 main.cleanup()
3092 main.exit()
3093
kelvin8ec71442015-01-15 16:57:00 -08003094 def getDeviceLinksActiveCount( self, dpid ):
3095 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003096 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003097 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003098 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003099 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003100 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3101 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003102 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003103 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003104 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003105 main.log.error( "Error in getting ports " )
3106 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003107 return output
Jon Hallc6793552016-01-19 14:18:37 -08003108 except AssertionError:
3109 main.log.exception( "" )
3110 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003111 except TypeError:
3112 main.log.exception( self.name + ": Object not as expected" )
3113 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003114 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003115 main.log.error( self.name + ": EOF exception found" )
3116 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003117 main.cleanup()
3118 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003119 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003120 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003121 main.cleanup()
3122 main.exit()
3123
kelvin8ec71442015-01-15 16:57:00 -08003124 def getAllIntentIds( self ):
3125 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003126 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003127 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003129 cmdStr = "onos:intents | grep id="
3130 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003131 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003132 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003133 if re.search( "Error", output ):
3134 main.log.error( "Error in getting ports" )
3135 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003136 return output
Jon Hallc6793552016-01-19 14:18:37 -08003137 except AssertionError:
3138 main.log.exception( "" )
3139 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003140 except TypeError:
3141 main.log.exception( self.name + ": Object not as expected" )
3142 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003143 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003144 main.log.error( self.name + ": EOF exception found" )
3145 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003146 main.cleanup()
3147 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003148 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003149 main.log.exception( self.name + ": Uncaught exception!" )
3150 main.cleanup()
3151 main.exit()
3152
Jon Hall73509952015-02-24 16:42:56 -08003153 def intentSummary( self ):
3154 """
Jon Hallefbd9792015-03-05 16:11:36 -08003155 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003156 """
3157 try:
3158 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003159 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003160 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003161 states.append( intent.get( 'state', None ) )
3162 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003163 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003164 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003165 except ( TypeError, ValueError ):
3166 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003167 return None
3168 except pexpect.EOF:
3169 main.log.error( self.name + ": EOF exception found" )
3170 main.log.error( self.name + ": " + self.handle.before )
3171 main.cleanup()
3172 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003173 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003174 main.log.exception( self.name + ": Uncaught exception!" )
3175 main.cleanup()
3176 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003177
Jon Hall61282e32015-03-19 11:34:11 -07003178 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003179 """
3180 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003181 Optional argument:
3182 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003183 """
Jon Hall63604932015-02-26 17:09:50 -08003184 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003185 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003186 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003187 cmdStr += " -j"
3188 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003189 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003190 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003191 return output
Jon Hallc6793552016-01-19 14:18:37 -08003192 except AssertionError:
3193 main.log.exception( "" )
3194 return None
Jon Hall63604932015-02-26 17:09:50 -08003195 except TypeError:
3196 main.log.exception( self.name + ": Object not as expected" )
3197 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003198 except pexpect.EOF:
3199 main.log.error( self.name + ": EOF exception found" )
3200 main.log.error( self.name + ": " + self.handle.before )
3201 main.cleanup()
3202 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003203 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003204 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003205 main.cleanup()
3206 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003207
acsmarsa4a4d1e2015-07-10 16:01:24 -07003208 def leaderCandidates( self, jsonFormat=True ):
3209 """
3210 Returns the output of the leaders -c command.
3211 Optional argument:
3212 * jsonFormat - boolean indicating if you want output in json
3213 """
3214 try:
3215 cmdStr = "onos:leaders -c"
3216 if jsonFormat:
3217 cmdStr += " -j"
3218 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003219 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003220 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003221 return output
Jon Hallc6793552016-01-19 14:18:37 -08003222 except AssertionError:
3223 main.log.exception( "" )
3224 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003225 except TypeError:
3226 main.log.exception( self.name + ": Object not as expected" )
3227 return None
3228 except pexpect.EOF:
3229 main.log.error( self.name + ": EOF exception found" )
3230 main.log.error( self.name + ": " + self.handle.before )
3231 main.cleanup()
3232 main.exit()
3233 except Exception:
3234 main.log.exception( self.name + ": Uncaught exception!" )
3235 main.cleanup()
3236 main.exit()
3237
Jon Hallc6793552016-01-19 14:18:37 -08003238 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003239 """
3240 Returns a list in format [leader,candidate1,candidate2,...] for a given
3241 topic parameter and an empty list if the topic doesn't exist
3242 If no leader is elected leader in the returned list will be "none"
3243 Returns None if there is a type error processing the json object
3244 """
3245 try:
Jon Hall6e709752016-02-01 13:38:46 -08003246 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003247 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003248 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003249 assert "Command not found:" not in rawOutput, rawOutput
3250 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003251 results = []
3252 for dict in output:
3253 if dict["topic"] == topic:
3254 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003255 candidates = re.split( ", ", dict["candidates"][1:-1] )
3256 results.append( leader )
3257 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003258 return results
Jon Hallc6793552016-01-19 14:18:37 -08003259 except AssertionError:
3260 main.log.exception( "" )
3261 return None
3262 except ( TypeError, ValueError ):
3263 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003264 return None
3265 except pexpect.EOF:
3266 main.log.error( self.name + ": EOF exception found" )
3267 main.log.error( self.name + ": " + self.handle.before )
3268 main.cleanup()
3269 main.exit()
3270 except Exception:
3271 main.log.exception( self.name + ": Uncaught exception!" )
3272 main.cleanup()
3273 main.exit()
3274
Jon Hall61282e32015-03-19 11:34:11 -07003275 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003276 """
3277 Returns the output of the intent Pending map.
3278 """
Jon Hall63604932015-02-26 17:09:50 -08003279 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003280 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003281 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003282 cmdStr += " -j"
3283 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003284 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003285 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003286 return output
Jon Hallc6793552016-01-19 14:18:37 -08003287 except AssertionError:
3288 main.log.exception( "" )
3289 return None
Jon Hall63604932015-02-26 17:09:50 -08003290 except TypeError:
3291 main.log.exception( self.name + ": Object not as expected" )
3292 return None
3293 except pexpect.EOF:
3294 main.log.error( self.name + ": EOF exception found" )
3295 main.log.error( self.name + ": " + self.handle.before )
3296 main.cleanup()
3297 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003298 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003299 main.log.exception( self.name + ": Uncaught exception!" )
3300 main.cleanup()
3301 main.exit()
3302
Jon Hall61282e32015-03-19 11:34:11 -07003303 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003304 """
3305 Returns the output of the raft partitions command for ONOS.
3306 """
Jon Hall61282e32015-03-19 11:34:11 -07003307 # Sample JSON
3308 # {
3309 # "leader": "tcp://10.128.30.11:7238",
3310 # "members": [
3311 # "tcp://10.128.30.11:7238",
3312 # "tcp://10.128.30.17:7238",
3313 # "tcp://10.128.30.13:7238",
3314 # ],
3315 # "name": "p1",
3316 # "term": 3
3317 # },
Jon Hall63604932015-02-26 17:09:50 -08003318 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003319 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003320 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003321 cmdStr += " -j"
3322 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003323 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003324 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003325 return output
Jon Hallc6793552016-01-19 14:18:37 -08003326 except AssertionError:
3327 main.log.exception( "" )
3328 return None
Jon Hall63604932015-02-26 17:09:50 -08003329 except TypeError:
3330 main.log.exception( self.name + ": Object not as expected" )
3331 return None
3332 except pexpect.EOF:
3333 main.log.error( self.name + ": EOF exception found" )
3334 main.log.error( self.name + ": " + self.handle.before )
3335 main.cleanup()
3336 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003337 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003338 main.log.exception( self.name + ": Uncaught exception!" )
3339 main.cleanup()
3340 main.exit()
3341
Jon Hallbe379602015-03-24 13:39:32 -07003342 def apps( self, jsonFormat=True ):
3343 """
3344 Returns the output of the apps command for ONOS. This command lists
3345 information about installed ONOS applications
3346 """
3347 # Sample JSON object
3348 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3349 # "description":"ONOS OpenFlow protocol southbound providers",
3350 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3351 # "features":"[onos-openflow]","state":"ACTIVE"}]
3352 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003353 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003354 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003355 cmdStr += " -j"
3356 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003357 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003358 assert "Command not found:" not in output, output
3359 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003360 return output
Jon Hallbe379602015-03-24 13:39:32 -07003361 # FIXME: look at specific exceptions/Errors
3362 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003363 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003364 return None
3365 except TypeError:
3366 main.log.exception( self.name + ": Object not as expected" )
3367 return None
3368 except pexpect.EOF:
3369 main.log.error( self.name + ": EOF exception found" )
3370 main.log.error( self.name + ": " + self.handle.before )
3371 main.cleanup()
3372 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003373 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003374 main.log.exception( self.name + ": Uncaught exception!" )
3375 main.cleanup()
3376 main.exit()
3377
Jon Hall146f1522015-03-24 15:33:24 -07003378 def appStatus( self, appName ):
3379 """
3380 Uses the onos:apps cli command to return the status of an application.
3381 Returns:
3382 "ACTIVE" - If app is installed and activated
3383 "INSTALLED" - If app is installed and deactivated
3384 "UNINSTALLED" - If app is not installed
3385 None - on error
3386 """
Jon Hall146f1522015-03-24 15:33:24 -07003387 try:
3388 if not isinstance( appName, types.StringType ):
3389 main.log.error( self.name + ".appStatus(): appName must be" +
3390 " a string" )
3391 return None
3392 output = self.apps( jsonFormat=True )
3393 appsJson = json.loads( output )
3394 state = None
3395 for app in appsJson:
3396 if appName == app.get('name'):
3397 state = app.get('state')
3398 break
3399 if state == "ACTIVE" or state == "INSTALLED":
3400 return state
3401 elif state is None:
3402 return "UNINSTALLED"
3403 elif state:
3404 main.log.error( "Unexpected state from 'onos:apps': " +
3405 str( state ) )
3406 return state
Jon Hallc6793552016-01-19 14:18:37 -08003407 except ( TypeError, ValueError ):
3408 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003409 return None
3410 except pexpect.EOF:
3411 main.log.error( self.name + ": EOF exception found" )
3412 main.log.error( self.name + ": " + self.handle.before )
3413 main.cleanup()
3414 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003415 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003416 main.log.exception( self.name + ": Uncaught exception!" )
3417 main.cleanup()
3418 main.exit()
3419
Jon Hallbe379602015-03-24 13:39:32 -07003420 def app( self, appName, option ):
3421 """
3422 Interacts with the app command for ONOS. This command manages
3423 application inventory.
3424 """
Jon Hallbe379602015-03-24 13:39:32 -07003425 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003426 # Validate argument types
3427 valid = True
3428 if not isinstance( appName, types.StringType ):
3429 main.log.error( self.name + ".app(): appName must be a " +
3430 "string" )
3431 valid = False
3432 if not isinstance( option, types.StringType ):
3433 main.log.error( self.name + ".app(): option must be a string" )
3434 valid = False
3435 if not valid:
3436 return main.FALSE
3437 # Validate Option
3438 option = option.lower()
3439 # NOTE: Install may become a valid option
3440 if option == "activate":
3441 pass
3442 elif option == "deactivate":
3443 pass
3444 elif option == "uninstall":
3445 pass
3446 else:
3447 # Invalid option
3448 main.log.error( "The ONOS app command argument only takes " +
3449 "the values: (activate|deactivate|uninstall)" +
3450 "; was given '" + option + "'")
3451 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003452 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003453 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003454 if "Error executing command" in output:
3455 main.log.error( "Error in processing onos:app command: " +
3456 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003457 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003458 elif "No such application" in output:
3459 main.log.error( "The application '" + appName +
3460 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003461 return main.FALSE
3462 elif "Command not found:" in output:
3463 main.log.error( "Error in processing onos:app command: " +
3464 str( output ) )
3465 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003466 elif "Unsupported command:" in output:
3467 main.log.error( "Incorrect command given to 'app': " +
3468 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003469 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003470 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003471 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003472 return main.TRUE
3473 except TypeError:
3474 main.log.exception( self.name + ": Object not as expected" )
3475 return main.ERROR
3476 except pexpect.EOF:
3477 main.log.error( self.name + ": EOF exception found" )
3478 main.log.error( self.name + ": " + self.handle.before )
3479 main.cleanup()
3480 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003481 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003482 main.log.exception( self.name + ": Uncaught exception!" )
3483 main.cleanup()
3484 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003485
Jon Hallbd16b922015-03-26 17:53:15 -07003486 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003487 """
3488 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003489 appName is the hierarchical app name, not the feature name
3490 If check is True, method will check the status of the app after the
3491 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003492 Returns main.TRUE if the command was successfully sent
3493 main.FALSE if the cli responded with an error or given
3494 incorrect input
3495 """
3496 try:
3497 if not isinstance( appName, types.StringType ):
3498 main.log.error( self.name + ".activateApp(): appName must be" +
3499 " a string" )
3500 return main.FALSE
3501 status = self.appStatus( appName )
3502 if status == "INSTALLED":
3503 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003504 if check and response == main.TRUE:
3505 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003506 status = self.appStatus( appName )
3507 if status == "ACTIVE":
3508 return main.TRUE
3509 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003510 main.log.debug( "The state of application " +
3511 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003512 time.sleep( 1 )
3513 return main.FALSE
3514 else: # not 'check' or command didn't succeed
3515 return response
Jon Hall146f1522015-03-24 15:33:24 -07003516 elif status == "ACTIVE":
3517 return main.TRUE
3518 elif status == "UNINSTALLED":
3519 main.log.error( self.name + ": Tried to activate the " +
3520 "application '" + appName + "' which is not " +
3521 "installed." )
3522 else:
3523 main.log.error( "Unexpected return value from appStatus: " +
3524 str( status ) )
3525 return main.ERROR
3526 except TypeError:
3527 main.log.exception( self.name + ": Object not as expected" )
3528 return main.ERROR
3529 except pexpect.EOF:
3530 main.log.error( self.name + ": EOF exception found" )
3531 main.log.error( self.name + ": " + self.handle.before )
3532 main.cleanup()
3533 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003534 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003535 main.log.exception( self.name + ": Uncaught exception!" )
3536 main.cleanup()
3537 main.exit()
3538
Jon Hallbd16b922015-03-26 17:53:15 -07003539 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003540 """
3541 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003542 appName is the hierarchical app name, not the feature name
3543 If check is True, method will check the status of the app after the
3544 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003545 Returns main.TRUE if the command was successfully sent
3546 main.FALSE if the cli responded with an error or given
3547 incorrect input
3548 """
3549 try:
3550 if not isinstance( appName, types.StringType ):
3551 main.log.error( self.name + ".deactivateApp(): appName must " +
3552 "be a string" )
3553 return main.FALSE
3554 status = self.appStatus( appName )
3555 if status == "INSTALLED":
3556 return main.TRUE
3557 elif status == "ACTIVE":
3558 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003559 if check and response == main.TRUE:
3560 for i in range(10): # try 10 times then give up
3561 status = self.appStatus( appName )
3562 if status == "INSTALLED":
3563 return main.TRUE
3564 else:
3565 time.sleep( 1 )
3566 return main.FALSE
3567 else: # not check or command didn't succeed
3568 return response
Jon Hall146f1522015-03-24 15:33:24 -07003569 elif status == "UNINSTALLED":
3570 main.log.warn( self.name + ": Tried to deactivate the " +
3571 "application '" + appName + "' which is not " +
3572 "installed." )
3573 return main.TRUE
3574 else:
3575 main.log.error( "Unexpected return value from appStatus: " +
3576 str( status ) )
3577 return main.ERROR
3578 except TypeError:
3579 main.log.exception( self.name + ": Object not as expected" )
3580 return main.ERROR
3581 except pexpect.EOF:
3582 main.log.error( self.name + ": EOF exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
3584 main.cleanup()
3585 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003586 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003587 main.log.exception( self.name + ": Uncaught exception!" )
3588 main.cleanup()
3589 main.exit()
3590
Jon Hallbd16b922015-03-26 17:53:15 -07003591 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003592 """
3593 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003594 appName is the hierarchical app name, not the feature name
3595 If check is True, method will check the status of the app after the
3596 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003597 Returns main.TRUE if the command was successfully sent
3598 main.FALSE if the cli responded with an error or given
3599 incorrect input
3600 """
3601 # TODO: check with Thomas about the state machine for apps
3602 try:
3603 if not isinstance( appName, types.StringType ):
3604 main.log.error( self.name + ".uninstallApp(): appName must " +
3605 "be a string" )
3606 return main.FALSE
3607 status = self.appStatus( appName )
3608 if status == "INSTALLED":
3609 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003610 if check and response == main.TRUE:
3611 for i in range(10): # try 10 times then give up
3612 status = self.appStatus( appName )
3613 if status == "UNINSTALLED":
3614 return main.TRUE
3615 else:
3616 time.sleep( 1 )
3617 return main.FALSE
3618 else: # not check or command didn't succeed
3619 return response
Jon Hall146f1522015-03-24 15:33:24 -07003620 elif status == "ACTIVE":
3621 main.log.warn( self.name + ": Tried to uninstall the " +
3622 "application '" + appName + "' which is " +
3623 "currently active." )
3624 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003625 if check and response == main.TRUE:
3626 for i in range(10): # try 10 times then give up
3627 status = self.appStatus( appName )
3628 if status == "UNINSTALLED":
3629 return main.TRUE
3630 else:
3631 time.sleep( 1 )
3632 return main.FALSE
3633 else: # not check or command didn't succeed
3634 return response
Jon Hall146f1522015-03-24 15:33:24 -07003635 elif status == "UNINSTALLED":
3636 return main.TRUE
3637 else:
3638 main.log.error( "Unexpected return value from appStatus: " +
3639 str( status ) )
3640 return main.ERROR
3641 except TypeError:
3642 main.log.exception( self.name + ": Object not as expected" )
3643 return main.ERROR
3644 except pexpect.EOF:
3645 main.log.error( self.name + ": EOF exception found" )
3646 main.log.error( self.name + ": " + self.handle.before )
3647 main.cleanup()
3648 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003649 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003650 main.log.exception( self.name + ": Uncaught exception!" )
3651 main.cleanup()
3652 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003653
3654 def appIDs( self, jsonFormat=True ):
3655 """
3656 Show the mappings between app id and app names given by the 'app-ids'
3657 cli command
3658 """
3659 try:
3660 cmdStr = "app-ids"
3661 if jsonFormat:
3662 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003663 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003664 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003665 assert "Command not found:" not in output, output
3666 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003667 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003668 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003669 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003670 return None
3671 except TypeError:
3672 main.log.exception( self.name + ": Object not as expected" )
3673 return None
3674 except pexpect.EOF:
3675 main.log.error( self.name + ": EOF exception found" )
3676 main.log.error( self.name + ": " + self.handle.before )
3677 main.cleanup()
3678 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003679 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003680 main.log.exception( self.name + ": Uncaught exception!" )
3681 main.cleanup()
3682 main.exit()
3683
3684 def appToIDCheck( self ):
3685 """
3686 This method will check that each application's ID listed in 'apps' is
3687 the same as the ID listed in 'app-ids'. The check will also check that
3688 there are no duplicate IDs issued. Note that an app ID should be
3689 a globaly unique numerical identifier for app/app-like features. Once
3690 an ID is registered, the ID is never freed up so that if an app is
3691 reinstalled it will have the same ID.
3692
3693 Returns: main.TRUE if the check passes and
3694 main.FALSE if the check fails or
3695 main.ERROR if there is some error in processing the test
3696 """
3697 try:
Jon Hall390696c2015-05-05 17:13:41 -07003698 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003699 rawJson = self.appIDs( jsonFormat=True )
3700 if rawJson:
3701 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003702 else:
Jon Hallc6793552016-01-19 14:18:37 -08003703 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003704 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003705 rawJson = self.apps( jsonFormat=True )
3706 if rawJson:
3707 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003708 else:
Jon Hallc6793552016-01-19 14:18:37 -08003709 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003710 bail = True
3711 if bail:
3712 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003713 result = main.TRUE
3714 for app in apps:
3715 appID = app.get( 'id' )
3716 if appID is None:
3717 main.log.error( "Error parsing app: " + str( app ) )
3718 result = main.FALSE
3719 appName = app.get( 'name' )
3720 if appName is None:
3721 main.log.error( "Error parsing app: " + str( app ) )
3722 result = main.FALSE
3723 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003724 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003725 # main.log.debug( "Comparing " + str( app ) + " to " +
3726 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003727 if not current: # if ids doesn't have this id
3728 result = main.FALSE
3729 main.log.error( "'app-ids' does not have the ID for " +
3730 str( appName ) + " that apps does." )
3731 elif len( current ) > 1:
3732 # there is more than one app with this ID
3733 result = main.FALSE
3734 # We will log this later in the method
3735 elif not current[0][ 'name' ] == appName:
3736 currentName = current[0][ 'name' ]
3737 result = main.FALSE
3738 main.log.error( "'app-ids' has " + str( currentName ) +
3739 " registered under id:" + str( appID ) +
3740 " but 'apps' has " + str( appName ) )
3741 else:
3742 pass # id and name match!
3743 # now make sure that app-ids has no duplicates
3744 idsList = []
3745 namesList = []
3746 for item in ids:
3747 idsList.append( item[ 'id' ] )
3748 namesList.append( item[ 'name' ] )
3749 if len( idsList ) != len( set( idsList ) ) or\
3750 len( namesList ) != len( set( namesList ) ):
3751 main.log.error( "'app-ids' has some duplicate entries: \n"
3752 + json.dumps( ids,
3753 sort_keys=True,
3754 indent=4,
3755 separators=( ',', ': ' ) ) )
3756 result = main.FALSE
3757 return result
Jon Hallc6793552016-01-19 14:18:37 -08003758 except ( TypeError, ValueError ):
3759 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003760 return main.ERROR
3761 except pexpect.EOF:
3762 main.log.error( self.name + ": EOF exception found" )
3763 main.log.error( self.name + ": " + self.handle.before )
3764 main.cleanup()
3765 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003766 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003767 main.log.exception( self.name + ": Uncaught exception!" )
3768 main.cleanup()
3769 main.exit()
3770
Jon Hallfb760a02015-04-13 15:35:03 -07003771 def getCfg( self, component=None, propName=None, short=False,
3772 jsonFormat=True ):
3773 """
3774 Get configuration settings from onos cli
3775 Optional arguments:
3776 component - Optionally only list configurations for a specific
3777 component. If None, all components with configurations
3778 are displayed. Case Sensitive string.
3779 propName - If component is specified, propName option will show
3780 only this specific configuration from that component.
3781 Case Sensitive string.
3782 jsonFormat - Returns output as json. Note that this will override
3783 the short option
3784 short - Short, less verbose, version of configurations.
3785 This is overridden by the json option
3786 returns:
3787 Output from cli as a string or None on error
3788 """
3789 try:
3790 baseStr = "cfg"
3791 cmdStr = " get"
3792 componentStr = ""
3793 if component:
3794 componentStr += " " + component
3795 if propName:
3796 componentStr += " " + propName
3797 if jsonFormat:
3798 baseStr += " -j"
3799 elif short:
3800 baseStr += " -s"
3801 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003802 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003803 assert "Command not found:" not in output, output
3804 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003805 return output
3806 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003807 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003808 return None
3809 except TypeError:
3810 main.log.exception( self.name + ": Object not as expected" )
3811 return None
3812 except pexpect.EOF:
3813 main.log.error( self.name + ": EOF exception found" )
3814 main.log.error( self.name + ": " + self.handle.before )
3815 main.cleanup()
3816 main.exit()
3817 except Exception:
3818 main.log.exception( self.name + ": Uncaught exception!" )
3819 main.cleanup()
3820 main.exit()
3821
3822 def setCfg( self, component, propName, value=None, check=True ):
3823 """
3824 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003825 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003826 component - The case sensitive name of the component whose
3827 property is to be set
3828 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003829 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003830 value - The value to set the property to. If None, will unset the
3831 property and revert it to it's default value(if applicable)
3832 check - Boolean, Check whether the option was successfully set this
3833 only applies when a value is given.
3834 returns:
3835 main.TRUE on success or main.FALSE on failure. If check is False,
3836 will return main.TRUE unless there is an error
3837 """
3838 try:
3839 baseStr = "cfg"
3840 cmdStr = " set " + str( component ) + " " + str( propName )
3841 if value is not None:
3842 cmdStr += " " + str( value )
3843 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003844 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003845 assert "Command not found:" not in output, output
3846 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003847 if value and check:
3848 results = self.getCfg( component=str( component ),
3849 propName=str( propName ),
3850 jsonFormat=True )
3851 # Check if current value is what we just set
3852 try:
3853 jsonOutput = json.loads( results )
3854 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003855 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003856 main.log.exception( "Error parsing cfg output" )
3857 main.log.error( "output:" + repr( results ) )
3858 return main.FALSE
3859 if current == str( value ):
3860 return main.TRUE
3861 return main.FALSE
3862 return main.TRUE
3863 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003864 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003865 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003866 except ( TypeError, ValueError ):
3867 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003868 return main.FALSE
3869 except pexpect.EOF:
3870 main.log.error( self.name + ": EOF exception found" )
3871 main.log.error( self.name + ": " + self.handle.before )
3872 main.cleanup()
3873 main.exit()
3874 except Exception:
3875 main.log.exception( self.name + ": Uncaught exception!" )
3876 main.cleanup()
3877 main.exit()
3878
Jon Hall390696c2015-05-05 17:13:41 -07003879 def setTestAdd( self, setName, values ):
3880 """
3881 CLI command to add elements to a distributed set.
3882 Arguments:
3883 setName - The name of the set to add to.
3884 values - The value(s) to add to the set, space seperated.
3885 Example usages:
3886 setTestAdd( "set1", "a b c" )
3887 setTestAdd( "set2", "1" )
3888 returns:
3889 main.TRUE on success OR
3890 main.FALSE if elements were already in the set OR
3891 main.ERROR on error
3892 """
3893 try:
3894 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3895 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003896 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003897 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003898 try:
3899 # TODO: Maybe make this less hardcoded
3900 # ConsistentMap Exceptions
3901 assert "org.onosproject.store.service" not in output
3902 # Node not leader
3903 assert "java.lang.IllegalStateException" not in output
3904 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003905 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003906 "command: " + str( output ) )
3907 retryTime = 30 # Conservative time, given by Madan
3908 main.log.info( "Waiting " + str( retryTime ) +
3909 "seconds before retrying." )
3910 time.sleep( retryTime ) # Due to change in mastership
3911 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003912 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003913 assert "Error executing command" not in output
3914 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3915 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3916 main.log.info( self.name + ": " + output )
3917 if re.search( positiveMatch, output):
3918 return main.TRUE
3919 elif re.search( negativeMatch, output):
3920 return main.FALSE
3921 else:
3922 main.log.error( self.name + ": setTestAdd did not" +
3923 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003924 main.log.debug( self.name + " actual: " + repr( output ) )
3925 return main.ERROR
3926 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003927 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003928 return main.ERROR
3929 except TypeError:
3930 main.log.exception( self.name + ": Object not as expected" )
3931 return main.ERROR
3932 except pexpect.EOF:
3933 main.log.error( self.name + ": EOF exception found" )
3934 main.log.error( self.name + ": " + self.handle.before )
3935 main.cleanup()
3936 main.exit()
3937 except Exception:
3938 main.log.exception( self.name + ": Uncaught exception!" )
3939 main.cleanup()
3940 main.exit()
3941
3942 def setTestRemove( self, setName, values, clear=False, retain=False ):
3943 """
3944 CLI command to remove elements from a distributed set.
3945 Required arguments:
3946 setName - The name of the set to remove from.
3947 values - The value(s) to remove from the set, space seperated.
3948 Optional arguments:
3949 clear - Clear all elements from the set
3950 retain - Retain only the given values. (intersection of the
3951 original set and the given set)
3952 returns:
3953 main.TRUE on success OR
3954 main.FALSE if the set was not changed OR
3955 main.ERROR on error
3956 """
3957 try:
3958 cmdStr = "set-test-remove "
3959 if clear:
3960 cmdStr += "-c " + str( setName )
3961 elif retain:
3962 cmdStr += "-r " + str( setName ) + " " + str( values )
3963 else:
3964 cmdStr += str( setName ) + " " + str( values )
3965 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003966 try:
Jon Halla495f562016-05-16 18:03:26 -07003967 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003968 # TODO: Maybe make this less hardcoded
3969 # ConsistentMap Exceptions
3970 assert "org.onosproject.store.service" not in output
3971 # Node not leader
3972 assert "java.lang.IllegalStateException" not in output
3973 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003974 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003975 "command: " + str( output ) )
3976 retryTime = 30 # Conservative time, given by Madan
3977 main.log.info( "Waiting " + str( retryTime ) +
3978 "seconds before retrying." )
3979 time.sleep( retryTime ) # Due to change in mastership
3980 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003981 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003982 assert "Command not found:" not in output, output
3983 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003984 main.log.info( self.name + ": " + output )
3985 if clear:
3986 pattern = "Set " + str( setName ) + " cleared"
3987 if re.search( pattern, output ):
3988 return main.TRUE
3989 elif retain:
3990 positivePattern = str( setName ) + " was pruned to contain " +\
3991 "only elements of set \[(.*)\]"
3992 negativePattern = str( setName ) + " was not changed by " +\
3993 "retaining only elements of the set " +\
3994 "\[(.*)\]"
3995 if re.search( positivePattern, output ):
3996 return main.TRUE
3997 elif re.search( negativePattern, output ):
3998 return main.FALSE
3999 else:
4000 positivePattern = "\[(.*)\] was removed from the set " +\
4001 str( setName )
4002 if ( len( values.split() ) == 1 ):
4003 negativePattern = "\[(.*)\] was not in set " +\
4004 str( setName )
4005 else:
4006 negativePattern = "No element of \[(.*)\] was in set " +\
4007 str( setName )
4008 if re.search( positivePattern, output ):
4009 return main.TRUE
4010 elif re.search( negativePattern, output ):
4011 return main.FALSE
4012 main.log.error( self.name + ": setTestRemove did not" +
4013 " match expected output" )
4014 main.log.debug( self.name + " expected: " + pattern )
4015 main.log.debug( self.name + " actual: " + repr( output ) )
4016 return main.ERROR
4017 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004018 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004019 return main.ERROR
4020 except TypeError:
4021 main.log.exception( self.name + ": Object not as expected" )
4022 return main.ERROR
4023 except pexpect.EOF:
4024 main.log.error( self.name + ": EOF exception found" )
4025 main.log.error( self.name + ": " + self.handle.before )
4026 main.cleanup()
4027 main.exit()
4028 except Exception:
4029 main.log.exception( self.name + ": Uncaught exception!" )
4030 main.cleanup()
4031 main.exit()
4032
4033 def setTestGet( self, setName, values="" ):
4034 """
4035 CLI command to get the elements in a distributed set.
4036 Required arguments:
4037 setName - The name of the set to remove from.
4038 Optional arguments:
4039 values - The value(s) to check if in the set, space seperated.
4040 returns:
4041 main.ERROR on error OR
4042 A list of elements in the set if no optional arguments are
4043 supplied OR
4044 A tuple containing the list then:
4045 main.FALSE if the given values are not in the set OR
4046 main.TRUE if the given values are in the set OR
4047 """
4048 try:
4049 values = str( values ).strip()
4050 setName = str( setName ).strip()
4051 length = len( values.split() )
4052 containsCheck = None
4053 # Patterns to match
4054 setPattern = "\[(.*)\]"
4055 pattern = "Items in set " + setName + ":\n" + setPattern
4056 containsTrue = "Set " + setName + " contains the value " + values
4057 containsFalse = "Set " + setName + " did not contain the value " +\
4058 values
4059 containsAllTrue = "Set " + setName + " contains the the subset " +\
4060 setPattern
4061 containsAllFalse = "Set " + setName + " did not contain the the" +\
4062 " subset " + setPattern
4063
4064 cmdStr = "set-test-get "
4065 cmdStr += setName + " " + values
4066 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004067 try:
Jon Halla495f562016-05-16 18:03:26 -07004068 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004069 # TODO: Maybe make this less hardcoded
4070 # ConsistentMap Exceptions
4071 assert "org.onosproject.store.service" not in output
4072 # Node not leader
4073 assert "java.lang.IllegalStateException" not in output
4074 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004075 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004076 "command: " + str( output ) )
4077 retryTime = 30 # Conservative time, given by Madan
4078 main.log.info( "Waiting " + str( retryTime ) +
4079 "seconds before retrying." )
4080 time.sleep( retryTime ) # Due to change in mastership
4081 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004082 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004083 assert "Command not found:" not in output, output
4084 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004085 main.log.info( self.name + ": " + output )
4086
4087 if length == 0:
4088 match = re.search( pattern, output )
4089 else: # if given values
4090 if length == 1: # Contains output
4091 patternTrue = pattern + "\n" + containsTrue
4092 patternFalse = pattern + "\n" + containsFalse
4093 else: # ContainsAll output
4094 patternTrue = pattern + "\n" + containsAllTrue
4095 patternFalse = pattern + "\n" + containsAllFalse
4096 matchTrue = re.search( patternTrue, output )
4097 matchFalse = re.search( patternFalse, output )
4098 if matchTrue:
4099 containsCheck = main.TRUE
4100 match = matchTrue
4101 elif matchFalse:
4102 containsCheck = main.FALSE
4103 match = matchFalse
4104 else:
4105 main.log.error( self.name + " setTestGet did not match " +\
4106 "expected output" )
4107 main.log.debug( self.name + " expected: " + pattern )
4108 main.log.debug( self.name + " actual: " + repr( output ) )
4109 match = None
4110 if match:
4111 setMatch = match.group( 1 )
4112 if setMatch == '':
4113 setList = []
4114 else:
4115 setList = setMatch.split( ", " )
4116 if length > 0:
4117 return ( setList, containsCheck )
4118 else:
4119 return setList
4120 else: # no match
4121 main.log.error( self.name + ": setTestGet did not" +
4122 " match expected output" )
4123 main.log.debug( self.name + " expected: " + pattern )
4124 main.log.debug( self.name + " actual: " + repr( output ) )
4125 return main.ERROR
4126 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004127 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004128 return main.ERROR
4129 except TypeError:
4130 main.log.exception( self.name + ": Object not as expected" )
4131 return main.ERROR
4132 except pexpect.EOF:
4133 main.log.error( self.name + ": EOF exception found" )
4134 main.log.error( self.name + ": " + self.handle.before )
4135 main.cleanup()
4136 main.exit()
4137 except Exception:
4138 main.log.exception( self.name + ": Uncaught exception!" )
4139 main.cleanup()
4140 main.exit()
4141
4142 def setTestSize( self, setName ):
4143 """
4144 CLI command to get the elements in a distributed set.
4145 Required arguments:
4146 setName - The name of the set to remove from.
4147 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004148 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004149 None on error
4150 """
4151 try:
4152 # TODO: Should this check against the number of elements returned
4153 # and then return true/false based on that?
4154 setName = str( setName ).strip()
4155 # Patterns to match
4156 setPattern = "\[(.*)\]"
4157 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4158 setPattern
4159 cmdStr = "set-test-get -s "
4160 cmdStr += setName
4161 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004162 try:
Jon Halla495f562016-05-16 18:03:26 -07004163 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004164 # TODO: Maybe make this less hardcoded
4165 # ConsistentMap Exceptions
4166 assert "org.onosproject.store.service" not in output
4167 # Node not leader
4168 assert "java.lang.IllegalStateException" not in output
4169 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004170 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004171 "command: " + str( output ) )
4172 retryTime = 30 # Conservative time, given by Madan
4173 main.log.info( "Waiting " + str( retryTime ) +
4174 "seconds before retrying." )
4175 time.sleep( retryTime ) # Due to change in mastership
4176 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004177 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004178 assert "Command not found:" not in output, output
4179 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004180 main.log.info( self.name + ": " + output )
4181 match = re.search( pattern, output )
4182 if match:
4183 setSize = int( match.group( 1 ) )
4184 setMatch = match.group( 2 )
4185 if len( setMatch.split() ) == setSize:
4186 main.log.info( "The size returned by " + self.name +
4187 " matches the number of elements in " +
4188 "the returned set" )
4189 else:
4190 main.log.error( "The size returned by " + self.name +
4191 " does not match the number of " +
4192 "elements in the returned set." )
4193 return setSize
4194 else: # no match
4195 main.log.error( self.name + ": setTestGet did not" +
4196 " match expected output" )
4197 main.log.debug( self.name + " expected: " + pattern )
4198 main.log.debug( self.name + " actual: " + repr( output ) )
4199 return None
4200 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004201 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004202 return None
Jon Hall390696c2015-05-05 17:13:41 -07004203 except TypeError:
4204 main.log.exception( self.name + ": Object not as expected" )
4205 return None
4206 except pexpect.EOF:
4207 main.log.error( self.name + ": EOF exception found" )
4208 main.log.error( self.name + ": " + self.handle.before )
4209 main.cleanup()
4210 main.exit()
4211 except Exception:
4212 main.log.exception( self.name + ": Uncaught exception!" )
4213 main.cleanup()
4214 main.exit()
4215
Jon Hall80daded2015-05-27 16:07:00 -07004216 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004217 """
4218 Command to list the various counters in the system.
4219 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004220 if jsonFormat, a string of the json object returned by the cli
4221 command
4222 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004223 None on error
4224 """
Jon Hall390696c2015-05-05 17:13:41 -07004225 try:
4226 counters = {}
4227 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004228 if jsonFormat:
4229 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004230 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004231 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004232 assert "Command not found:" not in output, output
4233 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004234 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004235 return output
Jon Hall390696c2015-05-05 17:13:41 -07004236 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004237 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004238 return None
Jon Hall390696c2015-05-05 17:13:41 -07004239 except TypeError:
4240 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004241 return None
Jon Hall390696c2015-05-05 17:13:41 -07004242 except pexpect.EOF:
4243 main.log.error( self.name + ": EOF exception found" )
4244 main.log.error( self.name + ": " + self.handle.before )
4245 main.cleanup()
4246 main.exit()
4247 except Exception:
4248 main.log.exception( self.name + ": Uncaught exception!" )
4249 main.cleanup()
4250 main.exit()
4251
Jon Hall935db192016-04-19 00:22:04 -07004252 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004253 """
Jon Halle1a3b752015-07-22 13:02:46 -07004254 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004255 Required arguments:
4256 counter - The name of the counter to increment.
4257 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004258 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004259 returns:
4260 integer value of the counter or
4261 None on Error
4262 """
4263 try:
4264 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004265 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004266 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004267 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004268 if delta != 1:
4269 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004270 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004271 try:
Jon Halla495f562016-05-16 18:03:26 -07004272 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004273 # TODO: Maybe make this less hardcoded
4274 # ConsistentMap Exceptions
4275 assert "org.onosproject.store.service" not in output
4276 # Node not leader
4277 assert "java.lang.IllegalStateException" not in output
4278 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004279 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004280 "command: " + str( output ) )
4281 retryTime = 30 # Conservative time, given by Madan
4282 main.log.info( "Waiting " + str( retryTime ) +
4283 "seconds before retrying." )
4284 time.sleep( retryTime ) # Due to change in mastership
4285 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004286 assert output is not None, "Error in sendline"
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 Hall390696c2015-05-05 17:13:41 -07004289 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004290 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004291 match = re.search( pattern, output )
4292 if match:
4293 return int( match.group( 1 ) )
4294 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004295 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004296 " 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 Hall390696c2015-05-05 17:13:41 -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
Jon Hall935db192016-04-19 00:22:04 -07004316 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004317 """
4318 CLI command to get a distributed counter then add a delta to it.
4319 Required arguments:
4320 counter - The name of the counter to increment.
4321 Optional arguments:
4322 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004323 returns:
4324 integer value of the counter or
4325 None on Error
4326 """
4327 try:
4328 counter = str( counter )
4329 delta = int( delta )
4330 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004331 cmdStr += counter
4332 if delta != 1:
4333 cmdStr += " " + str( delta )
4334 output = self.sendline( cmdStr )
4335 try:
Jon Halla495f562016-05-16 18:03:26 -07004336 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004337 # TODO: Maybe make this less hardcoded
4338 # ConsistentMap Exceptions
4339 assert "org.onosproject.store.service" not in output
4340 # Node not leader
4341 assert "java.lang.IllegalStateException" not in output
4342 except AssertionError:
4343 main.log.error( "Error in processing '" + cmdStr + "' " +
4344 "command: " + str( output ) )
4345 retryTime = 30 # Conservative time, given by Madan
4346 main.log.info( "Waiting " + str( retryTime ) +
4347 "seconds before retrying." )
4348 time.sleep( retryTime ) # Due to change in mastership
4349 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004350 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004351 assert "Command not found:" not in output, output
4352 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004353 main.log.info( self.name + ": " + output )
4354 pattern = counter + " was updated to (-?\d+)"
4355 match = re.search( pattern, output )
4356 if match:
4357 return int( match.group( 1 ) )
4358 else:
4359 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4360 " match expected output." )
4361 main.log.debug( self.name + " expected: " + pattern )
4362 main.log.debug( self.name + " actual: " + repr( output ) )
4363 return None
4364 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004365 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004366 return None
4367 except TypeError:
4368 main.log.exception( self.name + ": Object not as expected" )
4369 return None
4370 except pexpect.EOF:
4371 main.log.error( self.name + ": EOF exception found" )
4372 main.log.error( self.name + ": " + self.handle.before )
4373 main.cleanup()
4374 main.exit()
4375 except Exception:
4376 main.log.exception( self.name + ": Uncaught exception!" )
4377 main.cleanup()
4378 main.exit()
4379
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004380 def summary( self, jsonFormat=True ):
4381 """
4382 Description: Execute summary command in onos
4383 Returns: json object ( summary -j ), returns main.FALSE if there is
4384 no output
4385
4386 """
4387 try:
4388 cmdStr = "summary"
4389 if jsonFormat:
4390 cmdStr += " -j"
4391 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004392 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004393 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004394 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004395 if not handle:
4396 main.log.error( self.name + ": There is no output in " +
4397 "summary command" )
4398 return main.FALSE
4399 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004400 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004401 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004402 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004403 except TypeError:
4404 main.log.exception( self.name + ": Object not as expected" )
4405 return None
4406 except pexpect.EOF:
4407 main.log.error( self.name + ": EOF exception found" )
4408 main.log.error( self.name + ": " + self.handle.before )
4409 main.cleanup()
4410 main.exit()
4411 except Exception:
4412 main.log.exception( self.name + ": Uncaught exception!" )
4413 main.cleanup()
4414 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004415
Jon Hall935db192016-04-19 00:22:04 -07004416 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004417 """
4418 CLI command to get the value of a key in a consistent map using
4419 transactions. This a test function and can only get keys from the
4420 test map hard coded into the cli command
4421 Required arguments:
4422 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004423 returns:
4424 The string value of the key or
4425 None on Error
4426 """
4427 try:
4428 keyName = str( keyName )
4429 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004430 cmdStr += keyName
4431 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004432 assert output is not None, "Error in sendline"
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 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4445 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004446 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004447 return None
4448 else:
4449 match = re.search( pattern, output )
4450 if match:
4451 return match.groupdict()[ 'value' ]
4452 else:
4453 main.log.error( self.name + ": transactionlMapGet did not" +
4454 " match expected output." )
4455 main.log.debug( self.name + " expected: " + pattern )
4456 main.log.debug( self.name + " actual: " + repr( output ) )
4457 return None
Jon Hallc6793552016-01-19 14:18:37 -08004458 except AssertionError:
4459 main.log.exception( "" )
4460 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004461 except TypeError:
4462 main.log.exception( self.name + ": Object not as expected" )
4463 return None
4464 except pexpect.EOF:
4465 main.log.error( self.name + ": EOF exception found" )
4466 main.log.error( self.name + ": " + self.handle.before )
4467 main.cleanup()
4468 main.exit()
4469 except Exception:
4470 main.log.exception( self.name + ": Uncaught exception!" )
4471 main.cleanup()
4472 main.exit()
4473
Jon Hall935db192016-04-19 00:22:04 -07004474 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004475 """
4476 CLI command to put a value into 'numKeys' number of keys in a
4477 consistent map using transactions. This a test function and can only
4478 put into keys named 'Key#' of the test map hard coded into the cli command
4479 Required arguments:
4480 numKeys - Number of keys to add the value to
4481 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004482 returns:
4483 A dictionary whose keys are the name of the keys put into the map
4484 and the values of the keys are dictionaries whose key-values are
4485 'value': value put into map and optionaly
4486 'oldValue': Previous value in the key or
4487 None on Error
4488
4489 Example output
4490 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4491 'Key2': {'value': 'Testing'} }
4492 """
4493 try:
4494 numKeys = str( numKeys )
4495 value = str( value )
4496 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004497 cmdStr += numKeys + " " + value
4498 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004499 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004500 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004501 try:
4502 # TODO: Maybe make this less hardcoded
4503 # ConsistentMap Exceptions
4504 assert "org.onosproject.store.service" not in output
4505 # Node not leader
4506 assert "java.lang.IllegalStateException" not in output
4507 except AssertionError:
4508 main.log.error( "Error in processing '" + cmdStr + "' " +
4509 "command: " + str( output ) )
4510 return None
4511 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4512 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4513 results = {}
4514 for line in output.splitlines():
4515 new = re.search( newPattern, line )
4516 updated = re.search( updatedPattern, line )
4517 if new:
4518 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4519 elif updated:
4520 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004521 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004522 else:
4523 main.log.error( self.name + ": transactionlMapGet did not" +
4524 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004525 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4526 newPattern,
4527 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004528 main.log.debug( self.name + " actual: " + repr( output ) )
4529 return results
Jon Hallc6793552016-01-19 14:18:37 -08004530 except AssertionError:
4531 main.log.exception( "" )
4532 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004533 except TypeError:
4534 main.log.exception( self.name + ": Object not as expected" )
4535 return None
4536 except pexpect.EOF:
4537 main.log.error( self.name + ": EOF exception found" )
4538 main.log.error( self.name + ": " + self.handle.before )
4539 main.cleanup()
4540 main.exit()
4541 except Exception:
4542 main.log.exception( self.name + ": Uncaught exception!" )
4543 main.cleanup()
4544 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004545
acsmarsdaea66c2015-09-03 11:44:06 -07004546 def maps( self, jsonFormat=True ):
4547 """
4548 Description: Returns result of onos:maps
4549 Optional:
4550 * jsonFormat: enable json formatting of output
4551 """
4552 try:
4553 cmdStr = "maps"
4554 if jsonFormat:
4555 cmdStr += " -j"
4556 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004557 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004558 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004559 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004560 except AssertionError:
4561 main.log.exception( "" )
4562 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004563 except TypeError:
4564 main.log.exception( self.name + ": Object not as expected" )
4565 return None
4566 except pexpect.EOF:
4567 main.log.error( self.name + ": EOF exception found" )
4568 main.log.error( self.name + ": " + self.handle.before )
4569 main.cleanup()
4570 main.exit()
4571 except Exception:
4572 main.log.exception( self.name + ": Uncaught exception!" )
4573 main.cleanup()
4574 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004575
4576 def getSwController( self, uri, jsonFormat=True ):
4577 """
4578 Descrition: Gets the controller information from the device
4579 """
4580 try:
4581 cmd = "device-controllers "
4582 if jsonFormat:
4583 cmd += "-j "
4584 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004585 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004586 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004587 return response
Jon Hallc6793552016-01-19 14:18:37 -08004588 except AssertionError:
4589 main.log.exception( "" )
4590 return None
GlennRC050596c2015-11-18 17:06:41 -08004591 except TypeError:
4592 main.log.exception( self.name + ": Object not as expected" )
4593 return None
4594 except pexpect.EOF:
4595 main.log.error( self.name + ": EOF exception found" )
4596 main.log.error( self.name + ": " + self.handle.before )
4597 main.cleanup()
4598 main.exit()
4599 except Exception:
4600 main.log.exception( self.name + ": Uncaught exception!" )
4601 main.cleanup()
4602 main.exit()
4603
4604 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4605 """
4606 Descrition: sets the controller(s) for the specified device
4607
4608 Parameters:
4609 Required: uri - String: The uri of the device(switch).
4610 ip - String or List: The ip address of the controller.
4611 This parameter can be formed in a couple of different ways.
4612 VALID:
4613 10.0.0.1 - just the ip address
4614 tcp:10.0.0.1 - the protocol and the ip address
4615 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4616 so that you can add controllers with different
4617 protocols and ports
4618 INVALID:
4619 10.0.0.1:6653 - this is not supported by ONOS
4620
4621 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4622 port - The port number.
4623 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4624
4625 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4626 """
4627 try:
4628 cmd = "device-setcontrollers"
4629
4630 if jsonFormat:
4631 cmd += " -j"
4632 cmd += " " + uri
4633 if isinstance( ip, str ):
4634 ip = [ip]
4635 for item in ip:
4636 if ":" in item:
4637 sitem = item.split( ":" )
4638 if len(sitem) == 3:
4639 cmd += " " + item
4640 elif "." in sitem[1]:
4641 cmd += " {}:{}".format(item, port)
4642 else:
4643 main.log.error( "Malformed entry: " + item )
4644 raise TypeError
4645 else:
4646 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004647 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004648 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004649 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004650 if "Error" in response:
4651 main.log.error( response )
4652 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004653 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004654 except AssertionError:
4655 main.log.exception( "" )
4656 return None
GlennRC050596c2015-11-18 17:06:41 -08004657 except TypeError:
4658 main.log.exception( self.name + ": Object not as expected" )
4659 return main.FALSE
4660 except pexpect.EOF:
4661 main.log.error( self.name + ": EOF exception found" )
4662 main.log.error( self.name + ": " + self.handle.before )
4663 main.cleanup()
4664 main.exit()
4665 except Exception:
4666 main.log.exception( self.name + ": Uncaught exception!" )
4667 main.cleanup()
4668 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004669
4670 def removeDevice( self, device ):
4671 '''
4672 Description:
4673 Remove a device from ONOS by passing the uri of the device(s).
4674 Parameters:
4675 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4676 Returns:
4677 Returns main.FALSE if an exception is thrown or an error is present
4678 in the response. Otherwise, returns main.TRUE.
4679 NOTE:
4680 If a host cannot be removed, then this function will return main.FALSE
4681 '''
4682 try:
4683 if type( device ) is str:
4684 device = list( device )
4685
4686 for d in device:
4687 time.sleep( 1 )
4688 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004689 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004690 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004691 if "Error" in response:
4692 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4693 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004694 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004695 except AssertionError:
4696 main.log.exception( "" )
4697 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004698 except TypeError:
4699 main.log.exception( self.name + ": Object not as expected" )
4700 return main.FALSE
4701 except pexpect.EOF:
4702 main.log.error( self.name + ": EOF exception found" )
4703 main.log.error( self.name + ": " + self.handle.before )
4704 main.cleanup()
4705 main.exit()
4706 except Exception:
4707 main.log.exception( self.name + ": Uncaught exception!" )
4708 main.cleanup()
4709 main.exit()
4710
4711 def removeHost( self, host ):
4712 '''
4713 Description:
4714 Remove a host from ONOS by passing the id of the host(s)
4715 Parameters:
4716 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4717 Returns:
4718 Returns main.FALSE if an exception is thrown or an error is present
4719 in the response. Otherwise, returns main.TRUE.
4720 NOTE:
4721 If a host cannot be removed, then this function will return main.FALSE
4722 '''
4723 try:
4724 if type( host ) is str:
4725 host = list( host )
4726
4727 for h in host:
4728 time.sleep( 1 )
4729 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004730 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004731 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004732 if "Error" in response:
4733 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4734 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004735 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004736 except AssertionError:
4737 main.log.exception( "" )
4738 return None
GlennRC20fc6522015-12-23 23:26:57 -08004739 except TypeError:
4740 main.log.exception( self.name + ": Object not as expected" )
4741 return main.FALSE
4742 except pexpect.EOF:
4743 main.log.error( self.name + ": EOF exception found" )
4744 main.log.error( self.name + ": " + self.handle.before )
4745 main.cleanup()
4746 main.exit()
4747 except Exception:
4748 main.log.exception( self.name + ": Uncaught exception!" )
4749 main.cleanup()
4750 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004751
Jon Hallc6793552016-01-19 14:18:37 -08004752 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004753 '''
4754 Description:
4755 Bring link down or up in the null-provider.
4756 params:
4757 begin - (string) One end of a device or switch.
4758 end - (string) the other end of the device or switch
4759 returns:
4760 main.TRUE if no exceptions were thrown and no Errors are
4761 present in the resoponse. Otherwise, returns main.FALSE
4762 '''
4763 try:
Jon Hallc6793552016-01-19 14:18:37 -08004764 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004765 response = self.sendline( cmd, showResponse=True )
Jon Halla495f562016-05-16 18:03:26 -07004766 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004767 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004768 if "Error" in response or "Failure" in response:
4769 main.log.error( response )
4770 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004771 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004772 except AssertionError:
4773 main.log.exception( "" )
4774 return None
GlennRCed771242016-01-13 17:02:47 -08004775 except TypeError:
4776 main.log.exception( self.name + ": Object not as expected" )
4777 return main.FALSE
4778 except pexpect.EOF:
4779 main.log.error( self.name + ": EOF exception found" )
4780 main.log.error( self.name + ": " + self.handle.before )
4781 main.cleanup()
4782 main.exit()
4783 except Exception:
4784 main.log.exception( self.name + ": Uncaught exception!" )
4785 main.cleanup()
4786 main.exit()
4787