blob: 18f09148a4f2a438f8da45fc96d3b38920c89d75 [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
Jeremy Songsterae01bba2016-07-11 15:39:17 -070017Modified 2016 by ON.Lab
18
19Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
20the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
21or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlab95ce8322014-10-13 14:12:04 -040022
kelvin8ec71442015-01-15 16:57:00 -080023"""
andrewonlab95ce8322014-10-13 14:12:04 -040024import pexpect
25import re
Jon Hall30b82fa2015-03-04 17:15:43 -080026import json
27import types
Jon Hallbd16b922015-03-26 17:53:15 -070028import time
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
andrewonlab95ce8322014-10-13 14:12:04 -040030from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070031from core.graph import Graph
andrewonlab95ce8322014-10-13 14:12:04 -040032
andrewonlab95ce8322014-10-13 14:12:04 -040033
kelvin8ec71442015-01-15 16:57:00 -080034class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
42 self.handle = None
You Wangdb8cd0a2016-05-26 15:19:45 -070043 self.graph = Graph()
kelvin8ec71442015-01-15 16:57:00 -080044 super( CLI, self ).__init__()
45
46 def connect( self, **connectargs ):
47 """
andrewonlab95ce8322014-10-13 14:12:04 -040048 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080049 """
andrewonlab95ce8322014-10-13 14:12:04 -040050 try:
51 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080052 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054 for key in self.options:
55 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080056 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040057 break
kelvin-onlabfb521662015-02-27 09:52:40 -080058 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070059 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040060
kelvin-onlaba4074292015-07-09 15:19:49 -070061 for key in self.options:
62 if key == 'onosIp':
63 self.onosIp = self.options[ 'onosIp' ]
64 break
65
kelvin8ec71442015-01-15 16:57:00 -080066 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070067
68 try:
Jon Hallc6793552016-01-19 14:18:37 -080069 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070070 self.ip_address = os.getenv( str( self.ip_address ) )
71 else:
72 main.log.info( self.name +
73 ": Trying to connect to " +
74 self.ip_address )
75
76 except KeyError:
77 main.log.info( "Invalid host name," +
78 " connecting to local host instead" )
79 self.ip_address = 'localhost'
80 except Exception as inst:
81 main.log.error( "Uncaught exception: " + str( inst ) )
82
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080084 user_name=self.user_name,
85 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080086 port=self.port,
87 pwd=self.pwd,
88 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040089
kelvin8ec71442015-01-15 16:57:00 -080090 self.handle.sendline( "cd " + self.home )
91 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040092 if self.handle:
93 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080094 else:
95 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040096 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080097 except TypeError:
98 main.log.exception( self.name + ": Object not as expected" )
99 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800101 main.log.error( self.name + ": EOF exception found" )
102 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400103 main.cleanup()
104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 main.cleanup()
108 main.exit()
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def disconnect( self ):
111 """
andrewonlab95ce8322014-10-13 14:12:04 -0400112 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800113 """
Jon Halld61331b2015-02-17 16:35:47 -0800114 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400115 try:
Jon Hall61282e32015-03-19 11:34:11 -0700116 if self.handle:
117 i = self.logout()
118 if i == main.TRUE:
119 self.handle.sendline( "" )
120 self.handle.expect( "\$" )
121 self.handle.sendline( "exit" )
122 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800125 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700129 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700130 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700131 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400134 response = main.FALSE
135 return response
136
kelvin8ec71442015-01-15 16:57:00 -0800137 def logout( self ):
138 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700140 Returns main.TRUE if exited CLI and
141 main.FALSE on timeout (not guranteed you are disconnected)
142 None on TypeError
143 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800144 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500145 try:
Jon Hall61282e32015-03-19 11:34:11 -0700146 if self.handle:
147 self.handle.sendline( "" )
148 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
149 timeout=10 )
150 if i == 0: # In ONOS CLI
151 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700152 j = self.handle.expect( [ "\$",
153 "Command not found:",
154 pexpect.TIMEOUT ] )
155 if j == 0: # Successfully logged out
156 return main.TRUE
157 elif j == 1 or j == 2:
158 # ONOS didn't fully load, and logout command isn't working
159 # or the command timed out
160 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700161 try:
162 self.handle.expect( "\$" )
163 except pexpect.TIMEOUT:
164 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700165 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700166 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700167 main.log.warn( "Unknown repsonse to logout command: '{}'",
168 repr( self.handle.before ) )
169 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700170 elif i == 1: # not in CLI
171 return main.TRUE
172 elif i == 3: # Timeout
173 return main.FALSE
174 else:
andrewonlab9627f432014-11-14 12:45:10 -0500175 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800176 except TypeError:
177 main.log.exception( self.name + ": Object not as expected" )
178 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800180 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700181 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700184 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700185 main.log.error( self.name +
186 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800188 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500189 main.cleanup()
190 main.exit()
191
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800193 """
andrewonlab95ce8322014-10-13 14:12:04 -0400194 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800195
andrewonlab95ce8322014-10-13 14:12:04 -0400196 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800197 """
andrewonlab95ce8322014-10-13 14:12:04 -0400198 try:
199 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800200 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400201 main.cleanup()
202 main.exit()
203 else:
kelvin8ec71442015-01-15 16:57:00 -0800204 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800205 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800206 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400207 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800208 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800209 handleBefore = self.handle.before
210 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800211 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800212 self.handle.sendline("")
213 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800214 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 main.log.info( "Cell call returned: " + handleBefore +
217 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400218
219 return main.TRUE
220
Jon Halld4d4b372015-01-28 16:02:41 -0800221 except TypeError:
222 main.log.exception( self.name + ": Object not as expected" )
223 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800225 main.log.error( self.name + ": eof exception found" )
226 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400227 main.cleanup()
228 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800229 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800230 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400231 main.cleanup()
232 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800233
pingping-lin57a56ce2015-05-20 16:43:48 -0700234 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800235 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800236 """
Jon Hallefbd9792015-03-05 16:11:36 -0800237 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 by user would be used to set the current karaf shell idle timeout.
239 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800240 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 Below is an example to start a session with 60 seconds idle timeout
242 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800243
Hari Krishna25d42f72015-01-05 15:08:28 -0800244 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 Note: karafTimeout is left as str so that this could be read
248 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800249 """
You Wangf69ab392016-01-26 16:34:38 -0800250 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400251 try:
Jon Hall67253832016-12-05 09:47:13 -0800252 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800253 self.handle.sendline( "" )
254 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500256 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800257 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500258 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400259
Jon Hall67253832016-12-05 09:47:13 -0800260 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800261 if waitForStart:
262 # Wait for onos start ( -w ) and enter onos cli
263 startCliCommand = "onos -w "
264 else:
265 startCliCommand = "onos "
266 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800267 i = self.handle.expect( [
268 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700269 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400270
271 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800273 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800275 "config:property-set -p org.apache.karaf.shell\
276 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800277 karafTimeout )
278 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800279 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800280 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400281 return main.TRUE
282 else:
kelvin8ec71442015-01-15 16:57:00 -0800283 # If failed, send ctrl+c to process and try again
284 main.log.info( "Starting CLI failed. Retrying..." )
285 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800286 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
288 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800290 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800291 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800292 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800293 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 "config:property-set -p org.apache.karaf.shell\
295 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800296 karafTimeout )
297 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800298 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400300 return main.TRUE
301 else:
kelvin8ec71442015-01-15 16:57:00 -0800302 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800303 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400304 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400305
Jon Halld4d4b372015-01-28 16:02:41 -0800306 except TypeError:
307 main.log.exception( self.name + ": Object not as expected" )
308 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800310 main.log.error( self.name + ": EOF exception found" )
311 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400312 main.cleanup()
313 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800314 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800315 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400316 main.cleanup()
317 main.exit()
318
suibin zhang116647a2016-05-06 16:30:09 -0700319 def startCellCli( self, karafTimeout="",
320 commandlineTimeout=10, onosStartTimeout=60 ):
321 """
322 Start CLI on onos ecll handle.
323
324 karafTimeout is an optional argument. karafTimeout value passed
325 by user would be used to set the current karaf shell idle timeout.
326 Note that when ever this property is modified the shell will exit and
327 the subsequent login would reflect new idle timeout.
328 Below is an example to start a session with 60 seconds idle timeout
329 ( input value is in milliseconds ):
330
331 tValue = "60000"
332
333 Note: karafTimeout is left as str so that this could be read
334 and passed to startOnosCli from PARAMS file as str.
335 """
336
337 try:
338 self.handle.sendline( "" )
339 x = self.handle.expect( [
340 "\$", "onos>" ], commandlineTimeout)
341
342 if x == 1:
343 main.log.info( "ONOS cli is already running" )
344 return main.TRUE
345
346 # Wait for onos start ( -w ) and enter onos cli
347 self.handle.sendline( "/opt/onos/bin/onos" )
348 i = self.handle.expect( [
349 "onos>",
350 pexpect.TIMEOUT ], onosStartTimeout )
351
352 if i == 0:
353 main.log.info( self.name + " CLI Started successfully" )
354 if karafTimeout:
355 self.handle.sendline(
356 "config:property-set -p org.apache.karaf.shell\
357 sshIdleTimeout " +
358 karafTimeout )
359 self.handle.expect( "\$" )
360 self.handle.sendline( "/opt/onos/bin/onos" )
361 self.handle.expect( "onos>" )
362 return main.TRUE
363 else:
364 # If failed, send ctrl+c to process and try again
365 main.log.info( "Starting CLI failed. Retrying..." )
366 self.handle.send( "\x03" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
369 timeout=30 )
370 if i == 0:
371 main.log.info( self.name + " CLI Started " +
372 "successfully after retry attempt" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
378 self.handle.expect( "\$" )
379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 main.log.error( "Connection to CLI " +
384 self.name + " timeout" )
385 return main.FALSE
386
387 except TypeError:
388 main.log.exception( self.name + ": Object not as expected" )
389 return None
390 except pexpect.EOF:
391 main.log.error( self.name + ": EOF exception found" )
392 main.log.error( self.name + ": " + self.handle.before )
393 main.cleanup()
394 main.exit()
395 except Exception:
396 main.log.exception( self.name + ": Uncaught exception!" )
397 main.cleanup()
398 main.exit()
399
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800400 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800401 """
402 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800403 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800404 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700405 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800406 Available level: DEBUG, TRACE, INFO, WARN, ERROR
407 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800408 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800409 """
410 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800411 lvlStr = ""
412 if level:
413 lvlStr = "--level=" + level
414
kelvin-onlab338f5512015-02-06 10:53:16 -0800415 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700416 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800418
kelvin-onlab9f541032015-02-04 16:19:53 -0800419 response = self.handle.before
420 if re.search( "Error", response ):
421 return main.FALSE
422 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700423 except pexpect.TIMEOUT:
424 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700425 if noExit:
426 main.cleanup()
427 return None
428 else:
429 main.cleanup()
430 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800431 except pexpect.EOF:
432 main.log.error( self.name + ": EOF exception found" )
433 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700434 if noExit:
435 main.cleanup()
436 return None
437 else:
438 main.cleanup()
439 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800440 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800441 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
446 main.cleanup()
447 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400448
YPZhangebf9eb52016-05-12 15:20:24 -0700449 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800450 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800451 Send a completely user specified string to
452 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400453 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800454
YPZhang14a4aa92016-07-15 13:37:15 -0700455 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700456
andrewonlaba18f6bf2014-10-13 19:31:54 -0400457 Warning: There are no sanity checking to commands
458 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800459
kelvin8ec71442015-01-15 16:57:00 -0800460 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400461 try:
Jon Halla495f562016-05-16 18:03:26 -0700462 # Try to reconnect if disconnected from cli
463 self.handle.sendline( "" )
464 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
465 if i == 1:
466 main.log.error( self.name + ": onos cli session closed. ")
467 if self.onosIp:
468 main.log.warn( "Trying to reconnect " + self.onosIp )
469 reconnectResult = self.startOnosCli( self.onosIp )
470 if reconnectResult:
471 main.log.info( self.name + ": onos cli session reconnected." )
472 else:
473 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700474 if noExit:
475 return None
476 else:
477 main.cleanup()
478 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700479 else:
480 main.cleanup()
481 main.exit()
482 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700483 main.log.warn( "Timeout when testing cli responsiveness" )
484 main.log.debug( self.handle.before )
485 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700486 self.handle.expect( "onos>" )
487
Jon Hall14a03b52016-05-11 12:07:30 -0700488 if debug:
489 # NOTE: This adds and average of .4 seconds per call
490 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700491 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800493 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800494 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800495 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800496 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
497 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700498 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700499 main.log.debug( self.name + ": Raw output" )
500 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700501
502 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800503 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800504 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700506 main.log.debug( self.name + ": ansiEscape output" )
507 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508
kelvin-onlabfb521662015-02-27 09:52:40 -0800509 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800510 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700511 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700512 main.log.debug( self.name + ": Removed extra returns " +
513 "from output" )
514 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515
516 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800517 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700518 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700519 main.log.debug( self.name + ": parsed and stripped output" )
520 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700521
Jon Hall63604932015-02-26 17:09:50 -0800522 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700523 output = response.split( cmdStr.strip(), 1 )
524 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700525 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700526 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700527 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800528 output = output[1].strip()
529 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800530 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800531 return output
GlennRCed771242016-01-13 17:02:47 -0800532 except pexpect.TIMEOUT:
533 main.log.error( self.name + ":ONOS timeout" )
534 if debug:
535 main.log.debug( self.handle.before )
536 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700537 except IndexError:
538 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700539 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800541 except TypeError:
542 main.log.exception( self.name + ": Object not as expected" )
543 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400544 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800545 main.log.error( self.name + ": EOF exception found" )
546 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700547 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700548 return None
549 else:
550 main.cleanup()
551 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800552 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800553 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700554 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700555 return None
556 else:
557 main.cleanup()
558 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400559
kelvin8ec71442015-01-15 16:57:00 -0800560 # IMPORTANT NOTE:
561 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 # the cli command changing 'a:b' with 'aB'.
563 # Ex ) onos:topology > onosTopology
564 # onos:links > onosLinks
565 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800566
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800568 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 Adds a new cluster node by ID and address information.
570 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 * nodeId
572 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400573 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800575 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400576 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 cmdStr = "add-node " + str( nodeId ) + " " +\
578 str( ONOSIp ) + " " + str( tcpPort )
579 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700580 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800581 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800582 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800583 main.log.error( "Error in adding node" )
584 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800585 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800589 except AssertionError:
590 main.log.exception( "" )
591 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800592 except TypeError:
593 main.log.exception( self.name + ": Object not as expected" )
594 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400595 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800596 main.log.error( self.name + ": EOF exception found" )
597 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400598 main.cleanup()
599 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800600 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800601 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400602 main.cleanup()
603 main.exit()
604
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800606 """
andrewonlab86dc3082014-10-13 18:18:38 -0400607 Removes a cluster by ID
608 Issues command: 'remove-node [<node-id>]'
609 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800610 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800611 """
andrewonlab86dc3082014-10-13 18:18:38 -0400612 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400613
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700615 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700616 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800617 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700618 if re.search( "Error", handle ):
619 main.log.error( "Error in removing node" )
620 main.log.error( handle )
621 return main.FALSE
622 else:
623 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800624 except AssertionError:
625 main.log.exception( "" )
626 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800627 except TypeError:
628 main.log.exception( self.name + ": Object not as expected" )
629 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400633 main.cleanup()
634 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800635 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800636 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400637 main.cleanup()
638 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400639
Jon Hall61282e32015-03-19 11:34:11 -0700640 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800641 """
andrewonlab7c211572014-10-15 16:45:20 -0400642 List the nodes currently visible
643 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700644 Optional argument:
645 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800646 """
andrewonlab7c211572014-10-15 16:45:20 -0400647 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700648 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700649 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700650 cmdStr += " -j"
651 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700652 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800653 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700654 return output
Jon Hallc6793552016-01-19 14:18:37 -0800655 except AssertionError:
656 main.log.exception( "" )
657 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800658 except TypeError:
659 main.log.exception( self.name + ": Object not as expected" )
660 return None
andrewonlab7c211572014-10-15 16:45:20 -0400661 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800662 main.log.error( self.name + ": EOF exception found" )
663 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400664 main.cleanup()
665 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800666 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800667 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400668 main.cleanup()
669 main.exit()
670
kelvin8ec71442015-01-15 16:57:00 -0800671 def topology( self ):
672 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700673 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700674 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700675 Return:
676 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800677 """
andrewonlab95ce8322014-10-13 14:12:04 -0400678 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700679 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800681 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800682 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700683 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400684 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800685 except AssertionError:
686 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800687 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800688 except TypeError:
689 main.log.exception( self.name + ": Object not as expected" )
690 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400691 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800692 main.log.error( self.name + ": EOF exception found" )
693 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400694 main.cleanup()
695 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800696 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800697 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400698 main.cleanup()
699 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800700
jenkins7ead5a82015-03-13 10:28:21 -0700701 def deviceRemove( self, deviceId ):
702 """
703 Removes particular device from storage
704
705 TODO: refactor this function
706 """
707 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700708 cmdStr = "device-remove " + str( deviceId )
709 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800710 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800711 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700712 if re.search( "Error", handle ):
713 main.log.error( "Error in removing device" )
714 main.log.error( handle )
715 return main.FALSE
716 else:
717 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800718 except AssertionError:
719 main.log.exception( "" )
720 return None
jenkins7ead5a82015-03-13 10:28:21 -0700721 except TypeError:
722 main.log.exception( self.name + ": Object not as expected" )
723 return None
724 except pexpect.EOF:
725 main.log.error( self.name + ": EOF exception found" )
726 main.log.error( self.name + ": " + self.handle.before )
727 main.cleanup()
728 main.exit()
729 except Exception:
730 main.log.exception( self.name + ": Uncaught exception!" )
731 main.cleanup()
732 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700733
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800735 """
Jon Hall7b02d952014-10-17 20:14:54 -0400736 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400737 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800739 """
andrewonlab86dc3082014-10-13 18:18:38 -0400740 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700741 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700743 cmdStr += " -j"
744 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800745 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800746 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800748 except AssertionError:
749 main.log.exception( "" )
750 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800751 except TypeError:
752 main.log.exception( self.name + ": Object not as expected" )
753 return None
andrewonlab7c211572014-10-15 16:45:20 -0400754 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800755 main.log.error( self.name + ": EOF exception found" )
756 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400757 main.cleanup()
758 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800759 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800760 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400761 main.cleanup()
762 main.exit()
763
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800766 This balances the devices across all controllers
767 by issuing command: 'onos> onos:balance-masters'
768 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800769 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800770 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700772 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800773 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800774 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 if re.search( "Error", handle ):
776 main.log.error( "Error in balancing masters" )
777 main.log.error( handle )
778 return main.FALSE
779 else:
780 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800781 except AssertionError:
782 main.log.exception( "" )
783 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 main.cleanup()
791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800794 main.cleanup()
795 main.exit()
796
Jon Hallc6793552016-01-19 14:18:37 -0800797 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Returns the output of the masters command.
800 Optional argument:
801 * jsonFormat - boolean indicating if you want output in json
802 """
803 try:
804 cmdStr = "onos:masters"
805 if jsonFormat:
806 cmdStr += " -j"
807 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700808 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800809 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700810 return output
Jon Hallc6793552016-01-19 14:18:37 -0800811 except AssertionError:
812 main.log.exception( "" )
813 return None
acsmars24950022015-07-30 18:00:43 -0700814 except TypeError:
815 main.log.exception( self.name + ": Object not as expected" )
816 return None
817 except pexpect.EOF:
818 main.log.error( self.name + ": EOF exception found" )
819 main.log.error( self.name + ": " + self.handle.before )
820 main.cleanup()
821 main.exit()
822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
824 main.cleanup()
825 main.exit()
826
Jon Hallc6793552016-01-19 14:18:37 -0800827 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700828 """
829 Uses the master command to check that the devices' leadership
830 is evenly divided
831
832 Dependencies: checkMasters() and summary()
833
Jon Hall6509dbf2016-06-21 17:01:17 -0700834 Returns main.TRUE if the devices are balanced
835 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700836 Exits on Exception
837 Returns None on TypeError
838 """
839 try:
Jon Hallc6793552016-01-19 14:18:37 -0800840 summaryOutput = self.summary()
841 totalDevices = json.loads( summaryOutput )[ "devices" ]
842 except ( TypeError, ValueError ):
843 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
844 return None
845 try:
acsmars24950022015-07-30 18:00:43 -0700846 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800847 mastersOutput = self.checkMasters()
848 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700849 first = masters[ 0 ][ "size" ]
850 for master in masters:
851 totalOwnedDevices += master[ "size" ]
852 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
853 main.log.error( "Mastership not balanced" )
854 main.log.info( "\n" + self.checkMasters( False ) )
855 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700856 main.log.info( "Mastership balanced between " +
857 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700858 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800859 except ( TypeError, ValueError ):
860 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700861 return None
862 except pexpect.EOF:
863 main.log.error( self.name + ": EOF exception found" )
864 main.log.error( self.name + ": " + self.handle.before )
865 main.cleanup()
866 main.exit()
867 except Exception:
868 main.log.exception( self.name + ": Uncaught exception!" )
869 main.cleanup()
870 main.exit()
871
YPZhangfebf7302016-05-24 16:45:56 -0700872 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800873 """
Jon Halle8217482014-10-17 13:49:14 -0400874 Lists all core links
875 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800877 """
Jon Halle8217482014-10-17 13:49:14 -0400878 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700879 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700882 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800883 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800884 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700885 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800886 except AssertionError:
887 main.log.exception( "" )
888 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800889 except TypeError:
890 main.log.exception( self.name + ": Object not as expected" )
891 return None
Jon Halle8217482014-10-17 13:49:14 -0400892 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800893 main.log.error( self.name + ": EOF exception found" )
894 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400895 main.cleanup()
896 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800897 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800898 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400899 main.cleanup()
900 main.exit()
901
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800903 """
Jon Halle8217482014-10-17 13:49:14 -0400904 Lists all ports
905 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800907 """
Jon Halle8217482014-10-17 13:49:14 -0400908 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700911 cmdStr += " -j"
912 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800913 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800914 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700915 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800916 except AssertionError:
917 main.log.exception( "" )
918 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800919 except TypeError:
920 main.log.exception( self.name + ": Object not as expected" )
921 return None
Jon Halle8217482014-10-17 13:49:14 -0400922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400925 main.cleanup()
926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800927 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800928 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400929 main.cleanup()
930 main.exit()
931
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800933 """
Jon Hall983a1702014-10-28 18:44:22 -0400934 Lists all devices and the controllers with roles assigned to them
935 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800936 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800937 """
andrewonlab7c211572014-10-15 16:45:20 -0400938 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700939 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800940 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700941 cmdStr += " -j"
942 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800943 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800944 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700945 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800946 except AssertionError:
947 main.log.exception( "" )
948 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800949 except TypeError:
950 main.log.exception( self.name + ": Object not as expected" )
951 return None
Jon Hall983a1702014-10-28 18:44:22 -0400952 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800953 main.log.error( self.name + ": EOF exception found" )
954 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400955 main.cleanup()
956 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800957 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800958 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400959 main.cleanup()
960 main.exit()
961
kelvin-onlabd3b64892015-01-20 13:26:24 -0800962 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800963 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800964 Given the a string containing the json representation of the "roles"
965 cli command and a partial or whole device id, returns a json object
966 containing the roles output for the first device whose id contains
967 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400968
969 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800970 A dict of the role assignments for the given device or
971 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800972 """
Jon Hall983a1702014-10-28 18:44:22 -0400973 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400975 return None
976 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800977 rawRoles = self.roles()
978 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800979 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800980 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800981 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400983 return device
984 return None
Jon Hallc6793552016-01-19 14:18:37 -0800985 except ( TypeError, ValueError ):
986 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800987 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400988 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800989 main.log.error( self.name + ": EOF exception found" )
990 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400991 main.cleanup()
992 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800993 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800994 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400995 main.cleanup()
996 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800997
kelvin-onlabd3b64892015-01-20 13:26:24 -0800998 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800999 """
Jon Hall94fd0472014-12-08 11:52:42 -08001000 Iterates through each device and checks if there is a master assigned
1001 Returns: main.TRUE if each device has a master
1002 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001003 """
Jon Hall94fd0472014-12-08 11:52:42 -08001004 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 rawRoles = self.roles()
1006 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001007 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001009 # print device
1010 if device[ 'master' ] == "none":
1011 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001012 return main.FALSE
1013 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001014 except ( TypeError, ValueError ):
1015 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001016 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001017 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001018 main.log.error( self.name + ": EOF exception found" )
1019 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001020 main.cleanup()
1021 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001022 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001023 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001024 main.cleanup()
1025 main.exit()
1026
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001028 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 Returns string of paths, and the cost.
1030 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001031 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001032 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1034 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001035 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001036 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001037 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( "Error in getting paths" )
1039 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001040 else:
kelvin8ec71442015-01-15 16:57:00 -08001041 path = handle.split( ";" )[ 0 ]
1042 cost = handle.split( ";" )[ 1 ]
1043 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001044 except AssertionError:
1045 main.log.exception( "" )
1046 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001047 except TypeError:
1048 main.log.exception( self.name + ": Object not as expected" )
1049 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001050 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001051 main.log.error( self.name + ": EOF exception found" )
1052 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001053 main.cleanup()
1054 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001055 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001056 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001057 main.cleanup()
1058 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001059
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001061 """
Jon Hallffb386d2014-11-21 13:43:38 -08001062 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001063 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001065 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001066 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001067 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001069 cmdStr += " -j"
1070 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001071 if handle:
1072 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001073 # TODO: Maybe make this less hardcoded
1074 # ConsistentMap Exceptions
1075 assert "org.onosproject.store.service" not in handle
1076 # Node not leader
1077 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001078 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001079 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001080 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001081 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001082 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001083 except TypeError:
1084 main.log.exception( self.name + ": Object not as expected" )
1085 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001087 main.log.error( self.name + ": EOF exception found" )
1088 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 main.cleanup()
1090 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001091 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001092 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001093 main.cleanup()
1094 main.exit()
1095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001097 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001098 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001099
Jon Hallefbd9792015-03-05 16:11:36 -08001100 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001101 partial mac address
1102
Jon Hall42db6dc2014-10-24 19:03:48 -04001103 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001104 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001105 try:
kelvin8ec71442015-01-15 16:57:00 -08001106 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001107 return None
1108 else:
1109 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 rawHosts = self.hosts()
1111 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001112 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001114 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001115 if not host:
1116 pass
1117 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001118 return host
1119 return None
Jon Hallc6793552016-01-19 14:18:37 -08001120 except ( TypeError, ValueError ):
1121 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001122 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001126 main.cleanup()
1127 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001128 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001129 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001130 main.cleanup()
1131 main.exit()
1132
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001134 """
1135 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001136 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001137
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140 IMPORTANT:
1141 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001142 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001143 Furthermore, it assumes that value of VLAN is '-1'
1144 Description:
kelvin8ec71442015-01-15 16:57:00 -08001145 Converts mininet hosts ( h1, h2, h3... ) into
1146 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1147 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001150
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001152 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001153 hostHex = hex( int( host ) ).zfill( 12 )
1154 hostHex = str( hostHex ).replace( 'x', '0' )
1155 i = iter( str( hostHex ) )
1156 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1157 hostHex = hostHex + "/-1"
1158 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001159
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001161
Jon Halld4d4b372015-01-28 16:02:41 -08001162 except TypeError:
1163 main.log.exception( self.name + ": Object not as expected" )
1164 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001166 main.log.error( self.name + ": EOF exception found" )
1167 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001168 main.cleanup()
1169 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001170 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001171 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001172 main.cleanup()
1173 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001174
Jeremy Songsterc032f162016-08-04 17:14:49 -07001175 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001176 """
andrewonlabe6745342014-10-17 14:29:13 -04001177 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 * hostIdOne: ONOS host id for host1
1179 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001180 Optional:
1181 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001182 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001183 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001184 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001185 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001186 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001187 Returns:
1188 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001189 """
andrewonlabe6745342014-10-17 14:29:13 -04001190 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001191 cmdStr = "add-host-intent "
1192 if vlanId:
1193 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001194 if setVlan:
1195 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001196 if encap:
1197 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001198 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001200 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001201 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001202 if re.search( "Error", handle ):
1203 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001204 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001205 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001206 else:
1207 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001208 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1209 match = re.search('id=0x([\da-f]+),', handle)
1210 if match:
1211 return match.group()[3:-1]
1212 else:
1213 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001214 main.log.debug( "Response from ONOS was: " +
1215 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001216 return None
Jon Hallc6793552016-01-19 14:18:37 -08001217 except AssertionError:
1218 main.log.exception( "" )
1219 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001220 except TypeError:
1221 main.log.exception( self.name + ": Object not as expected" )
1222 return None
andrewonlabe6745342014-10-17 14:29:13 -04001223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001226 main.cleanup()
1227 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001229 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001230 main.cleanup()
1231 main.exit()
1232
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001234 """
andrewonlab7b31d232014-10-24 13:31:47 -04001235 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 * ingressDevice: device id of ingress device
1237 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001238 Optional:
1239 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 Description:
1241 Adds an optical intent by specifying an ingress and egress device
1242 Returns:
1243 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001244 """
andrewonlab7b31d232014-10-24 13:31:47 -04001245 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1247 " " + str( egressDevice )
1248 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001249 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001250 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001251 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001252 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001253 main.log.error( "Error in adding Optical intent" )
1254 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001255 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001256 main.log.info( "Optical intent installed between " +
1257 str( ingressDevice ) + " and " +
1258 str( egressDevice ) )
1259 match = re.search('id=0x([\da-f]+),', handle)
1260 if match:
1261 return match.group()[3:-1]
1262 else:
1263 main.log.error( "Error, intent ID not found" )
1264 return None
Jon Hallc6793552016-01-19 14:18:37 -08001265 except AssertionError:
1266 main.log.exception( "" )
1267 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001268 except TypeError:
1269 main.log.exception( self.name + ": Object not as expected" )
1270 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001271 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001272 main.log.error( self.name + ": EOF exception found" )
1273 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001274 main.cleanup()
1275 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001276 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001277 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001278 main.cleanup()
1279 main.exit()
1280
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001282 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 ingressDevice,
1284 egressDevice,
1285 portIngress="",
1286 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001287 ethType="",
1288 ethSrc="",
1289 ethDst="",
1290 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001292 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001293 ipProto="",
1294 ipSrc="",
1295 ipDst="",
1296 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001297 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001298 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001299 setVlan="",
1300 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001301 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001302 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 * ingressDevice: device id of ingress device
1304 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001305 Optional:
1306 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001307 * ethSrc: specify ethSrc ( i.e. src mac addr )
1308 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001309 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001311 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001312 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001313 * ipSrc: specify ip source address
1314 * ipDst: specify ip destination address
1315 * tcpSrc: specify tcp source port
1316 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001317 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001318 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001319 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001320 Description:
kelvin8ec71442015-01-15 16:57:00 -08001321 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001322 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001323 Returns:
1324 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001325
Jon Halle3f39ff2015-01-13 11:50:53 -08001326 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001327 options developers provide for point-to-point
1328 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001329 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001330 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001331 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001332
Jeremy Songsterff553672016-05-12 17:06:23 -07001333 if ethType:
1334 cmd += " --ethType " + str( ethType )
1335 if ethSrc:
1336 cmd += " --ethSrc " + str( ethSrc )
1337 if ethDst:
1338 cmd += " --ethDst " + str( ethDst )
1339 if bandwidth:
1340 cmd += " --bandwidth " + str( bandwidth )
1341 if lambdaAlloc:
1342 cmd += " --lambda "
1343 if ipProto:
1344 cmd += " --ipProto " + str( ipProto )
1345 if ipSrc:
1346 cmd += " --ipSrc " + str( ipSrc )
1347 if ipDst:
1348 cmd += " --ipDst " + str( ipDst )
1349 if tcpSrc:
1350 cmd += " --tcpSrc " + str( tcpSrc )
1351 if tcpDst:
1352 cmd += " --tcpDst " + str( tcpDst )
1353 if vlanId:
1354 cmd += " -v " + str( vlanId )
1355 if setVlan:
1356 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001357 if encap:
1358 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001359 if protected:
1360 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001361
kelvin8ec71442015-01-15 16:57:00 -08001362 # Check whether the user appended the port
1363 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001364 if "/" in ingressDevice:
1365 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001366 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001369 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 # Would it make sense to throw an exception and exit
1371 # the test?
1372 return None
andrewonlab36af3822014-11-18 17:48:18 -05001373
kelvin8ec71442015-01-15 16:57:00 -08001374 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 str( ingressDevice ) + "/" +\
1376 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001377
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 if "/" in egressDevice:
1379 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001380 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001382 main.log.error( "You must specify the egress port" )
1383 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001384
kelvin8ec71442015-01-15 16:57:00 -08001385 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 str( egressDevice ) + "/" +\
1387 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001388
kelvin-onlab898a6c62015-01-16 14:13:53 -08001389 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001390 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001391 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001392 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001393 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001395 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001396 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001397 # TODO: print out all the options in this message?
1398 main.log.info( "Point-to-point intent installed between " +
1399 str( ingressDevice ) + " and " +
1400 str( egressDevice ) )
1401 match = re.search('id=0x([\da-f]+),', handle)
1402 if match:
1403 return match.group()[3:-1]
1404 else:
1405 main.log.error( "Error, intent ID not found" )
1406 return None
Jon Hallc6793552016-01-19 14:18:37 -08001407 except AssertionError:
1408 main.log.exception( "" )
1409 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001410 except TypeError:
1411 main.log.exception( self.name + ": Object not as expected" )
1412 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001413 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001414 main.log.error( self.name + ": EOF exception found" )
1415 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001416 main.cleanup()
1417 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001418 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001419 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001420 main.cleanup()
1421 main.exit()
1422
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001424 self,
shahshreyac2f97072015-03-19 17:04:29 -07001425 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001427 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001429 ethType="",
1430 ethSrc="",
1431 ethDst="",
1432 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001434 ipProto="",
1435 ipSrc="",
1436 ipDst="",
1437 tcpSrc="",
1438 tcpDst="",
1439 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001440 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001441 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001442 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001443 partial=False,
1444 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001445 """
shahshreyad0c80432014-12-04 16:56:05 -08001446 Note:
shahshreya70622b12015-03-19 17:19:00 -07001447 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001448 is same. That is, all ingress devices include port numbers
1449 with a "/" or all ingress devices could specify device
1450 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001451 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001452 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001453 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001455 Optional:
1456 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001457 * ethSrc: specify ethSrc ( i.e. src mac addr )
1458 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001459 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001461 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001462 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001463 * ipSrc: specify ip source address
1464 * ipDst: specify ip destination address
1465 * tcpSrc: specify tcp source port
1466 * tcpDst: specify tcp destination port
1467 * setEthSrc: action to Rewrite Source MAC Address
1468 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001469 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001470 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001471 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001472 Description:
kelvin8ec71442015-01-15 16:57:00 -08001473 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001474 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001475 Returns:
1476 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001477
Jon Halle3f39ff2015-01-13 11:50:53 -08001478 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001479 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001480 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001481 """
shahshreyad0c80432014-12-04 16:56:05 -08001482 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001483 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001484
Jeremy Songsterff553672016-05-12 17:06:23 -07001485 if ethType:
1486 cmd += " --ethType " + str( ethType )
1487 if ethSrc:
1488 cmd += " --ethSrc " + str( ethSrc )
1489 if ethDst:
1490 cmd += " --ethDst " + str( ethDst )
1491 if bandwidth:
1492 cmd += " --bandwidth " + str( bandwidth )
1493 if lambdaAlloc:
1494 cmd += " --lambda "
1495 if ipProto:
1496 cmd += " --ipProto " + str( ipProto )
1497 if ipSrc:
1498 cmd += " --ipSrc " + str( ipSrc )
1499 if ipDst:
1500 cmd += " --ipDst " + str( ipDst )
1501 if tcpSrc:
1502 cmd += " --tcpSrc " + str( tcpSrc )
1503 if tcpDst:
1504 cmd += " --tcpDst " + str( tcpDst )
1505 if setEthSrc:
1506 cmd += " --setEthSrc " + str( setEthSrc )
1507 if setEthDst:
1508 cmd += " --setEthDst " + str( setEthDst )
1509 if vlanId:
1510 cmd += " -v " + str( vlanId )
1511 if setVlan:
1512 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001513 if partial:
1514 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001515 if encap:
1516 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001517
kelvin8ec71442015-01-15 16:57:00 -08001518 # Check whether the user appended the port
1519 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001520
1521 if portIngressList is None:
1522 for ingressDevice in ingressDeviceList:
1523 if "/" in ingressDevice:
1524 cmd += " " + str( ingressDevice )
1525 else:
1526 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001527 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001528 # TODO: perhaps more meaningful return
1529 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001530 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001531 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001532 for ingressDevice, portIngress in zip( ingressDeviceList,
1533 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001534 cmd += " " + \
1535 str( ingressDevice ) + "/" +\
1536 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001537 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001538 main.log.error( "Device list and port list does not " +
1539 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001540 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 if "/" in egressDevice:
1542 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001543 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001545 main.log.error( "You must specify " +
1546 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001547 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001548
kelvin8ec71442015-01-15 16:57:00 -08001549 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 str( egressDevice ) + "/" +\
1551 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001552 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001553 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001554 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001555 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001556 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001557 main.log.error( "Error in adding multipoint-to-singlepoint " +
1558 "intent" )
1559 return None
shahshreyad0c80432014-12-04 16:56:05 -08001560 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001561 match = re.search('id=0x([\da-f]+),', handle)
1562 if match:
1563 return match.group()[3:-1]
1564 else:
1565 main.log.error( "Error, intent ID not found" )
1566 return None
Jon Hallc6793552016-01-19 14:18:37 -08001567 except AssertionError:
1568 main.log.exception( "" )
1569 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001570 except TypeError:
1571 main.log.exception( self.name + ": Object not as expected" )
1572 return None
1573 except pexpect.EOF:
1574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
1576 main.cleanup()
1577 main.exit()
1578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
1580 main.cleanup()
1581 main.exit()
1582
1583 def addSinglepointToMultipointIntent(
1584 self,
1585 ingressDevice,
1586 egressDeviceList,
1587 portIngress="",
1588 portEgressList=None,
1589 ethType="",
1590 ethSrc="",
1591 ethDst="",
1592 bandwidth="",
1593 lambdaAlloc=False,
1594 ipProto="",
1595 ipSrc="",
1596 ipDst="",
1597 tcpSrc="",
1598 tcpDst="",
1599 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001600 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001602 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001603 partial=False,
1604 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001605 """
1606 Note:
1607 This function assumes the format of all egress devices
1608 is same. That is, all egress devices include port numbers
1609 with a "/" or all egress devices could specify device
1610 ids and port numbers seperately.
1611 Required:
1612 * EgressDeviceList: List of device ids of egress device
1613 ( Atleast 2 eress devices required in the list )
1614 * ingressDevice: device id of ingress device
1615 Optional:
1616 * ethType: specify ethType
1617 * ethSrc: specify ethSrc ( i.e. src mac addr )
1618 * ethDst: specify ethDst ( i.e. dst mac addr )
1619 * bandwidth: specify bandwidth capacity of link
1620 * lambdaAlloc: if True, intent will allocate lambda
1621 for the specified intent
1622 * ipProto: specify ip protocol
1623 * ipSrc: specify ip source address
1624 * ipDst: specify ip destination address
1625 * tcpSrc: specify tcp source port
1626 * tcpDst: specify tcp destination port
1627 * setEthSrc: action to Rewrite Source MAC Address
1628 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001629 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001630 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001631 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001632 Description:
1633 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1634 specifying device id's and optional fields
1635 Returns:
1636 A string of the intent id or None on error
1637
1638 NOTE: This function may change depending on the
1639 options developers provide for singlepoint-to-multipoint
1640 intent via cli
1641 """
1642 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001643 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001644
Jeremy Songsterff553672016-05-12 17:06:23 -07001645 if ethType:
1646 cmd += " --ethType " + str( ethType )
1647 if ethSrc:
1648 cmd += " --ethSrc " + str( ethSrc )
1649 if ethDst:
1650 cmd += " --ethDst " + str( ethDst )
1651 if bandwidth:
1652 cmd += " --bandwidth " + str( bandwidth )
1653 if lambdaAlloc:
1654 cmd += " --lambda "
1655 if ipProto:
1656 cmd += " --ipProto " + str( ipProto )
1657 if ipSrc:
1658 cmd += " --ipSrc " + str( ipSrc )
1659 if ipDst:
1660 cmd += " --ipDst " + str( ipDst )
1661 if tcpSrc:
1662 cmd += " --tcpSrc " + str( tcpSrc )
1663 if tcpDst:
1664 cmd += " --tcpDst " + str( tcpDst )
1665 if setEthSrc:
1666 cmd += " --setEthSrc " + str( setEthSrc )
1667 if setEthDst:
1668 cmd += " --setEthDst " + str( setEthDst )
1669 if vlanId:
1670 cmd += " -v " + str( vlanId )
1671 if setVlan:
1672 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001673 if partial:
1674 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001675 if encap:
1676 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001677
1678 # Check whether the user appended the port
1679 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001680
kelvin-onlabb9408212015-04-01 13:34:04 -07001681 if "/" in ingressDevice:
1682 cmd += " " + str( ingressDevice )
1683 else:
1684 if not portIngress:
1685 main.log.error( "You must specify " +
1686 "the Ingress port" )
1687 return main.FALSE
1688
1689 cmd += " " +\
1690 str( ingressDevice ) + "/" +\
1691 str( portIngress )
1692
1693 if portEgressList is None:
1694 for egressDevice in egressDeviceList:
1695 if "/" in egressDevice:
1696 cmd += " " + str( egressDevice )
1697 else:
1698 main.log.error( "You must specify " +
1699 "the egress port" )
1700 # TODO: perhaps more meaningful return
1701 return main.FALSE
1702 else:
1703 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001704 for egressDevice, portEgress in zip( egressDeviceList,
1705 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001706 cmd += " " + \
1707 str( egressDevice ) + "/" +\
1708 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001709 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001710 main.log.error( "Device list and port list does not " +
1711 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001712 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001713 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001714 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001715 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001716 # If error, return error message
1717 if re.search( "Error", handle ):
1718 main.log.error( "Error in adding singlepoint-to-multipoint " +
1719 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001720 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001721 else:
1722 match = re.search('id=0x([\da-f]+),', handle)
1723 if match:
1724 return match.group()[3:-1]
1725 else:
1726 main.log.error( "Error, intent ID not found" )
1727 return None
Jon Hallc6793552016-01-19 14:18:37 -08001728 except AssertionError:
1729 main.log.exception( "" )
1730 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001731 except TypeError:
1732 main.log.exception( self.name + ": Object not as expected" )
1733 return None
shahshreyad0c80432014-12-04 16:56:05 -08001734 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001735 main.log.error( self.name + ": EOF exception found" )
1736 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001737 main.cleanup()
1738 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001739 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001740 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001741 main.cleanup()
1742 main.exit()
1743
Hari Krishna9e232602015-04-13 17:29:08 -07001744 def addMplsIntent(
1745 self,
1746 ingressDevice,
1747 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001748 ingressPort="",
1749 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001750 ethType="",
1751 ethSrc="",
1752 ethDst="",
1753 bandwidth="",
1754 lambdaAlloc=False,
1755 ipProto="",
1756 ipSrc="",
1757 ipDst="",
1758 tcpSrc="",
1759 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001760 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001761 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001762 priority=""):
1763 """
1764 Required:
1765 * ingressDevice: device id of ingress device
1766 * egressDevice: device id of egress device
1767 Optional:
1768 * ethType: specify ethType
1769 * ethSrc: specify ethSrc ( i.e. src mac addr )
1770 * ethDst: specify ethDst ( i.e. dst mac addr )
1771 * bandwidth: specify bandwidth capacity of link
1772 * lambdaAlloc: if True, intent will allocate lambda
1773 for the specified intent
1774 * ipProto: specify ip protocol
1775 * ipSrc: specify ip source address
1776 * ipDst: specify ip destination address
1777 * tcpSrc: specify tcp source port
1778 * tcpDst: specify tcp destination port
1779 * ingressLabel: Ingress MPLS label
1780 * egressLabel: Egress MPLS label
1781 Description:
1782 Adds MPLS intent by
1783 specifying device id's and optional fields
1784 Returns:
1785 A string of the intent id or None on error
1786
1787 NOTE: This function may change depending on the
1788 options developers provide for MPLS
1789 intent via cli
1790 """
1791 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001792 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001793
Jeremy Songsterff553672016-05-12 17:06:23 -07001794 if ethType:
1795 cmd += " --ethType " + str( ethType )
1796 if ethSrc:
1797 cmd += " --ethSrc " + str( ethSrc )
1798 if ethDst:
1799 cmd += " --ethDst " + str( ethDst )
1800 if bandwidth:
1801 cmd += " --bandwidth " + str( bandwidth )
1802 if lambdaAlloc:
1803 cmd += " --lambda "
1804 if ipProto:
1805 cmd += " --ipProto " + str( ipProto )
1806 if ipSrc:
1807 cmd += " --ipSrc " + str( ipSrc )
1808 if ipDst:
1809 cmd += " --ipDst " + str( ipDst )
1810 if tcpSrc:
1811 cmd += " --tcpSrc " + str( tcpSrc )
1812 if tcpDst:
1813 cmd += " --tcpDst " + str( tcpDst )
1814 if ingressLabel:
1815 cmd += " --ingressLabel " + str( ingressLabel )
1816 if egressLabel:
1817 cmd += " --egressLabel " + str( egressLabel )
1818 if priority:
1819 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001820
1821 # Check whether the user appended the port
1822 # or provided it as an input
1823 if "/" in ingressDevice:
1824 cmd += " " + str( ingressDevice )
1825 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001826 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001827 main.log.error( "You must specify the ingress port" )
1828 return None
1829
1830 cmd += " " + \
1831 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001832 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001833
1834 if "/" in egressDevice:
1835 cmd += " " + str( egressDevice )
1836 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001837 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001838 main.log.error( "You must specify the egress port" )
1839 return None
1840
1841 cmd += " " +\
1842 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001843 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001844
1845 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001846 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001847 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001848 # If error, return error message
1849 if re.search( "Error", handle ):
1850 main.log.error( "Error in adding mpls intent" )
1851 return None
1852 else:
1853 # TODO: print out all the options in this message?
1854 main.log.info( "MPLS intent installed between " +
1855 str( ingressDevice ) + " and " +
1856 str( egressDevice ) )
1857 match = re.search('id=0x([\da-f]+),', handle)
1858 if match:
1859 return match.group()[3:-1]
1860 else:
1861 main.log.error( "Error, intent ID not found" )
1862 return None
Jon Hallc6793552016-01-19 14:18:37 -08001863 except AssertionError:
1864 main.log.exception( "" )
1865 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001866 except TypeError:
1867 main.log.exception( self.name + ": Object not as expected" )
1868 return None
1869 except pexpect.EOF:
1870 main.log.error( self.name + ": EOF exception found" )
1871 main.log.error( self.name + ": " + self.handle.before )
1872 main.cleanup()
1873 main.exit()
1874 except Exception:
1875 main.log.exception( self.name + ": Uncaught exception!" )
1876 main.cleanup()
1877 main.exit()
1878
Jon Hallefbd9792015-03-05 16:11:36 -08001879 def removeIntent( self, intentId, app='org.onosproject.cli',
1880 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001881 """
shahshreya1c818fc2015-02-26 13:44:08 -08001882 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001883 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001884 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001885 -p or --purge: Purge the intent from the store after removal
1886
Jon Halle3f39ff2015-01-13 11:50:53 -08001887 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001888 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001889 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001890 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001891 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001892 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001893 if purge:
1894 cmdStr += " -p"
1895 if sync:
1896 cmdStr += " -s"
1897
1898 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001900 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001901 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001902 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001903 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001904 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001905 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001906 # TODO: Should this be main.TRUE
1907 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001908 except AssertionError:
1909 main.log.exception( "" )
1910 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001914 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001917 main.cleanup()
1918 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001919 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001920 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001921 main.cleanup()
1922 main.exit()
1923
YPZhangfebf7302016-05-24 16:45:56 -07001924 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001925 """
1926 Description:
1927 Remove all the intents
1928 Optional args:-
1929 -s or --sync: Waits for the removal before returning
1930 -p or --purge: Purge the intent from the store after removal
1931 Returns:
1932 Returns main.TRUE if all intents are removed, otherwise returns
1933 main.FALSE; Returns None for exception
1934 """
1935 try:
1936 cmdStr = "remove-intent"
1937 if purge:
1938 cmdStr += " -p"
1939 if sync:
1940 cmdStr += " -s"
1941
1942 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001943 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001944 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001945 assert "Command not found:" not in handle, handle
1946 if re.search( "Error", handle ):
1947 main.log.error( "Error in removing intent" )
1948 return main.FALSE
1949 else:
1950 return main.TRUE
1951 except AssertionError:
1952 main.log.exception( "" )
1953 return None
1954 except TypeError:
1955 main.log.exception( self.name + ": Object not as expected" )
1956 return None
1957 except pexpect.EOF:
1958 main.log.error( self.name + ": EOF exception found" )
1959 main.log.error( self.name + ": " + self.handle.before )
1960 main.cleanup()
1961 main.exit()
1962 except Exception:
1963 main.log.exception( self.name + ": Uncaught exception!" )
1964 main.cleanup()
1965 main.exit()
1966
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001967 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001968 """
1969 Purges all WITHDRAWN Intents
1970 """
1971 try:
1972 cmdStr = "purge-intents"
1973 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001974 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001975 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001976 if re.search( "Error", handle ):
1977 main.log.error( "Error in purging intents" )
1978 return main.FALSE
1979 else:
1980 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001981 except AssertionError:
1982 main.log.exception( "" )
1983 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001984 except TypeError:
1985 main.log.exception( self.name + ": Object not as expected" )
1986 return None
1987 except pexpect.EOF:
1988 main.log.error( self.name + ": EOF exception found" )
1989 main.log.error( self.name + ": " + self.handle.before )
1990 main.cleanup()
1991 main.exit()
1992 except Exception:
1993 main.log.exception( self.name + ": Uncaught exception!" )
1994 main.cleanup()
1995 main.exit()
1996
kelvin-onlabd3b64892015-01-20 13:26:24 -08001997 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001998 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001999 NOTE: This method should be used after installing application:
2000 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002001 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002002 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002003 Description:
2004 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002005 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002006 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002007 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002009 cmdStr += " -j"
2010 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002011 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002012 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002013 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002014 except AssertionError:
2015 main.log.exception( "" )
2016 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002017 except TypeError:
2018 main.log.exception( self.name + ": Object not as expected" )
2019 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002021 main.log.error( self.name + ": EOF exception found" )
2022 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002023 main.cleanup()
2024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002026 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002027 main.cleanup()
2028 main.exit()
2029
pingping-lin54b03372015-08-13 14:43:10 -07002030 def ipv4RouteNumber( self ):
2031 """
2032 NOTE: This method should be used after installing application:
2033 onos-app-sdnip
2034 Description:
2035 Obtain the total IPv4 routes number in the system
2036 """
2037 try:
2038 cmdStr = "routes -s -j"
2039 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002040 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002041 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002042 jsonResult = json.loads( handle )
2043 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002044 except AssertionError:
2045 main.log.exception( "" )
2046 return None
2047 except ( TypeError, ValueError ):
2048 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002049 return None
2050 except pexpect.EOF:
2051 main.log.error( self.name + ": EOF exception found" )
2052 main.log.error( self.name + ": " + self.handle.before )
2053 main.cleanup()
2054 main.exit()
2055 except Exception:
2056 main.log.exception( self.name + ": Uncaught exception!" )
2057 main.cleanup()
2058 main.exit()
2059
pingping-lin8244a3b2015-09-16 13:36:56 -07002060 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002061 """
andrewonlabe6745342014-10-17 14:29:13 -04002062 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002063 Obtain intents from the ONOS cli.
2064 Optional:
2065 * jsonFormat: Enable output formatting in json, default to True
2066 * summary: Whether only output the intent summary, defaults to False
2067 * type: Only output a certain type of intent. This options is valid
2068 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002069 """
andrewonlabe6745342014-10-17 14:29:13 -04002070 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002071 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002072 if summary:
2073 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002075 cmdStr += " -j"
2076 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002077 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002078 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002079 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002080 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002081 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002082 else:
Jon Hallff566d52016-01-15 14:45:36 -08002083 intentType = ""
2084 # IF we want the summary of a specific intent type
2085 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002086 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002087 if intentType in jsonResult.keys():
2088 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002089 else:
Jon Hallff566d52016-01-15 14:45:36 -08002090 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002091 return handle
2092 else:
2093 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002094 except AssertionError:
2095 main.log.exception( "" )
2096 return None
2097 except ( TypeError, ValueError ):
2098 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002099 return None
2100 except pexpect.EOF:
2101 main.log.error( self.name + ": EOF exception found" )
2102 main.log.error( self.name + ": " + self.handle.before )
2103 main.cleanup()
2104 main.exit()
2105 except Exception:
2106 main.log.exception( self.name + ": Uncaught exception!" )
2107 main.cleanup()
2108 main.exit()
2109
kelvin-onlab54400a92015-02-26 18:05:51 -08002110 def getIntentState(self, intentsId, intentsJson=None):
2111 """
You Wangfdcbfc42016-05-16 12:16:53 -07002112 Description:
2113 Gets intent state. Accepts a single intent ID (string type) or a
2114 list of intent IDs.
2115 Parameters:
2116 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002117 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002118 Returns:
2119 Returns the state (string type) of the ID if a single intent ID is
2120 accepted.
2121 Returns a list of dictionaries if a list of intent IDs is accepted,
2122 and each dictionary maps 'id' to the Intent ID and 'state' to
2123 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002124 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002125 try:
2126 state = "State is Undefined"
2127 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002128 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002129 else:
Jon Hallc6793552016-01-19 14:18:37 -08002130 rawJson = intentsJson
2131 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002132 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002133 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002134 if intentsId == intent[ 'id' ]:
2135 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002136 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002137 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2138 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002139 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002140 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002141 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002142 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002143 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002144 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002145 if intentsId[ i ] == intents[ 'id' ]:
2146 stateDict[ 'state' ] = intents[ 'state' ]
2147 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002148 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002149 break
Jon Hallefbd9792015-03-05 16:11:36 -08002150 if len( intentsId ) != len( dictList ):
2151 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002152 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002153 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002154 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002155 return None
Jon Hallc6793552016-01-19 14:18:37 -08002156 except ( TypeError, ValueError ):
2157 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002158 return None
2159 except pexpect.EOF:
2160 main.log.error( self.name + ": EOF exception found" )
2161 main.log.error( self.name + ": " + self.handle.before )
2162 main.cleanup()
2163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002164 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002166 main.cleanup()
2167 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002168
kelvin-onlabf512e942015-06-08 19:42:59 -07002169 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002170 """
2171 Description:
2172 Check intents state
2173 Required:
2174 intentsId - List of intents ID to be checked
2175 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002176 expectedState - Check the expected state(s) of each intents
2177 state in the list.
2178 *NOTE: You can pass in a list of expected state,
2179 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002180 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002181 Returns main.TRUE only if all intent are the same as expected states
2182 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002183 """
2184 try:
2185 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002186 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002187 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002188 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002189 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002190 "getting intents state" )
2191 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002192
2193 if isinstance( expectedState, types.StringType ):
2194 for intents in intentsDict:
2195 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002196 main.log.debug( self.name + " : Intent ID - " +
2197 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002198 " actual state = " +
2199 intents.get( 'state' )
2200 + " does not equal expected state = "
2201 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002202 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002203
2204 elif isinstance( expectedState, types.ListType ):
2205 for intents in intentsDict:
2206 if not any( state == intents.get( 'state' ) for state in
2207 expectedState ):
2208 main.log.debug( self.name + " : Intent ID - " +
2209 intents.get( 'id' ) +
2210 " actual state = " +
2211 intents.get( 'state' ) +
2212 " does not equal expected states = "
2213 + str( expectedState ) )
2214 returnValue = main.FALSE
2215
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002216 if returnValue == main.TRUE:
2217 main.log.info( self.name + ": All " +
2218 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002219 " intents are in " + str( expectedState ) +
2220 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002221 return returnValue
2222 except TypeError:
2223 main.log.exception( self.name + ": Object not as expected" )
2224 return None
2225 except pexpect.EOF:
2226 main.log.error( self.name + ": EOF exception found" )
2227 main.log.error( self.name + ": " + self.handle.before )
2228 main.cleanup()
2229 main.exit()
2230 except Exception:
2231 main.log.exception( self.name + ": Uncaught exception!" )
2232 main.cleanup()
2233 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002234
You Wang66518af2016-05-16 15:32:59 -07002235 def compareIntent( self, intentDict ):
2236 """
2237 Description:
2238 Compare the intent ids and states provided in the argument with all intents in ONOS
2239 Return:
2240 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2241 Arguments:
2242 intentDict: a dictionary which maps intent ids to intent states
2243 """
2244 try:
2245 intentsRaw = self.intents()
2246 intentsJson = json.loads( intentsRaw )
2247 intentDictONOS = {}
2248 for intent in intentsJson:
2249 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002250 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002251 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002252 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002253 str( len( intentDict ) ) + " expected and " +
2254 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002255 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002256 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002257 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002258 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2259 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002260 else:
2261 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2262 main.log.debug( self.name + ": intent ID - " + intentID +
2263 " expected state is " + intentDict[ intentID ] +
2264 " but actual state is " + intentDictONOS[ intentID ] )
2265 returnValue = main.FALSE
2266 intentDictONOS.pop( intentID )
2267 if len( intentDictONOS ) > 0:
2268 returnValue = main.FALSE
2269 for intentID in intentDictONOS.keys():
2270 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002271 if returnValue == main.TRUE:
2272 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2273 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002274 except KeyError:
2275 main.log.exception( self.name + ": KeyError exception found" )
2276 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002277 except ( TypeError, ValueError ):
2278 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002279 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002280 except pexpect.EOF:
2281 main.log.error( self.name + ": EOF exception found" )
2282 main.log.error( self.name + ": " + self.handle.before )
2283 main.cleanup()
2284 main.exit()
2285 except Exception:
2286 main.log.exception( self.name + ": Uncaught exception!" )
2287 main.cleanup()
2288 main.exit()
2289
YPZhang14a4aa92016-07-15 13:37:15 -07002290 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002291 """
2292 Description:
2293 Check the number of installed intents.
2294 Optional:
2295 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002296 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002297 Return:
2298 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2299 , otherwise, returns main.FALSE.
2300 """
2301
2302 try:
2303 cmd = "intents -s -j"
2304
2305 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002306 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002307 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002308 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002309 response = json.loads( response )
2310
2311 # get total and installed number, see if they are match
2312 allState = response.get( 'all' )
2313 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002314 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002315 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002316 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002317 return main.FALSE
2318
Jon Hallc6793552016-01-19 14:18:37 -08002319 except ( TypeError, ValueError ):
2320 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002321 return None
2322 except pexpect.EOF:
2323 main.log.error( self.name + ": EOF exception found" )
2324 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002325 if noExit:
2326 return main.FALSE
2327 else:
2328 main.cleanup()
2329 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002330 except pexpect.TIMEOUT:
2331 main.log.error( self.name + ": ONOS timeout" )
2332 return None
GlennRCed771242016-01-13 17:02:47 -08002333 except Exception:
2334 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002335 if noExit:
2336 return main.FALSE
2337 else:
2338 main.cleanup()
2339 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002340
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002341 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002342 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002343 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002344 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002345 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002346 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002347 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002348 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002349 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002350 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002351 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002352 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002353 if noCore:
2354 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002355 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002356 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002357 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002358 assert "Command not found:" not in handle, handle
2359 if re.search( "Error:", handle ):
2360 main.log.error( self.name + ": flows() response: " +
2361 str( handle ) )
2362 return handle
2363 except AssertionError:
2364 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002365 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002366 except TypeError:
2367 main.log.exception( self.name + ": Object not as expected" )
2368 return None
Jon Hallc6793552016-01-19 14:18:37 -08002369 except pexpect.TIMEOUT:
2370 main.log.error( self.name + ": ONOS timeout" )
2371 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002373 main.log.error( self.name + ": EOF exception found" )
2374 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002375 main.cleanup()
2376 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002377 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002378 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002379 main.cleanup()
2380 main.exit()
2381
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002382 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002383 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002384 count = int( count ) if count else 0
2385 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002386
Jon Halle0f0b342017-04-18 11:43:47 -07002387 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002388 """
2389 Description:
GlennRCed771242016-01-13 17:02:47 -08002390 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002391 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2392 if the count of those states is 0, which means all current flows
2393 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002394 Optional:
GlennRCed771242016-01-13 17:02:47 -08002395 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002396 Return:
2397 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002398 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002399 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002400 """
2401 try:
GlennRCed771242016-01-13 17:02:47 -08002402 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2403 checkedStates = []
2404 statesCount = [0, 0, 0, 0]
2405 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002406 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002407 if rawFlows:
2408 # if we didn't get flows or flows function return None, we should return
2409 # main.Flase
2410 checkedStates.append( json.loads( rawFlows ) )
2411 else:
2412 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002413 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002414 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002415 try:
2416 statesCount[i] += int( c.get( "flowCount" ) )
2417 except TypeError:
2418 main.log.exception( "Json object not as expected" )
2419 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002420
GlennRCed771242016-01-13 17:02:47 -08002421 # We want to count PENDING_ADD if isPENDING is true
2422 if isPENDING:
2423 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2424 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002425 else:
GlennRCed771242016-01-13 17:02:47 -08002426 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2427 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002428 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002429 except ( TypeError, ValueError ):
2430 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002431 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002432
YPZhang240842b2016-05-17 12:00:50 -07002433 except AssertionError:
2434 main.log.exception( "" )
2435 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002436 except pexpect.TIMEOUT:
2437 main.log.error( self.name + ": ONOS timeout" )
2438 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002439 except pexpect.EOF:
2440 main.log.error( self.name + ": EOF exception found" )
2441 main.log.error( self.name + ": " + self.handle.before )
2442 main.cleanup()
2443 main.exit()
2444 except Exception:
2445 main.log.exception( self.name + ": Uncaught exception!" )
2446 main.cleanup()
2447 main.exit()
2448
GlennRCed771242016-01-13 17:02:47 -08002449 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002450 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002451 """
andrewonlab87852b02014-11-19 18:44:19 -05002452 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002453 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002454 a specific point-to-point intent definition
2455 Required:
GlennRCed771242016-01-13 17:02:47 -08002456 * ingress: specify source dpid
2457 * egress: specify destination dpid
2458 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002459 Optional:
GlennRCed771242016-01-13 17:02:47 -08002460 * offset: the keyOffset is where the next batch of intents
2461 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002462 * noExit: If set to True, TestON will not exit if any error when issus command
2463 * getResponse: If set to True, function will return ONOS response.
2464
GlennRCed771242016-01-13 17:02:47 -08002465 Returns: If failed to push test intents, it will returen None,
2466 if successful, return true.
2467 Timeout expection will return None,
2468 TypeError will return false
2469 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002470 """
andrewonlab87852b02014-11-19 18:44:19 -05002471 try:
GlennRCed771242016-01-13 17:02:47 -08002472 if background:
2473 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002474 else:
GlennRCed771242016-01-13 17:02:47 -08002475 back = ""
2476 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002477 ingress,
2478 egress,
2479 batchSize,
2480 offset,
2481 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002482 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002483 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002484 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002485 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002486 if getResponse:
2487 return response
2488
GlennRCed771242016-01-13 17:02:47 -08002489 # TODO: We should handle if there is failure in installation
2490 return main.TRUE
2491
Jon Hallc6793552016-01-19 14:18:37 -08002492 except AssertionError:
2493 main.log.exception( "" )
2494 return None
GlennRCed771242016-01-13 17:02:47 -08002495 except pexpect.TIMEOUT:
2496 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002497 return None
andrewonlab87852b02014-11-19 18:44:19 -05002498 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002499 main.log.error( self.name + ": EOF exception found" )
2500 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002501 main.cleanup()
2502 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002503 except TypeError:
2504 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002505 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002506 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002507 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002508 main.cleanup()
2509 main.exit()
2510
YPZhangebf9eb52016-05-12 15:20:24 -07002511 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002512 """
2513 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002514 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002515 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002516 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002517 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002518 """
YPZhange3109a72016-02-02 11:25:37 -08002519
YPZhangb5d3f832016-01-23 22:54:26 -08002520 try:
YPZhange3109a72016-02-02 11:25:37 -08002521 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002522 cmd = "flows -c added"
2523 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2524 if rawFlows:
2525 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002526 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002527 for l in rawFlows:
2528 totalFlows += int(l.split("Count=")[1])
2529 else:
2530 main.log.error("Response not as expected!")
2531 return None
2532 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002533
You Wangd3cb2ce2016-05-16 14:01:24 -07002534 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002535 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002536 return None
2537 except pexpect.EOF:
2538 main.log.error( self.name + ": EOF exception found" )
2539 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002540 if not noExit:
2541 main.cleanup()
2542 main.exit()
2543 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002544 except pexpect.TIMEOUT:
2545 main.log.error( self.name + ": ONOS timeout" )
2546 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002547 except Exception:
2548 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002549 if not noExit:
2550 main.cleanup()
2551 main.exit()
2552 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002553
YPZhang14a4aa92016-07-15 13:37:15 -07002554 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002555 """
2556 Description:
2557 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002558 Optional:
2559 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002560 Return:
2561 The number of intents
2562 """
2563 try:
2564 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002565 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002566 if response is None:
2567 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002568 response = json.loads( response )
2569 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002570 except ( TypeError, ValueError ):
2571 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002572 return None
2573 except pexpect.EOF:
2574 main.log.error( self.name + ": EOF exception found" )
2575 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002576 if noExit:
2577 return -1
2578 else:
2579 main.cleanup()
2580 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002581 except Exception:
2582 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002583 if noExit:
2584 return -1
2585 else:
2586 main.cleanup()
2587 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002588
kelvin-onlabd3b64892015-01-20 13:26:24 -08002589 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002590 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002591 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002592 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002594 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002595 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002596 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002597 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002598 cmdStr += " -j"
2599 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002600 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002601 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002602 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002603 except AssertionError:
2604 main.log.exception( "" )
2605 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002606 except TypeError:
2607 main.log.exception( self.name + ": Object not as expected" )
2608 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002610 main.log.error( self.name + ": EOF exception found" )
2611 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002612 main.cleanup()
2613 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002615 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002616 main.cleanup()
2617 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002618
kelvin-onlabd3b64892015-01-20 13:26:24 -08002619 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002620 """
2621 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002622 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002623 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002624 """
andrewonlab867212a2014-10-22 20:13:38 -04002625 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002626 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002627 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002628 cmdStr += " -j"
2629 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002630 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002631 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002632 if handle:
2633 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002634 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002635 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002636 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002637 else:
2638 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002639 except AssertionError:
2640 main.log.exception( "" )
2641 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002642 except TypeError:
2643 main.log.exception( self.name + ": Object not as expected" )
2644 return None
andrewonlab867212a2014-10-22 20:13:38 -04002645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002646 main.log.error( self.name + ": EOF exception found" )
2647 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002648 main.cleanup()
2649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002651 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002652 main.cleanup()
2653 main.exit()
2654
kelvin8ec71442015-01-15 16:57:00 -08002655 # Wrapper functions ****************
2656 # Wrapper functions use existing driver
2657 # functions and extends their use case.
2658 # For example, we may use the output of
2659 # a normal driver function, and parse it
2660 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002661
kelvin-onlabd3b64892015-01-20 13:26:24 -08002662 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002663 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002664 Description:
2665 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002666 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002667 try:
kelvin8ec71442015-01-15 16:57:00 -08002668 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002669 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002670 if intentsStr is None:
2671 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002672 # Convert to a dictionary
2673 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002675 for intent in intents:
2676 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002677 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002678 except TypeError:
2679 main.log.exception( self.name + ": Object not as expected" )
2680 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002682 main.log.error( self.name + ": EOF exception found" )
2683 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002684 main.cleanup()
2685 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002686 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002687 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002688 main.cleanup()
2689 main.exit()
2690
You Wang3c276252016-09-21 15:21:36 -07002691 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002692 """
2693 Determine the number of flow rules for the given device id that are
2694 in the added state
You Wang3c276252016-09-21 15:21:36 -07002695 Params:
2696 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002697 """
2698 try:
You Wang3c276252016-09-21 15:21:36 -07002699 if core:
2700 cmdStr = "flows any " + str( deviceId ) + " | " +\
2701 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2702 else:
2703 cmdStr = "flows any " + str( deviceId ) + " | " +\
2704 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002705 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002706 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002707 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002708 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002709 except AssertionError:
2710 main.log.exception( "" )
2711 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002712 except pexpect.EOF:
2713 main.log.error( self.name + ": EOF exception found" )
2714 main.log.error( self.name + ": " + self.handle.before )
2715 main.cleanup()
2716 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002717 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002718 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002719 main.cleanup()
2720 main.exit()
2721
kelvin-onlabd3b64892015-01-20 13:26:24 -08002722 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002723 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002724 Use 'devices' function to obtain list of all devices
2725 and parse the result to obtain a list of all device
2726 id's. Returns this list. Returns empty list if no
2727 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002728 List is ordered sequentially
2729
andrewonlab3e15ead2014-10-15 14:21:34 -04002730 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002731 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002732 the ids. By obtaining the list of device ids on the fly,
2733 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002734 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002735 try:
kelvin8ec71442015-01-15 16:57:00 -08002736 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002737 devicesStr = self.devices( jsonFormat=False )
2738 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002739
kelvin-onlabd3b64892015-01-20 13:26:24 -08002740 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002741 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002742 return idList
kelvin8ec71442015-01-15 16:57:00 -08002743
2744 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002745 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002746 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002748 # Split list further into arguments before and after string
2749 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002750 # append to idList
2751 for arg in tempList:
2752 idList.append( arg.split( "id=" )[ 1 ] )
2753 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002754
Jon Halld4d4b372015-01-28 16:02:41 -08002755 except TypeError:
2756 main.log.exception( self.name + ": Object not as expected" )
2757 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002761 main.cleanup()
2762 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002764 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002765 main.cleanup()
2766 main.exit()
2767
kelvin-onlabd3b64892015-01-20 13:26:24 -08002768 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002769 """
andrewonlab7c211572014-10-15 16:45:20 -04002770 Uses 'nodes' function to obtain list of all nodes
2771 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002772 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002773 Returns:
2774 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002775 """
andrewonlab7c211572014-10-15 16:45:20 -04002776 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002777 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002778 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002779 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002780 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002781 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002782 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002783 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002784 nodesJson = json.loads( nodesStr )
2785 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002786 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002787 except ( TypeError, ValueError ):
2788 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002789 return None
andrewonlab7c211572014-10-15 16:45:20 -04002790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002791 main.log.error( self.name + ": EOF exception found" )
2792 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002793 main.cleanup()
2794 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002795 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002796 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002797 main.cleanup()
2798 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002799
kelvin-onlabd3b64892015-01-20 13:26:24 -08002800 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002801 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002802 Return the first device from the devices api whose 'id' contains 'dpid'
2803 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002804 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002805 try:
kelvin8ec71442015-01-15 16:57:00 -08002806 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002807 return None
2808 else:
kelvin8ec71442015-01-15 16:57:00 -08002809 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002810 rawDevices = self.devices()
2811 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002812 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002814 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2815 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002816 return device
2817 return None
Jon Hallc6793552016-01-19 14:18:37 -08002818 except ( TypeError, ValueError ):
2819 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002820 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002821 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002822 main.log.error( self.name + ": EOF exception found" )
2823 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002824 main.cleanup()
2825 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002826 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002827 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002828 main.cleanup()
2829 main.exit()
2830
You Wang24139872016-05-03 11:48:47 -07002831 def getTopology( self, topologyOutput ):
2832 """
2833 Definition:
2834 Loads a json topology output
2835 Return:
2836 topology = current ONOS topology
2837 """
2838 import json
2839 try:
2840 # either onos:topology or 'topology' will work in CLI
2841 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002842 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002843 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002844 except ( TypeError, ValueError ):
2845 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2846 return None
You Wang24139872016-05-03 11:48:47 -07002847 except pexpect.EOF:
2848 main.log.error( self.name + ": EOF exception found" )
2849 main.log.error( self.name + ": " + self.handle.before )
2850 main.cleanup()
2851 main.exit()
2852 except Exception:
2853 main.log.exception( self.name + ": Uncaught exception!" )
2854 main.cleanup()
2855 main.exit()
2856
Flavio Castro82ee2f62016-06-07 15:04:12 -07002857 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002858 """
Jon Hallefbd9792015-03-05 16:11:36 -08002859 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002860 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002861 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002862
Flavio Castro82ee2f62016-06-07 15:04:12 -07002863 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002864 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002865 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002866 logLevel = level to log to.
2867 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002868
Jon Hallefbd9792015-03-05 16:11:36 -08002869 Returns: main.TRUE if the number of switches and links are correct,
2870 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002871 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002872 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002873 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002874 try:
You Wang13310252016-07-31 10:56:14 -07002875 summary = self.summary()
2876 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002877 except ( TypeError, ValueError ):
2878 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2879 return main.ERROR
2880 try:
2881 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002882 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002883 return main.ERROR
2884 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002885 # Is the number of switches is what we expected
2886 devices = topology.get( 'devices', False )
2887 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002888 nodes = summary.get( 'nodes', False )
2889 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002890 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002891 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002892 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002893 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002894 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2895 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002896 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002897 output = output + "The number of links and switches match "\
2898 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002899 result = main.TRUE
2900 else:
You Wang24139872016-05-03 11:48:47 -07002901 output = output + \
2902 "The number of links and switches does not match " + \
2903 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002904 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002905 output = output + "\n ONOS sees %i devices" % int( devices )
2906 output = output + " (%i expected) " % int( numoswitch )
2907 output = output + "and %i links " % int( links )
2908 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002909 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002910 output = output + "and %i controllers " % int( nodes )
2911 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002912 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002913 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002914 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002915 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002916 else:
You Wang24139872016-05-03 11:48:47 -07002917 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002918 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002920 main.log.error( self.name + ": EOF exception found" )
2921 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002922 main.cleanup()
2923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002925 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002926 main.cleanup()
2927 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002928
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002930 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002931 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002932 deviceId must be the id of a device as seen in the onos devices command
2933 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002934 role must be either master, standby, or none
2935
Jon Halle3f39ff2015-01-13 11:50:53 -08002936 Returns:
2937 main.TRUE or main.FALSE based on argument verification and
2938 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002939 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002940 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002941 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002942 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002943 cmdStr = "device-role " +\
2944 str( deviceId ) + " " +\
2945 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002946 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002947 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002948 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002949 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002950 if re.search( "Error", handle ):
2951 # end color output to escape any colours
2952 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002953 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002954 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002955 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002956 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002957 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002958 main.log.error( "Invalid 'role' given to device_role(). " +
2959 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002960 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002961 except AssertionError:
2962 main.log.exception( "" )
2963 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002964 except TypeError:
2965 main.log.exception( self.name + ": Object not as expected" )
2966 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002967 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002968 main.log.error( self.name + ": EOF exception found" )
2969 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002970 main.cleanup()
2971 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002972 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002973 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002974 main.cleanup()
2975 main.exit()
2976
kelvin-onlabd3b64892015-01-20 13:26:24 -08002977 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002978 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002979 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002980 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002981 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002982 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002983 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002984 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002986 cmdStr += " -j"
2987 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002988 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002989 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002990 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002991 except AssertionError:
2992 main.log.exception( "" )
2993 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002994 except TypeError:
2995 main.log.exception( self.name + ": Object not as expected" )
2996 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002997 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002998 main.log.error( self.name + ": EOF exception found" )
2999 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003000 main.cleanup()
3001 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003002 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003003 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003004 main.cleanup()
3005 main.exit()
3006
kelvin-onlabd3b64892015-01-20 13:26:24 -08003007 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003008 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003009 CLI command to get the current leader for the Election test application
3010 NOTE: Requires installation of the onos-app-election feature
3011 Returns: Node IP of the leader if one exists
3012 None if none exists
3013 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003014 """
Jon Hall94fd0472014-12-08 11:52:42 -08003015 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003016 cmdStr = "election-test-leader"
3017 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003018 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003019 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003020 # Leader
3021 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003022 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003023 nodeSearch = re.search( leaderPattern, response )
3024 if nodeSearch:
3025 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003026 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003027 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003028 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003029 # no leader
3030 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003031 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003032 nullSearch = re.search( nullPattern, response )
3033 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003034 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003035 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003036 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003037 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003038 main.log.error( "Error in electionTestLeader on " + self.name +
3039 ": " + "unexpected response" )
3040 main.log.error( repr( response ) )
3041 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003042 except AssertionError:
3043 main.log.exception( "" )
3044 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003045 except TypeError:
3046 main.log.exception( self.name + ": Object not as expected" )
3047 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003049 main.log.error( self.name + ": EOF exception found" )
3050 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003051 main.cleanup()
3052 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003054 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003055 main.cleanup()
3056 main.exit()
3057
kelvin-onlabd3b64892015-01-20 13:26:24 -08003058 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003059 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003060 CLI command to run for leadership of the Election test application.
3061 NOTE: Requires installation of the onos-app-election feature
3062 Returns: Main.TRUE on success
3063 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003064 """
Jon Hall94fd0472014-12-08 11:52:42 -08003065 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003066 cmdStr = "election-test-run"
3067 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003068 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003069 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003070 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003071 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003072 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003073 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003074 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003075 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003076 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003077 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003078 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003079 main.log.error( "Error in electionTestRun on " + self.name +
3080 ": " + "unexpected response" )
3081 main.log.error( repr( response ) )
3082 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003083 except AssertionError:
3084 main.log.exception( "" )
3085 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003086 except TypeError:
3087 main.log.exception( self.name + ": Object not as expected" )
3088 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003089 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003090 main.log.error( self.name + ": EOF exception found" )
3091 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003092 main.cleanup()
3093 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003094 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003095 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003096 main.cleanup()
3097 main.exit()
3098
kelvin-onlabd3b64892015-01-20 13:26:24 -08003099 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003100 """
Jon Hall94fd0472014-12-08 11:52:42 -08003101 * CLI command to withdraw the local node from leadership election for
3102 * the Election test application.
3103 #NOTE: Requires installation of the onos-app-election feature
3104 Returns: Main.TRUE on success
3105 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003106 """
Jon Hall94fd0472014-12-08 11:52:42 -08003107 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003108 cmdStr = "election-test-withdraw"
3109 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003110 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003111 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003112 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003113 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003114 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003115 if re.search( successPattern, response ):
3116 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003117 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003118 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003119 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003120 main.log.error( "Error in electionTestWithdraw on " +
3121 self.name + ": " + "unexpected response" )
3122 main.log.error( repr( response ) )
3123 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003124 except AssertionError:
3125 main.log.exception( "" )
3126 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003127 except TypeError:
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003130 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003133 main.cleanup()
3134 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003135 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003136 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003137 main.cleanup()
3138 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003139
kelvin8ec71442015-01-15 16:57:00 -08003140 def getDevicePortsEnabledCount( self, dpid ):
3141 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003142 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003143 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003144 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003145 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3147 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003148 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003149 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003150 if re.search( "No such device", output ):
3151 main.log.error( "Error in getting ports" )
3152 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003153 return output
Jon Hallc6793552016-01-19 14:18:37 -08003154 except AssertionError:
3155 main.log.exception( "" )
3156 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003157 except TypeError:
3158 main.log.exception( self.name + ": Object not as expected" )
3159 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003161 main.log.error( self.name + ": EOF exception found" )
3162 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003163 main.cleanup()
3164 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003165 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003166 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003167 main.cleanup()
3168 main.exit()
3169
kelvin8ec71442015-01-15 16:57:00 -08003170 def getDeviceLinksActiveCount( self, dpid ):
3171 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003172 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003173 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003174 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003175 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003176 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3177 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003178 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003179 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003180 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003181 main.log.error( "Error in getting ports " )
3182 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003183 return output
Jon Hallc6793552016-01-19 14:18:37 -08003184 except AssertionError:
3185 main.log.exception( "" )
3186 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003187 except TypeError:
3188 main.log.exception( self.name + ": Object not as expected" )
3189 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003190 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003191 main.log.error( self.name + ": EOF exception found" )
3192 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003193 main.cleanup()
3194 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003196 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003197 main.cleanup()
3198 main.exit()
3199
kelvin8ec71442015-01-15 16:57:00 -08003200 def getAllIntentIds( self ):
3201 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003202 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003203 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003204 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003205 cmdStr = "onos:intents | grep id="
3206 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003207 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003208 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003209 if re.search( "Error", output ):
3210 main.log.error( "Error in getting ports" )
3211 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003212 return output
Jon Hallc6793552016-01-19 14:18:37 -08003213 except AssertionError:
3214 main.log.exception( "" )
3215 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003216 except TypeError:
3217 main.log.exception( self.name + ": Object not as expected" )
3218 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003219 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003220 main.log.error( self.name + ": EOF exception found" )
3221 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003222 main.cleanup()
3223 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003224 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003225 main.log.exception( self.name + ": Uncaught exception!" )
3226 main.cleanup()
3227 main.exit()
3228
Jon Hall73509952015-02-24 16:42:56 -08003229 def intentSummary( self ):
3230 """
Jon Hallefbd9792015-03-05 16:11:36 -08003231 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003232 """
3233 try:
3234 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003235 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003236 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003237 states.append( intent.get( 'state', None ) )
3238 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003239 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003240 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003241 except ( TypeError, ValueError ):
3242 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003243 return None
3244 except pexpect.EOF:
3245 main.log.error( self.name + ": EOF exception found" )
3246 main.log.error( self.name + ": " + self.handle.before )
3247 main.cleanup()
3248 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003249 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003250 main.log.exception( self.name + ": Uncaught exception!" )
3251 main.cleanup()
3252 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003253
Jon Hall61282e32015-03-19 11:34:11 -07003254 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003255 """
3256 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003257 Optional argument:
3258 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003259 """
Jon Hall63604932015-02-26 17:09:50 -08003260 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003261 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003262 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003263 cmdStr += " -j"
3264 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003265 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003266 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003267 return output
Jon Hallc6793552016-01-19 14:18:37 -08003268 except AssertionError:
3269 main.log.exception( "" )
3270 return None
Jon Hall63604932015-02-26 17:09:50 -08003271 except TypeError:
3272 main.log.exception( self.name + ": Object not as expected" )
3273 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003274 except pexpect.EOF:
3275 main.log.error( self.name + ": EOF exception found" )
3276 main.log.error( self.name + ": " + self.handle.before )
3277 main.cleanup()
3278 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003279 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003280 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003281 main.cleanup()
3282 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003283
acsmarsa4a4d1e2015-07-10 16:01:24 -07003284 def leaderCandidates( self, jsonFormat=True ):
3285 """
3286 Returns the output of the leaders -c command.
3287 Optional argument:
3288 * jsonFormat - boolean indicating if you want output in json
3289 """
3290 try:
3291 cmdStr = "onos:leaders -c"
3292 if jsonFormat:
3293 cmdStr += " -j"
3294 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003295 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003296 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003297 return output
Jon Hallc6793552016-01-19 14:18:37 -08003298 except AssertionError:
3299 main.log.exception( "" )
3300 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003301 except TypeError:
3302 main.log.exception( self.name + ": Object not as expected" )
3303 return None
3304 except pexpect.EOF:
3305 main.log.error( self.name + ": EOF exception found" )
3306 main.log.error( self.name + ": " + self.handle.before )
3307 main.cleanup()
3308 main.exit()
3309 except Exception:
3310 main.log.exception( self.name + ": Uncaught exception!" )
3311 main.cleanup()
3312 main.exit()
3313
Jon Hallc6793552016-01-19 14:18:37 -08003314 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003315 """
3316 Returns a list in format [leader,candidate1,candidate2,...] for a given
3317 topic parameter and an empty list if the topic doesn't exist
3318 If no leader is elected leader in the returned list will be "none"
3319 Returns None if there is a type error processing the json object
3320 """
3321 try:
Jon Hall6e709752016-02-01 13:38:46 -08003322 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003323 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003324 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003325 assert "Command not found:" not in rawOutput, rawOutput
3326 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003327 results = []
3328 for dict in output:
3329 if dict["topic"] == topic:
3330 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003331 candidates = re.split( ", ", dict["candidates"][1:-1] )
3332 results.append( leader )
3333 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003334 return results
Jon Hallc6793552016-01-19 14:18:37 -08003335 except AssertionError:
3336 main.log.exception( "" )
3337 return None
3338 except ( TypeError, ValueError ):
3339 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003340 return None
3341 except pexpect.EOF:
3342 main.log.error( self.name + ": EOF exception found" )
3343 main.log.error( self.name + ": " + self.handle.before )
3344 main.cleanup()
3345 main.exit()
3346 except Exception:
3347 main.log.exception( self.name + ": Uncaught exception!" )
3348 main.cleanup()
3349 main.exit()
3350
Jon Hall61282e32015-03-19 11:34:11 -07003351 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003352 """
3353 Returns the output of the intent Pending map.
3354 """
Jon Hall63604932015-02-26 17:09:50 -08003355 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003356 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003357 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003358 cmdStr += " -j"
3359 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003360 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003361 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003362 return output
Jon Hallc6793552016-01-19 14:18:37 -08003363 except AssertionError:
3364 main.log.exception( "" )
3365 return None
Jon Hall63604932015-02-26 17:09:50 -08003366 except TypeError:
3367 main.log.exception( self.name + ": Object not as expected" )
3368 return None
3369 except pexpect.EOF:
3370 main.log.error( self.name + ": EOF exception found" )
3371 main.log.error( self.name + ": " + self.handle.before )
3372 main.cleanup()
3373 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003374 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003375 main.log.exception( self.name + ": Uncaught exception!" )
3376 main.cleanup()
3377 main.exit()
3378
Jon Hall2c8959e2016-12-16 12:17:34 -08003379 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003380 """
3381 Returns the output of the raft partitions command for ONOS.
3382 """
Jon Hall61282e32015-03-19 11:34:11 -07003383 # Sample JSON
3384 # {
3385 # "leader": "tcp://10.128.30.11:7238",
3386 # "members": [
3387 # "tcp://10.128.30.11:7238",
3388 # "tcp://10.128.30.17:7238",
3389 # "tcp://10.128.30.13:7238",
3390 # ],
3391 # "name": "p1",
3392 # "term": 3
3393 # },
Jon Hall63604932015-02-26 17:09:50 -08003394 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003395 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003396 if candidates:
3397 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003398 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003399 cmdStr += " -j"
3400 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003401 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003402 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003403 return output
Jon Hallc6793552016-01-19 14:18:37 -08003404 except AssertionError:
3405 main.log.exception( "" )
3406 return None
Jon Hall63604932015-02-26 17:09:50 -08003407 except TypeError:
3408 main.log.exception( self.name + ": Object not as expected" )
3409 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 Hall63604932015-02-26 17:09:50 -08003416 main.log.exception( self.name + ": Uncaught exception!" )
3417 main.cleanup()
3418 main.exit()
3419
Jon Halle9f909e2016-09-23 10:43:12 -07003420 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003421 """
3422 Returns the output of the apps command for ONOS. This command lists
3423 information about installed ONOS applications
3424 """
3425 # Sample JSON object
3426 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3427 # "description":"ONOS OpenFlow protocol southbound providers",
3428 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3429 # "features":"[onos-openflow]","state":"ACTIVE"}]
3430 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003431 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003432 if summary:
3433 cmdStr += " -s"
3434 if active:
3435 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003436 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003437 cmdStr += " -j"
3438 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003439 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003440 assert "Command not found:" not in output, output
3441 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003442 return output
Jon Hallbe379602015-03-24 13:39:32 -07003443 # FIXME: look at specific exceptions/Errors
3444 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003445 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003446 return None
3447 except TypeError:
3448 main.log.exception( self.name + ": Object not as expected" )
3449 return None
3450 except pexpect.EOF:
3451 main.log.error( self.name + ": EOF exception found" )
3452 main.log.error( self.name + ": " + self.handle.before )
3453 main.cleanup()
3454 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003455 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003456 main.log.exception( self.name + ": Uncaught exception!" )
3457 main.cleanup()
3458 main.exit()
3459
Jon Hall146f1522015-03-24 15:33:24 -07003460 def appStatus( self, appName ):
3461 """
3462 Uses the onos:apps cli command to return the status of an application.
3463 Returns:
3464 "ACTIVE" - If app is installed and activated
3465 "INSTALLED" - If app is installed and deactivated
3466 "UNINSTALLED" - If app is not installed
3467 None - on error
3468 """
Jon Hall146f1522015-03-24 15:33:24 -07003469 try:
3470 if not isinstance( appName, types.StringType ):
3471 main.log.error( self.name + ".appStatus(): appName must be" +
3472 " a string" )
3473 return None
3474 output = self.apps( jsonFormat=True )
3475 appsJson = json.loads( output )
3476 state = None
3477 for app in appsJson:
3478 if appName == app.get('name'):
3479 state = app.get('state')
3480 break
3481 if state == "ACTIVE" or state == "INSTALLED":
3482 return state
3483 elif state is None:
3484 return "UNINSTALLED"
3485 elif state:
3486 main.log.error( "Unexpected state from 'onos:apps': " +
3487 str( state ) )
3488 return state
Jon Hallc6793552016-01-19 14:18:37 -08003489 except ( TypeError, ValueError ):
3490 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003491 return None
3492 except pexpect.EOF:
3493 main.log.error( self.name + ": EOF exception found" )
3494 main.log.error( self.name + ": " + self.handle.before )
3495 main.cleanup()
3496 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003497 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003498 main.log.exception( self.name + ": Uncaught exception!" )
3499 main.cleanup()
3500 main.exit()
3501
Jon Hallbe379602015-03-24 13:39:32 -07003502 def app( self, appName, option ):
3503 """
3504 Interacts with the app command for ONOS. This command manages
3505 application inventory.
3506 """
Jon Hallbe379602015-03-24 13:39:32 -07003507 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003508 # Validate argument types
3509 valid = True
3510 if not isinstance( appName, types.StringType ):
3511 main.log.error( self.name + ".app(): appName must be a " +
3512 "string" )
3513 valid = False
3514 if not isinstance( option, types.StringType ):
3515 main.log.error( self.name + ".app(): option must be a string" )
3516 valid = False
3517 if not valid:
3518 return main.FALSE
3519 # Validate Option
3520 option = option.lower()
3521 # NOTE: Install may become a valid option
3522 if option == "activate":
3523 pass
3524 elif option == "deactivate":
3525 pass
3526 elif option == "uninstall":
3527 pass
3528 else:
3529 # Invalid option
3530 main.log.error( "The ONOS app command argument only takes " +
3531 "the values: (activate|deactivate|uninstall)" +
3532 "; was given '" + option + "'")
3533 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003534 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003535 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003536 assert output is not None, "Error in sendline"
3537 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003538 if "Error executing command" in output:
3539 main.log.error( "Error in processing onos:app command: " +
3540 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003541 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003542 elif "No such application" in output:
3543 main.log.error( "The application '" + appName +
3544 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003545 return main.FALSE
3546 elif "Command not found:" in output:
3547 main.log.error( "Error in processing onos:app command: " +
3548 str( output ) )
3549 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003550 elif "Unsupported command:" in output:
3551 main.log.error( "Incorrect command given to 'app': " +
3552 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003553 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003554 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003555 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003556 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003557 except AssertionError:
3558 main.log.exception( self.name + ": AssertionError exception found" )
3559 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003560 except TypeError:
3561 main.log.exception( self.name + ": Object not as expected" )
3562 return main.ERROR
3563 except pexpect.EOF:
3564 main.log.error( self.name + ": EOF exception found" )
3565 main.log.error( self.name + ": " + self.handle.before )
3566 main.cleanup()
3567 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003568 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003569 main.log.exception( self.name + ": Uncaught exception!" )
3570 main.cleanup()
3571 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003572
Jon Hallbd16b922015-03-26 17:53:15 -07003573 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003574 """
3575 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003576 appName is the hierarchical app name, not the feature name
3577 If check is True, method will check the status of the app after the
3578 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003579 Returns main.TRUE if the command was successfully sent
3580 main.FALSE if the cli responded with an error or given
3581 incorrect input
3582 """
3583 try:
3584 if not isinstance( appName, types.StringType ):
3585 main.log.error( self.name + ".activateApp(): appName must be" +
3586 " a string" )
3587 return main.FALSE
3588 status = self.appStatus( appName )
3589 if status == "INSTALLED":
3590 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003591 if check and response == main.TRUE:
3592 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003593 status = self.appStatus( appName )
3594 if status == "ACTIVE":
3595 return main.TRUE
3596 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003597 main.log.debug( "The state of application " +
3598 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003599 time.sleep( 1 )
3600 return main.FALSE
3601 else: # not 'check' or command didn't succeed
3602 return response
Jon Hall146f1522015-03-24 15:33:24 -07003603 elif status == "ACTIVE":
3604 return main.TRUE
3605 elif status == "UNINSTALLED":
3606 main.log.error( self.name + ": Tried to activate the " +
3607 "application '" + appName + "' which is not " +
3608 "installed." )
3609 else:
3610 main.log.error( "Unexpected return value from appStatus: " +
3611 str( status ) )
3612 return main.ERROR
3613 except TypeError:
3614 main.log.exception( self.name + ": Object not as expected" )
3615 return main.ERROR
3616 except pexpect.EOF:
3617 main.log.error( self.name + ": EOF exception found" )
3618 main.log.error( self.name + ": " + self.handle.before )
3619 main.cleanup()
3620 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003621 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003622 main.log.exception( self.name + ": Uncaught exception!" )
3623 main.cleanup()
3624 main.exit()
3625
Jon Hallbd16b922015-03-26 17:53:15 -07003626 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003627 """
3628 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003629 appName is the hierarchical app name, not the feature name
3630 If check is True, method will check the status of the app after the
3631 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003632 Returns main.TRUE if the command was successfully sent
3633 main.FALSE if the cli responded with an error or given
3634 incorrect input
3635 """
3636 try:
3637 if not isinstance( appName, types.StringType ):
3638 main.log.error( self.name + ".deactivateApp(): appName must " +
3639 "be a string" )
3640 return main.FALSE
3641 status = self.appStatus( appName )
3642 if status == "INSTALLED":
3643 return main.TRUE
3644 elif status == "ACTIVE":
3645 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003646 if check and response == main.TRUE:
3647 for i in range(10): # try 10 times then give up
3648 status = self.appStatus( appName )
3649 if status == "INSTALLED":
3650 return main.TRUE
3651 else:
3652 time.sleep( 1 )
3653 return main.FALSE
3654 else: # not check or command didn't succeed
3655 return response
Jon Hall146f1522015-03-24 15:33:24 -07003656 elif status == "UNINSTALLED":
3657 main.log.warn( self.name + ": Tried to deactivate the " +
3658 "application '" + appName + "' which is not " +
3659 "installed." )
3660 return main.TRUE
3661 else:
3662 main.log.error( "Unexpected return value from appStatus: " +
3663 str( status ) )
3664 return main.ERROR
3665 except TypeError:
3666 main.log.exception( self.name + ": Object not as expected" )
3667 return main.ERROR
3668 except pexpect.EOF:
3669 main.log.error( self.name + ": EOF exception found" )
3670 main.log.error( self.name + ": " + self.handle.before )
3671 main.cleanup()
3672 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003673 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003674 main.log.exception( self.name + ": Uncaught exception!" )
3675 main.cleanup()
3676 main.exit()
3677
Jon Hallbd16b922015-03-26 17:53:15 -07003678 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003679 """
3680 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003681 appName is the hierarchical app name, not the feature name
3682 If check is True, method will check the status of the app after the
3683 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003684 Returns main.TRUE if the command was successfully sent
3685 main.FALSE if the cli responded with an error or given
3686 incorrect input
3687 """
3688 # TODO: check with Thomas about the state machine for apps
3689 try:
3690 if not isinstance( appName, types.StringType ):
3691 main.log.error( self.name + ".uninstallApp(): appName must " +
3692 "be a string" )
3693 return main.FALSE
3694 status = self.appStatus( appName )
3695 if status == "INSTALLED":
3696 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003697 if check and response == main.TRUE:
3698 for i in range(10): # try 10 times then give up
3699 status = self.appStatus( appName )
3700 if status == "UNINSTALLED":
3701 return main.TRUE
3702 else:
3703 time.sleep( 1 )
3704 return main.FALSE
3705 else: # not check or command didn't succeed
3706 return response
Jon Hall146f1522015-03-24 15:33:24 -07003707 elif status == "ACTIVE":
3708 main.log.warn( self.name + ": Tried to uninstall the " +
3709 "application '" + appName + "' which is " +
3710 "currently active." )
3711 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003712 if check and response == main.TRUE:
3713 for i in range(10): # try 10 times then give up
3714 status = self.appStatus( appName )
3715 if status == "UNINSTALLED":
3716 return main.TRUE
3717 else:
3718 time.sleep( 1 )
3719 return main.FALSE
3720 else: # not check or command didn't succeed
3721 return response
Jon Hall146f1522015-03-24 15:33:24 -07003722 elif status == "UNINSTALLED":
3723 return main.TRUE
3724 else:
3725 main.log.error( "Unexpected return value from appStatus: " +
3726 str( status ) )
3727 return main.ERROR
3728 except TypeError:
3729 main.log.exception( self.name + ": Object not as expected" )
3730 return main.ERROR
3731 except pexpect.EOF:
3732 main.log.error( self.name + ": EOF exception found" )
3733 main.log.error( self.name + ": " + self.handle.before )
3734 main.cleanup()
3735 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003736 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003737 main.log.exception( self.name + ": Uncaught exception!" )
3738 main.cleanup()
3739 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003740
3741 def appIDs( self, jsonFormat=True ):
3742 """
3743 Show the mappings between app id and app names given by the 'app-ids'
3744 cli command
3745 """
3746 try:
3747 cmdStr = "app-ids"
3748 if jsonFormat:
3749 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003750 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003751 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003752 assert "Command not found:" not in output, output
3753 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003754 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003755 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003756 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003757 return None
3758 except TypeError:
3759 main.log.exception( self.name + ": Object not as expected" )
3760 return None
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
3771 def appToIDCheck( self ):
3772 """
3773 This method will check that each application's ID listed in 'apps' is
3774 the same as the ID listed in 'app-ids'. The check will also check that
3775 there are no duplicate IDs issued. Note that an app ID should be
3776 a globaly unique numerical identifier for app/app-like features. Once
3777 an ID is registered, the ID is never freed up so that if an app is
3778 reinstalled it will have the same ID.
3779
3780 Returns: main.TRUE if the check passes and
3781 main.FALSE if the check fails or
3782 main.ERROR if there is some error in processing the test
3783 """
3784 try:
Jon Hall390696c2015-05-05 17:13:41 -07003785 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003786 rawJson = self.appIDs( jsonFormat=True )
3787 if rawJson:
3788 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003789 else:
Jon Hallc6793552016-01-19 14:18:37 -08003790 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003791 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003792 rawJson = self.apps( jsonFormat=True )
3793 if rawJson:
3794 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003795 else:
Jon Hallc6793552016-01-19 14:18:37 -08003796 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003797 bail = True
3798 if bail:
3799 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003800 result = main.TRUE
3801 for app in apps:
3802 appID = app.get( 'id' )
3803 if appID is None:
3804 main.log.error( "Error parsing app: " + str( app ) )
3805 result = main.FALSE
3806 appName = app.get( 'name' )
3807 if appName is None:
3808 main.log.error( "Error parsing app: " + str( app ) )
3809 result = main.FALSE
3810 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003811 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003812 # main.log.debug( "Comparing " + str( app ) + " to " +
3813 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003814 if not current: # if ids doesn't have this id
3815 result = main.FALSE
3816 main.log.error( "'app-ids' does not have the ID for " +
3817 str( appName ) + " that apps does." )
3818 elif len( current ) > 1:
3819 # there is more than one app with this ID
3820 result = main.FALSE
3821 # We will log this later in the method
3822 elif not current[0][ 'name' ] == appName:
3823 currentName = current[0][ 'name' ]
3824 result = main.FALSE
3825 main.log.error( "'app-ids' has " + str( currentName ) +
3826 " registered under id:" + str( appID ) +
3827 " but 'apps' has " + str( appName ) )
3828 else:
3829 pass # id and name match!
3830 # now make sure that app-ids has no duplicates
3831 idsList = []
3832 namesList = []
3833 for item in ids:
3834 idsList.append( item[ 'id' ] )
3835 namesList.append( item[ 'name' ] )
3836 if len( idsList ) != len( set( idsList ) ) or\
3837 len( namesList ) != len( set( namesList ) ):
3838 main.log.error( "'app-ids' has some duplicate entries: \n"
3839 + json.dumps( ids,
3840 sort_keys=True,
3841 indent=4,
3842 separators=( ',', ': ' ) ) )
3843 result = main.FALSE
3844 return result
Jon Hallc6793552016-01-19 14:18:37 -08003845 except ( TypeError, ValueError ):
3846 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003847 return main.ERROR
3848 except pexpect.EOF:
3849 main.log.error( self.name + ": EOF exception found" )
3850 main.log.error( self.name + ": " + self.handle.before )
3851 main.cleanup()
3852 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003853 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003854 main.log.exception( self.name + ": Uncaught exception!" )
3855 main.cleanup()
3856 main.exit()
3857
Jon Hallfb760a02015-04-13 15:35:03 -07003858 def getCfg( self, component=None, propName=None, short=False,
3859 jsonFormat=True ):
3860 """
3861 Get configuration settings from onos cli
3862 Optional arguments:
3863 component - Optionally only list configurations for a specific
3864 component. If None, all components with configurations
3865 are displayed. Case Sensitive string.
3866 propName - If component is specified, propName option will show
3867 only this specific configuration from that component.
3868 Case Sensitive string.
3869 jsonFormat - Returns output as json. Note that this will override
3870 the short option
3871 short - Short, less verbose, version of configurations.
3872 This is overridden by the json option
3873 returns:
3874 Output from cli as a string or None on error
3875 """
3876 try:
3877 baseStr = "cfg"
3878 cmdStr = " get"
3879 componentStr = ""
3880 if component:
3881 componentStr += " " + component
3882 if propName:
3883 componentStr += " " + propName
3884 if jsonFormat:
3885 baseStr += " -j"
3886 elif short:
3887 baseStr += " -s"
3888 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003889 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003890 assert "Command not found:" not in output, output
3891 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003892 return output
3893 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003894 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003895 return None
3896 except TypeError:
3897 main.log.exception( self.name + ": Object not as expected" )
3898 return None
3899 except pexpect.EOF:
3900 main.log.error( self.name + ": EOF exception found" )
3901 main.log.error( self.name + ": " + self.handle.before )
3902 main.cleanup()
3903 main.exit()
3904 except Exception:
3905 main.log.exception( self.name + ": Uncaught exception!" )
3906 main.cleanup()
3907 main.exit()
3908
3909 def setCfg( self, component, propName, value=None, check=True ):
3910 """
3911 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003912 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003913 component - The case sensitive name of the component whose
3914 property is to be set
3915 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003916 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003917 value - The value to set the property to. If None, will unset the
3918 property and revert it to it's default value(if applicable)
3919 check - Boolean, Check whether the option was successfully set this
3920 only applies when a value is given.
3921 returns:
3922 main.TRUE on success or main.FALSE on failure. If check is False,
3923 will return main.TRUE unless there is an error
3924 """
3925 try:
3926 baseStr = "cfg"
3927 cmdStr = " set " + str( component ) + " " + str( propName )
3928 if value is not None:
3929 cmdStr += " " + str( value )
3930 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003931 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003932 assert "Command not found:" not in output, output
3933 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003934 if value and check:
3935 results = self.getCfg( component=str( component ),
3936 propName=str( propName ),
3937 jsonFormat=True )
3938 # Check if current value is what we just set
3939 try:
3940 jsonOutput = json.loads( results )
3941 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003942 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003943 main.log.exception( "Error parsing cfg output" )
3944 main.log.error( "output:" + repr( results ) )
3945 return main.FALSE
3946 if current == str( value ):
3947 return main.TRUE
3948 return main.FALSE
3949 return main.TRUE
3950 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003951 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003952 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003953 except ( TypeError, ValueError ):
3954 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003955 return main.FALSE
3956 except pexpect.EOF:
3957 main.log.error( self.name + ": EOF exception found" )
3958 main.log.error( self.name + ": " + self.handle.before )
3959 main.cleanup()
3960 main.exit()
3961 except Exception:
3962 main.log.exception( self.name + ": Uncaught exception!" )
3963 main.cleanup()
3964 main.exit()
3965
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003966 def distPrimitivesSend( self, cmd ):
3967 """
3968 Function to handle sending cli commands for the distributed primitives test app
3969
3970 This command will catch some exceptions and retry the command on some
3971 specific store exceptions.
3972
3973 Required arguments:
3974 cmd - The command to send to the cli
3975 returns:
3976 string containing the cli output
3977 None on Error
3978 """
3979 try:
3980 output = self.sendline( cmd )
3981 try:
3982 assert output is not None, "Error in sendline"
3983 # TODO: Maybe make this less hardcoded
3984 # ConsistentMap Exceptions
3985 assert "org.onosproject.store.service" not in output
3986 # Node not leader
3987 assert "java.lang.IllegalStateException" not in output
3988 except AssertionError:
3989 main.log.error( "Error in processing '" + cmd + "' " +
3990 "command: " + str( output ) )
3991 retryTime = 30 # Conservative time, given by Madan
3992 main.log.info( "Waiting " + str( retryTime ) +
3993 "seconds before retrying." )
3994 time.sleep( retryTime ) # Due to change in mastership
3995 output = self.sendline( cmd )
3996 assert output is not None, "Error in sendline"
3997 assert "Command not found:" not in output, output
3998 assert "Error executing command" not in output, output
3999 main.log.info( self.name + ": " + output )
4000 return output
4001 except AssertionError:
4002 main.log.exception( "Error in processing '" + cmd + "' command." )
4003 return None
4004 except TypeError:
4005 main.log.exception( self.name + ": Object not as expected" )
4006 return None
4007 except pexpect.EOF:
4008 main.log.error( self.name + ": EOF exception found" )
4009 main.log.error( self.name + ": " + self.handle.before )
4010 main.cleanup()
4011 main.exit()
4012 except Exception:
4013 main.log.exception( self.name + ": Uncaught exception!" )
4014 main.cleanup()
4015 main.exit()
4016
Jon Hall390696c2015-05-05 17:13:41 -07004017 def setTestAdd( self, setName, values ):
4018 """
4019 CLI command to add elements to a distributed set.
4020 Arguments:
4021 setName - The name of the set to add to.
4022 values - The value(s) to add to the set, space seperated.
4023 Example usages:
4024 setTestAdd( "set1", "a b c" )
4025 setTestAdd( "set2", "1" )
4026 returns:
4027 main.TRUE on success OR
4028 main.FALSE if elements were already in the set OR
4029 main.ERROR on error
4030 """
4031 try:
4032 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004033 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004034 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4035 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004036 if re.search( positiveMatch, output):
4037 return main.TRUE
4038 elif re.search( negativeMatch, output):
4039 return main.FALSE
4040 else:
4041 main.log.error( self.name + ": setTestAdd did not" +
4042 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004043 main.log.debug( self.name + " actual: " + repr( output ) )
4044 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004045 except TypeError:
4046 main.log.exception( self.name + ": Object not as expected" )
4047 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004048 except Exception:
4049 main.log.exception( self.name + ": Uncaught exception!" )
4050 main.cleanup()
4051 main.exit()
4052
4053 def setTestRemove( self, setName, values, clear=False, retain=False ):
4054 """
4055 CLI command to remove elements from a distributed set.
4056 Required arguments:
4057 setName - The name of the set to remove from.
4058 values - The value(s) to remove from the set, space seperated.
4059 Optional arguments:
4060 clear - Clear all elements from the set
4061 retain - Retain only the given values. (intersection of the
4062 original set and the given set)
4063 returns:
4064 main.TRUE on success OR
4065 main.FALSE if the set was not changed OR
4066 main.ERROR on error
4067 """
4068 try:
4069 cmdStr = "set-test-remove "
4070 if clear:
4071 cmdStr += "-c " + str( setName )
4072 elif retain:
4073 cmdStr += "-r " + str( setName ) + " " + str( values )
4074 else:
4075 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004076 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004077 if clear:
4078 pattern = "Set " + str( setName ) + " cleared"
4079 if re.search( pattern, output ):
4080 return main.TRUE
4081 elif retain:
4082 positivePattern = str( setName ) + " was pruned to contain " +\
4083 "only elements of set \[(.*)\]"
4084 negativePattern = str( setName ) + " was not changed by " +\
4085 "retaining only elements of the set " +\
4086 "\[(.*)\]"
4087 if re.search( positivePattern, output ):
4088 return main.TRUE
4089 elif re.search( negativePattern, output ):
4090 return main.FALSE
4091 else:
4092 positivePattern = "\[(.*)\] was removed from the set " +\
4093 str( setName )
4094 if ( len( values.split() ) == 1 ):
4095 negativePattern = "\[(.*)\] was not in set " +\
4096 str( setName )
4097 else:
4098 negativePattern = "No element of \[(.*)\] was in set " +\
4099 str( setName )
4100 if re.search( positivePattern, output ):
4101 return main.TRUE
4102 elif re.search( negativePattern, output ):
4103 return main.FALSE
4104 main.log.error( self.name + ": setTestRemove did not" +
4105 " match expected output" )
4106 main.log.debug( self.name + " expected: " + pattern )
4107 main.log.debug( self.name + " actual: " + repr( output ) )
4108 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004109 except TypeError:
4110 main.log.exception( self.name + ": Object not as expected" )
4111 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004112 except Exception:
4113 main.log.exception( self.name + ": Uncaught exception!" )
4114 main.cleanup()
4115 main.exit()
4116
4117 def setTestGet( self, setName, values="" ):
4118 """
4119 CLI command to get the elements in a distributed set.
4120 Required arguments:
4121 setName - The name of the set to remove from.
4122 Optional arguments:
4123 values - The value(s) to check if in the set, space seperated.
4124 returns:
4125 main.ERROR on error OR
4126 A list of elements in the set if no optional arguments are
4127 supplied OR
4128 A tuple containing the list then:
4129 main.FALSE if the given values are not in the set OR
4130 main.TRUE if the given values are in the set OR
4131 """
4132 try:
4133 values = str( values ).strip()
4134 setName = str( setName ).strip()
4135 length = len( values.split() )
4136 containsCheck = None
4137 # Patterns to match
4138 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004139 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004140 containsTrue = "Set " + setName + " contains the value " + values
4141 containsFalse = "Set " + setName + " did not contain the value " +\
4142 values
4143 containsAllTrue = "Set " + setName + " contains the the subset " +\
4144 setPattern
4145 containsAllFalse = "Set " + setName + " did not contain the the" +\
4146 " subset " + setPattern
4147
4148 cmdStr = "set-test-get "
4149 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004150 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004151 if length == 0:
4152 match = re.search( pattern, output )
4153 else: # if given values
4154 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004155 patternTrue = pattern + "\r\n" + containsTrue
4156 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004157 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004158 patternTrue = pattern + "\r\n" + containsAllTrue
4159 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004160 matchTrue = re.search( patternTrue, output )
4161 matchFalse = re.search( patternFalse, output )
4162 if matchTrue:
4163 containsCheck = main.TRUE
4164 match = matchTrue
4165 elif matchFalse:
4166 containsCheck = main.FALSE
4167 match = matchFalse
4168 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004169 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004170 "expected output" )
4171 main.log.debug( self.name + " expected: " + pattern )
4172 main.log.debug( self.name + " actual: " + repr( output ) )
4173 match = None
4174 if match:
4175 setMatch = match.group( 1 )
4176 if setMatch == '':
4177 setList = []
4178 else:
4179 setList = setMatch.split( ", " )
4180 if length > 0:
4181 return ( setList, containsCheck )
4182 else:
4183 return setList
4184 else: # no match
4185 main.log.error( self.name + ": setTestGet did not" +
4186 " match expected output" )
4187 main.log.debug( self.name + " expected: " + pattern )
4188 main.log.debug( self.name + " actual: " + repr( output ) )
4189 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004190 except TypeError:
4191 main.log.exception( self.name + ": Object not as expected" )
4192 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004193 except Exception:
4194 main.log.exception( self.name + ": Uncaught exception!" )
4195 main.cleanup()
4196 main.exit()
4197
4198 def setTestSize( self, setName ):
4199 """
4200 CLI command to get the elements in a distributed set.
4201 Required arguments:
4202 setName - The name of the set to remove from.
4203 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004204 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004205 None on error
4206 """
4207 try:
4208 # TODO: Should this check against the number of elements returned
4209 # and then return true/false based on that?
4210 setName = str( setName ).strip()
4211 # Patterns to match
4212 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004213 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004214 setPattern
4215 cmdStr = "set-test-get -s "
4216 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004217 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004218 match = re.search( pattern, output )
4219 if match:
4220 setSize = int( match.group( 1 ) )
4221 setMatch = match.group( 2 )
4222 if len( setMatch.split() ) == setSize:
4223 main.log.info( "The size returned by " + self.name +
4224 " matches the number of elements in " +
4225 "the returned set" )
4226 else:
4227 main.log.error( "The size returned by " + self.name +
4228 " does not match the number of " +
4229 "elements in the returned set." )
4230 return setSize
4231 else: # no match
4232 main.log.error( self.name + ": setTestGet did not" +
4233 " match expected output" )
4234 main.log.debug( self.name + " expected: " + pattern )
4235 main.log.debug( self.name + " actual: " + repr( output ) )
4236 return None
Jon Hall390696c2015-05-05 17:13:41 -07004237 except TypeError:
4238 main.log.exception( self.name + ": Object not as expected" )
4239 return None
Jon Hall390696c2015-05-05 17:13:41 -07004240 except Exception:
4241 main.log.exception( self.name + ": Uncaught exception!" )
4242 main.cleanup()
4243 main.exit()
4244
Jon Hall80daded2015-05-27 16:07:00 -07004245 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004246 """
4247 Command to list the various counters in the system.
4248 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004249 if jsonFormat, a string of the json object returned by the cli
4250 command
4251 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004252 None on error
4253 """
Jon Hall390696c2015-05-05 17:13:41 -07004254 try:
Jon Hall390696c2015-05-05 17:13:41 -07004255 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004256 if jsonFormat:
4257 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004258 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004259 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004260 assert "Command not found:" not in output, output
4261 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004262 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004263 return output
Jon Hall390696c2015-05-05 17:13:41 -07004264 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004265 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004266 return None
Jon Hall390696c2015-05-05 17:13:41 -07004267 except TypeError:
4268 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004269 return None
Jon Hall390696c2015-05-05 17:13:41 -07004270 except pexpect.EOF:
4271 main.log.error( self.name + ": EOF exception found" )
4272 main.log.error( self.name + ": " + self.handle.before )
4273 main.cleanup()
4274 main.exit()
4275 except Exception:
4276 main.log.exception( self.name + ": Uncaught exception!" )
4277 main.cleanup()
4278 main.exit()
4279
Jon Hall935db192016-04-19 00:22:04 -07004280 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004281 """
Jon Halle1a3b752015-07-22 13:02:46 -07004282 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004283 Required arguments:
4284 counter - The name of the counter to increment.
4285 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004286 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004287 returns:
4288 integer value of the counter or
4289 None on Error
4290 """
4291 try:
4292 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004293 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004294 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004295 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004296 if delta != 1:
4297 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004298 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004299 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004300 match = re.search( pattern, output )
4301 if match:
4302 return int( match.group( 1 ) )
4303 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004304 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004305 " match expected output." )
4306 main.log.debug( self.name + " expected: " + pattern )
4307 main.log.debug( self.name + " actual: " + repr( output ) )
4308 return None
Jon Hall390696c2015-05-05 17:13:41 -07004309 except TypeError:
4310 main.log.exception( self.name + ": Object not as expected" )
4311 return None
Jon Hall390696c2015-05-05 17:13:41 -07004312 except Exception:
4313 main.log.exception( self.name + ": Uncaught exception!" )
4314 main.cleanup()
4315 main.exit()
4316
Jon Hall935db192016-04-19 00:22:04 -07004317 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004318 """
4319 CLI command to get a distributed counter then add a delta to it.
4320 Required arguments:
4321 counter - The name of the counter to increment.
4322 Optional arguments:
4323 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004324 returns:
4325 integer value of the counter or
4326 None on Error
4327 """
4328 try:
4329 counter = str( counter )
4330 delta = int( delta )
4331 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004332 cmdStr += counter
4333 if delta != 1:
4334 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004335 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004336 pattern = counter + " was updated to (-?\d+)"
4337 match = re.search( pattern, output )
4338 if match:
4339 return int( match.group( 1 ) )
4340 else:
4341 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4342 " match expected output." )
4343 main.log.debug( self.name + " expected: " + pattern )
4344 main.log.debug( self.name + " actual: " + repr( output ) )
4345 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004346 except TypeError:
4347 main.log.exception( self.name + ": Object not as expected" )
4348 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004349 except Exception:
4350 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004351 main.cleanup()
4352 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004353
4354 def valueTestGet( self, valueName ):
4355 """
4356 CLI command to get the value of an atomic value.
4357 Required arguments:
4358 valueName - The name of the value to get.
4359 returns:
4360 string value of the value or
4361 None on Error
4362 """
4363 try:
4364 valueName = str( valueName )
4365 cmdStr = "value-test "
4366 operation = "get"
4367 cmdStr = "value-test {} {}".format( valueName,
4368 operation )
4369 output = self.distPrimitivesSend( cmdStr )
4370 pattern = "(\w+)"
4371 match = re.search( pattern, output )
4372 if match:
4373 return match.group( 1 )
4374 else:
4375 main.log.error( self.name + ": valueTestGet did not" +
4376 " match expected output." )
4377 main.log.debug( self.name + " expected: " + pattern )
4378 main.log.debug( self.name + " actual: " + repr( output ) )
4379 return None
4380 except TypeError:
4381 main.log.exception( self.name + ": Object not as expected" )
4382 return None
4383 except Exception:
4384 main.log.exception( self.name + ": Uncaught exception!" )
4385 main.cleanup()
4386 main.exit()
4387
4388 def valueTestSet( self, valueName, newValue ):
4389 """
4390 CLI command to set the value of an atomic value.
4391 Required arguments:
4392 valueName - The name of the value to set.
4393 newValue - The value to assign to the given value.
4394 returns:
4395 main.TRUE on success or
4396 main.ERROR on Error
4397 """
4398 try:
4399 valueName = str( valueName )
4400 newValue = str( newValue )
4401 operation = "set"
4402 cmdStr = "value-test {} {} {}".format( valueName,
4403 operation,
4404 newValue )
4405 output = self.distPrimitivesSend( cmdStr )
4406 if output is not None:
4407 return main.TRUE
4408 else:
4409 return main.ERROR
4410 except TypeError:
4411 main.log.exception( self.name + ": Object not as expected" )
4412 return main.ERROR
4413 except Exception:
4414 main.log.exception( self.name + ": Uncaught exception!" )
4415 main.cleanup()
4416 main.exit()
4417
4418 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4419 """
4420 CLI command to compareAndSet the value of an atomic value.
4421 Required arguments:
4422 valueName - The name of the value.
4423 oldValue - Compare the current value of the atomic value to this
4424 newValue - If the value equals oldValue, set the value to newValue
4425 returns:
4426 main.TRUE on success or
4427 main.FALSE on failure or
4428 main.ERROR on Error
4429 """
4430 try:
4431 valueName = str( valueName )
4432 oldValue = str( oldValue )
4433 newValue = str( newValue )
4434 operation = "compareAndSet"
4435 cmdStr = "value-test {} {} {} {}".format( valueName,
4436 operation,
4437 oldValue,
4438 newValue )
4439 output = self.distPrimitivesSend( cmdStr )
4440 pattern = "(\w+)"
4441 match = re.search( pattern, output )
4442 if match:
4443 result = match.group( 1 )
4444 if result == "true":
4445 return main.TRUE
4446 elif result == "false":
4447 return main.FALSE
4448 else:
4449 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4450 " match expected output." )
4451 main.log.debug( self.name + " expected: " + pattern )
4452 main.log.debug( self.name + " actual: " + repr( output ) )
4453 return main.ERROR
4454 except TypeError:
4455 main.log.exception( self.name + ": Object not as expected" )
4456 return main.ERROR
4457 except Exception:
4458 main.log.exception( self.name + ": Uncaught exception!" )
4459 main.cleanup()
4460 main.exit()
4461
4462 def valueTestGetAndSet( self, valueName, newValue ):
4463 """
4464 CLI command to getAndSet the value of an atomic value.
4465 Required arguments:
4466 valueName - The name of the value to get.
4467 newValue - The value to assign to the given value
4468 returns:
4469 string value of the value or
4470 None on Error
4471 """
4472 try:
4473 valueName = str( valueName )
4474 cmdStr = "value-test "
4475 operation = "getAndSet"
4476 cmdStr += valueName + " " + operation
4477 cmdStr = "value-test {} {} {}".format( valueName,
4478 operation,
4479 newValue )
4480 output = self.distPrimitivesSend( cmdStr )
4481 pattern = "(\w+)"
4482 match = re.search( pattern, output )
4483 if match:
4484 return match.group( 1 )
4485 else:
4486 main.log.error( self.name + ": valueTestGetAndSet did not" +
4487 " match expected output." )
4488 main.log.debug( self.name + " expected: " + pattern )
4489 main.log.debug( self.name + " actual: " + repr( output ) )
4490 return None
4491 except TypeError:
4492 main.log.exception( self.name + ": Object not as expected" )
4493 return None
4494 except Exception:
4495 main.log.exception( self.name + ": Uncaught exception!" )
4496 main.cleanup()
4497 main.exit()
4498
4499 def valueTestDestroy( self, valueName ):
4500 """
4501 CLI command to destroy an atomic value.
4502 Required arguments:
4503 valueName - The name of the value to destroy.
4504 returns:
4505 main.TRUE on success or
4506 main.ERROR on Error
4507 """
4508 try:
4509 valueName = str( valueName )
4510 cmdStr = "value-test "
4511 operation = "destroy"
4512 cmdStr += valueName + " " + operation
4513 output = self.distPrimitivesSend( cmdStr )
4514 if output is not None:
4515 return main.TRUE
4516 else:
4517 return main.ERROR
4518 except TypeError:
4519 main.log.exception( self.name + ": Object not as expected" )
4520 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004521 except Exception:
4522 main.log.exception( self.name + ": Uncaught exception!" )
4523 main.cleanup()
4524 main.exit()
4525
YPZhangfebf7302016-05-24 16:45:56 -07004526 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004527 """
4528 Description: Execute summary command in onos
4529 Returns: json object ( summary -j ), returns main.FALSE if there is
4530 no output
4531
4532 """
4533 try:
4534 cmdStr = "summary"
4535 if jsonFormat:
4536 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004537 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004538 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004539 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004540 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004541 if not handle:
4542 main.log.error( self.name + ": There is no output in " +
4543 "summary command" )
4544 return main.FALSE
4545 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004546 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004547 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004548 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004549 except TypeError:
4550 main.log.exception( self.name + ": Object not as expected" )
4551 return None
4552 except pexpect.EOF:
4553 main.log.error( self.name + ": EOF exception found" )
4554 main.log.error( self.name + ": " + self.handle.before )
4555 main.cleanup()
4556 main.exit()
4557 except Exception:
4558 main.log.exception( self.name + ": Uncaught exception!" )
4559 main.cleanup()
4560 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004561
Jon Hall935db192016-04-19 00:22:04 -07004562 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004563 """
4564 CLI command to get the value of a key in a consistent map using
4565 transactions. This a test function and can only get keys from the
4566 test map hard coded into the cli command
4567 Required arguments:
4568 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004569 returns:
4570 The string value of the key or
4571 None on Error
4572 """
4573 try:
4574 keyName = str( keyName )
4575 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004576 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004577 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004578 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4579 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004580 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004581 return None
4582 else:
4583 match = re.search( pattern, output )
4584 if match:
4585 return match.groupdict()[ 'value' ]
4586 else:
4587 main.log.error( self.name + ": transactionlMapGet did not" +
4588 " match expected output." )
4589 main.log.debug( self.name + " expected: " + pattern )
4590 main.log.debug( self.name + " actual: " + repr( output ) )
4591 return None
4592 except TypeError:
4593 main.log.exception( self.name + ": Object not as expected" )
4594 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004595 except Exception:
4596 main.log.exception( self.name + ": Uncaught exception!" )
4597 main.cleanup()
4598 main.exit()
4599
Jon Hall935db192016-04-19 00:22:04 -07004600 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004601 """
4602 CLI command to put a value into 'numKeys' number of keys in a
4603 consistent map using transactions. This a test function and can only
4604 put into keys named 'Key#' of the test map hard coded into the cli command
4605 Required arguments:
4606 numKeys - Number of keys to add the value to
4607 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004608 returns:
4609 A dictionary whose keys are the name of the keys put into the map
4610 and the values of the keys are dictionaries whose key-values are
4611 'value': value put into map and optionaly
4612 'oldValue': Previous value in the key or
4613 None on Error
4614
4615 Example output
4616 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4617 'Key2': {'value': 'Testing'} }
4618 """
4619 try:
4620 numKeys = str( numKeys )
4621 value = str( value )
4622 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004623 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004624 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004625 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4626 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4627 results = {}
4628 for line in output.splitlines():
4629 new = re.search( newPattern, line )
4630 updated = re.search( updatedPattern, line )
4631 if new:
4632 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4633 elif updated:
4634 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004635 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004636 else:
4637 main.log.error( self.name + ": transactionlMapGet did not" +
4638 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004639 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4640 newPattern,
4641 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004642 main.log.debug( self.name + " actual: " + repr( output ) )
4643 return results
4644 except TypeError:
4645 main.log.exception( self.name + ": Object not as expected" )
4646 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004647 except Exception:
4648 main.log.exception( self.name + ": Uncaught exception!" )
4649 main.cleanup()
4650 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004651
acsmarsdaea66c2015-09-03 11:44:06 -07004652 def maps( self, jsonFormat=True ):
4653 """
4654 Description: Returns result of onos:maps
4655 Optional:
4656 * jsonFormat: enable json formatting of output
4657 """
4658 try:
4659 cmdStr = "maps"
4660 if jsonFormat:
4661 cmdStr += " -j"
4662 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004663 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004664 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004665 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004666 except AssertionError:
4667 main.log.exception( "" )
4668 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004669 except TypeError:
4670 main.log.exception( self.name + ": Object not as expected" )
4671 return None
4672 except pexpect.EOF:
4673 main.log.error( self.name + ": EOF exception found" )
4674 main.log.error( self.name + ": " + self.handle.before )
4675 main.cleanup()
4676 main.exit()
4677 except Exception:
4678 main.log.exception( self.name + ": Uncaught exception!" )
4679 main.cleanup()
4680 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004681
4682 def getSwController( self, uri, jsonFormat=True ):
4683 """
4684 Descrition: Gets the controller information from the device
4685 """
4686 try:
4687 cmd = "device-controllers "
4688 if jsonFormat:
4689 cmd += "-j "
4690 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004691 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004692 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004693 return response
Jon Hallc6793552016-01-19 14:18:37 -08004694 except AssertionError:
4695 main.log.exception( "" )
4696 return None
GlennRC050596c2015-11-18 17:06:41 -08004697 except TypeError:
4698 main.log.exception( self.name + ": Object not as expected" )
4699 return None
4700 except pexpect.EOF:
4701 main.log.error( self.name + ": EOF exception found" )
4702 main.log.error( self.name + ": " + self.handle.before )
4703 main.cleanup()
4704 main.exit()
4705 except Exception:
4706 main.log.exception( self.name + ": Uncaught exception!" )
4707 main.cleanup()
4708 main.exit()
4709
4710 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4711 """
4712 Descrition: sets the controller(s) for the specified device
4713
4714 Parameters:
4715 Required: uri - String: The uri of the device(switch).
4716 ip - String or List: The ip address of the controller.
4717 This parameter can be formed in a couple of different ways.
4718 VALID:
4719 10.0.0.1 - just the ip address
4720 tcp:10.0.0.1 - the protocol and the ip address
4721 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4722 so that you can add controllers with different
4723 protocols and ports
4724 INVALID:
4725 10.0.0.1:6653 - this is not supported by ONOS
4726
4727 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4728 port - The port number.
4729 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4730
4731 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4732 """
4733 try:
4734 cmd = "device-setcontrollers"
4735
4736 if jsonFormat:
4737 cmd += " -j"
4738 cmd += " " + uri
4739 if isinstance( ip, str ):
4740 ip = [ip]
4741 for item in ip:
4742 if ":" in item:
4743 sitem = item.split( ":" )
4744 if len(sitem) == 3:
4745 cmd += " " + item
4746 elif "." in sitem[1]:
4747 cmd += " {}:{}".format(item, port)
4748 else:
4749 main.log.error( "Malformed entry: " + item )
4750 raise TypeError
4751 else:
4752 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004753 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004754 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004755 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004756 if "Error" in response:
4757 main.log.error( response )
4758 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004759 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004760 except AssertionError:
4761 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004762 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004763 except TypeError:
4764 main.log.exception( self.name + ": Object not as expected" )
4765 return main.FALSE
4766 except pexpect.EOF:
4767 main.log.error( self.name + ": EOF exception found" )
4768 main.log.error( self.name + ": " + self.handle.before )
4769 main.cleanup()
4770 main.exit()
4771 except Exception:
4772 main.log.exception( self.name + ": Uncaught exception!" )
4773 main.cleanup()
4774 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004775
4776 def removeDevice( self, device ):
4777 '''
4778 Description:
4779 Remove a device from ONOS by passing the uri of the device(s).
4780 Parameters:
4781 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4782 Returns:
4783 Returns main.FALSE if an exception is thrown or an error is present
4784 in the response. Otherwise, returns main.TRUE.
4785 NOTE:
4786 If a host cannot be removed, then this function will return main.FALSE
4787 '''
4788 try:
4789 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004790 deviceStr = device
4791 device = []
4792 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004793
4794 for d in device:
4795 time.sleep( 1 )
4796 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004797 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004798 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004799 if "Error" in response:
4800 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4801 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004802 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004803 except AssertionError:
4804 main.log.exception( "" )
4805 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004806 except TypeError:
4807 main.log.exception( self.name + ": Object not as expected" )
4808 return main.FALSE
4809 except pexpect.EOF:
4810 main.log.error( self.name + ": EOF exception found" )
4811 main.log.error( self.name + ": " + self.handle.before )
4812 main.cleanup()
4813 main.exit()
4814 except Exception:
4815 main.log.exception( self.name + ": Uncaught exception!" )
4816 main.cleanup()
4817 main.exit()
4818
4819 def removeHost( self, host ):
4820 '''
4821 Description:
4822 Remove a host from ONOS by passing the id of the host(s)
4823 Parameters:
4824 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4825 Returns:
4826 Returns main.FALSE if an exception is thrown or an error is present
4827 in the response. Otherwise, returns main.TRUE.
4828 NOTE:
4829 If a host cannot be removed, then this function will return main.FALSE
4830 '''
4831 try:
4832 if type( host ) is str:
4833 host = list( host )
4834
4835 for h in host:
4836 time.sleep( 1 )
4837 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004838 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004839 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004840 if "Error" in response:
4841 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4842 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004843 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004844 except AssertionError:
4845 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004846 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004847 except TypeError:
4848 main.log.exception( self.name + ": Object not as expected" )
4849 return main.FALSE
4850 except pexpect.EOF:
4851 main.log.error( self.name + ": EOF exception found" )
4852 main.log.error( self.name + ": " + self.handle.before )
4853 main.cleanup()
4854 main.exit()
4855 except Exception:
4856 main.log.exception( self.name + ": Uncaught exception!" )
4857 main.cleanup()
4858 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004859
YPZhangfebf7302016-05-24 16:45:56 -07004860 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004861 '''
4862 Description:
4863 Bring link down or up in the null-provider.
4864 params:
4865 begin - (string) One end of a device or switch.
4866 end - (string) the other end of the device or switch
4867 returns:
4868 main.TRUE if no exceptions were thrown and no Errors are
4869 present in the resoponse. Otherwise, returns main.FALSE
4870 '''
4871 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004872 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004873 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004874 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004875 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004876 if "Error" in response or "Failure" in response:
4877 main.log.error( response )
4878 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004879 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004880 except AssertionError:
4881 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004882 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004883 except TypeError:
4884 main.log.exception( self.name + ": Object not as expected" )
4885 return main.FALSE
4886 except pexpect.EOF:
4887 main.log.error( self.name + ": EOF exception found" )
4888 main.log.error( self.name + ": " + self.handle.before )
4889 main.cleanup()
4890 main.exit()
4891 except Exception:
4892 main.log.exception( self.name + ": Uncaught exception!" )
4893 main.cleanup()
4894 main.exit()
4895
Jon Hall2c8959e2016-12-16 12:17:34 -08004896 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004897 '''
4898 Description:
4899 Changes the state of port in an OF switch by means of the
4900 PORTSTATUS OF messages.
4901 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004902 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4903 port - (string) target port in the device. Ex: '2'
4904 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004905 returns:
4906 main.TRUE if no exceptions were thrown and no Errors are
4907 present in the resoponse. Otherwise, returns main.FALSE
4908 '''
4909 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004910 state = state.lower()
4911 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004912 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004913 response = self.sendline( cmd, showResponse=True )
4914 assert response is not None, "Error in sendline"
4915 assert "Command not found:" not in response, response
4916 if "Error" in response or "Failure" in response:
4917 main.log.error( response )
4918 return main.FALSE
4919 return main.TRUE
4920 except AssertionError:
4921 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004922 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004923 except TypeError:
4924 main.log.exception( self.name + ": Object not as expected" )
4925 return main.FALSE
4926 except pexpect.EOF:
4927 main.log.error( self.name + ": EOF exception found" )
4928 main.log.error( self.name + ": " + self.handle.before )
4929 main.cleanup()
4930 main.exit()
4931 except Exception:
4932 main.log.exception( self.name + ": Uncaught exception!" )
4933 main.cleanup()
4934 main.exit()
4935
4936 def logSet( self, level="INFO", app="org.onosproject" ):
4937 """
4938 Set the logging level to lvl for a specific app
4939 returns main.TRUE on success
4940 returns main.FALSE if Error occurred
4941 if noExit is True, TestON will not exit, but clean up
4942 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4943 Level defaults to INFO
4944 """
4945 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004946 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004947 self.handle.expect( "onos>" )
4948
4949 response = self.handle.before
4950 if re.search( "Error", response ):
4951 return main.FALSE
4952 return main.TRUE
4953 except pexpect.TIMEOUT:
4954 main.log.exception( self.name + ": TIMEOUT exception found" )
4955 main.cleanup()
4956 main.exit()
4957 except pexpect.EOF:
4958 main.log.error( self.name + ": EOF exception found" )
4959 main.log.error( self.name + ": " + self.handle.before )
4960 main.cleanup()
4961 main.exit()
4962 except Exception:
4963 main.log.exception( self.name + ": Uncaught exception!" )
4964 main.cleanup()
4965 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004966
4967 def getGraphDict( self, timeout=60, includeHost=False ):
4968 """
4969 Return a dictionary which describes the latest network topology data as a
4970 graph.
4971 An example of the dictionary:
4972 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4973 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4974 Each vertex should at least have an 'edges' attribute which describes the
4975 adjacency information. The value of 'edges' attribute is also represented by
4976 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4977 list of attributes.
4978 An example of the edges dictionary:
4979 'edges': { vertex2: { 'port': ..., 'weight': ... },
4980 vertex3: { 'port': ..., 'weight': ... } }
4981 If includeHost == True, all hosts (and host-switch links) will be included
4982 in topology data.
4983 """
4984 graphDict = {}
4985 try:
4986 links = self.links()
4987 links = json.loads( links )
4988 devices = self.devices()
4989 devices = json.loads( devices )
4990 idToDevice = {}
4991 for device in devices:
4992 idToDevice[ device[ 'id' ] ] = device
4993 if includeHost:
4994 hosts = self.hosts()
4995 # FIXME: support 'includeHost' argument
4996 for link in links:
4997 nodeA = link[ 'src' ][ 'device' ]
4998 nodeB = link[ 'dst' ][ 'device' ]
4999 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005000 if nodeA not in graphDict.keys():
5001 graphDict[ nodeA ] = { 'edges': {},
5002 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5003 'type': idToDevice[ nodeA ][ 'type' ],
5004 'available': idToDevice[ nodeA ][ 'available' ],
5005 'role': idToDevice[ nodeA ][ 'role' ],
5006 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5007 'hw': idToDevice[ nodeA ][ 'hw' ],
5008 'sw': idToDevice[ nodeA ][ 'sw' ],
5009 'serial': idToDevice[ nodeA ][ 'serial' ],
5010 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5011 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005012 else:
5013 # Assert nodeB is not connected to any current links of nodeA
5014 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005015 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5016 'type': link[ 'type' ],
5017 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005018 return graphDict
5019 except ( TypeError, ValueError ):
5020 main.log.exception( self.name + ": Object not as expected" )
5021 return None
5022 except KeyError:
5023 main.log.exception( self.name + ": KeyError exception found" )
5024 return None
5025 except AssertionError:
5026 main.log.exception( self.name + ": AssertionError exception found" )
5027 return None
5028 except pexpect.EOF:
5029 main.log.error( self.name + ": EOF exception found" )
5030 main.log.error( self.name + ": " + self.handle.before )
5031 return None
5032 except Exception:
5033 main.log.exception( self.name + ": Uncaught exception!" )
5034 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005035
5036 def getIntentPerfSummary( self ):
5037 '''
5038 Send command to check intent-perf summary
5039 Returns: dictionary for intent-perf summary
5040 if something wrong, function will return None
5041 '''
5042 cmd = "intent-perf -s"
5043 respDic = {}
5044 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005045 assert resp is not None, "Error in sendline"
5046 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005047 try:
5048 # Generate the dictionary to return
5049 for l in resp.split( "\n" ):
5050 # Delete any white space in line
5051 temp = re.sub( r'\s+', '', l )
5052 temp = temp.split( ":" )
5053 respDic[ temp[0] ] = temp[ 1 ]
5054
5055 except (TypeError, ValueError):
5056 main.log.exception( self.name + ": Object not as expected" )
5057 return None
5058 except KeyError:
5059 main.log.exception( self.name + ": KeyError exception found" )
5060 return None
5061 except AssertionError:
5062 main.log.exception( self.name + ": AssertionError exception found" )
5063 return None
5064 except pexpect.EOF:
5065 main.log.error( self.name + ": EOF exception found" )
5066 main.log.error( self.name + ": " + self.handle.before )
5067 return None
5068 except Exception:
5069 main.log.exception( self.name + ": Uncaught exception!" )
5070 return None
5071 return respDic
5072
Chiyu Chengec63bde2016-11-17 18:11:36 -08005073 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005074 """
5075 Searches the latest ONOS log file for the given search term and
5076 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005077
chengchiyu08303a02016-09-08 17:40:26 -07005078 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005079 searchTerm:
5080 The string to grep from the ONOS log.
5081 startLine:
5082 The term that decides which line is the start to search the searchTerm in
5083 the karaf log. For now, startTerm only works in 'first' mode.
5084 logNum:
5085 In some extreme cases, one karaf log is not big enough to contain all the
5086 information.Because of this, search mutiply logs is necessary to capture
5087 the right result. logNum is the number of karaf logs that we need to search
5088 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005089 mode:
5090 all: return all the strings that contain the search term
5091 last: return the last string that contains the search term
5092 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005093 num: return the number of times that the searchTerm appears in the log
5094 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005095 """
5096 try:
5097 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005098 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005099 logPath = '/opt/onos/log/karaf.log.'
5100 logPaths = '/opt/onos/log/karaf.log'
5101 for i in range( 1, logNum ):
5102 logPaths = logPath + str( i ) + " " + logPaths
5103 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005104 if startLine:
5105 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5106 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005107 if mode == 'all':
5108 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005109 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005110 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005111 elif mode == 'first':
5112 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5113 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005114 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005115 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005116 return num
You Wang6d301d42017-04-21 10:49:33 -07005117 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005118 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5119 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005120 else:
5121 main.log.error( self.name + " unsupported mode" )
5122 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005123 before = self.sendline( cmd )
5124 before = before.splitlines()
5125 # make sure the returned list only contains the search term
5126 returnLines = [line for line in before if searchTerm in line]
5127 return returnLines
5128 except AssertionError:
5129 main.log.error( self.name + " searchTerm is not string type" )
5130 return None
5131 except pexpect.EOF:
5132 main.log.error( self.name + ": EOF exception found" )
5133 main.log.error( self.name + ": " + self.handle.before )
5134 main.cleanup()
5135 main.exit()
5136 except pexpect.TIMEOUT:
5137 main.log.error( self.name + ": TIMEOUT exception found" )
5138 main.log.error( self.name + ": " + self.handle.before )
5139 main.cleanup()
5140 main.exit()
5141 except Exception:
5142 main.log.exception( self.name + ": Uncaught exception!" )
5143 main.cleanup()
5144 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005145
5146 def vplsShow( self, jsonFormat=True ):
5147 """
5148 Description: Returns result of onos:vpls show, which should list the
5149 configured VPLS networks and the assigned interfaces.
5150 Optional:
5151 * jsonFormat: enable json formatting of output
5152 Returns:
5153 The output of the command or None on error.
5154 """
5155 try:
5156 cmdStr = "vpls show"
5157 if jsonFormat:
5158 raise NotImplementedError
5159 cmdStr += " -j"
5160 handle = self.sendline( cmdStr )
5161 assert handle is not None, "Error in sendline"
5162 assert "Command not found:" not in handle, handle
5163 return handle
5164 except AssertionError:
5165 main.log.exception( "" )
5166 return None
5167 except TypeError:
5168 main.log.exception( self.name + ": Object not as expected" )
5169 return None
5170 except pexpect.EOF:
5171 main.log.error( self.name + ": EOF exception found" )
5172 main.log.error( self.name + ": " + self.handle.before )
5173 main.cleanup()
5174 main.exit()
5175 except NotImplementedError:
5176 main.log.exception( self.name + ": Json output not supported")
5177 return None
5178 except Exception:
5179 main.log.exception( self.name + ": Uncaught exception!" )
5180 main.cleanup()
5181 main.exit()
5182
5183 def parseVplsShow( self ):
5184 """
5185 Parse the cli output of 'vpls show' into json output. This is required
5186 as there is currently no json output available.
5187 """
5188 try:
5189 output = []
5190 raw = self.vplsShow( jsonFormat=False )
5191 namePat = "VPLS name: (?P<name>\w+)"
5192 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5193 encapPat = "Encapsulation: (?P<encap>\w+)"
5194 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5195 mIter = re.finditer( pattern, raw )
5196 for match in mIter:
5197 item = {}
5198 item[ 'name' ] = match.group( 'name' )
5199 ifaces = match.group( 'interfaces' ).split( ', ')
5200 if ifaces == [ "" ]:
5201 ifaces = []
5202 item[ 'interfaces' ] = ifaces
5203 encap = match.group( 'encap' )
5204 if encap != 'NONE':
5205 item[ 'encapsulation' ] = encap.lower()
5206 output.append( item )
5207 return output
5208 except Exception:
5209 main.log.exception( self.name + ": Uncaught exception!" )
5210 main.cleanup()
5211 main.exit()
5212
5213 def vplsList( self, jsonFormat=True ):
5214 """
5215 Description: Returns result of onos:vpls list, which should list the
5216 configured VPLS networks.
5217 Optional:
5218 * jsonFormat: enable json formatting of output
5219 """
5220 try:
5221 cmdStr = "vpls list"
5222 if jsonFormat:
5223 raise NotImplementedError
5224 cmdStr += " -j"
5225 handle = self.sendline( cmdStr )
5226 assert handle is not None, "Error in sendline"
5227 assert "Command not found:" not in handle, handle
5228 return handle
5229 except AssertionError:
5230 main.log.exception( "" )
5231 return None
5232 except TypeError:
5233 main.log.exception( self.name + ": Object not as expected" )
5234 return None
5235 except pexpect.EOF:
5236 main.log.error( self.name + ": EOF exception found" )
5237 main.log.error( self.name + ": " + self.handle.before )
5238 main.cleanup()
5239 main.exit()
5240 except NotImplementedError:
5241 main.log.exception( self.name + ": Json output not supported")
5242 return None
5243 except Exception:
5244 main.log.exception( self.name + ": Uncaught exception!" )
5245 main.cleanup()
5246 main.exit()
5247
5248 def vplsCreate( self, network ):
5249 """
5250 CLI command to create a new VPLS network.
5251 Required arguments:
5252 network - String name of the network to create.
5253 returns:
5254 main.TRUE on success and main.FALSE on failure
5255 """
5256 try:
5257 network = str( network )
5258 cmdStr = "vpls create "
5259 cmdStr += network
5260 output = self.sendline( cmdStr )
5261 assert output is not None, "Error in sendline"
5262 assert "Command not found:" not in output, output
5263 assert "Error executing command" not in output, output
5264 assert "VPLS already exists:" not in output, output
5265 return main.TRUE
5266 except AssertionError:
5267 main.log.exception( "" )
5268 return main.FALSE
5269 except TypeError:
5270 main.log.exception( self.name + ": Object not as expected" )
5271 return main.FALSE
5272 except pexpect.EOF:
5273 main.log.error( self.name + ": EOF exception found" )
5274 main.log.error( self.name + ": " + self.handle.before )
5275 main.cleanup()
5276 main.exit()
5277 except Exception:
5278 main.log.exception( self.name + ": Uncaught exception!" )
5279 main.cleanup()
5280 main.exit()
5281
5282 def vplsDelete( self, network ):
5283 """
5284 CLI command to delete a VPLS network.
5285 Required arguments:
5286 network - Name of the network to delete.
5287 returns:
5288 main.TRUE on success and main.FALSE on failure
5289 """
5290 try:
5291 network = str( network )
5292 cmdStr = "vpls delete "
5293 cmdStr += network
5294 output = self.sendline( cmdStr )
5295 assert output is not None, "Error in sendline"
5296 assert "Command not found:" not in output, output
5297 assert "Error executing command" not in output, output
5298 assert " not found" not in output, output
5299 return main.TRUE
5300 except AssertionError:
5301 main.log.exception( "" )
5302 return main.FALSE
5303 except TypeError:
5304 main.log.exception( self.name + ": Object not as expected" )
5305 return main.FALSE
5306 except pexpect.EOF:
5307 main.log.error( self.name + ": EOF exception found" )
5308 main.log.error( self.name + ": " + self.handle.before )
5309 main.cleanup()
5310 main.exit()
5311 except Exception:
5312 main.log.exception( self.name + ": Uncaught exception!" )
5313 main.cleanup()
5314 main.exit()
5315
5316 def vplsAddIface( self, network, iface ):
5317 """
5318 CLI command to add an interface to a VPLS network.
5319 Required arguments:
5320 network - Name of the network to add the interface to.
5321 iface - The ONOS name for an interface.
5322 returns:
5323 main.TRUE on success and main.FALSE on failure
5324 """
5325 try:
5326 network = str( network )
5327 iface = str( iface )
5328 cmdStr = "vpls add-if "
5329 cmdStr += network + " " + iface
5330 output = self.sendline( cmdStr )
5331 assert output is not None, "Error in sendline"
5332 assert "Command not found:" not in output, output
5333 assert "Error executing command" not in output, output
5334 assert "already associated to network" not in output, output
5335 assert "Interface cannot be added." not in output, output
5336 return main.TRUE
5337 except AssertionError:
5338 main.log.exception( "" )
5339 return main.FALSE
5340 except TypeError:
5341 main.log.exception( self.name + ": Object not as expected" )
5342 return main.FALSE
5343 except pexpect.EOF:
5344 main.log.error( self.name + ": EOF exception found" )
5345 main.log.error( self.name + ": " + self.handle.before )
5346 main.cleanup()
5347 main.exit()
5348 except Exception:
5349 main.log.exception( self.name + ": Uncaught exception!" )
5350 main.cleanup()
5351 main.exit()
5352
5353 def vplsRemIface( self, network, iface ):
5354 """
5355 CLI command to remove an interface from a VPLS network.
5356 Required arguments:
5357 network - Name of the network to remove the interface from.
5358 iface - Name of the interface to remove.
5359 returns:
5360 main.TRUE on success and main.FALSE on failure
5361 """
5362 try:
5363 iface = str( iface )
5364 cmdStr = "vpls rem-if "
5365 cmdStr += network + " " + iface
5366 output = self.sendline( cmdStr )
5367 assert output is not None, "Error in sendline"
5368 assert "Command not found:" not in output, output
5369 assert "Error executing command" not in output, output
5370 assert "is not configured" not in output, output
5371 return main.TRUE
5372 except AssertionError:
5373 main.log.exception( "" )
5374 return main.FALSE
5375 except TypeError:
5376 main.log.exception( self.name + ": Object not as expected" )
5377 return main.FALSE
5378 except pexpect.EOF:
5379 main.log.error( self.name + ": EOF exception found" )
5380 main.log.error( self.name + ": " + self.handle.before )
5381 main.cleanup()
5382 main.exit()
5383 except Exception:
5384 main.log.exception( self.name + ": Uncaught exception!" )
5385 main.cleanup()
5386 main.exit()
5387
5388 def vplsClean( self ):
5389 """
5390 Description: Clears the VPLS app configuration.
5391 Returns: main.TRUE on success and main.FALSE on failure
5392 """
5393 try:
5394 cmdStr = "vpls clean"
5395 handle = self.sendline( cmdStr )
5396 assert handle is not None, "Error in sendline"
5397 assert "Command not found:" not in handle, handle
5398 return handle
5399 except AssertionError:
5400 main.log.exception( "" )
5401 return main.FALSE
5402 except TypeError:
5403 main.log.exception( self.name + ": Object not as expected" )
5404 return main.FALSE
5405 except pexpect.EOF:
5406 main.log.error( self.name + ": EOF exception found" )
5407 main.log.error( self.name + ": " + self.handle.before )
5408 main.cleanup()
5409 main.exit()
5410 except Exception:
5411 main.log.exception( self.name + ": Uncaught exception!" )
5412 main.cleanup()
5413 main.exit()
5414
5415 def vplsSetEncap( self, network, encapType ):
5416 """
5417 CLI command to add an interface to a VPLS network.
5418 Required arguments:
5419 network - Name of the network to create.
5420 encapType - Type of encapsulation.
5421 returns:
5422 main.TRUE on success and main.FALSE on failure
5423 """
5424 try:
5425 network = str( network )
5426 encapType = str( encapType ).upper()
5427 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5428 cmdStr = "vpls set-encap "
5429 cmdStr += network + " " + encapType
5430 output = self.sendline( cmdStr )
5431 assert output is not None, "Error in sendline"
5432 assert "Command not found:" not in output, output
5433 assert "Error executing command" not in output, output
5434 assert "already associated to network" not in output, output
5435 assert "Encapsulation type " not in output, output
5436 return main.TRUE
5437 except AssertionError:
5438 main.log.exception( "" )
5439 return main.FALSE
5440 except TypeError:
5441 main.log.exception( self.name + ": Object not as expected" )
5442 return main.FALSE
5443 except pexpect.EOF:
5444 main.log.error( self.name + ": EOF exception found" )
5445 main.log.error( self.name + ": " + self.handle.before )
5446 main.cleanup()
5447 main.exit()
5448 except Exception:
5449 main.log.exception( self.name + ": Uncaught exception!" )
5450 main.cleanup()
5451 main.exit()
5452
5453 def interfaces( self, jsonFormat=True ):
5454 """
5455 Description: Returns result of interfaces command.
5456 Optional:
5457 * jsonFormat: enable json formatting of output
5458 Returns:
5459 The output of the command or None on error.
5460 """
5461 try:
5462 cmdStr = "interfaces"
5463 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005464 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005465 cmdStr += " -j"
5466 handle = self.sendline( cmdStr )
5467 assert handle is not None, "Error in sendline"
5468 assert "Command not found:" not in handle, handle
5469 return handle
5470 except AssertionError:
5471 main.log.exception( "" )
5472 return None
5473 except TypeError:
5474 main.log.exception( self.name + ": Object not as expected" )
5475 return None
5476 except pexpect.EOF:
5477 main.log.error( self.name + ": EOF exception found" )
5478 main.log.error( self.name + ": " + self.handle.before )
5479 main.cleanup()
5480 main.exit()
5481 except NotImplementedError:
5482 main.log.exception( self.name + ": Json output not supported")
5483 return None
5484 except Exception:
5485 main.log.exception( self.name + ": Uncaught exception!" )
5486 main.cleanup()
5487 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005488
5489 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5490 '''
5491 Get the timestamp of searchTerm from karaf log.
5492
5493 Arguments:
5494 splitTerm_before and splitTerm_after:
5495
5496 The terms that split the string that contains the timeStamp of
5497 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5498 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5499 and the splitTerm_after is "x"
5500
5501 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005502 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005503 '''
5504 if logNum < 0:
5505 main.log.error("Get wrong log number ")
5506 return main.ERROR
5507 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5508 if len(lines) == 0:
5509 main.log.warn( "Captured timestamp string is empty" )
5510 return main.ERROR
5511 lines = lines[ 0 ]
5512 try:
5513 assert type(lines) is str
5514 # get the target value
5515 line = lines.split( splitTerm_before )
5516 key = line[ 1 ].split( splitTerm_after )
5517 return int( key[ 0 ] )
5518 except IndexError:
5519 main.log.warn( "Index Error!" )
5520 return main.ERROR
5521 except AssertionError:
5522 main.log.warn( "Search Term Not Found " )
5523 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005524
5525 def workQueueAdd( self, queueName, value ):
5526 """
5527 CLI command to add a string to the specified Work Queue.
5528 This function uses the distributed primitives test app, which
5529 gives some cli access to distributed primitives for testing
5530 purposes only.
5531
5532 Required arguments:
5533 queueName - The name of the queue to add to
5534 value - The value to add to the queue
5535 returns:
5536 main.TRUE on success, main.FALSE on failure and
5537 main.ERROR on error.
5538 """
5539 try:
5540 queueName = str( queueName )
5541 value = str( value )
5542 prefix = "work-queue-test"
5543 operation = "add"
5544 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5545 output = self.distPrimitivesSend( cmdStr )
5546 if "Invalid operation name" in output:
5547 main.log.warn( output )
5548 return main.ERROR
5549 elif "Done" in output:
5550 return main.TRUE
5551 except TypeError:
5552 main.log.exception( self.name + ": Object not as expected" )
5553 return main.ERROR
5554 except Exception:
5555 main.log.exception( self.name + ": Uncaught exception!" )
5556 main.cleanup()
5557 main.exit()
5558
5559 def workQueueAddMultiple( self, queueName, value1, value2 ):
5560 """
5561 CLI command to add two strings to the specified Work Queue.
5562 This function uses the distributed primitives test app, which
5563 gives some cli access to distributed primitives for testing
5564 purposes only.
5565
5566 Required arguments:
5567 queueName - The name of the queue to add to
5568 value1 - The first value to add to the queue
5569 value2 - The second value to add to the queue
5570 returns:
5571 main.TRUE on success, main.FALSE on failure and
5572 main.ERROR on error.
5573 """
5574 try:
5575 queueName = str( queueName )
5576 value1 = str( value1 )
5577 value2 = str( value2 )
5578 prefix = "work-queue-test"
5579 operation = "addMultiple"
5580 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5581 output = self.distPrimitivesSend( cmdStr )
5582 if "Invalid operation name" in output:
5583 main.log.warn( output )
5584 return main.ERROR
5585 elif "Done" in output:
5586 return main.TRUE
5587 except TypeError:
5588 main.log.exception( self.name + ": Object not as expected" )
5589 return main.ERROR
5590 except Exception:
5591 main.log.exception( self.name + ": Uncaught exception!" )
5592 main.cleanup()
5593 main.exit()
5594
5595 def workQueueTakeAndComplete( self, queueName, number=1 ):
5596 """
5597 CLI command to take a value from the specified Work Queue and compelte it.
5598 This function uses the distributed primitives test app, which
5599 gives some cli access to distributed primitives for testing
5600 purposes only.
5601
5602 Required arguments:
5603 queueName - The name of the queue to add to
5604 number - The number of items to take and complete
5605 returns:
5606 main.TRUE on success, main.FALSE on failure and
5607 main.ERROR on error.
5608 """
5609 try:
5610 queueName = str( queueName )
5611 number = str( int( number ) )
5612 prefix = "work-queue-test"
5613 operation = "takeAndComplete"
5614 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5615 output = self.distPrimitivesSend( cmdStr )
5616 if "Invalid operation name" in output:
5617 main.log.warn( output )
5618 return main.ERROR
5619 elif "Done" in output:
5620 return main.TRUE
5621 except TypeError:
5622 main.log.exception( self.name + ": Object not as expected" )
5623 return main.ERROR
5624 except Exception:
5625 main.log.exception( self.name + ": Uncaught exception!" )
5626 main.cleanup()
5627 main.exit()
5628
5629 def workQueueDestroy( self, queueName ):
5630 """
5631 CLI command to destroy the specified Work Queue.
5632 This function uses the distributed primitives test app, which
5633 gives some cli access to distributed primitives for testing
5634 purposes only.
5635
5636 Required arguments:
5637 queueName - The name of the queue to add to
5638 returns:
5639 main.TRUE on success, main.FALSE on failure and
5640 main.ERROR on error.
5641 """
5642 try:
5643 queueName = str( queueName )
5644 prefix = "work-queue-test"
5645 operation = "destroy"
5646 cmdStr = " ".join( [ prefix, queueName, operation ] )
5647 output = self.distPrimitivesSend( cmdStr )
5648 if "Invalid operation name" in output:
5649 main.log.warn( output )
5650 return main.ERROR
5651 return main.TRUE
5652 except TypeError:
5653 main.log.exception( self.name + ": Object not as expected" )
5654 return main.ERROR
5655 except Exception:
5656 main.log.exception( self.name + ": Uncaught exception!" )
5657 main.cleanup()
5658 main.exit()
5659
5660 def workQueueTotalPending( self, queueName ):
5661 """
5662 CLI command to get the Total Pending items of the specified Work Queue.
5663 This function uses the distributed primitives test app, which
5664 gives some cli access to distributed primitives for testing
5665 purposes only.
5666
5667 Required arguments:
5668 queueName - The name of the queue to add to
5669 returns:
5670 The number of Pending items in the specified work queue or
5671 None on error
5672 """
5673 try:
5674 queueName = str( queueName )
5675 prefix = "work-queue-test"
5676 operation = "totalPending"
5677 cmdStr = " ".join( [ prefix, queueName, operation ] )
5678 output = self.distPrimitivesSend( cmdStr )
5679 pattern = r'\d+'
5680 if "Invalid operation name" in output:
5681 main.log.warn( output )
5682 return None
5683 else:
5684 match = re.search( pattern, output )
5685 return match.group(0)
5686 except ( AttributeError, TypeError ):
5687 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5688 return None
5689 except Exception:
5690 main.log.exception( self.name + ": Uncaught exception!" )
5691 main.cleanup()
5692 main.exit()
5693
5694 def workQueueTotalCompleted( self, queueName ):
5695 """
5696 CLI command to get the Total Completed items of the specified Work Queue.
5697 This function uses the distributed primitives test app, which
5698 gives some cli access to distributed primitives for testing
5699 purposes only.
5700
5701 Required arguments:
5702 queueName - The name of the queue to add to
5703 returns:
5704 The number of complete items in the specified work queue or
5705 None on error
5706 """
5707 try:
5708 queueName = str( queueName )
5709 prefix = "work-queue-test"
5710 operation = "totalCompleted"
5711 cmdStr = " ".join( [ prefix, queueName, operation ] )
5712 output = self.distPrimitivesSend( cmdStr )
5713 pattern = r'\d+'
5714 if "Invalid operation name" in output:
5715 main.log.warn( output )
5716 return None
5717 else:
5718 match = re.search( pattern, output )
5719 return match.group(0)
5720 except ( AttributeError, TypeError ):
5721 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5722 return None
5723 except Exception:
5724 main.log.exception( self.name + ": Uncaught exception!" )
5725 main.cleanup()
5726 main.exit()
5727
5728 def workQueueTotalInProgress( self, queueName ):
5729 """
5730 CLI command to get the Total In Progress items of the specified Work Queue.
5731 This function uses the distributed primitives test app, which
5732 gives some cli access to distributed primitives for testing
5733 purposes only.
5734
5735 Required arguments:
5736 queueName - The name of the queue to add to
5737 returns:
5738 The number of In Progress items in the specified work queue or
5739 None on error
5740 """
5741 try:
5742 queueName = str( queueName )
5743 prefix = "work-queue-test"
5744 operation = "totalInProgress"
5745 cmdStr = " ".join( [ prefix, queueName, operation ] )
5746 output = self.distPrimitivesSend( cmdStr )
5747 pattern = r'\d+'
5748 if "Invalid operation name" in output:
5749 main.log.warn( output )
5750 return None
5751 else:
5752 match = re.search( pattern, output )
5753 return match.group(0)
5754 except ( AttributeError, TypeError ):
5755 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5756 return None
5757 except Exception:
5758 main.log.exception( self.name + ": Uncaught exception!" )
5759 main.cleanup()
5760 main.exit()